From a3814d59e4340716f7dadc0308ea59606fd93d06 Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Sun, 5 Dec 2021 09:37:38 +0200 Subject: [PATCH 001/184] [mstflint] print not required error message when openssl version not supported Description: the fips module is not acctually required and is not part of the minimal version check. removed the mention of fips module from the massage Issue: 2872291 --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index e8ec4d4c..e2515b44 100644 --- a/configure.ac +++ b/configure.ac @@ -52,13 +52,13 @@ AC_PROG_LIBTOOL AC_CONFIG_HEADERS( config.h ) # OPENSSL_VERSION_NUMBER < 0x100020bf -#0x100020bfL = OpenSSL 1.0.2k-fips 26 Jan 2017 -MIN_OPENSSL_VER="1.0.2k-fips" +#0x100020bfL = OpenSSL 1.0.2k - 26 Jan 2017 +MIN_OPENSSL_VER="1.0.2k" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[ #include #if OPENSSL_VERSION_NUMBER < 0x100020bf - ERROR: OPENSSL_VERSION_NUMBER version must be >= 0x100020bf ("OpenSSL 1.0.2k-fips 26 Jan 2017") + ERROR: OPENSSL_VERSION_NUMBER version must be >= 0x100020bf ("OpenSSL 1.0.2k - 26 Jan 2017") #endif ]])], [OPENSSL_VERSION_VALID=yes], [OPENSSL_VERSION_VALID=no]) OS=$(uname -s) From a045344dabe3294bc9f748028bf76358dc28250f Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Wed, 8 Dec 2021 14:10:31 +0200 Subject: [PATCH 002/184] [mstlink] Supporting port access for downstream devices Description: Supporting port access for downstream devices which came with Spectrum-3 Issue: 2839979 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_commander.cpp | 227 +++++++++++++++++-- mlxlink/modules/mlxlink_commander.h | 33 +-- mlxlink/modules/mlxlink_enums.h | 2 + mlxlink/modules/mlxlink_ui.cpp | 9 +- mlxlink/modules/mlxlink_utils.cpp | 4 - mlxlink/modules/printutil/mlxlink_record.cpp | 1 - mlxlink/modules/printutil/mlxlink_record.h | 1 - 7 files changed, 233 insertions(+), 44 deletions(-) diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index 404253f0..fbded37d 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -77,6 +77,7 @@ MlxlinkCommander::MlxlinkCommander() : _userInput() _isPam4Speed = false; _ignorePortType = true; _ignorePortStatus = true; + _isGboxPort = false; _protoAdmin = 0; _protoAdminEx = 0; _speedBerCsv = 0; @@ -127,11 +128,55 @@ MlxlinkCommander::~MlxlinkCommander() } } +void MlxlinkCommander::updatePortType() +{ + if (!_isHCA) { + try { + updateField("port_type", _portType); + } catch (MlxRegException &exc) { + // Ignore updating the port type field if it's not exist + } + } +} + void MlxlinkCommander::validatePortType(const string &portTypeStr) { - if (portTypeStr != "NETWORK" && portTypeStr != "PCIE") { - throw MlxRegException( - "Please provide a valid Port Type [NETWORK(Default)/PCIE]"); + _portType = NETWORK_PORT_TYPE; + map::iterator it = + _mlxlinkMaps->_networkPorts.find(portTypeStr); + if (it == _mlxlinkMaps->_networkPorts.end()) { + string errMsg = ""; + for (it = _mlxlinkMaps->_networkPorts.begin(); + it != _mlxlinkMaps->_networkPorts.end(); it++) { + errMsg += it->first; + if (it->second == NETWORK_PORT_TYPE) { + errMsg += "(Default)"; + } + errMsg += ", "; + } + errMsg = deleteLastChar(errMsg, 2); + throw MlxRegException("Invalid port type, valid port types are [" + errMsg + "]"); + } else if (it->second != NETWORK_PORT_TYPE_LAST) { + _portType = it->second; + } + + if ((_portType == NETWORK_PORT_TYPE_NEAR) || + (_portType == NETWORK_PORT_TYPE_IC_LR) || + (_portType == NETWORK_PORT_TYPE_FAR)) { + _isGboxPort = true; + } + + if(_isGboxPort && !isDSdevice()) { + throw MlxRegException("Port types of GEARBOX_HOST, INTERNAL_IC_LR and "\ + "GEARBOX_LINE can be used with Switches supporting downstream devices only"); + } +} + +void MlxlinkCommander::gearboxBlock(const string &option) +{ + if (_isGboxPort) { + throw MlxRegException("--" + option + " flag is not applicable for " + + _userInput._portType + " port type"); } } @@ -320,6 +365,37 @@ void MlxlinkCommander::checkAllPortsStatus() } } +void MlxlinkCommander::validatePortToLC() +{ + bool isDownStreamDevValid = true; + string regName = "PMLP"; + resetParser(regName); + updateField("local_port", _localPort); + genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); + + u_int32_t slotIndex = getFieldValue("lane0_module_mapping.slot_index"); + + try { + regName = "MDDQ"; + resetParser(regName); + updateField("query_type", 1); //1 for slot query + updateField("slot_index", slotIndex); + genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); + } catch (MlxRegException &exc) { + isDownStreamDevValid = false; + } + + if (!isDownStreamDevValid) { + if (slotIndex == 0 && _isGboxPort) { + throw MlxRegException("No cards detected on the device."); + } + } else if (_isGboxPort) { + if (getFieldValue("lc_ready") != 1) { + throw MlxRegException("Invalid port number, Line card %d is not ready", slotIndex); + } + } +} + void MlxlinkCommander::handlePortStr(const string &portStr) { auto portParts = MlxlinkRecord::split(portStr, "/"); @@ -390,12 +466,72 @@ void MlxlinkCommander::labelToLocalPort() { if (_devID == DeviceSpectrum || _devID == DeviceSpectrum2 || _devID == DeviceSpectrum3 || _devID == DeviceSpectrum4) { - labelToSpectLocalPort(); + if (isDSdevice()) { + labeltoDSlocalPort(); + } else { + labelToSpectLocalPort(); + } } else if (dm_dev_is_ib_switch(_devID)) { labelToIBLocalPort(); } } +bool MlxlinkCommander::isDSdevice() +{ + bool isDownStreamDevValid = true; + + try { + resetParser(ACCESS_REG_MDDQ); + updateField("query_type", 1); + updateField("slot_index", 1); + genBuffSendRegister(ACCESS_REG_MDDQ, MACCESS_REG_METHOD_GET); + } catch (MlxRegException &exc) { + isDownStreamDevValid = false; + } + + return isDownStreamDevValid; +} + +void MlxlinkCommander::labeltoDSlocalPort() +{ + u_int32_t lineCard = _userInput._labelPort; + u_int32_t port = _userInput._splitPort; + bool isLocalPortValid = false; + + if (_userInput._secondSplitProvided) { + throw MlxRegException("No split supported for downstream devices"); + } + + for (u_int32_t localPort = 1 ; localPort <= maxLocalPort(); localPort++) { + resetParser(ACCESS_REG_PLLP); + updateField("local_port", localPort); + try { + genBuffSendRegister(ACCESS_REG_PLLP, MACCESS_REG_METHOD_GET); + } catch(MlxRegException &exp) { + continue; + } + + if ((getFieldValue("label_port") == port) && (getFieldValue("slot_num") == lineCard)) { + _localPort = localPort; + isLocalPortValid = true; + break; + } + } + + if (!isLocalPortValid) { + throw MlxRegException("Invalid port number"); + } + + resetParser(ACCESS_REG_MDDQ); + updateField("query_type", 1); + updateField("slot_index", lineCard); + genBuffSendRegister(ACCESS_REG_MDDQ, MACCESS_REG_METHOD_GET); + + if (getFieldValue("lc_ready") != 1) { + throw MlxRegException("Invalid port number, Line card %d is not ready", lineCard); + } +} + void MlxlinkCommander::checkLocalPortDPNMapping(u_int32_t localPort) { string regName = "MPIR"; @@ -768,18 +904,35 @@ bool MlxlinkCommander::inPrbsTestMode() return false; } -bool MlxlinkCommander::checkPaosDown() +bool MlxlinkCommander::checkGBPpaosDown() { - string regName = "PAOS"; + string regName = "PPAOS"; resetParser(regName); + updatePortType(); + updateField("swid", SWID); updateField("local_port", _localPort); genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); - u_int32_t paosOperStatus = getFieldValue("oper_status"); - if (paosOperStatus == PAOS_DOWN) { - return true; + + return getFieldValue("phy_status") != PAOS_UP; +} + +bool MlxlinkCommander::checkPaosDown() +{ + if (_isGboxPort) { + return checkGBPpaosDown(); + } else { + string regName = "PAOS"; + resetParser(regName); + updateField("swid", SWID); + updateField("local_port", _localPort); + genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); + u_int32_t paosOperStatus = getFieldValue("oper_status"); + if (paosOperStatus == PAOS_DOWN) { + return true; + } + return false; } - return false; } bool MlxlinkCommander::checkPpaosTestMode() @@ -1346,6 +1499,8 @@ void MlxlinkCommander::prepareBerModuleInfoNdr(bool valid) void MlxlinkCommander::showModuleInfo() { try { + gearboxBlock(MODULE_INFO_FLAG); + string regName = "PMAOS"; resetParser(regName); updateField("module", _moduleNumber); @@ -2418,6 +2573,7 @@ void MlxlinkCommander::showBerMonitorInfo() void MlxlinkCommander::showExternalPhy() { try { + gearboxBlock(PEPC_SHOW_FLAG); if (_isHCA || _devID == DeviceSwitchIB || _devID == DeviceSwitchIB2 || _devID == DeviceQuantum || _devID == DeviceQuantum2) { throw MlxRegException("\"--" PEPC_SHOW_FLAG "\" option is not supported for HCA and InfiniBand switches"); @@ -3160,22 +3316,47 @@ bool MlxlinkCommander::isForceDownSupported() return supported; } -void MlxlinkCommander::sendPaosCmd(PAOS_ADMIN adminStatus, bool forceDown) +void MlxlinkCommander::sendGBPaosCmd(PAOS_ADMIN adminStatus, bool forceDown) { try { - string regName = "PAOS"; + string regName = "PPAOS"; resetParser(regName); updateField("swid", SWID); + updatePortType(); updateField("local_port", _localPort); - updateField("admin_status", adminStatus); - updateField("ase", 1); - // Send force down for test mode only - if (!_userInput._prbsMode.empty()) { - if (forceDown) { - updateField("fd", 1); - } + updateField("phy_status_admin", adminStatus == PAOS_UP); + if (forceDown) { + updateField("fpd", forceDown); } + genBuffSendRegister(regName, MACCESS_REG_METHOD_SET); + } catch (const std::exception &exc) { + string portCommand = (adminStatus == PAOS_DOWN)? "down" : "up"; + throw MlxRegException( + "Sending port " + portCommand + " command failed, " + string(exc.what())); + } +} + +void MlxlinkCommander::sendPaosCmd(PAOS_ADMIN adminStatus, bool forceDown) +{ + try { + if (_isGboxPort) { + sendGBPaosCmd(adminStatus, forceDown); + } else { + string regName = "PAOS"; + resetParser(regName); + updateField("swid", SWID); + updateField("local_port", _localPort); + updateField("admin_status", adminStatus); + updateField("ase", 1); + // Send force down for test mode only + if (!_userInput._prbsMode.empty()) { + if (forceDown) { + updateField("fd", 1); + } + } + genBuffSendRegister(regName, MACCESS_REG_METHOD_SET); + } } catch (const std::exception &exc) { string portCommand = (adminStatus == PAOS_DOWN)? "down" : "up"; throw MlxRegException("Sending port " + portCommand + " command failed"); @@ -3573,6 +3754,7 @@ void MlxlinkCommander::sendPtys() ptysMask |= ptysSpeedToMask(_ptysSpeeds[i]); } if (_linkModeForce == true) { + gearboxBlock(PTYS_LINK_MODE_FORCE_FLAG); updateField("an_disable_admin", 1); } if (_protoActive == IB) { @@ -4037,6 +4219,8 @@ u_int32_t MlxlinkCommander::getLoopbackMode(const string &lb) void MlxlinkCommander::sendPepc() { try { + gearboxBlock(PEPC_SET_FLAG); + if (_isHCA || _devID == DeviceSwitchIB || _devID == DeviceSwitchIB2 || _devID == DeviceQuantum || _devID == DeviceQuantum2) { throw MlxRegException("\"--" PEPC_SET_FLAG "\" option is not supported for HCA and InfiniBand switches"); @@ -4164,6 +4348,8 @@ void MlxlinkCommander::printOuptputVector(vector &cmdOut) void MlxlinkCommander::initCablesCommander() { + gearboxBlock(CABLE_FLAG); + if (_plugged && !_mngCableUnplugged) { _cablesCommander = new MlxlinkCablesCommander(_jsonRoot); _cablesCommander->_mf = _mf; @@ -4256,6 +4442,7 @@ void MlxlinkCommander::readCableEEPROM() void MlxlinkCommander::initEyeOpener() { try { + gearboxBlock(MARGIN_SCAN_FLAG); if (_linkUP || _userInput._pcie) { _eyeOpener = new MlxlinkEyeOpener(_jsonRoot); _eyeOpener->_mf = _mf; @@ -4298,6 +4485,8 @@ void MlxlinkCommander::initEyeOpener() void MlxlinkCommander::initErrInj() { try { + gearboxBlock(PREI_RX_ERR_INJ_FLAG); + if (!_isHCA) { throw MlxRegException("This feature supporting NIC's only"); } diff --git a/mlxlink/modules/mlxlink_commander.h b/mlxlink/modules/mlxlink_commander.h index 71b351d1..88a194a1 100644 --- a/mlxlink/modules/mlxlink_commander.h +++ b/mlxlink/modules/mlxlink_commander.h @@ -305,8 +305,10 @@ class MlxlinkCommander: public MlxlinkRegParser { virtual ~MlxlinkCommander(); void checkRegCmd(); - virtual void validatePortType(const string &portTypeStr); - void updatePortType() {}; + void validatePortToLC(); + void validatePortType(const string &portTypeStr); + void updatePortType(); + void gearboxBlock(const string &option); void checkLocalPortDPNMapping(u_int32_t localPort); int getLocalPortFromMPIR(DPN& dpn); void checkValidFW(); @@ -316,6 +318,8 @@ class MlxlinkCommander: public MlxlinkRegParser { void handlePortStr(const string &portStr); void labelToLocalPort(); void labelToHCALocalPort(); + void labeltoDSlocalPort(); + bool isDSdevice(); void labelToSpectLocalPort(); void labelToIBLocalPort(); bool isIBSplitReady(); @@ -329,6 +333,7 @@ class MlxlinkCommander: public MlxlinkRegParser { string activeSpeed2Str(u_int32_t mask, bool extended); void getCableParams(); bool inPrbsTestMode(); + bool checkGBPpaosDown(); bool checkPaosDown(); bool checkPpaosTestMode(); u_int32_t getPtysCap(); @@ -351,20 +356,20 @@ class MlxlinkCommander: public MlxlinkRegParser { virtual void showModuleInfo(); void prepareBerModuleInfoNdr(bool valid); virtual void runningVersion(); - virtual void operatingInfoPage(); - virtual void supportedInfoPage(); + void operatingInfoPage(); + void supportedInfoPage(); virtual void troubInfoPage(); - virtual void showPddr(); + void showPddr(); void getPtys(); virtual void showBer(); - virtual void prepare40_28_16nmEyeInfo(u_int32_t numOfLanesToUse); - virtual void prepare7nmEyeInfo(u_int32_t numOfLanesToUse); + void prepare40_28_16nmEyeInfo(u_int32_t numOfLanesToUse); + void prepare7nmEyeInfo(u_int32_t numOfLanesToUse); virtual void showEye(); virtual void showFEC(); virtual void showSltp(); virtual void showDeviceData(); void showBerMonitorInfo(); - virtual void showExternalPhy(); + void showExternalPhy(); void showPcie(); void showPcieLinks(); void collectAMBER(); @@ -430,9 +435,9 @@ class MlxlinkCommander: public MlxlinkRegParser { // Cable operation bool isPassiveQSFP(); bool isSFP51Paging(); - virtual void initCablesCommander(); - virtual void initEyeOpener(); - virtual void initErrInj(); + void initCablesCommander(); + void initEyeOpener(); + void initErrInj(); void initPortInfo(); void setAmBerCollectorFields(); virtual void initAmBerCollector(); @@ -473,12 +478,13 @@ class MlxlinkCommander: public MlxlinkRegParser { void sendPplm(); virtual void sendSltp(); void sendPplr(); - virtual void sendPepc(); + void sendPepc(); void setTxGroupMapping(); // Config helper functions bool isForceDownSupported(); bool isPPHCRSupported(); + void sendGBPaosCmd(PAOS_ADMIN adminStatus, bool forceDown); void sendPaosCmd(PAOS_ADMIN adminStatus, bool forceDown = false); void sendPaosDown(bool toggleCommand = false); void sendPaosUP(); @@ -506,7 +512,7 @@ class MlxlinkCommander: public MlxlinkRegParser { void getSltpRegAndLeva(u_int32_t lane); u_int32_t getLaneSpeed(u_int32_t lane); void validateNumOfParamsForNDRGen(); - virtual void checkSltpParamsSize(); + void checkSltpParamsSize(); // Mlxlink params UserInput _userInput; @@ -559,6 +565,7 @@ class MlxlinkCommander: public MlxlinkRegParser { bool _isPam4Speed; bool _ignorePortType; bool _ignorePortStatus; + bool _isGboxPort; std::vector _ptysSpeeds; std::vector _localPortsPerGroup; std::vector _validDpns; diff --git a/mlxlink/modules/mlxlink_enums.h b/mlxlink/modules/mlxlink_enums.h index 809eb966..af4a13dc 100644 --- a/mlxlink/modules/mlxlink_enums.h +++ b/mlxlink/modules/mlxlink_enums.h @@ -47,6 +47,8 @@ #define ACCESS_REG_MPEIN "MPEIN" #define ACCESS_REG_PMDR "PMDR" #define ACCESS_REG_PMCR "PMCR" +#define ACCESS_REG_PLLP "PLLP" +#define ACCESS_REG_MDDQ "MDDQ" #define ACCESS_REG_SLRG "SLRG" #define ACCESS_REG_SLTP "SLTP" #define ACCESS_REG_SLRIP "SLRIP" diff --git a/mlxlink/modules/mlxlink_ui.cpp b/mlxlink/modules/mlxlink_ui.cpp index 03fc6abc..518dbc39 100644 --- a/mlxlink/modules/mlxlink_ui.cpp +++ b/mlxlink/modules/mlxlink_ui.cpp @@ -71,7 +71,8 @@ void MlxlinkUi::printSynopsisHeader() "Perform operation for a specified mst device"); MlxlinkRecord::printFlagLine(LABEL_PORT_FLAG_SHORT, LABEL_PORT_FLAG, "port_number", "Port Number"); - MlxlinkRecord::printFlagLine(PORT_TYPE_FLAG_SHORT, PORT_TYPE_FLAG, "port_type", "Port Type [NETWORK(Default)/PCIE]"); + MlxlinkRecord::printFlagLine(PORT_TYPE_FLAG_SHORT, PORT_TYPE_FLAG, "port_type", + "Port Type [NETWORK(Default)/PCIE/GEARBOX_HOST/INTERNAL_IC_LR/GEARBOX_LINE]"); MlxlinkRecord::printFlagLine(DEPTH_FLAG_SHORT, DEPTH_FLAG, "depth", "depth level of the DUT of some hierarchy (PCIE only)"); MlxlinkRecord::printFlagLine(PCIE_INDEX_FLAG_SHORT, PCIE_INDEX_FLAG, "pcie_index", "PCIe index number (Internal domain index) (PCIE only)"); MlxlinkRecord::printFlagLine(NODE_FLAG_SHORT, NODE_FLAG, "node", "the node within each depth (PCIE only)"); @@ -592,10 +593,6 @@ void MlxlinkUi::paramValidate() void MlxlinkUi::initCmdParser() { -/* - for (u_int32_t it = SHOW_PDDR; it < FUNCTION_LAST; it++) { - _sendRegFuncMap.push_back(0); - }*/ AddOptions(DEVICE_FLAG, DEVICE_FLAG_SHORT, "MstDevice", "Mellanox mst device name"); AddOptions(HELP_FLAG, HELP_FLAG_SHORT, "", "Show help message and exit"); @@ -1149,8 +1146,8 @@ int MlxlinkUi::run(int argc, char **argv) _mlxlinkCommander->_gvmiAddress = _mlxlinkCommander->_userInput._gvmiAddress; _mlxlinkCommander->_devID = _mlxlinkCommander->_regLib->getDevId(); _mlxlinkCommander->_isHCA = dm_dev_is_hca(_mlxlinkCommander->_devID); - _mlxlinkCommander->validatePortType(_mlxlinkCommander->_userInput._portType); _mlxlinkCommander->labelToLocalPort(); + _mlxlinkCommander->validatePortType(_mlxlinkCommander->_userInput._portType); if (!_mlxlinkCommander->_userInput._pcie) { _mlxlinkCommander->checkValidFW(); } diff --git a/mlxlink/modules/mlxlink_utils.cpp b/mlxlink/modules/mlxlink_utils.cpp index 722059dc..a98e300f 100644 --- a/mlxlink/modules/mlxlink_utils.cpp +++ b/mlxlink/modules/mlxlink_utils.cpp @@ -1302,10 +1302,6 @@ void setPrintVal(MlxlinkCmdPrint &mlxlinkCmdPrint, string key, void setPrintTitle(MlxlinkCmdPrint &mlxlinkCmdPrint, string title, u_int32_t size, bool print) { - if (!MlxlinkRecord::gboxTitle.empty()) { - title = MlxlinkRecord::gboxTitle + " - " + title; - } - mlxlinkCmdPrint.title = title; mlxlinkCmdPrint.visible = print; mlxlinkCmdPrint.initRecords(size); diff --git a/mlxlink/modules/printutil/mlxlink_record.cpp b/mlxlink/modules/printutil/mlxlink_record.cpp index 159bac60..9a4cdace 100644 --- a/mlxlink/modules/printutil/mlxlink_record.cpp +++ b/mlxlink/modules/printutil/mlxlink_record.cpp @@ -38,7 +38,6 @@ #define MAX_LEN_OF_DDM_FIELD 14 bool MlxlinkRecord::jsonFormat = false; -std::string MlxlinkRecord::gboxTitle = ""; std::ostream* MlxlinkRecord::cOut = &std::cout; FILE* MlxlinkRecord::stdOut = stdout; diff --git a/mlxlink/modules/printutil/mlxlink_record.h b/mlxlink/modules/printutil/mlxlink_record.h index 801206f7..07ce2eb6 100644 --- a/mlxlink/modules/printutil/mlxlink_record.h +++ b/mlxlink/modules/printutil/mlxlink_record.h @@ -145,7 +145,6 @@ class MlxlinkRecord { bool arrayValue; bool colorKey; static bool jsonFormat; - static std::string gboxTitle; static std::ostream* cOut; static FILE* stdOut; }; From ea277d9d828791541a041c61c8016ff24a7d4741 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Wed, 8 Dec 2021 14:43:49 +0200 Subject: [PATCH 003/184] [mstlink] Supporting a new speeds\FECs for FEC configuration Description: As part of supporting the new FECs for NDR generation, this feature came with a new FEC configuration: -> Supporting a new FEC configuration for different speeds: NRZ, PAM4 and IB speeds. -> Fixing worng command (set and get) flows Issue: 2633054 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_commander.cpp | 379 +++++++++++++-------- mlxlink/modules/mlxlink_commander.h | 15 +- mlxlink/modules/mlxlink_enums.h | 21 +- mlxlink/modules/mlxlink_maps.cpp | 31 ++ mlxlink/modules/mlxlink_maps.h | 2 + mlxlink/modules/mlxlink_ui.cpp | 21 +- mlxlink/modules/mlxlink_utils.cpp | 126 +------ mlxlink/modules/mlxlink_utils.h | 8 +- mlxlink/modules/printutil/mlxlink_record.h | 2 +- 9 files changed, 336 insertions(+), 269 deletions(-) diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index fbded37d..deaa3f05 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -68,6 +68,7 @@ MlxlinkCommander::MlxlinkCommander() : _userInput() _activeSpeed = 0; _activeSpeedEx = 0; _protoCapability = 0; + _deviceCapability = 0; _linkSpeed = 0; _protoCapabilityEx = false; _ddmSupported = false; @@ -78,6 +79,7 @@ MlxlinkCommander::MlxlinkCommander() : _userInput() _ignorePortType = true; _ignorePortStatus = true; _isGboxPort = false; + _ignoreIbFECCheck = true; _protoAdmin = 0; _protoAdminEx = 0; _speedBerCsv = 0; @@ -952,21 +954,6 @@ bool MlxlinkCommander::checkPpaosTestMode() return false; } -u_int32_t MlxlinkCommander::getPtysCap() -{ - string regName = "PTYS"; - resetParser(regName); - updatePortType(); - - updateField("local_port", _localPort); - updateField("proto_mask", _protoActive); - updateField("an_disable_admin", 0); - - genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); - string proto = (_protoActive == IB) ? "ib" : "eth"; - return getFieldValue(proto + "_proto_capability"); -} - void MlxlinkCommander::getSltpParamsFromVector(std::vector sltpParams) { for (u_int32_t i = 0; i < sltpParams.size(); i++) { @@ -1887,6 +1874,10 @@ void MlxlinkCommander::getPtys() _protoAdmin = getFieldValue("eth_proto_admin"); _protoAdminEx = getFieldValue("ext_eth_proto_admin"); _protoCapabilityEx = getFieldValue("ext_eth_proto_capability"); + _deviceCapability = _protoCapabilityEx ? getFieldValue("ext_eth_proto_capability") + : getFieldValue("eth_proto_capability"); + } else { + _deviceCapability = getFieldValue("ib_proto_capability"); } _anDisable = getFieldValue("an_disable_admin"); @@ -2358,84 +2349,106 @@ void MlxlinkCommander::showEye() } } -void MlxlinkCommander::showFEC() +string MlxlinkCommander::fecMaskToUserInputStr(u_int32_t fecCapMask) { - try { - /*string regName = "PPLM"; - //std::vector _buffer; - //RegAccessParser parser = getRegAccessParser(regName); - //resetParser(regName); - - updateField("local_port", _localPort); - - genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); - u_int32_t FECSupported100G = getFieldValue("fec_override_cap_100g"); - u_int32_t FECSupported25G50G = getFieldValue("fec_override_cap_50g"); - u_int32_t FECAdmin100G = getFieldValue("fec_override_admin_100g"); - u_int32_t FECAdmin25G50G = getFieldValue("fec_override_admin_50g"); - - u_int32_t FEC100G = (FECAdmin100G) ? FECAdmin100G : FECSupported100G; - u_int32_t FEC25G50G = (FECAdmin25G50G) ? FECAdmin25G50G : FECSupported25G50G; - - std::vector showFecValues; - showFecValues.push_back("0x" + convertIntToHexString(FEC100G) + " (" + FEC2Str100G(FEC100G) + ")"); - showFecValues.push_back("0x" + convertIntToHexString(FEC25G50G) + " (" + FEC2Str50G25G(FEC25G50G) + ")"); - showFecValues.push_back("0x" + convertIntToHexString(_fecModeRequest) + " (" + FECReq2Str(_fecModeRequest, _linkUP) + ")"); - printCmdOutput(_showFecTitle, _showFecLines, showFecValues);*/ - string fecCap100,fecCap50,fecCap40,fecCap25,fecCap10; - if (_protoActive == IB || _prbsTestMode) { - fecCap100 = "0x0 (N/A)"; - fecCap50 = "0x0 (N/A)"; - fecCap40 = "0x0 (N/A)"; - fecCap25 = "0x0 (N/A)"; - fecCap10 = "0x0 (N/A)"; - } else { - string supportedSpeeds = EthSupportedSpeeds2Str(getPtysCap()); - if (supportedSpeeds.find("100G") != string::npos) { - if (_devID == DeviceConnectX4) { - fecCap100 = "0x4 (RS-FEC(528,514))"; - } else { - fecCap100 = "0x5 (No-FEC, RS-FEC(528,514))"; + u_int32_t mask = 0; + string validFecStr = ""; + string shortFec = ""; + for (double bitIdx = 0; bitIdx < 16; bitIdx++) { + mask = (u_int32_t)pow(2.0, bitIdx); + if (fecCapMask & mask) { + if (_mlxlinkMaps->_fecModeMask.count(mask)) { + shortFec = _mlxlinkMaps->_fecModeMask[mask].second; + if (shortFec.find("PLR") != string::npos) { + continue; } - } else { - fecCap100 = "0x0 (N/A)"; - } - if (supportedSpeeds.find("50G") != string::npos) { - fecCap50 = "0x7 (No-FEC, FireCode FEC, RS-FEC(528,514))"; - } else { - fecCap50 = "0x0 (N/A)"; - } - if (supportedSpeeds.find("40G") != string::npos) { - fecCap40 = "0x3 (No-FEC, FireCode FEC)"; - } else { - fecCap40 = "0x0 (N/A)"; - } - if (supportedSpeeds.find("25G") != string::npos) { - fecCap25 = "0x7 (No-FEC, FireCode FEC, RS-FEC(528,514))"; - } else { - fecCap25 = "0x0 (N/A)"; - } - if (supportedSpeeds.find("10G") != string::npos) { - fecCap10 = "0x3 (No-FEC, FireCode FEC)"; - } else { - fecCap10 = "0x0 (N/A)"; + if (shortFec.find("-544") != string::npos || shortFec.find("-272") != string::npos) { + shortFec = shortFec.substr(0, 2); + } + validFecStr += shortFec + "(" + _mlxlinkMaps->_fecModeMask[mask].first + ")/"; } } + } - setPrintTitle(_fecCapInfoCmd, HEADER_FEC_INFO, FEC_CAP_INFO_LASE); - setPrintVal(_fecCapInfoCmd, "FEC Capability 100GbE", fecCap100, - ANSI_COLOR_RESET, true, true, true); - setPrintVal(_fecCapInfoCmd, "FEC Capability 50GbE", fecCap50, - ANSI_COLOR_RESET, true, true, true); - setPrintVal(_fecCapInfoCmd, "FEC Capability 40GbE", fecCap40, - ANSI_COLOR_RESET, true, true, true); - setPrintVal(_fecCapInfoCmd, "FEC Capability 25GbE", fecCap25, - ANSI_COLOR_RESET, true, true, true); - setPrintVal(_fecCapInfoCmd, "FEC Capability 10GbE", fecCap10, - ANSI_COLOR_RESET, true, true, true); + validFecStr = validFecStr.empty()? "" : deleteLastChar(validFecStr); + + return validFecStr; +} + +string MlxlinkCommander::getSupportedFecForSpeed(const string &speed) +{ + string fecCap = "0x0 (N/A)"; + string protoStr = _protoActive == IB? "ib_" : ""; + if (!_prbsTestMode) { + string speedToCheck = speed; + speedToCheck = toLowerCase(speedToCheck); + if (speedToCheck == "10g" || speedToCheck == "40g") { + speedToCheck = "10g_40g"; + } + if (speedToCheck == "50g_2x") { + speedToCheck = "50g"; + } + if (speedToCheck == "100g_4x") { + speedToCheck = "100g"; + } + fecCap = fecMaskToStr(getFieldValue(protoStr + "fec_override_cap_" + speedToCheck)); + } + return fecCap; +} + +string MlxlinkCommander::fecMaskToStr(u_int32_t mask) +{ + char strMask[32]; + snprintf(strMask, sizeof(strMask), "0x%x (", mask); + + string fecStr = string(strMask); + + if (mask) { + fecStr += getFieldsByPairMap(mask, _mlxlinkMaps->_fecModeMask, ", "); + } else { + fecStr = "0x0 (N/A"; + } + fecStr += ")"; + + return fecStr; +} + +void MlxlinkCommander::showFEC() +{ + try { + resetParser(ACCESS_REG_PPLM); + updateField("local_port", _localPort); + genBuffSendRegister(ACCESS_REG_PPLM, MACCESS_REG_METHOD_GET); + + string supportedSpeedsStr = SupportedSpeeds2Str(_protoActive, _deviceCapability, _protoCapabilityEx); + vector supportedSpeeds = MlxlinkRecord::split(supportedSpeedsStr, ","); + + for (auto it = _mlxlinkMaps->_fecPerSpeed.begin(); it != _mlxlinkMaps->_fecPerSpeed.end(); it++) { + if (isIn((*it).first, supportedSpeeds)) { + it->second = getSupportedFecForSpeed((*it).first); + } + } - cout << _fecCapInfoCmd; + setPrintTitle(_fecCapInfoCmd, HEADER_FEC_INFO, supportedSpeeds.size() + 1); + bool noFecDetected = true; + string bitEthIndecator = "bE"; + for (auto it = _mlxlinkMaps->_fecPerSpeed.begin(); it != _mlxlinkMaps->_fecPerSpeed.end(); it++) { + if (!(*it).second.empty()) { + noFecDetected = false; + } + if (isIn((*it).first, supportedSpeeds)) { + setPrintVal(_fecCapInfoCmd, "FEC Capability " + (*it).first + + ((_productTechnology < PRODUCT_16NM && + _protoActive == ETH) ? bitEthIndecator : ""), (*it).second, + ANSI_COLOR_RESET, true, true, true); + } + } + if (noFecDetected) { + MlxlinkRecord::printWar("FEC information is not available for InfiniBand protocol", _jsonRoot); + } else { + cout << _fecCapInfoCmd; + } } catch (const std::exception &exc) { _allUnhandledErrors += string("Showing FEC raised the following exception: ") + string(exc.what()) + string("\n"); } @@ -3839,83 +3852,183 @@ void MlxlinkCommander::sendPplm() throw MlxRegException("Cannot Configure FEC in Physical Test Mode. Please Disable First."); } MlxlinkRecord::printCmdLine("Configuring Port FEC", _jsonRoot); - if (_protoActive == IB) { + if (_protoActive == IB && _ignoreIbFECCheck) { throw MlxRegException("FEC Configuration is Valid for ETHERNET only!"); } if (!_linkUP && _userInput._speedFec == "") { throw MlxRegException("When Port is Not Active, You Must Specify the Speed to Configure FEC (--fec_speed )"); } - checkPplmCap(); + checkPplmCap(); // after calling checkPplmCap, _userInput._speedFec will be changed to the correct fec speed - string regName = "PPLM"; - resetParser(regName); + resetParser(ACCESS_REG_PPLM); updatePortType(); updateField("local_port", _localPort); - string fecSpeed = toLowerCase(_userInput._speedFec); - string speedStrG = (_linkUP && _userInput._speedFec == "") ? - speedToStr(_speedStrG, _numOfLanes) : fecSpeed; + string speedToConfigure = (_linkUP && _userInput._speedFec == "") ? speedToFecSpeedStr(_speedStrG, _numOfLanes) + : _userInput._speedFec; + u_int32_t fecAdmin = fecToBit(_userInput._pplmFec, speedToConfigure); + if (speedToConfigure == "50g" || speedToConfigure == "25g") { // 25g and 50g must be set the same + updateField("fec_override_admin_25g", fecAdmin); + updateField("fec_override_admin_50g", fecAdmin); + } else { + updateField(string(_protoActive == IB ? "ib_":"") + "fec_override_admin_" + speedToConfigure, fecAdmin); + } - if (speedStrG != "100g") { - updateField("fec_override_admin_100g", 0); + genBuffSendRegister(ACCESS_REG_PPLM, MACCESS_REG_METHOD_SET); + } catch (const std::exception &exc) { + _allUnhandledErrors += string("Sending PPLM (Configuring port FEC) raised the following exception: ") + string(exc.what()) + string("\n"); + } +} + +string MlxlinkCommander::speedToFecSpeedStr(const string &speed, u_int32_t numOfLanes) +{ + string fecSpeedStrFormat = ""; + string numberOfLanesStr = to_string(numOfLanes) + "x"; + if (_protoActive == IB) { + string speedStr = speed; + if (speedStr.find("IB-") != string::npos) { + speedStr = speedStr.substr(3); } - if (speedStrG != "50g" && speedStrG != "25g") { - updateField("fec_override_admin_50g", 0); - updateField("fec_override_admin_25g", 0); + fecSpeedStrFormat = toLowerCase(speedStr); + } else { + if (speed == "800G") { + fecSpeedStrFormat = "800g_" + numberOfLanesStr; } - if (speedStrG != "10g" && speedStrG != "40g") { - updateField("fec_override_admin_10g_40g", 0); + if (speed == "400G") { + fecSpeedStrFormat = "400g_" + numberOfLanesStr; } - if (speedStrG == "10g" || speedStrG == "40g") { - speedStrG = "10g_40g"; + if (speed == "200G") { + fecSpeedStrFormat = "200g_" + numberOfLanesStr; } - if (speedStrG != "56g") { - updateField("fec_override_admin_56g", 0); + if (speed == "100G") { + if (numOfLanes == 4) { + fecSpeedStrFormat = "100g"; + } else { + fecSpeedStrFormat = "100g_" + numberOfLanesStr; + } } - string fieldToUpdate = "fec_override_admin_" + speedStrG; - updateField(fieldToUpdate, fecToBit(_userInput._pplmFec, speedStrG)); - if (speedStrG == "50g") { - updateField("fec_override_admin_25g", fecToBit(_userInput._pplmFec, speedStrG)); - } else if (speedStrG == "25g") { - updateField("fec_override_admin_50g", fecToBit(_userInput._pplmFec, speedStrG)); + if (speed == "50G") { + if (numOfLanes == 1) { + fecSpeedStrFormat = "50g_" + numberOfLanesStr; + } else { + fecSpeedStrFormat = "50g"; + } + } + if (speed == "100GbE") { + fecSpeedStrFormat = "100g"; + } + if (speed == "50GbE") { + fecSpeedStrFormat = "50g"; + } + if (speed == "25GbE" || speed == "25G") { + fecSpeedStrFormat = "25g"; + } + if (speed == "40GbE" || speed == "40G" || speed == "10GbE" || speed == "10G") { + fecSpeedStrFormat = "10g_40g"; + } + if (speed == "56GbE") { + fecSpeedStrFormat = "56g"; } - genBuffSendRegister(regName, MACCESS_REG_METHOD_SET); - } catch (const std::exception &exc) { - _allUnhandledErrors += string("Sending PPLM (Configuring port FEC) raised the following exception: ") + string(exc.what()) + string("\n"); } + return fecSpeedStrFormat; } -void MlxlinkCommander::checkPplmCap() +u_int32_t MlxlinkCommander::fecToBit(const string &fec, const string &speedStrG) { - if (_userInput._pplmFec == "AU") { - return; + string fecToCheck = fec; + u_int32_t fecAdmin = FEC_MODE_MASK_AU; + + // Work with different RS and LL FEC for HDR, NDR and ETH PAM4 speeds + if ((speedStrG == "ndr" || speedStrG == "hdr") || + (speedStrG.find("x") != string::npos && speedStrG != "100g_4x" && speedStrG != "50g_2x")) { + if (fec == _mlxlinkMaps->_fecModeMask[FEC_MODE_MASK_RS_528].second) { + fecToCheck += "-544"; + } else if (fec == _mlxlinkMaps->_fecModeMask[FEC_MODE_MASK_LL_271].second && speedStrG != "hdr") { + fecToCheck += "-272"; + } + } + for (auto it = _mlxlinkMaps->_fecModeMask.begin(); it != _mlxlinkMaps->_fecModeMask.end(); it++) { + if (it->second.second == fecToCheck) { + fecAdmin = it->first; + } } - string regName = "PPLM"; - resetParser(regName); + return fecAdmin; +} + +u_int32_t MlxlinkCommander::getFecCapForCheck(const string &speedStr) +{ + u_int32_t fecCapMask = 0; + resetParser(ACCESS_REG_PPLM); updatePortType(); updateField("local_port", _localPort); - genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); - string speedStrG = (_linkUP && _userInput._speedFec.empty()) ? - speedToStr(_speedStrG, _numOfLanes) : toLowerCase(_userInput._speedFec); - string originalSpeed = speedStrG; - if (speedStrG == "10g" || speedStrG == "40g") { - speedStrG = "10g_40g"; + genBuffSendRegister(ACCESS_REG_PPLM, MACCESS_REG_METHOD_GET); + + try { + fecCapMask = getFieldValue(string(_protoActive == IB ? "ib_" : "") + "fec_override_cap_" + speedStr); + } catch (MlxRegException &exc){ + throw MlxRegException("\nFEC configuration is not available for this speed: " + speedStr); } - u_int32_t fecCap = getFieldValue("fec_override_cap_" + speedStrG); - string supportedSpeeds = EthSupportedSpeeds2Str(getPtysCap()); + return fecCapMask; +} - if (_linkUP && !_userInput._speedFec.empty() && - supportedSpeeds.find(toUpperCase(_userInput._speedFec)) == string::npos) { - throw MlxRegException("FEC speed " + _userInput._speedFec + - " is not supported, supported speeds are: [" + supportedSpeeds + "]"); +void MlxlinkCommander::checkPplmCap() +{ + if (_userInput._pplmFec == "AU") { + return; + } + string speedFec = _userInput._speedFec; + string uiSpeed = _userInput._speedFec; + if (_linkUP && _userInput._speedFec.empty()) { + speedFec = speedToFecSpeedStr(_speedStrG, _numOfLanes); + uiSpeed = _speedStrG; + } + // Validate the speed + if (!_userInput._speedFec.empty()) { + vector supportedSpeeds = MlxlinkRecord::split(SupportedSpeeds2Str(_protoActive, _deviceCapability, + _protoCapabilityEx), ","); + string speedToCheck = _userInput._speedFec; + speedToCheck = toUpperCase(speedToCheck); + if (_protoCapabilityEx) { + if (speedToCheck == "50G") { + speedToCheck += "_2X"; + } else if (speedToCheck == "100G") { + speedToCheck += "_4X"; + } + } + if (!isIn(speedToCheck, supportedSpeeds)) { + throw MlxRegException("\nFEC speed %s is not valid", uiSpeed.c_str()); + } } - if (!(fecToBit(_userInput._pplmFec, speedStrG) & fecCap)) { - throw MlxRegException(FEC2Str(_userInput._pplmFec, speedStrG) + - " is not supported in " + originalSpeed); + // Validate the FEC for the speed + if (speedFec == "10g" || speedFec == "40g") { + speedFec = "10g_40g"; + } + if (speedFec == "50g_2x") { + speedFec = "50g"; + } + if (speedFec =="100g_4x") { + speedFec = "100g"; + } + _userInput._speedFec = speedFec; + u_int32_t fecCap = getFecCapForCheck(_userInput._speedFec); + if (!(fecToBit(_userInput._pplmFec, _userInput._speedFec) & fecCap)) { + string supportedFec = fecMaskToUserInputStr(fecCap); + string validFecs = fecMaskToUserInputStr(BIT_MASK_ALL_DWORD); + + string errorMsg = _userInput._pplmFec + " FEC is not supported in " + uiSpeed + " speed, "; + if (validFecs.find(_userInput._pplmFec) == string::npos) { + errorMsg = _userInput._pplmFec + " FEC configuration is not valid, "; + } + if (supportedFec.empty()) { + errorMsg += "it's not available for this speed"; + } else { + errorMsg += "valid FEC configurations are [" + supportedFec + "]"; + } + throw MlxRegException("\n" + errorMsg); } } diff --git a/mlxlink/modules/mlxlink_commander.h b/mlxlink/modules/mlxlink_commander.h index 88a194a1..a1add28c 100644 --- a/mlxlink/modules/mlxlink_commander.h +++ b/mlxlink/modules/mlxlink_commander.h @@ -336,7 +336,6 @@ class MlxlinkCommander: public MlxlinkRegParser { bool checkGBPpaosDown(); bool checkPaosDown(); bool checkPpaosTestMode(); - u_int32_t getPtysCap(); void getSltpParamsFromVector(std::vector sltpParams); void getprbsLanesFromParams(std::vector prbsLanesParams); std::vector parseParamsFromLine(const string & ParamsLine); @@ -365,7 +364,7 @@ class MlxlinkCommander: public MlxlinkRegParser { void prepare40_28_16nmEyeInfo(u_int32_t numOfLanesToUse); void prepare7nmEyeInfo(u_int32_t numOfLanesToUse); virtual void showEye(); - virtual void showFEC(); + void showFEC(); virtual void showSltp(); virtual void showDeviceData(); void showBerMonitorInfo(); @@ -395,6 +394,9 @@ class MlxlinkCommander: public MlxlinkRegParser { u_int32_t laneNumber); void initValidDPNList(); u_int32_t readBitFromField(const string &fieldName, u_int32_t bitIndex); + string getSupportedFecForSpeed(const string &speed); + string fecMaskToUserInputStr(u_int32_t fecCapMask); + string fecMaskToStr(u_int32_t mask); void showTestMode(); void showTestModeBer(); @@ -475,8 +477,8 @@ class MlxlinkCommander: public MlxlinkRegParser { void sendPaos(); void handlePrbs(); void sendPtys(); - void sendPplm(); - virtual void sendSltp(); + virtual void sendPplm(); + void sendSltp(); void sendPplr(); void sendPepc(); void setTxGroupMapping(); @@ -503,6 +505,9 @@ class MlxlinkCommander: public MlxlinkRegParser { u_int32_t ptysSpeedToMask(const string & speed); void validateSpeedStr(); void checkSupportedSpeed(const string & speed, u_int32_t cap, bool extSpeed = false); + string speedToFecSpeedStr(const string &speed, u_int32_t numOfLanes); + u_int32_t fecToBit(const string &fec, const string &speedStrG); + u_int32_t getFecCapForCheck(const string &speedStr); void checkPplmCap(); void updateSltp28_40nmFields(); void updateSltp16nmFields(); @@ -537,6 +542,7 @@ class MlxlinkCommander: public MlxlinkRegParser { u_int32_t _activeSpeed; u_int32_t _activeSpeedEx; u_int32_t _protoCapability; + u_int32_t _deviceCapability; u_int32_t _protoAdmin; u_int32_t _protoAdminEx; u_int32_t _productTechnology; @@ -566,6 +572,7 @@ class MlxlinkCommander: public MlxlinkRegParser { bool _ignorePortType; bool _ignorePortStatus; bool _isGboxPort; + bool _ignoreIbFECCheck; std::vector _ptysSpeeds; std::vector _localPortsPerGroup; std::vector _validDpns; diff --git a/mlxlink/modules/mlxlink_enums.h b/mlxlink/modules/mlxlink_enums.h index af4a13dc..ab490d45 100644 --- a/mlxlink/modules/mlxlink_enums.h +++ b/mlxlink/modules/mlxlink_enums.h @@ -41,6 +41,7 @@ #define ACCESS_REG_SPAD "SPAD" #define ACCESS_REG_PPCNT "PPCNT" #define ACCESS_REG_PPHCR "PPHCR" +#define ACCESS_REG_PPLM "PPLM" #define ACCESS_REG_PDDR "PDDR" #define ACCESS_REG_PTYS "PTYS" #define ACCESS_REG_MPCNT "MPCNT" @@ -684,6 +685,23 @@ enum FEC_MODE_ACTIVE { FEC_MODE_RS_FEC_PLR_272_257 = 14, }; +enum FEC_MODE_MASK { + FEC_MODE_MASK_AU = 0, + FEC_MODE_MASK_NF = 0x1, + FEC_MODE_MASK_FC = 0x2, + FEC_MODE_MASK_RS_528 = 0x4, + FEC_MODE_MASK_LL_271 = 0x8, + FEC_MODE_MASK_DF_RS = 0x40, + FEC_MODE_MASK_RS_544 = 0x80, + FEC_MODE_MASK_LL_272 = 0x200, + FEC_MODE_MASK_DF_LL_272 = 0x400, + FEC_MODE_MASK_DF_RS_PLR = 0x800, + FEC_MODE_MASK_RS_PLR = 0x1000, + FEC_MODE_MASK_LL_271_PLR = 0x2000, + FEC_MODE_MASK_LL_272_PLR = 0x4000, + FEC_MODE_MASK_DF_LL_272_PLR = 0x8000 +}; + enum DATA_PATH_STATE { DATA_PATH_STATE_RES = 0, DATA_PATH_STATE_DEACTIVATED = 0x1, @@ -1223,7 +1241,8 @@ enum ETH_LINK_SPEED_EXT { ETH_LINK_SPEED_EXT_200GAUI_2 = 0x2000, ETH_LINK_SPEED_EXT_Reserved_14 = 0x4000, ETH_LINK_SPEED_EXT_400GAUI_8 = 0x8000, - ETH_LINK_SPEED_EXT_400GAUI_4 = 0x10000 + ETH_LINK_SPEED_EXT_400GAUI_4 = 0x10000, + ETH_LINK_SPEED_EXT_800GAUI_8 = 0x80000 }; enum IB_LINK_SPEED { diff --git a/mlxlink/modules/mlxlink_maps.cpp b/mlxlink/modules/mlxlink_maps.cpp index 18e06094..0070f301 100644 --- a/mlxlink/modules/mlxlink_maps.cpp +++ b/mlxlink/modules/mlxlink_maps.cpp @@ -150,6 +150,34 @@ void MlxlinkMaps::initFecAndLoopbackMapping() _fecModeActive[FEC_MODE_RS_FEC_PLR_272_257] = "Ethernet_Consortium_LL_50G_RS_FEC_PLR -(272,257+1)"; + _fecModeMask[FEC_MODE_MASK_AU] = make_pair("Auto-FEC", "AU"); + _fecModeMask[FEC_MODE_MASK_NF] = make_pair("No-FEC", "NF"); + _fecModeMask[FEC_MODE_MASK_FC] = make_pair("Firecode_FEC", "FC"); + _fecModeMask[FEC_MODE_MASK_RS_528] = make_pair("RS-FEC (528,514)", "RS"); + _fecModeMask[FEC_MODE_MASK_LL_271] = make_pair("LL_RS-FEC (271,257)", "LL"); + _fecModeMask[FEC_MODE_MASK_DF_RS] = make_pair("Interleaved_RS-FEC (544,514)", "DF-RS"); + _fecModeMask[FEC_MODE_MASK_RS_544] = make_pair("RS-FEC (544,514)", "RS-544"); + _fecModeMask[FEC_MODE_MASK_LL_272] = make_pair("LL_RS-FEC (272,257+1)", "LL-272"); + _fecModeMask[FEC_MODE_MASK_DF_LL_272] = make_pair("Interleaved_LL_RS-FEC (272,257+1)", "DF-LL"); + + _fecPerSpeed.push_back(make_pair("800G_8X", "")); + _fecPerSpeed.push_back(make_pair("400G_4X", "")); + _fecPerSpeed.push_back(make_pair("200G_2X", "")); + _fecPerSpeed.push_back(make_pair("100G_1X", "")); + + _fecPerSpeed.push_back(make_pair("400G_8X", "")); + _fecPerSpeed.push_back(make_pair("200G_4X", "")); + _fecPerSpeed.push_back(make_pair("100G_2X", "")); + _fecPerSpeed.push_back(make_pair("50G_1X", "")); + _fecPerSpeed.push_back(make_pair("50G_2X", "")); + _fecPerSpeed.push_back(make_pair("100G_4X", "")); + + _fecPerSpeed.push_back(make_pair("100G", "")); + _fecPerSpeed.push_back(make_pair("56G", "")); + _fecPerSpeed.push_back(make_pair("50G", "")); + _fecPerSpeed.push_back(make_pair("40G", "")); + _fecPerSpeed.push_back(make_pair("25G", "")); + _fecPerSpeed.push_back(make_pair("10G", "")); _loopbackModeList[PHY_NO_LOOPBACK] = "No Loopback"; _loopbackModeList[PHY_REMOTE_LOOPBACK] = "PHY Remote Loopback"; @@ -228,6 +256,7 @@ void MlxlinkMaps::extEthSpeedMapping() _EthExtSpeed2gNum[ETH_LINK_SPEED_EXT_200GAUI_2] = 200; _EthExtSpeed2gNum[ETH_LINK_SPEED_EXT_400GAUI_8] = 400; _EthExtSpeed2gNum[ETH_LINK_SPEED_EXT_400GAUI_4] = 400; + _EthExtSpeed2gNum[ETH_LINK_SPEED_EXT_800GAUI_8] = 800; _EthExtSpeed2Str[ETH_LINK_SPEED_EXT_SGMII_100M] = "100M"; _EthExtSpeed2Str[ETH_LINK_SPEED_EXT_1000BASE_X] = "1G"; @@ -245,6 +274,7 @@ void MlxlinkMaps::extEthSpeedMapping() _EthExtSpeed2Str[ETH_LINK_SPEED_EXT_200GAUI_2] = "200G"; _EthExtSpeed2Str[ETH_LINK_SPEED_EXT_400GAUI_8] = "400G"; _EthExtSpeed2Str[ETH_LINK_SPEED_EXT_400GAUI_4] = "400G"; + _EthExtSpeed2Str[ETH_LINK_SPEED_EXT_800GAUI_8] = "800G"; } void MlxlinkMaps::ibSpeedMapping() @@ -315,6 +345,7 @@ void MlxlinkMaps::speedToLanesMapping() _ExtETHSpeed2Lanes[ETH_LINK_SPEED_EXT_200GAUI_2] = 2; _ExtETHSpeed2Lanes[ETH_LINK_SPEED_EXT_400GAUI_8] = 8; _ExtETHSpeed2Lanes[ETH_LINK_SPEED_EXT_400GAUI_4] = 4; + _ExtETHSpeed2Lanes[ETH_LINK_SPEED_EXT_800GAUI_8] = 8; } void MlxlinkMaps::initPortSpeedMapping() diff --git a/mlxlink/modules/mlxlink_maps.h b/mlxlink/modules/mlxlink_maps.h index 7705869a..9056cbb1 100644 --- a/mlxlink/modules/mlxlink_maps.h +++ b/mlxlink/modules/mlxlink_maps.h @@ -173,6 +173,8 @@ class MlxlinkMaps{ std::map _SLTP7BadSetStatus2Str; std::map _ethANFsmState; std::map _fecModeActive; + std::map> _fecModeMask; + std::vector> _fecPerSpeed; std::map _loopbackModeList; std::map _anDisableList; std::map _tech; diff --git a/mlxlink/modules/mlxlink_ui.cpp b/mlxlink/modules/mlxlink_ui.cpp index 518dbc39..a5706975 100644 --- a/mlxlink/modules/mlxlink_ui.cpp +++ b/mlxlink/modules/mlxlink_ui.cpp @@ -112,10 +112,10 @@ void MlxlinkUi::printSynopsisCommands() MlxlinkRecord::printFlagLine(PPLR_FLAG_SHORT, PPLR_FLAG, "loopback", "Configure Loopback Mode [NO(no loopback)/RM(phy remote Rx-to-Tx loopback)/PH(internal phy Tx-to-Rx loopback)/EX(external loopback connector needed)/EX(external Tx-to-Rx loopback)]"); MlxlinkRecord::printFlagLine(PPLM_FLAG_SHORT, PPLM_FLAG, "fec_override", - "Configure FEC [AU(Auto)/NF(No-FEC)/FC(FireCode FEC)/RS(RS-FEC)]"); + "Configure FEC [AU(Auto)/NF(No-FEC)/FC(FireCode FEC)/RS(RS-FEC)/LL(LL-RS-FEC)/DF-RS(Interleaved_RS-FEC)/DF-LL(Interleaved_LL_RS-FEC)]"); printf(IDENT); MlxlinkRecord::printFlagLine(FEC_SPEED_FLAG_SHORT, FEC_SPEED_FLAG, "fec_speed", - "Speed to Configure FEC [100G,56G,50G,40G,25G,10G] (Default is Active Speed)"); + "Speed to Configure FEC [100G,56G,50G,40G,25G,10G,800G_8X,400G_4x,400G_8X,200G_2X,200G_4X,100G_2X,50G_1X,100G_4X] (Default is Active Speed)"); MlxlinkRecord::printFlagLine(SLTP_SET_FLAG_SHORT, SLTP_SET_FLAG, "params", "Configure Transmitter Parameters For 16nm devices: [pre2Tap,preTap,mainTap,postTap,m2lp,amp] For 28nm devices: [Pol,tap0,tap1,tap2,bias,preemp_mode]"); printf(IDENT); @@ -355,25 +355,10 @@ void MlxlinkUi::validateGeneralCmdsParams() throw MlxRegException( "Please provide a valid paos command [UP(up)/DN(down)/TG(toggle)]"); } - if (isIn(SEND_PPLM, _sendRegFuncMap) && !checkPplmCmd(_mlxlinkCommander->_userInput._pplmFec)) { - throw MlxRegException( - "Please provide a valid FEC [AU(Auto)/NF(No-Fec)/FC(FireCode FEC)/RS(RS FEC)]"); - } if (!isIn(SEND_PPLM, _sendRegFuncMap) && _mlxlinkCommander->_userInput._speedFec != "") { throw MlxRegException( "The --fec_speed flag is valid only with --fec flag"); } - if (isIn(SEND_PPLM, _sendRegFuncMap)) { - if (_mlxlinkCommander->_userInput._speedFec != "" && - _mlxlinkCommander->_userInput._speedFec != "100G" && - _mlxlinkCommander->_userInput._speedFec != "56G" && - _mlxlinkCommander->_userInput._speedFec != "50G" && - _mlxlinkCommander->_userInput._speedFec != "40G" && - _mlxlinkCommander->_userInput._speedFec != "25G" && - _mlxlinkCommander->_userInput._speedFec != "10G") { - throw MlxRegException("Please Provide a Valid Speed to Configure FEC (100G/56G/50G/40G/25G/10G)"); - } - } if (isIn(SEND_SLTP, _sendRegFuncMap)) { if (_mlxlinkCommander->_userInput._sltpLane && _mlxlinkCommander->_userInput._db) { throw MlxRegException( @@ -934,7 +919,7 @@ ParseStatus MlxlinkUi::HandleOption(string name, string value) _mlxlinkCommander->_uniqueCmds++; return PARSE_OK; } else if (name == FEC_SPEED_FLAG) { - _mlxlinkCommander->_userInput._speedFec = toUpperCase(value); + _mlxlinkCommander->_userInput._speedFec = toLowerCase(value); return PARSE_OK; } else if (name == PPLR_FLAG) { addCmd(SEND_PPLR); diff --git a/mlxlink/modules/mlxlink_utils.cpp b/mlxlink/modules/mlxlink_utils.cpp index a98e300f..89966360 100644 --- a/mlxlink/modules/mlxlink_utils.cpp +++ b/mlxlink/modules/mlxlink_utils.cpp @@ -228,7 +228,9 @@ string EthSupportedSpeeds2Str(u_int32_t int_mask) string EthExtSupportedSpeeds2Str(u_int32_t int_mask) { string maskStr = ""; - + if (int_mask & ETH_LINK_SPEED_EXT_800GAUI_8) { + maskStr += "800G_8x,"; + } if (int_mask & ETH_LINK_SPEED_EXT_400GAUI_4) { maskStr += "400G_4x,"; } @@ -496,25 +498,35 @@ bool isPAM4Speed(u_int32_t activeSpeed, u_int32_t protoActive, bool extended) return pam4Signal; } -string getFieldsByMap(u_int32_t bitmask, std::map map) +string getFieldsByPairMap(u_int32_t bitmask, map> maskMap, + const string &fieldSeparator, u_int32_t pairIndex) +{ + map strMap; + for (auto it = maskMap.begin(); it != maskMap.end(); it++) { + strMap.insert(pair(it->first, pairIndex == 0 ? it->second.first : + it->second.second)); + } + return getFieldsByMap(bitmask, strMap, fieldSeparator); +} + +string getFieldsByMap(u_int32_t bitmask, std::map maskMap, const string &fieldSeparator) { string bitMaskStr = ""; string tmpMaskStr = ""; u_int32_t i = 1; u_int32_t bitmask_tmp = bitmask; - if (bitmask) { while(bitmask_tmp != 0){ if(getBitvalue(bitmask, i)){ - tmpMaskStr = map[pow(2.0, i - 1)]; + tmpMaskStr = maskMap[pow(2.0, i - 1)]; if (!tmpMaskStr.empty()) { - bitMaskStr += tmpMaskStr + ","; + bitMaskStr += tmpMaskStr + fieldSeparator; } } i++; bitmask_tmp >>= 1; } - bitMaskStr = deleteLastChar(bitMaskStr); + bitMaskStr = deleteLastChar(bitMaskStr, fieldSeparator.size()); } else { bitMaskStr = "N/A"; } @@ -546,15 +558,6 @@ bool checkPepcANMode(const string &anMode) return true; } -bool checkPplmCmd(const string &pplmCmd) -{ - if (pplmCmd != "AU" && pplmCmd != "NF" && pplmCmd != "FC" - && pplmCmd != "RS") { - return false; - } - return true; -} - bool checkPplrCmd(const string &pplrCmd) { if (pplrCmd != "NO" && pplrCmd != "PH" && pplrCmd != "EX") { @@ -733,99 +736,6 @@ bool checkTestMode(const string &testMode) return true; } -string FEC2Str(const string &fecShort, const string &speedStrG) -{ - string fec = ""; - if (fecShort == "NF") { - fec = "No FEC"; - } else if (fecShort == "FC") { - fec = "Firecode FEC"; - } else if (fecShort == "RS") { - fec = "RS FEC"; - } - if (speedStrG == "400g_8x" || speedStrG == "200g_4x" || - speedStrG == "100g_2x" || speedStrG == "50g_1x") { - if (fec == "RS544") { - fec = "Standard_RS-FEC - (544,514)"; - } - if (fec == "RS272") { - fec = "Ethernet_Consortium_LL_50G_RS-FEC - (272,257+1)"; - } - } - return fec; -} - -int fecToBit(const string &fec, const string &speedStrG) -{ - if (fec == "AU") { - return 0; - } - if (fec == "NF") { - return 1; - } - if (fec == "FC") { - return 2; - } - if (fec == "RS") { - return 4; - } - if (speedStrG == "400g_8x" || speedStrG == "200g_4x" || - speedStrG == "100g_2x" || speedStrG == "50g_1x") { - if (fec == "RS544") { - return 0x80; - } - if (fec == "RS272") { - return 0x200; - } - } - return 0; -} - -string speedToStr(const string &speed, u_int32_t numOfLanes) -{ - string fecSpeedStrFormat = "100g"; - string numberOfLanesStr = to_string(numOfLanes) + "x"; - if (speed == "800G") { - fecSpeedStrFormat = "800g_" + numberOfLanesStr; - } - if (speed == "400G") { - fecSpeedStrFormat = "400g_" + numberOfLanesStr; - } - if (speed == "200G") { - fecSpeedStrFormat = "200g_" + numberOfLanesStr; - } - if (speed == "100G") { - if (numOfLanes == 4) { - fecSpeedStrFormat = "100g"; - } else { - fecSpeedStrFormat = "100g_" + numberOfLanesStr; - } - } - if (speed == "50G") { - if (numOfLanes == 1) { - fecSpeedStrFormat = "50g_" + numberOfLanesStr; - } else { - fecSpeedStrFormat = "50g"; - } - } - if (speed == "100GbE") { - fecSpeedStrFormat = "100g"; - } - if (speed == "50GbE") { - fecSpeedStrFormat = "50g"; - } - if (speed == "25GbE" || speed == "25G") { - fecSpeedStrFormat = "25g"; - } - if (speed == "40GbE" || speed == "40G" || speed == "10GbE" || speed == "10G") { - fecSpeedStrFormat = "10g_40g"; - } - if (speed == "56GbE") { - fecSpeedStrFormat = "56g"; - } - return fecSpeedStrFormat; -} - PAOS_CMD paos_to_int(const string &cmd) { if (cmd == "UP") { diff --git a/mlxlink/modules/mlxlink_utils.h b/mlxlink/modules/mlxlink_utils.h index 4c37aa65..3c1d8885 100644 --- a/mlxlink/modules/mlxlink_utils.h +++ b/mlxlink/modules/mlxlink_utils.h @@ -105,8 +105,7 @@ string prbsMaskToLockStatus(u_int32_t mask, u_int32_t numOfLanesToUse); bool checkPrbsCmd(const string &prbsCmd); bool checkTestMode(const string &testMode); string FEC2Str(const string &fecShort, const string &speedStrG); -int fecToBit(const string &fec, const string &speedStrG); -string speedToStr(const string &speed, u_int32_t numOfLanes); +string speedToFecSpeedStr(const string &speed, u_int32_t numOfLanes); PAOS_CMD paos_to_int(const string &cmd); int pepc_force_mode_to_int(const string &forceMode); int pepc_an_mode_to_int(const string &anMode); @@ -146,6 +145,7 @@ string getRxTxCDRState(u_int32_t state, u_int32_t numOfLanes); string getStringByActiveLanes(string allLanes, int numOfActiveLanes); string getFwVersion(bool passive, u_int32_t moduleFWVer); string getVendorRev(u_int32_t rev); -string getFieldsByMap(u_int32_t bitmask, std::map map); - +string getFieldsByMap(u_int32_t bitmask, map maskMap, const string &fieldSeparator = ","); +string getFieldsByPairMap(u_int32_t bitmask, map> maskMap, + const string &fieldSeparator = ",", u_int32_t pairIndex = 0); #endif diff --git a/mlxlink/modules/printutil/mlxlink_record.h b/mlxlink/modules/printutil/mlxlink_record.h index 07ce2eb6..fd3ec4cb 100644 --- a/mlxlink/modules/printutil/mlxlink_record.h +++ b/mlxlink/modules/printutil/mlxlink_record.h @@ -108,7 +108,7 @@ enum STATUS_DDM_FLAGS_TYPE { #define MPCNT_PERFORMANCE_INFO_LAST 4 #define MPCNT_TIMER_INFO_LAST 1 #define EYE_OPENING_INFO_LAST 9 -#define FEC_CAP_INFO_LASE 5 +#define FEC_CAP_INFO_LAST 6 #define DEVICE_INFO_LAST 5 #define BER_MONITOR_INFO_LAST 2 #define EXT_PHY_INFO_INFO_LAST 1 From 9c9587353babc82ab0c5230b0bcadcbf8ac00ab7 Mon Sep 17 00:00:00 2001 From: Oded Burstein Date: Sun, 19 Dec 2021 12:35:05 +0200 Subject: [PATCH 004/184] fixed several fields for BF3 --- mtcr_ul/mtcr_ib_ofed.c | 4 ++++ small_utils/mstfwreset.py | 4 ++-- tools_res_mgmt/tools_res_mgmt.c | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/mtcr_ul/mtcr_ib_ofed.c b/mtcr_ul/mtcr_ib_ofed.c index d78af077..8e40cf68 100644 --- a/mtcr_ul/mtcr_ib_ofed.c +++ b/mtcr_ul/mtcr_ib_ofed.c @@ -304,11 +304,15 @@ static int verbose = 0; void set_mkey_for_smp_mad(ibvs_mad *vsmad) { +#ifdef __linux__ if (vsmad->mkey) { vsmad->smp_mkey_set(vsmad->srcport, vsmad->mkey); } else { vsmad->smp_mkey_set(vsmad->srcport, 0); } +#else + (void)vsmad; +#endif } // Attribute modifier for mode 0: diff --git a/small_utils/mstfwreset.py b/small_utils/mstfwreset.py index 64d40487..2803802f 100644 --- a/small_utils/mstfwreset.py +++ b/small_utils/mstfwreset.py @@ -95,8 +95,8 @@ class SyncOwner(): dict(name="ConnectX4LX", devid=0x20b, status_config_not_done=(0xb0004, 31)), dict(name="ConnectX5", devid=0x20d, status_config_not_done=(0xb5e04, 31)), dict(name="BlueField", devid=0x211, status_config_not_done=(0xb5e04, 31)), - dict(name="BlueField2", devid=0x214, status_config_not_done=(0xb5e04, 31)), - dict(name="BlueField3", devid=0x21c, status_config_not_done=(0xb5e04, 31)), + dict(name="BlueField2", devid=0x214, status_config_not_done=(0xb5f04, 31)), + dict(name="BlueField3", devid=0x21c, status_config_not_done=(0xb5f04, 31)), dict(name="ConnectX6", devid=0x20f, status_config_not_done=(0xb5f04, 31)), dict(name="ConnectX6DX", devid=0x212, status_config_not_done=(0xb5f04, 31)), dict(name="ConnectX6LX", devid=0x216, status_config_not_done=(0xb5f04, 31)), diff --git a/tools_res_mgmt/tools_res_mgmt.c b/tools_res_mgmt/tools_res_mgmt.c index a104140c..208b5a1b 100644 --- a/tools_res_mgmt/tools_res_mgmt.c +++ b/tools_res_mgmt/tools_res_mgmt.c @@ -148,7 +148,7 @@ static struct device_sem_info g_dev_sem_info_db[] = { }, { DeviceBlueField3, // dev_id - {0xe74e0}, // hw_sem_addr + {0xe5660}, // hw_sem_addr 1, // vsec_sem_supported }, { From dbdd1e4f916e2a2a8b245f58622b2b59af872627 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Mon, 20 Dec 2021 10:23:16 +0200 Subject: [PATCH 005/184] [mstlink][maber] Updating amber_collect to 1.78 Description: -> Updating amber collection to version 1.78 -> Collecting more fields in --amber_collect flag Issue: 2843995 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/amber_field.cpp | 45 +- mlxlink/modules/amber_field.h | 8 +- mlxlink/modules/mlxlink_amBER_collector.cpp | 770 +++++++++++++------- mlxlink/modules/mlxlink_amBER_collector.h | 34 +- mlxlink/modules/mlxlink_commander.cpp | 211 ++---- mlxlink/modules/mlxlink_commander.h | 11 +- mlxlink/modules/mlxlink_enums.h | 69 +- mlxlink/modules/mlxlink_maps.cpp | 113 ++- mlxlink/modules/mlxlink_maps.h | 20 +- mlxlink/modules/mlxlink_utils.cpp | 41 +- mlxlink/modules/mlxlink_utils.h | 8 +- 11 files changed, 839 insertions(+), 491 deletions(-) diff --git a/mlxlink/modules/amber_field.cpp b/mlxlink/modules/amber_field.cpp index 02633bf8..5c905e65 100644 --- a/mlxlink/modules/amber_field.cpp +++ b/mlxlink/modules/amber_field.cpp @@ -32,6 +32,7 @@ #include "amber_field.h" #include "mlxlink_utils.h" +#include "mlxlink_reg_parser.h" u_int32_t AmberField::_lastFieldIndex = 1; bool AmberField::_dataValid = true; @@ -47,21 +48,23 @@ AmberField::AmberField(const string &uiField, const string &uiValue, if (visible) { _fieldIndex = _lastFieldIndex; _lastFieldIndex++; + } else { + _fieldIndex = 0; } findAndReplace(_uiValue, ",", "_"); } -AmberField::AmberField(const string &uiField, const string &uiValue, u_int64_t prmValue, - bool visible) : _uiField(uiField), _prmValue(prmValue), _visible(visible) +AmberField::AmberField(const string &uiField, const string &uiValue, u_int32_t fieldIndex, + bool visible) : _uiField(uiField), _visible(visible) { _prmReg = ""; _prmField = ""; _fieldGroup = ""; + _prmValue = 0; _uiValue = AmberField::_dataValid? uiValue : "N/A"; - if (visible) { - _fieldIndex = _lastFieldIndex; - _lastFieldIndex++; - } + + _fieldIndex = fieldIndex; + _lastFieldIndex = _fieldIndex + 1; findAndReplace(_uiValue, ",", "_"); } @@ -70,19 +73,26 @@ AmberField::~AmberField() } string AmberField::getValueFromFields(const vector &fields, - const string &uiField, bool getPrmValue) + const string &uiField, bool matchUiField) { - string value = "N/A"; + string value = ""; + bool found = false; for (auto it = fields.begin(); it != fields.end(); it++) { - if (it->getUiField() == uiField) { - if(getPrmValue){ - value = to_string(it->getPrmValue()); - }else{ - value = it->getUiValue(); + if (it->getUiField().find(uiField) != string::npos) { + if (matchUiField && it->getUiField() != uiField) { + continue; + } else { + value += it->getUiValue() + "_"; + found = true; } - break; } } + if (!found) { + throw MlxRegException("Requested field does not exist: %s", uiField.c_str()); + } + + value = deleteLastChar(value); + return value; } @@ -97,6 +107,11 @@ ostream& operator<<(ostream& os, const AmberField &amberField) return os; } +bool operator<(const AmberField &first, const AmberField &second) +{ + return first._fieldIndex < second._fieldIndex; +} + string AmberField::getUiField() const { return _uiField; @@ -118,7 +133,7 @@ bool AmberField::isVisible() return _visible; } -u_int32_t AmberField::getFieldIndex() +u_int32_t AmberField::getFieldIndex() const { return _fieldIndex; } diff --git a/mlxlink/modules/amber_field.h b/mlxlink/modules/amber_field.h index 00b8b3e1..23ddcc8e 100644 --- a/mlxlink/modules/amber_field.h +++ b/mlxlink/modules/amber_field.h @@ -42,19 +42,19 @@ using namespace std; class AmberField { public: AmberField (const string &uiField, const string &uiValue, bool visible = true); - AmberField (const string &uiField, const string &uiValue, u_int64_t prmValue, bool visible = true); - + AmberField (const string &uiField, const string &uiValue, u_int32_t fieldIndex, bool visible = true); ~AmberField (); + friend bool operator<(const AmberField &first, const AmberField &second); friend ostream& operator<<(ostream& os, const AmberField &amberField); string getUiField() const; string getUiValue() const; u_int64_t getPrmValue() const; bool isVisible(); - u_int32_t getFieldIndex(); + u_int32_t getFieldIndex() const; static void reset(); - static string getValueFromFields(const vector &fields, const string &uiField, bool getPrmValue = false); + static string getValueFromFields(const vector &fields, const string &uiField, bool matchUiField = true); static u_int32_t _lastFieldIndex; static bool _dataValid; diff --git a/mlxlink/modules/mlxlink_amBER_collector.cpp b/mlxlink/modules/mlxlink_amBER_collector.cpp index 89d7efa9..79f57a47 100644 --- a/mlxlink/modules/mlxlink_amBER_collector.cpp +++ b/mlxlink/modules/mlxlink_amBER_collector.cpp @@ -42,6 +42,7 @@ MlxlinkAmBerCollector::MlxlinkAmBerCollector(Json::Value &jsonRoot): _jsonRoot(j _secondSplit = 0; _numOfLanes = 0; _csvFileName = ""; + _mstDevName = ""; _iteration = 0; _testMode = "NOMINAL"; _depth = 0; @@ -51,6 +52,8 @@ MlxlinkAmBerCollector::MlxlinkAmBerCollector(Json::Value &jsonRoot): _jsonRoot(j _productTechnology = PRODUCT_16NM; _activeSpeed = 0; _devID = 0; + _moduleIndex = 0; + _slotIndex = 0; _isPortIB = false; _isPortETH = false; @@ -65,6 +68,8 @@ MlxlinkAmBerCollector::MlxlinkAmBerCollector(Json::Value &jsonRoot): _jsonRoot(j _isQsfpCable = false; _isSfpCable = false; _cablePlugged = false; + _inPRBSMode = false; + _invalidate = false; _mlxlinkMaps = NULL; } @@ -76,7 +81,7 @@ MlxlinkAmBerCollector::~MlxlinkAmBerCollector() void MlxlinkAmBerCollector::resetLocalParser(const string ®Name) { #ifndef VALIDATE_REG_REQUEST - AmberField::_dataValid = true; + AmberField::_dataValid = !_invalidate; #endif resetParser(regName); } @@ -84,7 +89,9 @@ void MlxlinkAmBerCollector::resetLocalParser(const string ®Name) void MlxlinkAmBerCollector::sendRegister(const string ®Name, maccess_reg_method_t method) { try { - genBuffSendRegister(regName, method); + if (AmberField::_dataValid) { + genBuffSendRegister(regName, method); + } } catch (MlxRegException &exc) { #ifdef VALIDATE_REG_REQUEST throw MlxRegException(regName + ": " + exc.what()); @@ -147,18 +154,11 @@ void MlxlinkAmBerCollector::startCollector() void MlxlinkAmBerCollector::init() { try { - string regName = "SLRG"; - resetParser(regName); - updateField("local_port", _localPort); - updateField("pnat", _pnat); - genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); - - _productTechnology = getVersion(getFieldValue("version")); if (!_isPortPCIE) { resetLocalParser(ACCESS_REG_PDDR); updateField("local_port", _localPort); updateField("page_select", PDDR_OPERATIONAL_INFO_PAGE); - sendRegister(ACCESS_REG_PDDR, MACCESS_REG_METHOD_GET); + genBuffSendRegister(ACCESS_REG_PDDR, MACCESS_REG_METHOD_GET); bool linkUp = getFieldValue("phy_mngr_fsm_state") == PHY_MNGR_ACTIVE_LINKUP; @@ -194,6 +194,12 @@ void MlxlinkAmBerCollector::init() } } + resetLocalParser(ACCESS_REG_PPAOS); + updateField("local_port", _localPort); + genBuffSendRegister(ACCESS_REG_PPAOS, MACCESS_REG_METHOD_GET); + + _inPRBSMode = getFieldValue("phy_test_mode_status") == 1; + resetLocalParser(ACCESS_REG_PDDR); updateField("local_port", _localPort); updateField("pnat", PNAT_LOCAL); @@ -203,6 +209,13 @@ void MlxlinkAmBerCollector::init() u_int32_t cableType = getFieldValue("cable_type"); _cablePlugged = (cableType != UNIDENTIFIED) && (cableType != UNPLUGGED); + + resetLocalParser(ACCESS_REG_PMLP); + updateField("local_port", _localPort); + genBuffSendRegister(ACCESS_REG_PMLP, MACCESS_REG_METHOD_GET); + + _moduleIndex = getFieldValue("lane0_module_mapping.module"); + _slotIndex = getFieldValue("lane0_module_mapping.slot_index"); } else { resetParser(ACCESS_REG_MPEIN); updateField("pcie_index", _pcieIndex); @@ -212,6 +225,21 @@ void MlxlinkAmBerCollector::init() _numOfLanes = getFieldValue("link_width_active"); } + + _sheetsList[AMBER_SHEET_GENERAL] = FIELDS_COUNT{4, 4, 4}; + _sheetsList[AMBER_SHEET_INDEXES] = FIELDS_COUNT{2, 2, 3}; + _sheetsList[AMBER_SHEET_LINK_STATUS] = FIELDS_COUNT{48, 72, 6}; + _sheetsList[AMBER_SHEET_MODULE_STATUS] = FIELDS_COUNT{111, 111, 0}; + _sheetsList[AMBER_SHEET_SYSTEM] = FIELDS_COUNT{16, 19, 11}; + _sheetsList[AMBER_SHEET_SERDES_16NM] = FIELDS_COUNT{736, 736, 0}; + _sheetsList[AMBER_SHEET_SERDES_7NM] = FIELDS_COUNT{283, 283, 57}; + _sheetsList[AMBER_SHEET_PORT_COUNTERS] = FIELDS_COUNT{35, 0, 35}; + _sheetsList[AMBER_SHEET_TROUBLESHOOTING] = FIELDS_COUNT{2, 2, 0}; + _sheetsList[AMBER_SHEET_PHY_OPERATION_INFO] = FIELDS_COUNT{18, 18, 15}; + _sheetsList[AMBER_SHEET_LINK_UP_INFO] = FIELDS_COUNT{6, 6, 0}; + _sheetsList[AMBER_SHEET_LINK_DOWN_INFO] = FIELDS_COUNT{5, 5, 0}; + _sheetsList[AMBER_SHEET_TEST_MODE_INFO] = FIELDS_COUNT{144, 144, 0}; + _sheetsList[AMBER_SHEET_TEST_MODE_MODULE_INFO] = FIELDS_COUNT{110, 110, 0}; } catch (...) { } } @@ -296,11 +324,11 @@ vector MlxlinkAmBerCollector::getIndexesInfo() vector fields; if (_isPortIB) { - fields.push_back(AmberField("Node GUID", getNodeGUID())); + fields.push_back(AmberField("Node_GUID", getNodeGUID())); } if (_isPortETH) { - fields.push_back(AmberField("MAC Address", getMACAddress())); + fields.push_back(AmberField("MAC_Address", getMACAddress())); } AmberField::_dataValid = true; @@ -314,7 +342,7 @@ vector MlxlinkAmBerCollector::getIndexesInfo() if ((_secondSplit && _secondSplit != 1) && _devID == DeviceQuantum2) { labelPortStr += "/" + to_string(_secondSplit); } - fields.push_back(AmberField("Port Number", labelPortStr + "(" + + fields.push_back(AmberField("Port_Number", labelPortStr + "(" + to_string(_localPort) + ")" , !_isPortPCIE)); fields.push_back(AmberField("depth", to_string(_depth), _isPortPCIE)); @@ -330,10 +358,10 @@ vector MlxlinkAmBerCollector::getGeneralInfo() AmberField::_dataValid = true; - fields.push_back(AmberField("amBer Version", AMBER_VERSION)); - fields.push_back(AmberField("Time Stamp", getCurrentTimeStamp())); + fields.push_back(AmberField("amBer_Version", AMBER_VERSION)); + fields.push_back(AmberField("Time_Stamp", getCurrentTimeStamp())); fields.push_back(AmberField("Iteration/Sweep", to_string(_iteration))); - fields.push_back(AmberField("Test Mode (Nominal/Corner/Drift)", _testMode)); + fields.push_back(AmberField("Test_Description", _testMode)); return fields; } @@ -349,9 +377,11 @@ vector MlxlinkAmBerCollector::getSystemInfo() string sensNameTemp = "N/A"; string temp = "N/A"; + fields.push_back(AmberField("Device_Description", _mstDevName.c_str())); + resetLocalParser(ACCESS_REG_MSGI); sendRegister(ACCESS_REG_MSGI, MACCESS_REG_METHOD_GET); - fields.push_back(AmberField("Device PartNumber", getAscii("part_number", 20))); + fields.push_back(AmberField("Device_PartNumber", getAscii("part_number", 20))); resetLocalParser(ACCESS_REG_MGIR); sendRegister(ACCESS_REG_MGIR, MACCESS_REG_METHOD_GET); @@ -359,12 +389,12 @@ vector MlxlinkAmBerCollector::getSystemInfo() getFieldStr("extended_minor") + "." + getFieldStr("extended_sub_minor"); string tech = _mlxlinkMaps->_tech[getFieldValue("technology")]; - fields.push_back(AmberField("Device FW Version", fwVersion)); + fields.push_back(AmberField("Device_FW_Version", fwVersion)); resetLocalParser(ACCESS_REG_MDIR); sendRegister(ACCESS_REG_MDIR, MACCESS_REG_METHOD_GET); - fields.push_back(AmberField("Device ID", getRawFieldValueStr("device_id"))); - fields.push_back(AmberField("SerDes Technology", tech)); + fields.push_back(AmberField("Device_ID", getRawFieldValueStr("device_id"))); + fields.push_back(AmberField("SerDes_Technology_(16nm/7nm_5nm)", tech)); resetLocalParser(ACCESS_REG_MVCAP); sendRegister(ACCESS_REG_MVCAP, MACCESS_REG_METHOD_GET); @@ -377,9 +407,9 @@ vector MlxlinkAmBerCollector::getSystemInfo() sysCur = getFieldStr("current_sensor_value"); sensNameVoltage = getFullString(add32BitTo64(getFieldValue("sensor_name_hi"), getFieldValue("sensor_name_lo"))); } - fields.push_back(AmberField("System Voltage", sysVol)); - fields.push_back(AmberField("System Current", sysCur)); - fields.push_back(AmberField("Voltage/Current sensor name", sensNameVoltage)); + fields.push_back(AmberField("System_Voltage", sysVol)); + fields.push_back(AmberField("System_Current", sysCur)); + fields.push_back(AmberField("Voltage/Current_sensor_name", sensNameVoltage)); resetLocalParser(ACCESS_REG_MTCAP); sendRegister(ACCESS_REG_MTCAP, MACCESS_REG_METHOD_GET); @@ -391,19 +421,19 @@ vector MlxlinkAmBerCollector::getSystemInfo() temp = getTemp(getFieldValue("temperature"), 8); sensNameTemp = getFullString(add32BitTo64(getFieldValue("sensor_name_hi"), getFieldValue("sensor_name_lo"))); } - fields.push_back(AmberField("Chip Temp",temp)); + fields.push_back(AmberField("Chip_Temp",temp)); resetLocalParser(ACCESS_REG_MSGI); sendRegister(ACCESS_REG_MSGI, MACCESS_REG_METHOD_GET); - fields.push_back(AmberField("Device SN", getAscii("serial_number", 24))); + fields.push_back(AmberField("Device_SN", getAscii("serial_number", 24))); - fields.push_back(AmberField("Temp sensor name", sensNameTemp)); + fields.push_back(AmberField("Temp_sensor_name", sensNameTemp)); resetLocalParser(ACCESS_REG_PDDR); updateField("local_port", _localPort); updateField("page_select", PDDR_MODULE_INFO_PAGE); sendRegister(ACCESS_REG_PDDR, MACCESS_REG_METHOD_GET); - fields.push_back(AmberField("Module Temp", getTemp(getFieldValue("temperature")), !_isPortPCIE)); + fields.push_back(AmberField("Module_Temp", getTemp(getFieldValue("temperature")), !_isPortPCIE)); } catch (const std::exception &exc) { throw MlxRegException( @@ -452,23 +482,23 @@ vector MlxlinkAmBerCollector::getPhyOperationInfo() fields.push_back(AmberField("eth_an_fsm_state",_mlxlinkMaps->_ethANFsmState[getFieldValue("eth_an_fsm_state")])); fields.push_back(AmberField("ib_phy_fsm_state",_mlxlinkMaps->_ibPhyFsmState[getFieldValue("ib_phy_fsm_state")])); if(_isPortIB){ - phyManagerLinkEnabledStr = getFieldsByMap(getFieldValue("phy_manager_link_proto_enabled"),_mlxlinkMaps->_IBSpeed2Str); - coreToPhyLinkEnabledStr = getFieldsByMap(getFieldValue("core_to_phy_link_proto_enabled"),_mlxlinkMaps->_IBSpeed2Str); - cableProtoCapStr = getFieldsByMap(getFieldValue("cable_link_speed_cap"),_mlxlinkMaps->_IBSpeed2Str); + phyManagerLinkEnabledStr = getStrByMask(getFieldValue("phy_manager_link_proto_enabled"),_mlxlinkMaps->_IBSpeed2Str); + coreToPhyLinkEnabledStr = getStrByMask(getFieldValue("core_to_phy_link_proto_enabled"),_mlxlinkMaps->_IBSpeed2Str); + cableProtoCapStr = getStrByMask(getFieldValue("cable_link_speed_cap"),_mlxlinkMaps->_IBSpeed2Str); }else if(_isPortETH){ - phyManagerLinkEnabledStr = getFieldsByMap(getFieldValue("phy_manager_link_eth_enabled"),_mlxlinkMaps->_EthExtSpeed2Str); - coreToPhyLinkEnabledStr = getFieldsByMap(getFieldValue("core_to_phy_link_eth_enabled"),_mlxlinkMaps->_EthExtSpeed2Str); - cableProtoCapStr = getFieldsByMap(getFieldValue("cable_ext_eth_proto_cap"),_mlxlinkMaps->_EthExtSpeed2Str); + phyManagerLinkEnabledStr = getStrByMask(getFieldValue("phy_manager_link_eth_enabled"),_mlxlinkMaps->_EthExtSpeed2Str); + coreToPhyLinkEnabledStr = getStrByMask(getFieldValue("core_to_phy_link_eth_enabled"),_mlxlinkMaps->_EthExtSpeed2Str); + cableProtoCapStr = getStrByMask(getFieldValue("cable_ext_eth_proto_cap"),_mlxlinkMaps->_EthExtSpeed2Str); } fields.push_back(AmberField("phy_manager_link_enabled",phyManagerLinkEnabledStr)); fields.push_back(AmberField("core_to_phy_link_enabled",coreToPhyLinkEnabledStr)); fields.push_back(AmberField("cable_proto_cap",cableProtoCapStr)); u_int32_t phyMngrFsmState = getFieldValue("phy_mngr_fsm_state"); string loopbackMode = (phyMngrFsmState != PHY_MNGR_DISABLED) ? _mlxlinkMaps->_loopbackModeList[getFieldValue("loopback_mode")] : "-1"; + u_int32_t fecModeRequest = (u_int32_t)log2((float)getFieldValue("fec_mode_request")); fields.push_back(AmberField("loopback_mode",loopbackMode)); - fields.push_back(AmberField("fec_mode_active ",_mlxlinkMaps->_fecModeActive[getFieldValue("fec_mode_active")])); - fields.push_back(AmberField("fec_mode_request ",_mlxlinkMaps->_fecModeActive[getFieldValue("fec_mode_request")])); + fields.push_back(AmberField("fec_mode_request ",_mlxlinkMaps->_fecModeActive[fecModeRequest])); if (_isPortPCIE) { resetLocalParser(ACCESS_REG_MPEIN); @@ -509,56 +539,42 @@ string MlxlinkAmBerCollector::getBerAndErrorTitle(u_int32_t portType) return title; } -void MlxlinkAmBerCollector::getPpcntErrors(u_int32_t portType, vector &fields) -{ - resetLocalParser(ACCESS_REG_PPCNT); - updateField("local_port", _localPort); - if (portType != NETWORK_PORT_TYPE && !_isHca) { - updateField("port_type",portType); - } - updateField("grp", PPCNT_STATISTICAL_GROUP); - sendRegister(ACCESS_REG_PPCNT, MACCESS_REG_METHOD_GET); - - string preTitle = getBerAndErrorTitle(portType); - string effErrorsStr = "N/A"; - if (portType == NETWORK_PORT_TYPE) { - effErrorsStr = to_string(add32BitTo64( - getFieldValue("phy_effective_errors_high"), - getFieldValue("phy_effective_errors_low"))); - } - fields.push_back(AmberField(preTitle + "Effective Errors", effErrorsStr)); - - u_int64_t symErrors = add32BitTo64( - getFieldValue("phy_symbol_errors_high"), - getFieldValue("phy_symbol_errors_low")); - fields.push_back(AmberField(preTitle + "Symbol Errors", to_string(symErrors), _isPortIB)); -} - void MlxlinkAmBerCollector::getPpcntBer(u_int32_t portType, vector &fields) { resetLocalParser(ACCESS_REG_PPCNT); updateField("local_port", _localPort); if (portType != NETWORK_PORT_TYPE && !_isHca) { - updateField("port_type",portType); + updateField("port_type", portType); } updateField("grp", PPCNT_STATISTICAL_GROUP); sendRegister(ACCESS_REG_PPCNT, MACCESS_REG_METHOD_GET); string preTitle = getBerAndErrorTitle(portType); - string berStr = to_string(getFieldValue("raw_ber_coef")) + "E-" + to_string(getFieldValue("raw_ber_magnitude")); + string confLevelStr = preTitle+"Conf_Level_Raw_BER"; + if (portType == NETWORK_PORT_TYPE_MAIN_USR || portType == NETWORK_PORT_TYPE_TILE_USR) { + confLevelStr = "Conf_Level"+preTitle+"Raw_BER"; + } - fields.push_back(AmberField("Conf Level - " + preTitle + " Raw BER", getClRawBer())); - fields.push_back(AmberField(preTitle + "Raw BER", berStr)); + fields.push_back(AmberField(confLevelStr, getClRawBer())); + fields.push_back(AmberField(preTitle + "Raw_BER", berStr)); berStr = to_string(getFieldValue("effective_ber_coef")) + "E-" + to_string(getFieldValue("effective_ber_magnitude")); - fields.push_back(AmberField(preTitle + "Effective BER", berStr)); + fields.push_back(AmberField(preTitle + "Effective_BER", berStr)); - berStr = to_string(getFieldValue("symbol_fec_ber_coef")) + "E-" + - to_string(getFieldValue("symbol_ber_magnitude")); - fields.push_back(AmberField(preTitle + "Symbol BER", berStr, _isPortIB)); + if (portType != NETWORK_PORT_TYPE || (portType == NETWORK_PORT_TYPE && _isPortIB)) { + berStr = to_string(getFieldValue("symbol_fec_ber_coef")) + "E-" + + to_string(getFieldValue("symbol_ber_magnitude")); + fields.push_back(AmberField(preTitle + "Symbol_BER", berStr)); + + if (portType != NETWORK_PORT_TYPE ) { + u_int64_t symErrors = add32BitTo64(getFieldValue("phy_symbol_errors_high"), + getFieldValue("phy_symbol_errors_low")); + fields.push_back(AmberField(preTitle + "Symbol_Errors", to_string(symErrors))); + } + } } vector MlxlinkAmBerCollector::getLinkStatus() @@ -572,7 +588,7 @@ vector MlxlinkAmBerCollector::getLinkStatus() updateField("page_select", PDDR_OPERATIONAL_INFO_PAGE); sendRegister(ACCESS_REG_PDDR, MACCESS_REG_METHOD_GET); - fields.push_back(AmberField("Phy Manager State", + fields.push_back(AmberField("Phy_Manager_State", _mlxlinkMaps->_pmFsmState[getFieldValue("phy_mngr_fsm_state")])); fields.push_back(AmberField("Protocol", _mlxlinkMaps->_networkProtocols[_protoActive])); @@ -585,8 +601,8 @@ vector MlxlinkAmBerCollector::getLinkStatus() char dataRateStr[64]; sprintf(dataRateStr, "%.2f", dataRate); u_int32_t ethLinkActive = getFieldValue("ext_eth_proto_oper"); - fields.push_back(AmberField("Speed [Gb/s]", string(dataRateStr))); - fields.push_back(AmberField("Ethernet Protocol Active", + fields.push_back(AmberField("Speed_[Gb/s]", string(dataRateStr))); + fields.push_back(AmberField("Ethernet_Protocol_Active", ethLinkActive? _mlxlinkMaps->_EthExtSpeed2Str[ethLinkActive] : "N/A", _isPortETH)); resetLocalParser(ACCESS_REG_PDDR); @@ -595,11 +611,11 @@ vector MlxlinkAmBerCollector::getLinkStatus() sendRegister(ACCESS_REG_PDDR, MACCESS_REG_METHOD_GET); string linkSpeedActive = SupportedSpeeds2Str(IB, getFieldValue("link_speed_active"), true); - fields.push_back(AmberField("Link Speed Active", + fields.push_back(AmberField("Link_Speed_Active", linkSpeedActive.empty()? "N/A" : linkSpeedActive, _isPortIB)); - fields.push_back(AmberField("Link Width Active", + fields.push_back(AmberField("Link_Width_Active", linkWidthMaskToStr(getFieldValue("link_width_active")), _isPortIB)); - fields.push_back(AmberField("Active FEC", + fields.push_back(AmberField("Active_FEC", _mlxlinkMaps->_fecModeActive[getFieldValue("fec_mode_active")])); } else { // Getting link info for PCIE @@ -608,9 +624,9 @@ vector MlxlinkAmBerCollector::getLinkStatus() updateField("pcie_index", _pcieIndex); updateField("node", _node); sendRegister(ACCESS_REG_MPEIN, MACCESS_REG_METHOD_GET); - fields.push_back(AmberField("Link speed active", + fields.push_back(AmberField("Link_speed_active", pcieSpeedStr(getFieldValue("link_speed_active")))); - fields.push_back(AmberField("Link width active", + fields.push_back(AmberField("Link_width_active", to_string(getFieldValue("link_width_active")) + "x")); } @@ -624,7 +640,7 @@ vector MlxlinkAmBerCollector::getLinkStatus() getFieldValue("time_since_last_clear_low"))/60000.0; char timeFrmt[64]; sprintf(timeFrmt, "%.1f", lastClear); - fields.push_back(AmberField("Time since last clear [Min]", string(timeFrmt))); + fields.push_back(AmberField("Time_since_last_clear_[Min]", string(timeFrmt))); getPpcntBer(NETWORK_PORT_TYPE, fields); @@ -660,9 +676,9 @@ vector MlxlinkAmBerCollector::getLinkStatus() } histPerLane.push_back(val); } - fields.push_back(AmberField("FC Zero Hist", firstZeroHist >= 0 ? to_string(firstZeroHist) + fields.push_back(AmberField("FC_Zero_Hist", firstZeroHist >= 0 ? to_string(firstZeroHist) : "N/A")); - fields.push_back(AmberField("Number of histogram bins", to_string(numOfBins))); + fields.push_back(AmberField("Number_of_histogram_bins", to_string(numOfBins))); fillParamsToFields("hist", histPerLane, fields, false); // Getting raw errors per lane for ETH and IB only resetLocalParser(ACCESS_REG_PPCNT); @@ -678,10 +694,19 @@ vector MlxlinkAmBerCollector::getLinkStatus() getFieldValue("phy_raw_errors_lane" + to_string(lane) + "_low")); val = to_string(rawError); } - fields.push_back(AmberField("Raw Errors Lane " + to_string(lane), val)); + fields.push_back(AmberField("Raw_Errors_Lane" + to_string(lane), val)); } + resetLocalParser(ACCESS_REG_PPCNT); + updateField("local_port", _localPort); + updateField("grp", PPCNT_STATISTICAL_GROUP); + sendRegister(ACCESS_REG_PPCNT, MACCESS_REG_METHOD_GET); - getPpcntErrors(NETWORK_PORT_TYPE, fields); + string effErrorsStr = to_string(add32BitTo64(getFieldValue("phy_effective_errors_high"), + getFieldValue("phy_effective_errors_low"))); + fields.push_back(AmberField("Effective_Errors", effErrorsStr)); + u_int64_t symErrors = add32BitTo64(getFieldValue("phy_symbol_errors_high"), + getFieldValue("phy_symbol_errors_low")); + fields.push_back(AmberField("Symbol_Errors", to_string(symErrors), _isPortIB)); } else { // Getting link errors info for PCIE resetLocalParser(ACCESS_REG_MPCNT); @@ -716,47 +741,84 @@ void MlxlinkAmBerCollector::fillParamsToFields(const string &title, if ((idx < _numOfLanes) || !laneLimit) { val = values[idx]; } - fieldName = laneLimit ? ("Lane " + to_string(idx) + " " + title) : (title + to_string(idx)); + fieldName = laneLimit ? ("Lane" + to_string(idx) + "_" + title) : (title + to_string(idx)); fields.push_back(AmberField(fieldName, val)); } } -void MlxlinkAmBerCollector::getSltpFields(vector &fields) +vector MlxlinkAmBerCollector::getSerdesHDR() { - vector> sltpParams (PARAMS_16NM_LAST, vector (_numOfLanes, "")); - vector sltpStatus; + vector fields; - for (u_int32_t lane = 0; lane < _numOfLanes; lane++) { - resetLocalParser(ACCESS_REG_SLTP); - updateField("local_port", _localPort); - updateField("lane", lane); - sendRegister(ACCESS_REG_SLTP, MACCESS_REG_METHOD_GET); - - sltpParams[PRE_2_TAP][lane] = getFieldStr("pre_2_tap"); - sltpParams[PRE_TAP][lane] = getFieldStr("pre_tap"); - sltpParams[MAIN_TAP][lane] = getFieldStr("main_tap"); - sltpParams[POST_TAP][lane] = getFieldStr("post_tap"); - sltpParams[OB_M2LP][lane] = getFieldStr("ob_m2lp"); - sltpParams[OB_AMP][lane] = getFieldStr("ob_amp"); - sltpParams[OB_ALEV_OUT][lane] = getFieldStr("ob_alev_out"); - sltpStatus.push_back(getFieldValue("status") ? "Valid" : "Invalid"); - } - - fillParamsToFields("Status", sltpStatus, fields); - fillParamsToFields("pre_2_tap", sltpParams[PRE_2_TAP], fields); - fillParamsToFields("pre_tap", sltpParams[PRE_TAP], fields); - fillParamsToFields("main_tap", sltpParams[MAIN_TAP], fields); - fillParamsToFields("post_tap", sltpParams[POST_TAP], fields); - fillParamsToFields("ob_m2lp", sltpParams[OB_M2LP], fields); - fillParamsToFields("ob_amp", sltpParams[OB_AMP], fields); - fillParamsToFields("ob_alev_out", sltpParams[OB_ALEV_OUT], fields); + try { + if (!_isPortPCIE) { + vector> slrgParams (SLRG_PARAMS_LAST, vector (_numOfLanes, "")); + vector> sltpParams (PARAMS_16NM_LAST, vector (_numOfLanes, "")); + vector sltpStatus; + u_int32_t lane = 0; + // Getting 16nm SLRG information for all lanes + for (; lane < _numOfLanes; lane++) { + resetLocalParser(ACCESS_REG_SLRG); + updateField("local_port", _localPort); + updateField("lane", lane); + sendRegister(ACCESS_REG_SLRG, MACCESS_REG_METHOD_GET); + + slrgParams[SLRG_PARAMS_INITIAL_FOM][lane] = getFieldStr("grade"); + slrgParams[SLRG_PARAMS_UPPER_EYE][lane] = getFieldStr("up_eye_grade"); + slrgParams[SLRG_PARAMS_MID_EYE][lane] = getFieldStr("mid_eye_grade"); + slrgParams[SLRG_PARAMS_LOWER_EYE][lane] = getFieldStr("dn_eye_grade"); + } + fillParamsToFields("Grade", slrgParams[SLRG_PARAMS_INITIAL_FOM], fields); + AmberField::_dataValid = false; // TODO: remove this line when supporting following fields + fillParamsToFields("up_eye_grade", slrgParams[SLRG_PARAMS_UPPER_EYE], fields); + fillParamsToFields("mid_eye_grade", slrgParams[SLRG_PARAMS_MID_EYE], fields); + fillParamsToFields("low_eye_grade", slrgParams[SLRG_PARAMS_LOWER_EYE], fields); + AmberField::_dataValid = true; // TODO: remove this line when supporting fields above + + // Getting 16nm SLTP information for all lanes + for (u_int32_t lane = 0; lane < _numOfLanes; lane++) { + resetLocalParser(ACCESS_REG_SLTP); + updateField("local_port", _localPort); + updateField("lane", lane); + sendRegister(ACCESS_REG_SLTP, MACCESS_REG_METHOD_GET); + + sltpParams[PRE_2_TAP][lane] = getFieldStr("pre_2_tap"); + sltpParams[PRE_TAP][lane] = getFieldStr("pre_tap"); + sltpParams[MAIN_TAP][lane] = getFieldStr("main_tap"); + sltpParams[POST_TAP][lane] = getFieldStr("post_tap"); + sltpParams[OB_M2LP][lane] = getFieldStr("ob_m2lp"); + sltpParams[OB_AMP][lane] = getFieldStr("ob_amp"); + sltpParams[OB_ALEV_OUT][lane] = getFieldStr("ob_alev_out"); + sltpStatus.push_back(getFieldValue("status") ? "Valid" : "Invalid"); + } + + fillParamsToFields("Status", sltpStatus, fields); + fillParamsToFields("pre_2_tap", sltpParams[PRE_2_TAP], fields); + fillParamsToFields("pre_tap", sltpParams[PRE_TAP], fields); + fillParamsToFields("main_tap", sltpParams[MAIN_TAP], fields); + fillParamsToFields("post_tap", sltpParams[POST_TAP], fields); + fillParamsToFields("ob_m2lp", sltpParams[OB_M2LP], fields); + fillParamsToFields("ob_amp", sltpParams[OB_AMP], fields); + fillParamsToFields("ob_alev_out", sltpParams[OB_ALEV_OUT], fields); + } + } catch (const std::exception &exc) { + throw MlxRegException( + "Failed to get SerDes[16nm] information: %s", exc.what()); + } + + return fields; } -void MlxlinkAmBerCollector::getSlrgFields(vector &fields) +vector MlxlinkAmBerCollector::getSerdesNDR() { - vector> slrgParams (SLRG_PARAMS_LAST, vector (_numOfLanes, "")); - u_int32_t lane = 0; - if (_productTechnology == PRODUCT_7NM) { + vector fields; + + try { + fields.push_back(AmberField("UPHY_version", "N/A")); + fields.push_back(AmberField("BKV_version", "N/A")); + + vector> slrgParams (SLRG_PARAMS_LAST, vector (_numOfLanes, "")); + u_int32_t lane = 0; // Getting 7nm SLRG information for all lanes for (; lane < _numOfLanes; lane++) { resetLocalParser(ACCESS_REG_SLRG); @@ -780,53 +842,6 @@ void MlxlinkAmBerCollector::getSlrgFields(vector &fields) fillParamsToFields("lower_eye", slrgParams[SLRG_PARAMS_INITIAL_FOM], fields); } fillParamsToFields("composite_eye", slrgParams[SLRG_PARAMS_LAST_FOM], fields); - } else if (_productTechnology == PRODUCT_16NM) { - // Getting 16nm SLRG information for all lanes - for (; lane < _numOfLanes; lane++) { - resetLocalParser(ACCESS_REG_SLRG); - updateField("local_port", _localPort); - updateField("lane", lane); - sendRegister(ACCESS_REG_SLRG, MACCESS_REG_METHOD_GET); - - slrgParams[SLRG_PARAMS_INITIAL_FOM][lane] = getFieldStr("grade"); - slrgParams[SLRG_PARAMS_UPPER_EYE][lane] = getFieldStr("up_eye_grade"); - slrgParams[SLRG_PARAMS_MID_EYE][lane] = getFieldStr("mid_eye_grade"); - slrgParams[SLRG_PARAMS_LOWER_EYE][lane] = getFieldStr("dn_eye_grade"); - } - fillParamsToFields("Grade", slrgParams[SLRG_PARAMS_INITIAL_FOM], fields); - AmberField::_dataValid = false; // TODO: remove this line when supporting following fields - fillParamsToFields("up eye grade", slrgParams[SLRG_PARAMS_UPPER_EYE], fields); - fillParamsToFields("mid eye grade", slrgParams[SLRG_PARAMS_MID_EYE], fields); - fillParamsToFields("low eye grade", slrgParams[SLRG_PARAMS_LOWER_EYE], fields); - AmberField::_dataValid = true; // TODO: remove this line when supporting fields above - } -} - -vector MlxlinkAmBerCollector::getSerdesHDR() -{ - vector fields; - try { - if (_productTechnology == PRODUCT_16NM && !_isPortPCIE) { - getSlrgFields(fields); - getSltpFields(fields); - } - - } catch (const std::exception &exc) { - throw MlxRegException( - "Failed to get SerDes[16nm] information: %s", exc.what()); - } - - return fields; -} - -vector MlxlinkAmBerCollector::getSerdesNDR() -{ - vector fields; - - try { - if (_productTechnology == PRODUCT_7NM) { - getSlrgFields(fields); - } } catch (const std::exception &exc) { throw MlxRegException( "Failed to get SerDes[7nm] information: %s", exc.what()); @@ -935,7 +950,7 @@ string MlxlinkAmBerCollector::getCableTechnologyStr(u_int32_t cableTechnology) return technologyStr; } -string MlxlinkAmBerCollector::getCableBreakoutStr(u_int32_t cableBreakout) +string MlxlinkAmBerCollector::getCableBreakoutStr(u_int32_t cableBreakout, u_int32_t cableIdentifier) { string cableBreakoutStr = ""; string impCh = ""; @@ -943,7 +958,7 @@ string MlxlinkAmBerCollector::getCableBreakoutStr(u_int32_t cableBreakout) if (_isCmisCable) { cableBreakoutStr = _mlxlinkMaps->_cimsCableBreakout[cableBreakout]; - + findAndReplace(cableBreakoutStr, "X", getCableIdentifier(cableIdentifier)); } else if (_isQsfpCable){ u_int32_t near_end_bits = cableBreakout & 0xF; u_int32_t far_end_bits = (cableBreakout >> 4) & 0xF; @@ -970,6 +985,7 @@ string MlxlinkAmBerCollector::getCableBreakoutStr(u_int32_t cableBreakout) } else { cableBreakoutStr = "N/A"; } + return cableBreakoutStr; } @@ -992,10 +1008,13 @@ void MlxlinkAmBerCollector::getTxBiasLane(vector &fields) void MlxlinkAmBerCollector::loopAllLanesStr(vector &fields, const string str) { string dpStateStr = "N/A"; + string fieldName = str; + + fieldName = toLowerCase(fieldName); for (u_int32_t lane = 0; lane < LANES_NUM; lane++) { string laneStr = to_string(lane); - dpStateStr = getFieldsByMap(getFieldValue(str + laneStr),_mlxlinkMaps->_dataPathSt); + dpStateStr = getStrByMask(getFieldValue(fieldName + laneStr),_mlxlinkMaps->_dataPathSt); fields.push_back(AmberField(str + laneStr, dpStateStr)); dpStateStr = "N/A"; } @@ -1077,6 +1096,7 @@ void MlxlinkAmBerCollector::getModuleInfoPage(vector &fields) string activeSetHostComplianceCode = "N/A"; string activeSetMediaComplianceCode = "N/A"; string nbrString = "N/A"; + string error_code_res = "N/A"; char vendorOUIStr [32]; sprintf(vendorOUIStr, "0x%X", vendorOUI); @@ -1088,91 +1108,103 @@ void MlxlinkAmBerCollector::getModuleInfoPage(vector &fields) getIbComplianceCodes(ibComplianceCodeStr); } - fields.push_back(AmberField("ethernet_compliance_code", ethComplianceStr, _isPortETH)); - fields.push_back(AmberField("ext_ethernet_compliance_code", extComplianceStr, _isPortETH)); - fields.push_back(AmberField("ib_compliance_code", ibComplianceCodeStr, _isPortIB)); + fields.push_back(AmberField("ethernet_compliance_code", ethComplianceStr, _isPortETH)); + fields.push_back(AmberField("ext_ethernet_compliance_code", extComplianceStr, _isPortETH)); + fields.push_back(AmberField("ib_compliance_code", ibComplianceCodeStr, _isPortIB)); fields.push_back(AmberField("ib_width", ibWidthStr, _isPortIB)); - fields.push_back(AmberField("Memory map rev", getFieldStr("memory_map_rev"))); - fields.push_back(AmberField("Vendor OUI", string(vendorOUIStr))); - fields.push_back(AmberField("Cable PN", getAscii("vendor_pn", 16))); - fields.push_back(AmberField("Cable SN", getAscii("vendor_sn", 16))); + fields.push_back(AmberField("Memory_map_rev", getFieldStr("memory_map_rev"))); + fields.push_back(AmberField("Vendor_OUI", string(vendorOUIStr))); + fields.push_back(AmberField("Cable_PN", getAscii("vendor_pn", 16))); + fields.push_back(AmberField("Cable_SN", getAscii("vendor_sn", 16))); fields.push_back(AmberField("cable_technology", getCableTechnologyStr(cableTechnology))); - fields.push_back(AmberField("linear direct drive", getFieldStr("did_cap"))); - fields.push_back(AmberField("cable_breakout", getCableBreakoutStr(cableBreakout))); - fields.push_back(AmberField("cable_type", getCableType(getFieldValue("cable_type")))); - fields.push_back(AmberField("cable_vendor", getOui(getFieldValue("cable_vendor")))); - fields.push_back(AmberField("cable_length", getCableLengthStr(getFieldValue("cable_length"), _isCmisCable) + 'm')); - fields.push_back(AmberField("smf_length", getSmfLength(getFieldValue("smf_length"),cableTechnology,optical))); - fields.push_back(AmberField("cable_identifier", getCableIdentifier(getFieldValue("cable_identifier")))); + fields.push_back(AmberField("linear_direct_drive", getFieldStr("did_cap"))); + fields.push_back(AmberField("cable_breakout", getCableBreakoutStr(cableBreakout, cableIdentifier))); + fields.push_back(AmberField("cable_type", getCableType(getFieldValue("cable_type")))); + fields.push_back(AmberField("cable_vendor", getOui(getFieldValue("cable_vendor")))); + fields.push_back(AmberField("cable_length", getCableLengthStr(getFieldValue("cable_length"), _isCmisCable) + 'm')); + fields.push_back(AmberField("smf_length", getSmfLength(getFieldValue("smf_length"),cableTechnology,optical))); + fields.push_back(AmberField("cable_identifier", getCableIdentifier(getFieldValue("cable_identifier")))); fields.push_back(AmberField("cable_power_class", - getPowerClass(_mlxlinkMaps, cableIdentifier, getFieldValue("cable_power_class"), getFieldValue("max_power")))); - fields.push_back(AmberField("max_power", getFieldStr("max_power"))); - fields.push_back(AmberField("cable_rx_amp", passive ? "N/A" : getFieldStr("cable_rx_amp"))); - fields.push_back(AmberField("cable_rx_emphasis", passive ? "N/A" : getFieldStr("cable_rx_emphasis"))); + getPowerClass(_mlxlinkMaps, cableIdentifier, getFieldValue("cable_power_class"), + getFieldValue("max_power")))); + fields.push_back(AmberField("max_power", getFieldStr("max_power"))); + fields.push_back(AmberField("cable_rx_amp", passive ? "N/A" : getFieldStr("cable_rx_amp"))); + fields.push_back(AmberField("cable_rx_emphasis", passive ? "N/A" : getFieldStr("cable_rx_emphasis"))); fields.push_back(AmberField("cable_rx_post_emphasis", passive ? "N/A" : getFieldStr("cable_rx_post_emphasis"))); fields.push_back(AmberField("cable_tx_equalization", passive ? "N/A" : getFieldStr("cable_tx_equalization"))); - fields.push_back(AmberField("cable_attenuation_25g", getFieldStr("cable_attenuation_25g"))); - fields.push_back(AmberField("cable_attenuation_12g", getFieldStr("cable_attenuation_12g"))); - fields.push_back(AmberField("cable_attenuation_7g", getFieldStr("cable_attenuation_7g"))); - fields.push_back(AmberField("cable_attenuation_5g", getFieldStr("cable_attenuation_5g"))); - fields.push_back(AmberField("rx_cdr_cap", _mlxlinkMaps->_rxTxCdrCap[getFieldValue("rx_cdr_cap")])); - fields.push_back(AmberField("tx_cdr_cap", _mlxlinkMaps->_rxTxCdrCap[getFieldValue("tx_cdr_cap")])); - fields.push_back(AmberField("rx_cdr_state", getRxTxCDRState(getFieldValue("rx_cdr_state"),LANES_NUM))); - fields.push_back(AmberField("tx_cdr_state", getRxTxCDRState(getFieldValue("tx_cdr_state"),LANES_NUM))); - fields.push_back(AmberField("vendor_name", getAscii("vendor_name", 16))); - fields.push_back(AmberField("vendor_rev", getVendorRev(getFieldValue("vendor_rev")))); - fields.push_back(AmberField("module_fw_version", getFwVersion(passive,getFieldValue("fw_version")))); + fields.push_back(AmberField("cable_attenuation_25g", getFieldStr("cable_attenuation_25g"))); + fields.push_back(AmberField("cable_attenuation_12g", getFieldStr("cable_attenuation_12g"))); + fields.push_back(AmberField("cable_attenuation_7g", getFieldStr("cable_attenuation_7g"))); + fields.push_back(AmberField("cable_attenuation_5g", getFieldStr("cable_attenuation_5g"))); + fields.push_back(AmberField("tx_input_freq_sync", getStrByValue(getFieldValue("tx_input_freq_sync"), + _mlxlinkMaps->_txInputFreq))); + fields.push_back(AmberField("rx_cdr_cap", _mlxlinkMaps->_rxTxCdrCap[getFieldValue("rx_cdr_cap")])); + fields.push_back(AmberField("tx_cdr_cap", _mlxlinkMaps->_rxTxCdrCap[getFieldValue("tx_cdr_cap")])); + fields.push_back(AmberField("rx_cdr_state", getRxTxCDRState(getFieldValue("rx_cdr_state"),LANES_NUM))); + fields.push_back(AmberField("tx_cdr_state", getRxTxCDRState(getFieldValue("tx_cdr_state"),LANES_NUM))); + fields.push_back(AmberField("vendor_name", getAscii("vendor_name", 16))); + fields.push_back(AmberField("vendor_rev", getVendorRev(getFieldValue("vendor_rev")))); + fields.push_back(AmberField("module_fw_version", getFwVersion(passive,getFieldValue("fw_version")))); + calcRxTxPowerLane(fields,"rx_power_lane"); calcRxTxPowerLane(fields,"tx_power_lane"); getTxBiasLane(fields); - fields.push_back(AmberField("temperature_high_th", getTemp(getFieldValue("temperature_high_th")))); - fields.push_back(AmberField("temperature_low_th", getTemp(getFieldValue("temperature_low_th")))); - fields.push_back(AmberField("voltage_high_th", to_string(getFieldValue("voltage_high_th") / 10.0))); - fields.push_back(AmberField("voltage_low_th", to_string(getFieldValue("voltage_low_th") / 10.0))); - fields.push_back(AmberField("rx_power_high_th", to_string(getPower(getFieldValue("rx_power_high_th"))))); - fields.push_back(AmberField("rx_power_low_th", to_string(getPower(getFieldValue("rx_power_low_th"))))); - fields.push_back(AmberField("tx_power_high_th", to_string(getPower(getFieldValue("tx_power_high_th"))))); - fields.push_back(AmberField("tx_power_low_th", to_string(getPower(getFieldValue("tx_power_low_th"))))); - fields.push_back(AmberField("tx_bias_high_th", to_string(getFieldValue("tx_bias_high_th") / 500.0))); - fields.push_back(AmberField("tx_bias_low_th", to_string(getFieldValue("tx_bias_low_th") / 500.0))); - fields.push_back(AmberField("wavelength", getFieldStr("wavelength"))); - fields.push_back(AmberField("wavelength_tolerance", passive ? "N/A" : getFieldStr("wavelength_tolerance") + "nm")); + + fields.push_back(AmberField("temperature_high_th", getTemp(getFieldValue("temperature_high_th")))); + fields.push_back(AmberField("temperature_low_th", getTemp(getFieldValue("temperature_low_th")))); + fields.push_back(AmberField("voltage_high_th", to_string(getFieldValue("voltage_high_th") / 10.0))); + fields.push_back(AmberField("voltage_low_th", to_string(getFieldValue("voltage_low_th") / 10.0))); + fields.push_back(AmberField("rx_power_high_th", to_string(getPower(getFieldValue("rx_power_high_th"))))); + fields.push_back(AmberField("rx_power_low_th", to_string(getPower(getFieldValue("rx_power_low_th"))))); + fields.push_back(AmberField("tx_power_high_th", to_string(getPower(getFieldValue("tx_power_high_th"))))); + fields.push_back(AmberField("tx_power_low_th", to_string(getPower(getFieldValue("tx_power_low_th"))))); + fields.push_back(AmberField("tx_bias_high_th", to_string(getFieldValue("tx_bias_high_th") / 500.0))); + fields.push_back(AmberField("tx_bias_low_th", to_string(getFieldValue("tx_bias_low_th") / 500.0))); + fields.push_back(AmberField("wavelength", getFieldStr("wavelength"))); + + float waveLenTol = float(getFieldValue("wavelength_tolerance")) / 200.0; + char waveLenTolCh[64]; + sprintf(waveLenTolCh, "%.1f", waveLenTol); + string waveLenTolStr = waveLenTolCh; + + fields.push_back(AmberField("wavelength_tolerance", passive ? "N/A" : waveLenTolStr + "nm")); + if(_isCmisCable){ moduleSt = _mlxlinkMaps->_cimsModuleSt[getFieldValue("module_st")]; } + fields.push_back(AmberField("Module_st",moduleSt)); - loopAllLanesStr(fields, "dp_st_lane"); + + loopAllLanesStr(fields, "Dp_st_lane"); + fields.push_back(AmberField("rx_output_valid", getBitmaskPerLaneStr(getFieldValue("rx_output_valid")))); fields.push_back(AmberField("rx_input_valid", getBitmaskPerLaneStr(getFieldValue("rx_input_valid")))); + if(cableIdentifier < IDENTIFIER_SFP_DD){ float nbr = float(getFieldValue("nbr250") * 250) / float(1000); char nbrCh[64]; sprintf(nbrCh, "%.3f", nbr); nbrString = nbrCh + string("Gb/s"); } - fields.push_back(AmberField("nbr250", nbrString)); - fields.push_back(AmberField("Rx Power Type", _mlxlinkMaps->_rxPowerType[getFieldValue("rx_power_type")])); - fields.push_back(AmberField("date_code", getDateCode(add32BitTo64( - getFieldValue("date_code_hi"), - getFieldValue("date_code_lo"))))); - fields.push_back(AmberField("Module temperature", getTemp(getFieldValue("temperature")))); - fields.push_back(AmberField("Module voltage", to_string(getFieldValue("voltage") / 10.0))); + fields.push_back(AmberField("Nominal_Bit_Rate", nbrString)); + + fields.push_back(AmberField("Rx_Power_Type", _mlxlinkMaps->_rxPowerType[getFieldValue("rx_power_type")])); + fields.push_back(AmberField("Date_code", getDateCode(add32BitTo64(getFieldValue("date_code_hi"), + getFieldValue("date_code_lo"))))); + fields.push_back(AmberField("Module_temperature", getTemp(getFieldValue("temperature")))); + fields.push_back(AmberField("Module_voltage", to_string(getFieldValue("voltage") / 10.0))); + if(_isCmisCable){ activeSetHostComplianceCode = ethComplianceStr; activeSetMediaComplianceCode = extComplianceStr; } - fields.push_back(AmberField("active_set_host_compliance_code", activeSetHostComplianceCode)); - fields.push_back(AmberField("active_set_media_compliance_code", activeSetMediaComplianceCode)); -} + fields.push_back(AmberField("Active_set_host_compliance_code", activeSetHostComplianceCode)); + fields.push_back(AmberField("Active_set_media_compliance_code", activeSetMediaComplianceCode)); -string MlxlinkAmBerCollector::getFlagsByMap(u_int32_t flags, std::map map) -{ - string flagsStr = "N/A"; - if (flags){ - flagsStr = map[flags]; + if(_isCmisCable) { + error_code_res = getStrByValue(getFieldValue("error_code") , _mlxlinkMaps->_errorCodeRes); } - - return flagsStr; + fields.push_back(AmberField("error_code_response", error_code_res)); } string MlxlinkAmBerCollector::getBitmaskPerLaneStr(u_int32_t bitmask) @@ -1199,10 +1231,9 @@ void MlxlinkAmBerCollector::getModuleLatchedFlagInfoPage(vector &fie modFwFault = getFieldStr("mod_fw_fault"); dpFwFault = getFieldStr("dp_fw_fault"); } - fields.push_back(AmberField("Temperature Alarm", _mlxlinkMaps->_tempFLags[getFieldValue("temp_flags") & 0x3], (u_int64_t)getFieldValue("temp_flags"))); - fields.push_back(AmberField("Temperature Warning", _mlxlinkMaps->_tempFLags[getFieldValue("temp_flags") & 0xc])); - fields.push_back(AmberField("Voltage Alarm", _mlxlinkMaps->_vccFLags[getFieldValue("vcc_flags") & 0x3], (u_int64_t)getFieldValue("vcc_flags"))); - fields.push_back(AmberField("Voltage Warning", _mlxlinkMaps->_vccFLags[getFieldValue("vcc_flags") & 0xc])); + + fields.push_back(AmberField("Temp_flags", getStrByMask(getFieldValue("temp_flags"), _mlxlinkMaps->_tempFlags))); + fields.push_back(AmberField("Vcc_flags", getStrByMask(getFieldValue("vcc_flags"), _mlxlinkMaps->_vccFlags))); fields.push_back(AmberField("Mod_fw_fault", modFwFault )); fields.push_back(AmberField("Dp_fw_fault", dpFwFault )); fields.push_back(AmberField("tx_fault", getBitmaskPerLaneStr(getFieldValue("tx_fault")))); @@ -1237,7 +1268,21 @@ vector MlxlinkAmBerCollector::getModuleStatus() try { if (!_isPortPCIE) { - string error_code_res = "N/A"; + + resetLocalParser(ACCESS_REG_PMAOS); + updateField("module", _moduleIndex); + updateField("slot_index", _slotIndex); + sendRegister(ACCESS_REG_PMAOS, MACCESS_REG_METHOD_GET); + + u_int32_t operSt = getFieldValue("oper_status"); + string operStStr = getStrByValue(operSt , _mlxlinkMaps->_moduleOperSt); + string errTypeStr = "N/A"; + if (operSt == MODULE_OPER_STATUS_PLUGGED_WITH_ERROR) { + errTypeStr = getStrByValue(getFieldValue("error_type") , _mlxlinkMaps->_moduleErrType); + } + + fields.push_back(AmberField("module_oper_status", operStStr)); + fields.push_back(AmberField("module_error_type", errTypeStr)); resetLocalParser(ACCESS_REG_PDDR); updateField("local_port", _localPort); @@ -1249,17 +1294,6 @@ vector MlxlinkAmBerCollector::getModuleStatus() } getModuleInfoPage(fields); - if(_isCmisCable) { - // TODO: Change it to PDDR when it moved - resetLocalParser(ACCESS_REG_PMCR); - updateField("local_port", _localPort); - sendRegister(ACCESS_REG_PMCR, MACCESS_REG_METHOD_GET); - - error_code_res = getFlagsByMap(getFieldValue("error_code_response") , _mlxlinkMaps->_errorCodeRes); - } - - fields.push_back(AmberField("error_code_response", error_code_res)); - resetLocalParser(ACCESS_REG_PDDR); updateField("local_port", _localPort); updateField("page_select", PDDR_MODULE_LATCHED_FLAG_INFO_PAGE); @@ -1462,7 +1496,7 @@ vector MlxlinkAmBerCollector::getTroubleshootingInfo() updateField("pnat", PNAT_LOCAL); updateField("page_select", PDDR_TROUBLESHOOTING_INFO_PAGE); updateField("group_opcode", ADVANCED_OPCODE); - genBuffSendRegister(ACCESS_REG_PDDR, MACCESS_REG_METHOD_GET); + sendRegister(ACCESS_REG_PDDR, MACCESS_REG_METHOD_GET); string message = ""; char txt[16], c; @@ -1487,8 +1521,8 @@ vector MlxlinkAmBerCollector::getTroubleshootingInfo() } } - fields.push_back(AmberField("Advanced Status Opcode", getFieldStr("advanced_opcode"))); - fields.push_back(AmberField("Status Message",message)); + fields.push_back(AmberField("Advanced_Status_Opcode", getFieldStr("advanced_opcode"))); + fields.push_back(AmberField("Status_Message",message)); } } catch (const std::exception &exc) { throw MlxRegException( @@ -1498,33 +1532,248 @@ vector MlxlinkAmBerCollector::getTroubleshootingInfo() return fields; } -vector MlxlinkAmBerCollector::getLinkUpDownInfo() +vector MlxlinkAmBerCollector::getLinkUpInfo() { vector fields; try { - // Access regs: [PDDR.linkup_info_page, linkdown_info_page] + // Access regs: [PDDR.linkup_info_page] } catch (const std::exception &exc) { throw MlxRegException( - "Failed to get LinkUp and LinkDown information: %s", exc.what()); + "Failed to get LinkUp information: %s", exc.what()); } return fields; } +vector MlxlinkAmBerCollector::getLinkDownInfo() +{ + vector fields; + + try { + // Access regs: [PDDR.linkdown_info_page] + } catch (const std::exception &exc) { + throw MlxRegException( + "Failed to get LinkDown information: %s", exc.what()); + } + + return fields; +} + +string MlxlinkAmBerCollector::getPrbsModeCap(u_int32_t modeSelector, u_int32_t capsMask) +{ + string modeCapStr = ""; + u_int32_t mask = 0; + for (map::iterator it = _mlxlinkMaps->_prbsModesList.begin(); + it != _mlxlinkMaps->_prbsModesList.end(); it++) { + mask = PRBS31_CAP << it->first; + if (capsMask & mask) { + modeCapStr += it->second; + if (modeSelector == PRBS_RX && mask == SQUARE_WAVEA_CAP) { + // return SQUARE_WAVE without A for RX pattern + modeCapStr = deleteLastChar(modeCapStr); + } + modeCapStr += ","; + } + } + return deleteLastChar(modeCapStr); +} + +void MlxlinkAmBerCollector::getTestModePrpsInfo(const string &prbsReg, vector> ¶ms) +{ + string laneRateStr = "lane_rate_admin"; + if (prbsReg == ACCESS_REG_PPRT) { + laneRateStr = "lane_rate_oper"; + } + + for (u_int32_t lane = 0; lane < _numOfLanes; lane++) { + resetLocalParser(prbsReg); + updateField("local_port", _localPort); + updateField("lane", lane); + updateField("pnat", _pnat); + sendRegister(prbsReg, MACCESS_REG_METHOD_GET); + + if (prbsReg == ACCESS_REG_PPRT) { + params[PRBS_PARAMS_RX_TUNING_STATUS][lane] = getStrByValue(getFieldValue("prbs_rx_tuning_status"), + _mlxlinkMaps->_prbsRxTuningStatus); + params[PRBS_PARAMS_LOCK_STATUS][lane] = getStrByValue(getFieldValue("prbs_lock_status"), + _mlxlinkMaps->_prbsLockStatus); + } + params[PRBS_PARAMS_E][lane] = getStrByValue(getFieldValue("e"), _mlxlinkMaps->_prbsEStatus); + params[PRBS_PARAMS_P][lane] = getStrByValue(getFieldValue("p"), _mlxlinkMaps->_prbsPStatus); + params[PRBS_PARAMS_MODES_CAP][lane] = getPrbsModeCap(PRBS_TX, getFieldValue("prbs_modes_cap")); + params[PRBS_PARAMS_MODE_ADMIN][lane] = getStrByValue(getFieldValue("prbs_mode_admin"), _mlxlinkMaps->_prbsModesList); + params[PRBS_PARAMS_MODULATION][lane] = getStrByValue(getFieldValue("modulation"), _mlxlinkMaps->_prbsModulation); + params[PRBS_PARAMS_LANE_RATE_CAP][lane] = getStrByMask(getFieldValue("lane_rate_cap"), _mlxlinkMaps->_prbsLaneRateCap); + params[PRBS_PARAMS_LANE_RATE_ADMIN][lane] = getStrByValue(getFieldValue(laneRateStr), _mlxlinkMaps->_prbsLaneRateList); + } +} + +vector MlxlinkAmBerCollector::getTestModeInfo() +{ + vector fields; + try { + vector> pprtParams (PRBS_PARAMS_LAST, vector (_numOfLanes, "")); + vector> ppttParams (PRBS_PARAMS_LAST, vector (_numOfLanes, "")); + getTestModePrpsInfo(ACCESS_REG_PPRT, pprtParams); + getTestModePrpsInfo(ACCESS_REG_PPTT, ppttParams); + + fillParamsToFields("prbs_rx_tuning_status", pprtParams[PRBS_PARAMS_RX_TUNING_STATUS], fields); + fillParamsToFields("prbs_rx_lock_status", pprtParams[PRBS_PARAMS_LOCK_STATUS], fields); + fillParamsToFields("prbs_rx_enable", pprtParams[PRBS_PARAMS_E], fields); + fillParamsToFields("prbs_rx_polarity", pprtParams[PRBS_PARAMS_P], fields); + fillParamsToFields("prbs_rx_modes_cap", pprtParams[PRBS_PARAMS_MODES_CAP], fields); + fillParamsToFields("prbs_rx_mode_admin", pprtParams[PRBS_PARAMS_MODE_ADMIN], fields); + fillParamsToFields("prbs_rx_modulation", pprtParams[PRBS_PARAMS_MODULATION], fields); + fillParamsToFields("prbs_rx_lane_rate_cap", pprtParams[PRBS_PARAMS_LANE_RATE_CAP], fields); + fillParamsToFields("prbs_rx_lane_rate_admin", pprtParams[PRBS_PARAMS_LANE_RATE_ADMIN], fields); + + fillParamsToFields("prbs_tx_enable", ppttParams[PRBS_PARAMS_E], fields); + fillParamsToFields("prbs_tx_polarity", ppttParams[PRBS_PARAMS_P], fields); + fillParamsToFields("prbs_tx_modes_cap", ppttParams[PRBS_PARAMS_MODES_CAP], fields); + fillParamsToFields("prbs_tx_mode_admin", ppttParams[PRBS_PARAMS_MODE_ADMIN], fields); + fillParamsToFields("prbs_tx_modulation", ppttParams[PRBS_PARAMS_MODULATION], fields); + fillParamsToFields("prbs_tx_lane_rate_cap", ppttParams[PRBS_PARAMS_LANE_RATE_CAP], fields); + fillParamsToFields("prbs_tx_lane_rate_admin", ppttParams[PRBS_PARAMS_LANE_RATE_ADMIN], fields); + } catch (const std::exception &exc) { + throw MlxRegException( + "Failed to get Test Mode information: %s", exc.what()); + } + + return fields; +} + +vector MlxlinkAmBerCollector::getTestModeModuleInfo() +{ + vector fields; + + try { + } catch (const std::exception &exc) { + throw MlxRegException( + "Failed to get Test Mode Module information: %s", exc.what()); + } + + return fields; +} + +void MlxlinkAmBerCollector::groupValidIf(bool condition) +{ + if (condition) { + _invalidate = false; + } else { + _invalidate = true; + } +} + +vector MlxlinkAmBerCollector::collectSheet(AMBER_SHEET sheet) +{ + vector fields; + fields.push_back(AmberField("N/A", "N/A")); + + AmberField::reset(); + + switch (sheet) { + case AMBER_SHEET_GENERAL: + fields = getGeneralInfo(); + break; + case AMBER_SHEET_INDEXES: + fields = getIndexesInfo(); + break; + case AMBER_SHEET_LINK_STATUS: + fields = getLinkStatus(); + break; + case AMBER_SHEET_MODULE_STATUS: + fields = getModuleStatus(); + break; + case AMBER_SHEET_SYSTEM: + fields = getSystemInfo(); + break; + case AMBER_SHEET_SERDES_16NM: + groupValidIf(_productTechnology == PRODUCT_16NM); + fields = getSerdesHDR(); + break; + case AMBER_SHEET_SERDES_7NM: + groupValidIf(_productTechnology == PRODUCT_7NM); + fields = getSerdesNDR(); + break; + case AMBER_SHEET_PORT_COUNTERS: + if (!_inPRBSMode) { + fields = getPortCounters(); + } + break; + case AMBER_SHEET_TROUBLESHOOTING: + if (!_inPRBSMode) { + fields = getTroubleshootingInfo(); + } + break; + case AMBER_SHEET_PHY_OPERATION_INFO: + if (!_inPRBSMode) { + fields = getPhyOperationInfo(); + } + break; + case AMBER_SHEET_LINK_UP_INFO: + if (!_inPRBSMode) { + fields = getLinkUpInfo(); + } + break; + case AMBER_SHEET_LINK_DOWN_INFO: + if (!_inPRBSMode) { + fields = getLinkDownInfo(); + } + break; + case AMBER_SHEET_TEST_MODE_INFO: + if (_inPRBSMode) { + fields = getTestModeInfo(); + } + break; + case AMBER_SHEET_TEST_MODE_MODULE_INFO: + if (_inPRBSMode) { + fields = getTestModeModuleInfo(); + } + break; + } + return fields; +} + void MlxlinkAmBerCollector::collect() { - _amberCollection.push_back(getGeneralInfo()); - _amberCollection.push_back(getIndexesInfo()); - _amberCollection.push_back(getLinkStatus()); - _amberCollection.push_back(getModuleStatus()); - _amberCollection.push_back(getSystemInfo()); - _amberCollection.push_back(getSerdesHDR()); - _amberCollection.push_back(getSerdesNDR()); - _amberCollection.push_back(getPortCounters()); - _amberCollection.push_back(getTroubleshootingInfo()); - _amberCollection.push_back(getPhyOperationInfo()); - _amberCollection.push_back(getLinkUpDownInfo()); + for (auto it = _sheetsList.begin(); it != _sheetsList.end(); it++) { + auto sheetFields = collectSheet(it->first); + if (!sheetFields.empty() && sheetFields.back().getUiField() == "N/A") { + continue; + } + _amberCollection[it->first] = sheetFields; + } +} + +u_int32_t MlxlinkAmBerCollector::fixFieldsData() +{ + u_int32_t lastFieldIndexPerGroup = 0 ; + u_int32_t totalFields = 0; + + for (auto it = _amberCollection.begin(); it != _amberCollection.end(); it++) { + for (auto fieldIt = (*it).second.begin(); fieldIt != (*it).second.end();) { + if ((*fieldIt).getFieldIndex() == 0) { + (*it).second.erase(fieldIt); + } else { + ++fieldIt; + } + } + } + for (auto it = _amberCollection.begin(); it != _amberCollection.end(); it++) { + if (_isPortPCIE) { + lastFieldIndexPerGroup = _sheetsList[(*it).first].numOfPcieFields; + } else if (_isPortETH) { + lastFieldIndexPerGroup = _sheetsList[(*it).first].numOfEthFields; + } else if (_isPortIB) { + lastFieldIndexPerGroup = _sheetsList[(*it).first].numOfIbFields; + } + for (u_int32_t fieldIdx = (*it).second.size() + 1; fieldIdx <= lastFieldIndexPerGroup; fieldIdx++) { + (*it).second.push_back(AmberField("F" + to_string(totalFields + fieldIdx), "N/A", fieldIdx)); + } + totalFields += lastFieldIndexPerGroup; + } + return totalFields; } void MlxlinkAmBerCollector::exportToCSV() @@ -1539,14 +1788,15 @@ void MlxlinkAmBerCollector::exportToCSV() skipHeader = true; } + u_int32_t totalNumOfFields = fixFieldsData(); // Preparing CSV header line if (!skipHeader) { // Going over all groups inside _amberCollection and getting the field name for each one for (auto it = _amberCollection.begin(); it != _amberCollection.end(); it++) { - for (auto fieldIt = (*it).begin(); fieldIt != (*it).end(); fieldIt++) { + for (auto fieldIt = (*it).second.begin(); fieldIt != (*it).second.end(); fieldIt++) { if ((*fieldIt).isVisible()) { berFile << (*fieldIt).getUiField(); - if ((*fieldIt).getFieldIndex() != (AmberField::_lastFieldIndex - 1)) { + if ((*fieldIt).getFieldIndex() != (totalNumOfFields - 1)) { berFile << ","; } } @@ -1557,10 +1807,10 @@ void MlxlinkAmBerCollector::exportToCSV() // Preparing CSV values // Going over all groups inside _amberCollection and getting the field value for each one for (auto it = _amberCollection.begin(); it != _amberCollection.end(); it++) { - for (auto fieldIt = (*it).begin(); fieldIt != (*it).end(); fieldIt++) { + for (auto fieldIt = (*it).second.begin(); fieldIt != (*it).second.end(); fieldIt++) { if ((*fieldIt).isVisible()) { berFile << (*fieldIt).getUiValue(); - if ((*fieldIt).getFieldIndex() != (AmberField::_lastFieldIndex - 1)) { + if ((*fieldIt).getFieldIndex() != (totalNumOfFields - 1)) { berFile << ","; } } @@ -1574,7 +1824,7 @@ void MlxlinkAmBerCollector::exportToConsole() { // Printing all fields to the console (for debugging, will be removed later) for (auto it = _amberCollection.begin(); it != _amberCollection.end(); it++) { - for (auto fieldIt = (*it).begin(); fieldIt != (*it).end(); fieldIt++) { + for (auto fieldIt = (*it).second.begin(); fieldIt != (*it).second.end(); fieldIt++) { if ((*fieldIt).isVisible()) { cout << *fieldIt << endl; } diff --git a/mlxlink/modules/mlxlink_amBER_collector.h b/mlxlink/modules/mlxlink_amBER_collector.h index 0ace90b9..c04444d1 100644 --- a/mlxlink/modules/mlxlink_amBER_collector.h +++ b/mlxlink/modules/mlxlink_amBER_collector.h @@ -41,6 +41,12 @@ using namespace std; +struct FIELDS_COUNT { + u_int32_t numOfIbFields; + u_int32_t numOfEthFields; + u_int32_t numOfPcieFields; +}; + class MlxlinkAmBerCollector :public MlxlinkRegParser { public: MlxlinkAmBerCollector(Json::Value &jsonRoot); @@ -58,9 +64,11 @@ class MlxlinkAmBerCollector :public MlxlinkRegParser { virtual vector getPortCounters(); virtual vector getTroubleshootingInfo(); virtual vector getPhyOperationInfo(); - virtual vector getLinkUpDownInfo(); + virtual vector getLinkUpInfo(); + virtual vector getLinkDownInfo(); + virtual vector getTestModeInfo(); + virtual vector getTestModeModuleInfo(); - void getPpcntErrors(u_int32_t portType, vector &fields); void getPpcntBer(u_int32_t portType, vector &fields); bool isGBValid(); bool isMCMValid(); @@ -73,7 +81,9 @@ class MlxlinkAmBerCollector :public MlxlinkRegParser { u_int32_t _pcieIndex; u_int32_t _node; u_int32_t _devID; + u_int32_t _productTechnology; string _csvFileName; + string _mstDevName; u_int32_t _iteration; string _testMode; MlxlinkMaps *_mlxlinkMaps; @@ -88,7 +98,7 @@ class MlxlinkAmBerCollector :public MlxlinkRegParser { void getEthComplianceCodes(u_int32_t cableTechnology , string ðComplianceStr , string &extComplianceStr, u_int32_t cableMediaType); void getIbComplianceCodes(string &ibComplianceCodeStr); string getCableTechnologyStr(u_int32_t cableTechnology); - string getCableBreakoutStr(u_int32_t cableBreakout); + string getCableBreakoutStr(u_int32_t cableBreakout, u_int32_t cableIdentifier); void calcRxTxPowerLane(vector &fields ,string str); void getModuleInfoPage(vector &fields); string getSmfLength(const u_int32_t smfLength, const u_int32_t cableTechnology, const bool optical); @@ -99,17 +109,16 @@ class MlxlinkAmBerCollector :public MlxlinkRegParser { void getCmisComplianceCode(u_int32_t ethComplianceCode, u_int32_t extEthComplianceCode, string ðComplianceStr , string &extComplianceStr, u_int32_t cableMediaType, u_int32_t cableTechnology); void initCableIdentifier(u_int32_t cableIdentifier); void getModuleLatchedFlagInfoPage(vector &fields); - string getFlagsByMap(u_int32_t flags, std::map map); - void getSltpFields(vector &fields); - void getSlrgFields(vector &fields); + void groupValidIf(bool condition); bool _isQsfpCable; bool _isSfpCable; bool _cablePlugged; + bool _invalidate; u_int32_t _labelPort; u_int32_t _splitPort; u_int32_t _secondSplit; - vector> _amberCollection; + map> _amberCollection; protected: string getBitmaskPerLaneStr(u_int32_t bitmask); @@ -120,14 +129,19 @@ class MlxlinkAmBerCollector :public MlxlinkRegParser { void fillParamsToFields(const string &title, const vector &values, vector &fields, bool laneLimit = true); + string getPrbsModeCap(u_int32_t modeSelector, u_int32_t capsMask); + string getPrpsRateCap(u_int32_t capsMask); + virtual void getTestModePrpsInfo(const string &prbsReg, vector> ¶ms); // Helper functions virtual string getBerAndErrorTitle(u_int32_t portType); string getClRawBer(); // Callers + vector collectSheet(AMBER_SHEET sheet); void collect(); + u_int32_t fixFieldsData(); void exportToCSV(); void exportToConsole(); @@ -139,13 +153,17 @@ class MlxlinkAmBerCollector :public MlxlinkRegParser { bool _isGBSysValid; bool _isValidSensorMvcap; bool _isValidSensorMtcap; + bool _inPRBSMode; Json::Value &_jsonRoot; vector _amBerCollectorOutput; - u_int32_t _productTechnology; + map _sheetsList; + u_int32_t _activeSpeed; u_int32_t _protoActive; u_int32_t _numOfLanes; + u_int32_t _moduleIndex; + u_int32_t _slotIndex; }; #endif /* MLXLINK_AMBER_COLLECTOR_H */ diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index deaa3f05..f84b4a81 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -1353,17 +1353,19 @@ void MlxlinkCommander::prepareDDMSection(bool valid) ANSI_COLOR_RESET, true, valid); } -string MlxlinkCommander::loopAllLanesStr(vector &fields, string str) +string MlxlinkCommander::getValuesOfActiveLanes(const string &row) { - string strVal = ""; - for (u_int32_t lane = 0; lane < LANES_NUM; lane++) { - string laneStr = to_string(lane); - strVal += AmberField::getValueFromFields(fields, str + laneStr) + "_"; + string newValue = row; + + auto valuesPerLane = MlxlinkRecord::split(newValue, ","); + + if (valuesPerLane.size() > 1) { + valuesPerLane.erase(valuesPerLane.begin() + _numOfLanes, valuesPerLane.end()); + newValue = getStringFromVector(valuesPerLane); } - strVal = deleteLastChar(strVal); - return strVal; -} + return newValue; +} void MlxlinkCommander::prepareBerModuleInfoNdr(bool valid) { initAmBerCollector(); @@ -1371,116 +1373,54 @@ void MlxlinkCommander::prepareBerModuleInfoNdr(bool valid) vector moduleInfoFields = _amberCollector->getModuleStatus(); - string cableWStr = AmberField::getValueFromFields(moduleInfoFields, "ib_width"); - findAndReplace(cableWStr, "_", ","); - setPrintVal(_moduleInfoCmd, "IB Cable Width", - cableWStr, - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Memory Map Revision", - AmberField::getValueFromFields(moduleInfoFields, "Memory map rev"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Linear Direct Drive", - AmberField::getValueFromFields(moduleInfoFields, "linear direct drive"), - ANSI_COLOR_RESET, true, valid); - string cableBreakoutStr = AmberField::getValueFromFields(moduleInfoFields, "cable_breakout"); - findAndReplace(cableBreakoutStr, "_", ","); - setPrintVal(_moduleInfoCmd, "Cable Breakout", - cableBreakoutStr, - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "SMF Length", - AmberField::getValueFromFields(moduleInfoFields, "smf_length"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "MAX Power", - AmberField::getValueFromFields(moduleInfoFields, "max_power"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Cable Rx AMP", - AmberField::getValueFromFields(moduleInfoFields, "cable_rx_amp"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Cable Rx Emphasis", - AmberField::getValueFromFields(moduleInfoFields, "cable_rx_emphasis"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Cable Rx Post Emphasis", - AmberField::getValueFromFields(moduleInfoFields, "cable_rx_post_emphasis"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Cable Tx Equalization", - AmberField::getValueFromFields(moduleInfoFields, "cable_tx_equalization"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Wavelength Tolerance", - AmberField::getValueFromFields(moduleInfoFields, "wavelength_tolerance"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Module State", - AmberField::getValueFromFields(moduleInfoFields, "Module_st"), - ANSI_COLOR_RESET, true, valid); - string dpStr = loopAllLanesStr(moduleInfoFields,"dp_st_lane"); - findAndReplace(dpStr, "_", ","); - setPrintVal(_moduleInfoCmd, "DataPath state [per lane]", - getStringByActiveLanes(dpStr,_numOfLanes), - ANSI_COLOR_RESET, true, valid); - string rxOutStr = AmberField::getValueFromFields(moduleInfoFields, "rx_output_valid"); - findAndReplace(rxOutStr, "_", ","); - setPrintVal(_moduleInfoCmd, "Rx Output Valid", - getStringByActiveLanes(rxOutStr,_numOfLanes), - ANSI_COLOR_RESET, true, valid); - string rxInStr = AmberField::getValueFromFields(moduleInfoFields, "rx_input_valid"); - findAndReplace(rxInStr, "_", ","); - setPrintVal(_moduleInfoCmd, "Rx Input Valid", - getStringByActiveLanes(rxInStr,_numOfLanes), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Nominal bit rate", - AmberField::getValueFromFields(moduleInfoFields, "nbr250"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Rx Power Type", - AmberField::getValueFromFields(moduleInfoFields, "Rx Power Type"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Manufacturing Date", - AmberField::getValueFromFields(moduleInfoFields, "date_code"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Active Set Host Compliance Code", - AmberField::getValueFromFields(moduleInfoFields, "active_set_host_compliance_code"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Active Set Media Compliance Code", - AmberField::getValueFromFields(moduleInfoFields, "active_set_media_compliance_code"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Error Code Response", - AmberField::getValueFromFields(moduleInfoFields, "error_code_response"), - ANSI_COLOR_RESET, true, valid); - setPrintVal(_moduleInfoCmd, "Module FW Fault", - AmberField::getValueFromFields(moduleInfoFields, "Mod_fw_fault"), - ANSI_COLOR_RESET, true, valid && _ddmSupported); - setPrintVal(_moduleInfoCmd, "DataPath FW Fault", - AmberField::getValueFromFields(moduleInfoFields, "Dp_fw_fault"), - ANSI_COLOR_RESET, true, valid && _ddmSupported); - string txStr = AmberField::getValueFromFields(moduleInfoFields, "tx_fault"); - findAndReplace(txStr, "_", ","); - setPrintVal(_moduleInfoCmd, "Tx Fault [per lane]", - getStringByActiveLanes(txStr,_numOfLanes), - ANSI_COLOR_RESET, true, valid && _ddmSupported); - string txLosStr = AmberField::getValueFromFields(moduleInfoFields, "tx_los"); - findAndReplace(txLosStr, "_", ","); - setPrintVal(_moduleInfoCmd, "Tx LOS [per lane]", - getStringByActiveLanes(txLosStr,_numOfLanes), - ANSI_COLOR_RESET, true, valid && _ddmSupported); - string txCdrStr = AmberField::getValueFromFields(moduleInfoFields, "tx_cdr_lol"); - findAndReplace(txCdrStr, "_", ","); - setPrintVal(_moduleInfoCmd, "Tx CDR LOL [per lane]", - getStringByActiveLanes(txCdrStr,_numOfLanes), - ANSI_COLOR_RESET, true, valid && _ddmSupported); - string rxLosStr = AmberField::getValueFromFields(moduleInfoFields, "rx_los"); - findAndReplace(rxLosStr, "_", ","); - setPrintVal(_moduleInfoCmd, "Rx LOS [per lane]", - getStringByActiveLanes(rxLosStr,_numOfLanes), - ANSI_COLOR_RESET, true, valid && _ddmSupported); - string rxCdrLolStr = AmberField::getValueFromFields(moduleInfoFields, "rx_cdr_lol"); - findAndReplace(rxCdrLolStr, "_", ","); - setPrintVal(_moduleInfoCmd, "Rx CDR LOL [per lane]", - getStringByActiveLanes(rxCdrLolStr,_numOfLanes), - ANSI_COLOR_RESET, true, valid && _ddmSupported); - string txAdEqFaultStr = AmberField::getValueFromFields(moduleInfoFields, "tx_ad_eq_fault"); - findAndReplace(txAdEqFaultStr, "_", ","); - setPrintVal(_moduleInfoCmd, "Tx Adaptive EQ Fault [per lane]", - getStringByActiveLanes(txAdEqFaultStr,_numOfLanes), - ANSI_COLOR_RESET, true, valid && _ddmSupported); - + vector fieldsToQuery; + + fieldsToQuery.push_back(MODULE_FIELD{"IB Cable Width", "ib_width",true, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Memory Map Revision", "Memory_map_rev",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Linear Direct Drive", "linear_direct_drive",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Cable Breakout", "cable_breakout",true, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"SMF Length", "smf_length",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"MAX Power", "max_power",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Cable Rx AMP", "cable_rx_amp",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Cable Rx Emphasis", "cable_rx_emphasis",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Cable Rx Post Emphasis", "cable_rx_post_emphasis",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Cable Tx Equalization", "cable_tx_equalization",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Wavelength Tolerance", "wavelength_tolerance",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Module State", "Module_st",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"DataPath state [per lane]", "Dp_st_lane",true, true, true}); + fieldsToQuery.push_back(MODULE_FIELD{"Rx Output Valid [per lane]", "rx_output_valid",true, true, true}); + fieldsToQuery.push_back(MODULE_FIELD{"Rx Input Valid [per lane]", "rx_input_valid",true, true, true}); + fieldsToQuery.push_back(MODULE_FIELD{"Nominal bit rate", "Nominal_Bit_Rate",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Rx Power Type", "Rx_Power_Type",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Manufacturing Date", "Date_code",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Active Set Host Compliance Code", "Active_set_host_compliance_code",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Active Set Media Compliance Code", "Active_set_media_compliance_code",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Error Code Response", "error_code_response",false, false, false}); + fieldsToQuery.push_back(MODULE_FIELD{"Module FW Fault", "Mod_fw_fault",false, false, true}); + fieldsToQuery.push_back(MODULE_FIELD{"DataPath FW Fault", "Dp_fw_fault",false, false, true}); + fieldsToQuery.push_back(MODULE_FIELD{"Tx Fault [per lane]", "tx_fault",true, true, true}); + fieldsToQuery.push_back(MODULE_FIELD{"Tx LOS [per lane]", "tx_los",true, true, true}); + fieldsToQuery.push_back(MODULE_FIELD{"Tx CDR LOL [per lane]", "tx_cdr_lol",true, true, true}); + fieldsToQuery.push_back(MODULE_FIELD{"Rx LOS [per lane]", "rx_los",true, true, true}); + fieldsToQuery.push_back(MODULE_FIELD{"Rx CDR LOL [per lane]", "rx_cdr_lol",true, true, true}); + fieldsToQuery.push_back(MODULE_FIELD{"Tx Adaptive EQ Fault [per lane]", "tx_ad_eq_fault",true, true, true}); + + string fieldValue = ""; + for (auto it = fieldsToQuery.begin(); it != fieldsToQuery.end(); it++) { + fieldValue = AmberField::getValueFromFields(moduleInfoFields, it->amberName, !it->perLane); + if (it->multiVal) { + findAndReplace(fieldValue, "_", ","); + } + if (it->perLane) { + fieldValue = getValuesOfActiveLanes(fieldValue); + } + + if (it->uiName == "Cable Rx Emphasis" && _cmisCable) { + it->uiName += " (Pre)"; + } + setPrintVal(_moduleInfoCmd, it->uiName, fieldValue, ANSI_COLOR_RESET, true, + it->requireDdm? valid && _ddmSupported : valid, it->perLane); + } } void MlxlinkCommander::showModuleInfo() @@ -2006,31 +1946,26 @@ void MlxlinkCommander::prepareBerInfo() _ppcntFields = _amberCollector->getLinkStatus(); setPrintVal(_berInfoCmd, "Time Since Last Clear [Min]", - AmberField::getValueFromFields(_ppcntFields, "Time since last clear [Min]"), + AmberField::getValueFromFields(_ppcntFields, "Time_since_last_clear_[Min]"), ANSI_COLOR_RESET, true, _linkUP); setPrintVal(_berInfoCmd, "Symbol Errors", - AmberField::getValueFromFields(_ppcntFields, "Symbol Errors"), + AmberField::getValueFromFields(_ppcntFields, "Symbol_Errors"), ANSI_COLOR_RESET, _protoActive == IB, _linkUP); setPrintVal(_berInfoCmd, "Symbol BER", - AmberField::getValueFromFields(_ppcntFields, "Symbol BER"), + AmberField::getValueFromFields(_ppcntFields, "Symbol_BER"), ANSI_COLOR_RESET, _protoActive == IB, _linkUP); setPrintVal(_berInfoCmd, "Effective Physical Errors", - AmberField::getValueFromFields(_ppcntFields, "Effective Errors"), + AmberField::getValueFromFields(_ppcntFields, "Effective_Errors"), ANSI_COLOR_RESET, true, _linkUP); setPrintVal(_berInfoCmd, "Effective Physical BER", - AmberField::getValueFromFields(_ppcntFields, "Effective BER"), + AmberField::getValueFromFields(_ppcntFields, "Effective_BER"), ANSI_COLOR_RESET, true, _linkUP); - std::vector rawErrorsPerLane; - string phyRawErr = ""; - for (u_int32_t lane = 0; lane < _numOfLanes; lane++) { - phyRawErr = AmberField::getValueFromFields(_ppcntFields, - "Raw Errors Lane " + to_string(lane)); - rawErrorsPerLane.push_back(phyRawErr); - } - setPrintVal(_berInfoCmd, "Raw Physical Errors Per Lane", - getStringFromVector(rawErrorsPerLane), - ANSI_COLOR_RESET,true,_linkUP); + string phyRawErr = AmberField::getValueFromFields(_ppcntFields, "Raw_Errors_Lane", false); + findAndReplace(phyRawErr, "_", ","); + phyRawErr = getValuesOfActiveLanes(phyRawErr); + + setPrintVal(_berInfoCmd, "Raw Physical Errors Per Lane", phyRawErr, ANSI_COLOR_RESET, true, _linkUP, true); } @@ -2102,7 +2037,7 @@ void MlxlinkCommander::showBer() prepareBerInfoEDR(); } else { prepareBerInfo(); - setPrintVal(_berInfoCmd, "Raw Physical BER", AmberField::getValueFromFields(_ppcntFields, "Raw BER"), + setPrintVal(_berInfoCmd, "Raw Physical BER", AmberField::getValueFromFields(_ppcntFields, "Raw_BER"), ANSI_COLOR_RESET, true, _linkUP); } @@ -2404,7 +2339,7 @@ string MlxlinkCommander::fecMaskToStr(u_int32_t mask) string fecStr = string(strMask); if (mask) { - fecStr += getFieldsByPairMap(mask, _mlxlinkMaps->_fecModeMask, ", "); + fecStr += getStrByMaskFromPair(mask, _mlxlinkMaps->_fecModeMask, ", "); } else { fecStr = "0x0 (N/A"; } @@ -2626,7 +2561,7 @@ void MlxlinkCommander::initValidDPNList() updateField("node", 0); try { genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); - valid = true; + valid = getFieldValue("bdf0"); } catch (...) { valid = false; } @@ -2762,7 +2697,6 @@ void MlxlinkCommander::collectAMBER() if (_userInput._portSpecified) { PortGroup pg {_localPort, _userInput._labelPort, 0, _userInput._splitPort}; if (_devID == DeviceQuantum2) { - pg.labelPort = pg.labelPort * 2 + _userInput._splitPort - 2; pg.secondSplit = _userInput._secondSplitProvided ? _userInput._secondSplitPort : 0; } @@ -4705,8 +4639,11 @@ void MlxlinkCommander::setAmBerCollectorFields() _amberCollector->_mlxlinkMaps = _mlxlinkMaps; _amberCollector->_isHca = _isHCA; _amberCollector->_devID = _devID; + _amberCollector->_productTechnology = _productTechnology; + _amberCollector->_mstDevName = _device; } + void MlxlinkCommander::initAmBerCollector() { if (!_amberCollector) { diff --git a/mlxlink/modules/mlxlink_commander.h b/mlxlink/modules/mlxlink_commander.h index a1add28c..800eb945 100644 --- a/mlxlink/modules/mlxlink_commander.h +++ b/mlxlink/modules/mlxlink_commander.h @@ -296,6 +296,15 @@ struct DPN { u_int32_t node; }; +struct MODULE_FIELD +{ + string uiName; + string amberName; + bool multiVal; + bool perLane; + bool requireDdm; +}; + using namespace std; class MlxlinkCommander: public MlxlinkRegParser { @@ -350,6 +359,7 @@ class MlxlinkCommander: public MlxlinkRegParser { void handleLabelPorts(std::vector labelPortsStr, bool skipException = false); vector localToPortsPerGroup(vector localPorts); u_int32_t getPortGroup(u_int32_t localPort); + string getValuesOfActiveLanes(const string &row); //Mlxlink query functions virtual void showModuleInfo(); @@ -587,7 +597,6 @@ class MlxlinkCommander: public MlxlinkRegParser { protected: vector _ppcntFields; - string loopAllLanesStr(vector &fields, string str); }; #endif /* MLXLINK_COMMANDER_H */ diff --git a/mlxlink/modules/mlxlink_enums.h b/mlxlink/modules/mlxlink_enums.h index ab490d45..c09f8b1b 100644 --- a/mlxlink/modules/mlxlink_enums.h +++ b/mlxlink/modules/mlxlink_enums.h @@ -34,7 +34,7 @@ #define MLXLINK_ENUMS_H // Common definitions -#define AMBER_VERSION "1.64" +#define AMBER_VERSION "1.78" #define ACCESS_REG_PGUID "PGUID" #define ACCESS_REG_SPZR "SPZR" @@ -67,6 +67,13 @@ #define ACCESS_REG_MTCAP "MTCAP" #define ACCESS_REG_SLRED "SLRED" #define ACCESS_REG_PLIB "PLIB" +#define ACCESS_REG_PMLP "PMLP" +#define ACCESS_REG_PMAOS "PMAOS" +#define ACCESS_REG_PPAOS "PPAOS" +#define ACCESS_REG_PPTT "PPTT" +#define ACCESS_REG_PPRT "PPRT" +#define ACCESS_REG_PMPT "PMPT" +#define ACCESS_REG_PMPD "PMPD" //define all used regs above this line #define QSFP_CHANNELS 4 @@ -713,6 +720,32 @@ enum DATA_PATH_STATE { DATA_PATH_STATE_INITALIZED = 0x7, }; +enum MODULE_OPER_STATUS { + MODULE_OPER_STATUS_INIT = 0, + MODULE_OPER_STATUS_PLUGGED_EN, + MODULE_OPER_STATUS_UNPLUGGED, + MODULE_OPER_STATUS_PLUGGED_WITH_ERROR, + MODULE_OPER_STATUS_PLUGGED_DS +}; + +enum MODULE_ERROR_TYPE { + MODULE_ERROR_TYPE_POWER = 0, + MODULE_ERROR_TYPE_LONG_RANGE, + MODULE_ERROR_TYPE_BUS_STUCK, + MODULE_ERROR_TYPE_BAD, + MODULE_ERROR_TYPE_ENF, + MODULE_ERROR_TYPE_UNSUPPORTED, + MODULE_ERROR_TYPE_HIGH_TEMP, + MODULE_ERROR_TYPE_BAD_CBL, + MODULE_ERROR_TYPE_PMD, + MODULE_ERROR_TYPE_LASTER, + MODULE_ERROR_TYPE_HIGH_CUR, + MODULE_ERROR_TYPE_HIGH_VOLT, + MODULE_ERROR_TYPE_PCIE, + MODULE_ERROR_TYPE_HIGH_PWR, + MODULE_ERROR_TYPE_ST_FAULT +}; + enum ERROR_CODE_RES{ ERROR_CODE_RES_CONFIG_UNDEF = 0, ERROR_CODE_RES_CONFIG_SUCC = 0x1, @@ -722,8 +755,7 @@ enum ERROR_CODE_RES{ ERROR_CODE_RES_CONFIG_REJ_INV_SI = 0x5, ERROR_CODE_RES_CONFIG_REJ_LANES_IN_USE = 0x6, ERROR_CODE_RES_CONFIG_REJ_PART_DATA_PTH = 0x7, - ERROR_CODE_RES_CONFIG_IN_PROG = 0xc, - ERROR_CODE_RES_CONFIG_REJ_CUST = 0xd, + ERROR_CODE_RES_CONFIG_IN_PROG = 0xc }; enum CABLE_IDENTIFIER { @@ -1296,4 +1328,35 @@ enum SLRG_FOM_MODE { SLRG_FOM_MODE_EYEM_VP }; +enum PRBS_PARAMS { + PRBS_PARAMS_RX_TUNING_STATUS, + PRBS_PARAMS_LOCK_STATUS, + PRBS_PARAMS_E, + PRBS_PARAMS_P, + PRBS_PARAMS_MODES_CAP, + PRBS_PARAMS_MODE_ADMIN, + PRBS_PARAMS_TUNING_TYPE, + PRBS_PARAMS_MODULATION, + PRBS_PARAMS_LANE_RATE_CAP, + PRBS_PARAMS_LANE_RATE_ADMIN, + PRBS_PARAMS_LAST +}; + +enum AMBER_SHEET { + AMBER_SHEET_GENERAL = 1, + AMBER_SHEET_INDEXES = 2, + AMBER_SHEET_LINK_STATUS = 3, + AMBER_SHEET_MODULE_STATUS = 4, + AMBER_SHEET_SYSTEM = 5, + AMBER_SHEET_SERDES_16NM = 6, + AMBER_SHEET_SERDES_7NM = 7, + AMBER_SHEET_PORT_COUNTERS = 8, + AMBER_SHEET_TROUBLESHOOTING = 9, + AMBER_SHEET_PHY_OPERATION_INFO = 10, + AMBER_SHEET_LINK_UP_INFO = 11, + AMBER_SHEET_LINK_DOWN_INFO = 12, + AMBER_SHEET_TEST_MODE_INFO = 13, + AMBER_SHEET_TEST_MODE_MODULE_INFO = 14 +}; + #endif /* MLXLINK_ENUMS_H */ diff --git a/mlxlink/modules/mlxlink_maps.cpp b/mlxlink/modules/mlxlink_maps.cpp index 0070f301..d635448b 100644 --- a/mlxlink/modules/mlxlink_maps.cpp +++ b/mlxlink/modules/mlxlink_maps.cpp @@ -451,6 +451,38 @@ void MlxlinkMaps::initPrbsMapping() _prbsLaneRate["200G_2X"] = {LANE_RATE_NDR_CAP, PRBS_NDR}; _prbsLaneRate["400G_4X"] = {LANE_RATE_NDR_CAP, PRBS_NDR}; _prbsLaneRate["800G_8X"] = {LANE_RATE_NDR_CAP, PRBS_NDR}; + + _prbsRxTuningStatus[0] = "PRBS mode tuning was not performed."; + _prbsRxTuningStatus[1] = "Performing PRBS mode tuning."; + _prbsRxTuningStatus[2] = "PRBS mode tuning completed."; + _prbsRxTuningStatus[3] = "Signal Detect in progress."; + + _prbsLaneRateCap[0x1] = "1G (1.25 Gb/s)"; + _prbsLaneRateCap[0x2] = "SDR (2.5 Gb/s)"; + _prbsLaneRateCap[0x4] = "XAUI/2.5G (3.125 Gb/s)"; + _prbsLaneRateCap[0x8] = "DDR/5G (5 Gb/s)"; + _prbsLaneRateCap[0x10] = "QDR (10 Gb/s)"; + _prbsLaneRateCap[0x20] = "FDR10/10G/40G (10.3125 Gb/s)"; + _prbsLaneRateCap[0x40] = "FDR/14G (14.0625 Gb/s)"; + _prbsLaneRateCap[0x80] = "EDR/25G/50G/100G (25.78125 Gb/s)"; + _prbsLaneRateCap[0x100] = "50GE-KR4/12.89G (12.89 Gb/s)"; + _prbsLaneRateCap[0x200] = "HDR/50G/100G/200G/400G (26.5625Gbd/53.125Gb/s)"; + _prbsLaneRateCap[0x400] = "NDR/100G/200G/400G/800G (53.125Gbd/106.25Gb/s)"; + + _prbsLockStatus[0] = "Not locked"; + _prbsLockStatus[1] = "Locked"; + + _prbsEStatus[0] = "PRBS RX is disabled"; + _prbsEStatus[1] = "PRBS RX is enabled"; + + _prbsPStatus[0] = "No polarity inversion"; + _prbsPStatus[1] = "PRBS RX polarity inversion."; + + _prbsModulation[0] = "NRZ test pattern"; + _prbsModulation[1] = "PAM4 encoding"; + _prbsModulation[2] = "PAM4 with precoding"; + _prbsModulation[3] = "PAM4 without gray no precoding"; + _prbsModulation[4] = "PAM4 without gray with precoding"; } void MlxlinkMaps::initPpbmcAndPepcMapping() @@ -625,28 +657,33 @@ void MlxlinkMaps::cimsCableBreakoutMapping() _cimsCableBreakout[CMIS_CABLE_BREAKOUT_UNSPECIFIED] = "Unspecified"; _cimsCableBreakout[CMIS_CABLE_BREAKOUT_QSFPDD_to_QSFPDD] = - "QSFP-DD to QSFP-DD"; + "X to X"; _cimsCableBreakout[CMIS_CABLE_BREAKOUT_QSFPDD_to_2QSFP_or_2QSFPDD] = - "QSFP-DD to 2xQSFP or 2xQSFP-DD (depopulated / 4 lanes)"; + "X to 2xQSFP or 2xX (depopulated / 4 lanes)"; _cimsCableBreakout[CMIS_CABLE_BREAKOUT_QSFPDD_to_4SFPDD_or_4QSFP] = - "QSFP-DD to 4xSFP-DD or 4xQSFP (depopulated / 2 lanes)"; + "X to 4xSFP-DD or 4xX (depopulated / 2 lanes)"; _cimsCableBreakout[CMIS_CABLE_BREAKOUT_QSFPDD_to_8SFP] = - "QSFP-DD to 8xSFP"; + "X to 8xSFP"; _cimsCableBreakout[CMIS_CABLE_BREAKOUT_QSFPDD_to_QSFP_or_QSFPDD] = - "QSFP-DD (depopulated / 4 lanes) to QSFP or QSFP-DD (depopulated / 4 lanes)"; + "X (depopulated / 4 lanes) to QSFP or X (depopulated / 4 lanes)"; _cimsCableBreakout[CMIS_CABLE_BREAKOUT_QSFPDD_to_2QSFP] = - "QSFP-DD (depopulated / 4 lanes) to 2xQSFP(depopulated / 2 lanes) or 2xSFP-DD"; + "X (depopulated / 4 lanes) to 2xX(depopulated / 2 lanes) or 2xSFP-DD"; _cimsCableBreakout[CMIS_CABLE_BREAKOUT_QSFPDD_to_4SFP] = - "QSFP-DD (depopulated / 4 lanes) to 4xSFP"; + "X (depopulated / 4 lanes) to 4xSFP"; _cimsCableBreakout[CMIS_CABLE_BREAKOUT_SFPDD_to_SFPDD] = - "SFP-DD(/ 2 lane module) to SFP-DD"; + "X(/ 2 lane module) to X"; _cimsCableBreakout[CMIS_CABLE_BREAKOUT_SFPDD_to_2SFPDD] = - "SFP-DD(/ 2 lane module) to 2xSFP"; + "X(/ 2 lane module) to 2xSFP"; } void MlxlinkMaps::rxTxCdrCapMapping() { + _txInputFreq[0] = "Tx_input_lanes_1_8"; + _txInputFreq[1] = "Tx_input_lanes_1_4_and_5-8"; + _txInputFreq[2] = "Tx_input_lanes_1_2_and_3_4_and_5_6_and_7_8"; + _txInputFreq[3] = "Lanes_may_be_asynchronous_in_frequency"; + _rxTxCdrCap[RX_TX_CDR_CAP_NO_CDR] = "No CDR"; _rxTxCdrCap[RX_TX_CDR_CAP_BUILD_IN_CDR_WITH_ON_OFF_CONTROL] = "Build-in CDR with on/off control"; _rxTxCdrCap[RX_TX_CDR_CAP_BUILD_IN_CDR_WITHOUT_ON_OFF_CONTROL] = "Build-in CDR without on/off control"; @@ -753,26 +790,26 @@ void MlxlinkMaps::cmisModuleStMapping() void MlxlinkMaps::tempFlagsMapping() { - _tempFLags[TEMP_FLAGS_NO_ALARM_WARN] = "0"; - _tempFLags[TEMP_FLAGS_HI_TEMP_ALARM] = "high_temp_alarm"; - _tempFLags[TEMP_FLAGS_LO_TEMP_ALARM] = "low_temp_alarm"; - _tempFLags[TEMP_FLAGS_HI_TEMP_WARNING] = "high_temp_warning"; - _tempFLags[TEMP_FLAGS_LO_TEMP_WARNING] = "low_temp_warning"; + _tempFlags[TEMP_FLAGS_NO_ALARM_WARN] = "N/A"; + _tempFlags[TEMP_FLAGS_HI_TEMP_ALARM] = "high_temp_alarm"; + _tempFlags[TEMP_FLAGS_LO_TEMP_ALARM] = "low_temp_alarm"; + _tempFlags[TEMP_FLAGS_HI_TEMP_WARNING] = "high_temp_warning"; + _tempFlags[TEMP_FLAGS_LO_TEMP_WARNING] = "low_temp_warning"; } void MlxlinkMaps::vccFlagsMapping() { - _vccFLags[VCC_FLAGS_NO_ALARM_WARN] = "0"; - _vccFLags[VCC_FLAGS_HI_VCC_ALARM] = "high_vcc_alarm"; - _vccFLags[VCC_FLAGS_LO_VCC_ALARM] = "low_vcc_alarm"; - _vccFLags[VCC_FLAGS_HI_VCC_WARNING] = "high_vcc_warning"; - _vccFLags[VCC_FLAGS_LO_VCC_WARNING] = "low_vcc_warning"; + _vccFlags[VCC_FLAGS_NO_ALARM_WARN] = "N/A"; + _vccFlags[VCC_FLAGS_HI_VCC_ALARM] = "high_vcc_alarm"; + _vccFlags[VCC_FLAGS_LO_VCC_ALARM] = "low_vcc_alarm"; + _vccFlags[VCC_FLAGS_HI_VCC_WARNING] = "high_vcc_warning"; + _vccFlags[VCC_FLAGS_LO_VCC_WARNING] = "low_vcc_warning"; } void MlxlinkMaps::dataPathStateMapping() { _dataPathSt[DATA_PATH_STATE_RES] = "N/A"; - _dataPathSt[DATA_PATH_STATE_DEACTIVATED] = "DPDeactivated (or unused lane)"; + _dataPathSt[DATA_PATH_STATE_DEACTIVATED] = "DPDeactivated"; _dataPathSt[DATA_PATH_STATE_INIT] = "DPInit"; _dataPathSt[DATA_PATH_STATE_DEINIT] = "DPDeinit"; _dataPathSt[DATA_PATH_STATE_ACTIVATED] = "DPActivated"; @@ -783,17 +820,31 @@ void MlxlinkMaps::dataPathStateMapping() void MlxlinkMaps::errorCodeResMapping() { - _errorCodeRes[ERROR_CODE_RES_CONFIG_UNDEF] = "No status information available (initial register value)"; - _errorCodeRes[ERROR_CODE_RES_CONFIG_SUCC] = "The last accepted configuration command has been completed successfully"; - _errorCodeRes[ERROR_CODE_RES_CONFIG_REJ] = "Configuration rejected: unspecific validation failure"; - _errorCodeRes[ERROR_CODE_RES_CONFIG_REJ_INV_APP_SEI] = "Configuration rejected: invalid AppSel Code"; - _errorCodeRes[ERROR_CODE_RES_CONFIG_REJ_INV_DATA_PTH] = "Configuration rejected: invalid set of lanes for AppSel"; - _errorCodeRes[ERROR_CODE_RES_CONFIG_REJ_INV_SI] = "Configuration rejected: invalid SI control settingd"; - _errorCodeRes[ERROR_CODE_RES_CONFIG_REJ_LANES_IN_USE] = "Configuration rejected: some lanes not in DPDeactivated"; - _errorCodeRes[ERROR_CODE_RES_CONFIG_REJ_PART_DATA_PTH] = "Configuration rejected: lanes are only subset of DataPath"; - _errorCodeRes[ERROR_CODE_RES_CONFIG_IN_PROG] = "A configuration command is still bening processed by the module" - " a new configuration command is ignored for this lane while ConfigInProgress"; - _errorCodeRes[ERROR_CODE_RES_CONFIG_REJ_CUST] = "Configuration rejected for custom reasons"; + _moduleOperSt[MODULE_OPER_STATUS_INIT] = "initializing"; + _moduleOperSt[MODULE_OPER_STATUS_PLUGGED_EN] = "plugged_enable"; + _moduleOperSt[MODULE_OPER_STATUS_UNPLUGGED] = "unplugged"; + _moduleOperSt[MODULE_OPER_STATUS_PLUGGED_WITH_ERROR] = "module_plugged_with_error"; + + _moduleErrType[MODULE_ERROR_TYPE_POWER] = "Power_Budget_Exceeded"; + _moduleErrType[MODULE_ERROR_TYPE_LONG_RANGE] = "Long_Range_for_non_MLNX_cable_or_module"; + _moduleErrType[MODULE_ERROR_TYPE_BUS_STUCK] = "Bus_stuck - (I2C Data or clock shorted)"; + _moduleErrType[MODULE_ERROR_TYPE_BAD] = "bad_or_unsupported_EEPROM"; + _moduleErrType[MODULE_ERROR_TYPE_ENF] = "Enforce_part_number_list"; + _moduleErrType[MODULE_ERROR_TYPE_UNSUPPORTED] = "unsupported_cable"; + _moduleErrType[MODULE_ERROR_TYPE_HIGH_TEMP] = "unsupported_cable"; + _moduleErrType[MODULE_ERROR_TYPE_BAD_CBL] = "bad_cable - (Module/Cable is shorted)"; + _moduleErrType[MODULE_ERROR_TYPE_PMD] = "PMD_type_is_not_enabled"; + _moduleErrType[MODULE_ERROR_TYPE_PCIE] = "pcie_system_power_slot_Exceeded"; + + _errorCodeRes[ERROR_CODE_RES_CONFIG_UNDEF] = "ConfigUndefined"; + _errorCodeRes[ERROR_CODE_RES_CONFIG_SUCC] = "ConfigSuccess"; + _errorCodeRes[ERROR_CODE_RES_CONFIG_REJ] = "ConfigRejected"; + _errorCodeRes[ERROR_CODE_RES_CONFIG_REJ_INV_APP_SEI] = "ConfigRejectedInvalidAppSel"; + _errorCodeRes[ERROR_CODE_RES_CONFIG_REJ_INV_DATA_PTH] = "ConfigRejectedInvalidDataPath"; + _errorCodeRes[ERROR_CODE_RES_CONFIG_REJ_INV_SI] = "ConfigRejectedInvalidSI"; + _errorCodeRes[ERROR_CODE_RES_CONFIG_REJ_LANES_IN_USE] = "ConfigRejectedLanesInUse"; + _errorCodeRes[ERROR_CODE_RES_CONFIG_REJ_PART_DATA_PTH] = "ConfigRejectedPartialDataPath"; + _errorCodeRes[ERROR_CODE_RES_CONFIG_IN_PROG] = "ConfigInProgress"; } void MlxlinkMaps::qsfpFarEndCableBreakoutMapping() diff --git a/mlxlink/modules/mlxlink_maps.h b/mlxlink/modules/mlxlink_maps.h index 9056cbb1..b5d0d294 100644 --- a/mlxlink/modules/mlxlink_maps.h +++ b/mlxlink/modules/mlxlink_maps.h @@ -159,6 +159,19 @@ class MlxlinkMaps{ std::map _prbsModesList; std::map _prbsLaneRateList; std::map _prbsLaneRate; + std::map _prbsLaneRateCap; + std::map _prbsTuningType; + std::map _prbsEStatus; + std::map _prbsPStatus; + std::map _prbsRxTuningStatus; + std::map _prbsLockStatus; + std::map _prbsModulation; + std::map _modulePrbsSt; + std::map _modulePrbsSwapAdmin; + std::map _modulePrbsInvAdmin; + std::map _modulePrbsModulation; + std::map _modulePrbsRateCap; + std::map _modulePMPDStatus; std::map _pepcStatus; std::map _IBSpeed2Str; std::map _EthExtSpeed2Str; @@ -181,15 +194,18 @@ class MlxlinkMaps{ std::map _cableComplianceSfp; std::map _cableComplianceQsfp; std::map _cableComplianceCmisIb; - std::map _tempFLags; - std::map _vccFLags; + std::map _tempFlags; + std::map _vccFlags; std::map _dataPathSt; + std::map _moduleOperSt; + std::map _moduleErrType; std::map _errorCodeRes; std::map _cimsCableBreakout; std::map _qsfpNearEndCableBreakout; std::map _qsfpFarEndCableBreakout; std::map _cableComplianceExt; std::map _cmisHostCompliance; + std::map _txInputFreq; std::map _rxTxCdrCap; std::map _rxPowerType; std::map _maxReadReqSize; diff --git a/mlxlink/modules/mlxlink_utils.cpp b/mlxlink/modules/mlxlink_utils.cpp index 89966360..a8bcbd16 100644 --- a/mlxlink/modules/mlxlink_utils.cpp +++ b/mlxlink/modules/mlxlink_utils.cpp @@ -498,18 +498,29 @@ bool isPAM4Speed(u_int32_t activeSpeed, u_int32_t protoActive, bool extended) return pam4Signal; } -string getFieldsByPairMap(u_int32_t bitmask, map> maskMap, - const string &fieldSeparator, u_int32_t pairIndex) +string getStrByValue(u_int32_t flags, std::map map) +{ + string flagsStr = map[flags]; + + if (flagsStr.empty()){ + flagsStr = "N/A"; + } + + return flagsStr; +} + +string getStrByMaskFromPair(u_int32_t bitmask, map> maskMap, + const string &fieldSeparator, u_int32_t pairIndex) { map strMap; for (auto it = maskMap.begin(); it != maskMap.end(); it++) { strMap.insert(pair(it->first, pairIndex == 0 ? it->second.first : it->second.second)); } - return getFieldsByMap(bitmask, strMap, fieldSeparator); + return getStrByMask(bitmask, strMap, fieldSeparator); } -string getFieldsByMap(u_int32_t bitmask, std::map maskMap, const string &fieldSeparator) +string getStrByMask(u_int32_t bitmask, std::map maskMap, const string &fieldSeparator) { string bitMaskStr = ""; string tmpMaskStr = ""; @@ -1119,28 +1130,6 @@ string getRxTxCDRState(u_int32_t state, u_int32_t numOfLanes) return deleteLastChar(stateMask); } -string getStringByActiveLanes(string allLanes, int numOfActiveLanes) -{ - string delimiter = ","; - size_t pos = 0; - int i = numOfActiveLanes; - string newStr = ""; - while ((pos = allLanes.find(delimiter)) != string::npos && i != 0) { - newStr += allLanes.substr(0, pos); - allLanes.erase(0, pos + delimiter.length()); - i--; - if( i != 0){ - newStr += ","; - } - } - - if(char(newStr[newStr.length() - 1]) == ','){ - newStr = deleteLastChar(newStr); - } - - return newStr; -} - string pcieDeviceStatusStr(u_int32_t deviceStatus) { string deviceStatusStr, comma; diff --git a/mlxlink/modules/mlxlink_utils.h b/mlxlink/modules/mlxlink_utils.h index 3c1d8885..b55040de 100644 --- a/mlxlink/modules/mlxlink_utils.h +++ b/mlxlink/modules/mlxlink_utils.h @@ -142,10 +142,10 @@ bool isSpeed100GPerLane(u_int32_t speed, u_int32_t protocol); bool askUser(const char *question, bool force = false); string getCableLengthStr(u_int32_t cableLength, bool cmisCable); string getRxTxCDRState(u_int32_t state, u_int32_t numOfLanes); -string getStringByActiveLanes(string allLanes, int numOfActiveLanes); string getFwVersion(bool passive, u_int32_t moduleFWVer); string getVendorRev(u_int32_t rev); -string getFieldsByMap(u_int32_t bitmask, map maskMap, const string &fieldSeparator = ","); -string getFieldsByPairMap(u_int32_t bitmask, map> maskMap, - const string &fieldSeparator = ",", u_int32_t pairIndex = 0); +string getStrByValue(u_int32_t flags, map map); +string getStrByMask(u_int32_t bitmask, map maskMap, const string &fieldSeparator = ","); +string getStrByMaskFromPair(u_int32_t bitmask, map> maskMap, + const string &fieldSeparator = ",", u_int32_t pairIndex = 0); #endif From f0f89942ea9e9702552c8baf2188370333ff2723 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Tue, 21 Dec 2021 12:33:26 +0200 Subject: [PATCH 006/184] [mstlink] Fixing cable dump command Description: -> Fixing seg fault while using un-ordered flags with cable feature -> Fixing dumping redundant cables Issue: 2860300 Issue: 2853424 Issue: 2854445 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_cables_commander.cpp | 24 ++++---------------- mlxlink/modules/mlxlink_commander.cpp | 6 ++++- mlxlink/modules/mlxlink_commander.h | 1 - mlxlink/modules/mlxlink_ui.cpp | 5 ---- 4 files changed, 9 insertions(+), 27 deletions(-) diff --git a/mlxlink/modules/mlxlink_cables_commander.cpp b/mlxlink/modules/mlxlink_cables_commander.cpp index f5e79767..178356ee 100644 --- a/mlxlink/modules/mlxlink_cables_commander.cpp +++ b/mlxlink/modules/mlxlink_cables_commander.cpp @@ -851,28 +851,20 @@ void MlxlinkCablesCommander::initValidPages() readFromPage(page0L, EXTENDED_PAGES_1_2_10_11_ADDR, &extendedPages); free(page0L); if (!(extendedPages & EXTENDED_PAGES_1_2_10_11_MASK)) { - p = (page_t){PAGE_01, LOWER_PAGE_OFFSET, I2C_ADDR_LOW}; - _validPages.push_back(p); p = (page_t){PAGE_01, UPPER_PAGE_OFFSET, I2C_ADDR_LOW}; _validPages.push_back(p); if (_cableIdentifier != IDENTIFIER_SFP_DD) { - p = (page_t){PAGE_02, LOWER_PAGE_OFFSET, I2C_ADDR_LOW}; - _validPages.push_back(p); p = (page_t){PAGE_02, UPPER_PAGE_OFFSET, I2C_ADDR_LOW}; _validPages.push_back(p); - p = (page_t){PAGE_10, LOWER_PAGE_OFFSET, I2C_ADDR_LOW}; - _validPages.push_back(p); p = (page_t){PAGE_10, UPPER_PAGE_OFFSET, I2C_ADDR_LOW}; _validPages.push_back(p); - p = (page_t){PAGE_11, LOWER_PAGE_OFFSET, I2C_ADDR_LOW}; - _validPages.push_back(p); p = (page_t){PAGE_11, UPPER_PAGE_OFFSET, I2C_ADDR_LOW}; _validPages.push_back(p); - // if p 1, B155:6=1, dump page 0x4 (L&H) - // dump page 0x12 (L&H) - // B142:5=1, dump page 0x13 (L&H) - // dump page 0x14 (L&H) + // if p 1, B155:6=1, dump page 0x4 (H) + // dump page 0x12 (H) + // B142:5=1, dump page 0x13 (H) + // dump page 0x14 (H) u_int8_t *page1H = (u_int8_t*)malloc(sizeof(u_int8_t) * CABLE_PAGE_SIZE); loadEEPRMPage(PAGE_01, UPPER_PAGE_OFFSET, page1H);; u_int8_t extendedQsfpPages = 0; @@ -880,12 +872,8 @@ void MlxlinkCablesCommander::initValidPages() (EXTENDED_PAGES_4_12_ADDR - UPPER_PAGE_OFFSET), &extendedQsfpPages); if (extendedQsfpPages & EXTENDED_PAGES_4_12_MASK) { - p = (page_t){PAGE_04, LOWER_PAGE_OFFSET, I2C_ADDR_LOW}; - _validPages.push_back(p); p = (page_t){PAGE_04, UPPER_PAGE_OFFSET, I2C_ADDR_LOW}; _validPages.push_back(p); - p = (page_t){PAGE_12, LOWER_PAGE_OFFSET, I2C_ADDR_LOW}; - _validPages.push_back(p); p = (page_t){PAGE_12, UPPER_PAGE_OFFSET, I2C_ADDR_LOW}; _validPages.push_back(p); } @@ -894,12 +882,8 @@ void MlxlinkCablesCommander::initValidPages() (EXTENDED_PAGES_13_14_ADDR - UPPER_PAGE_OFFSET), &extendedQsfpPages); if (extendedQsfpPages & EXTENDED_PAGES_13_14_MASK) { - p = (page_t){PAGE_13, LOWER_PAGE_OFFSET, I2C_ADDR_LOW}; - _validPages.push_back(p); p = (page_t){PAGE_13, UPPER_PAGE_OFFSET, I2C_ADDR_LOW}; _validPages.push_back(p); - p = (page_t){PAGE_14, LOWER_PAGE_OFFSET, I2C_ADDR_LOW}; - _validPages.push_back(p); p = (page_t){PAGE_14, UPPER_PAGE_OFFSET, I2C_ADDR_LOW}; _validPages.push_back(p); } diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index f84b4a81..908e3dfe 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -4410,13 +4410,14 @@ void MlxlinkCommander::initCablesCommander() _cablesCommander->_sfp51Paging = isSFP51Paging(); _cablesCommander->_passiveQsfp = isPassiveQSFP(); } else { - _allUnhandledErrors += "No plugged cable detected"; + throw MlxRegException(string("No plugged cable detected")); } } void MlxlinkCommander::showCableDump() { try { + initCablesCommander(); if (_plugged && !_mngCableUnplugged) { vector dumpOutput = _cablesCommander->getPagesToDump(); printOuptputVector(dumpOutput); @@ -4430,6 +4431,7 @@ void MlxlinkCommander::showCableDump() void MlxlinkCommander::showCableDDM() { try { + initCablesCommander(); if (_plugged && !_mngCableUnplugged) { if (_ddmSupported) { vector ddmOutput = _cablesCommander->getCableDDM(); @@ -4461,6 +4463,7 @@ vector MlxlinkCommander::validateBytes(const vector &strBytes) void MlxlinkCommander::writeCableEEPROM() { try { + initCablesCommander(); MlxlinkRecord::printCmdLine("Writing To Cable EEPROM", _jsonRoot); if (_plugged && !_mngCableUnplugged) { vector bytesToWrite = validateBytes(_userInput._bytesToWrite); @@ -4475,6 +4478,7 @@ void MlxlinkCommander::writeCableEEPROM() void MlxlinkCommander::readCableEEPROM() { try { + initCablesCommander(); if (_plugged && !_mngCableUnplugged) { MlxlinkCmdPrint bytesOutput = _cablesCommander->readFromEEPRM(_userInput._page , _userInput._offset, _userInput._len); diff --git a/mlxlink/modules/mlxlink_commander.h b/mlxlink/modules/mlxlink_commander.h index 800eb945..6c1ca8d8 100644 --- a/mlxlink/modules/mlxlink_commander.h +++ b/mlxlink/modules/mlxlink_commander.h @@ -244,7 +244,6 @@ enum OPTION_TYPE { SHOW_EXTERNAL_PHY, SHOW_LINK_DOWN_BLAME, SHOW_TX_GROUP_MAP, - CABLE_EEPROM_INI, CABLE_SHOW_DUMP, CABLE_SHOW_DDM, CABLE_EEPROM_WRITE, diff --git a/mlxlink/modules/mlxlink_ui.cpp b/mlxlink/modules/mlxlink_ui.cpp index a5706975..721c7af0 100644 --- a/mlxlink/modules/mlxlink_ui.cpp +++ b/mlxlink/modules/mlxlink_ui.cpp @@ -760,10 +760,6 @@ void MlxlinkUi::commandsCaller() PRINT_LOG(_mlxlinkCommander->_mlxlinkLogger,"-> \"Set External PHY\""); _mlxlinkCommander->sendPepc(); break; - case CABLE_EEPROM_INI: - PRINT_LOG(_mlxlinkCommander->_mlxlinkLogger,"-> Initializing cable EEPROM pages"); - _mlxlinkCommander->initCablesCommander(); - break; case CABLE_SHOW_DUMP: PRINT_LOG(_mlxlinkCommander->_mlxlinkLogger,"-> \"Dump cable pages\""); _mlxlinkCommander->showCableDump(); @@ -995,7 +991,6 @@ ParseStatus MlxlinkUi::HandleOption(string name, string value) return PARSE_OK; } else if (name == CABLE_FLAG) { _mlxlinkCommander->_userInput._cable = true; - addCmd(CABLE_EEPROM_INI); return PARSE_OK; } else if (name == CABLE_DUMP_FLAG) { _mlxlinkCommander->_userInput._dump = true; From 68c973047a1318906c10e00bdc7174a9236f28e1 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Tue, 21 Dec 2021 14:51:07 +0200 Subject: [PATCH 007/184] [mstlink] Fixing label port display in csv file Description: Fixing label port display in csv file Issue: 2861535 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_commander.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index f84b4a81..d2085d80 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -723,7 +723,7 @@ void MlxlinkCommander::checkUnSplit(u_int32_t localPort) void MlxlinkCommander::labelToIBLocalPort() { u_int32_t labelPort = _userInput._labelPort; - bool ibSplitReady = isIBSplitReady(); + bool ibSplitReady = isIBSplitReady() && (_devID == DeviceQuantum || _devID == DeviceQuantum2); if (_userInput._splitProvided && _devID != DeviceQuantum && _devID != DeviceQuantum2) { throw MlxRegException("No split in IB!"); } From 8911691f27362a87bee7b69fe8ed1496f4a1b530 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Tue, 21 Dec 2021 15:16:35 +0200 Subject: [PATCH 008/184] [mstlink] Fixing device tech for Connect-X7 Description: Fixing device tech for Connect-X7 Issue: 2901548 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_commander.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index f84b4a81..cedee76f 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -252,14 +252,21 @@ void MlxlinkCommander::checkValidFW() void MlxlinkCommander::getProductTechnology() { try { - string regName = "SLRG"; - resetParser(regName); - updateField("local_port", _localPort); - updateField("pnat", (_userInput._pcie) ? PNAT_PCIE : PNAT_LOCAL); + if (_devID == DeviceConnectX7) { //TODO: remove after supporting SLRG for Carmel + resetParser(ACCESS_REG_MGIR); - genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); + genBuffSendRegister(ACCESS_REG_MGIR, MACCESS_REG_METHOD_GET); + + _productTechnology = getFieldValue("technology"); + } else { + resetParser(ACCESS_REG_SLRG); + updateField("local_port", _localPort); + updateField("pnat", (_userInput._pcie) ? PNAT_PCIE : PNAT_LOCAL); - _productTechnology = getVersion(getFieldValue("version")); + genBuffSendRegister(ACCESS_REG_SLRG, MACCESS_REG_METHOD_GET); + + _productTechnology = getVersion(getFieldValue("version")); + } } catch (MlxRegException &exc) { throw MlxRegException( "Unable to get product technology: %s", exc.what_s().c_str()); From 3b9e14449973c2426fe71491401798b69cc5c2fd Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Wed, 22 Dec 2021 16:24:34 +0200 Subject: [PATCH 009/184] [mstlink] Fixing formatting issues Description: -> Fixing json format for some fields -> Fixing error message with invalid fec_speed -> Adding NDR speed to the help menu -> Fixing mst pkg versioning in mstlink Issue: 2854445 Issue: 2899194 Issue: 2902805 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_commander.cpp | 144 +++++++++++++------------- mlxlink/modules/mlxlink_commander.h | 7 +- mlxlink/modules/mlxlink_ui.cpp | 2 +- 3 files changed, 76 insertions(+), 77 deletions(-) diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index 14fd03b1..6b699c2b 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -640,7 +640,7 @@ void MlxlinkCommander::labelToSpectLocalPort() } splitAdjustment = 0; if ((getFieldValue("lane0_module_mapping.module") + 1) == _userInput._labelPort) { - checkWidthSplit(localPort); + checkWidthSplit(); if (_userInput._splitProvided) { if (_devID == DeviceSpectrum3 || _devID == DeviceSpectrum4 || (_devID != DeviceSpectrum && !spectWithGearBox)) { @@ -672,59 +672,44 @@ void MlxlinkCommander::labelToSpectLocalPort() "Failed to find Local Port, please provide valid Port Number"); } -void MlxlinkCommander::checkWidthSplit(u_int32_t localPort) +void MlxlinkCommander::checkWidthSplit() { - if (!_userInput._splitProvided) { - checkUnSplit(localPort); - return; - } - switch (_userInput._splitPort) { - case 1: - throw MlxRegException("Invalid split number!"); - case 2: - if (_numOfLanes < 4 || - ((_devID == DeviceSpectrum3 || _devID == DeviceSpectrum4) && _numOfLanes == 4)) { - return; - } - break; - case 3: - case 4: - if (_numOfLanes == 1 || - ((_devID == DeviceSpectrum3 || _devID == DeviceSpectrum4) && _numOfLanes == 2)) { - return; + if (_userInput._splitProvided) { + if (_userInput._secondSplitProvided) { + throw MlxRegException("Invalid port number!"); } - break; - case 5: - case 6: - case 7: - case 8: - if ((_devID == DeviceSpectrum3 || _devID == DeviceSpectrum4) && _numOfLanes == 1) { - return; + switch (_userInput._splitPort) { + case 1: + throw MlxRegException("Invalid split number!"); + case 2: + if (_numOfLanes < 4 || + ((_devID == DeviceSpectrum3 || _devID == DeviceSpectrum4) && _numOfLanes == 4)) { + return; + } + break; + case 3: + case 4: + if (_numOfLanes == 1 || + ((_devID == DeviceSpectrum3 || _devID == DeviceSpectrum4) && _numOfLanes == 2)) { + return; + } + break; + case 5: + case 6: + case 7: + case 8: + if ((_devID == DeviceSpectrum3 || _devID == DeviceSpectrum4) && _numOfLanes == 1) { + return; + } + break; + default: + break; } - break; - default: - break; - } - throw MlxRegException( - "Port " + to_string(_userInput._labelPort) + "/" - + to_string(_userInput._splitPort) - + " does not exist!"); -} - -void MlxlinkCommander::checkUnSplit(u_int32_t localPort) -{ - if (localPort) { + throw MlxRegException( + "Port " + to_string(_userInput._labelPort) + "/" + + to_string(_userInput._splitPort) + + " does not exist!"); } - return; - /*if (_numOfLanes == 4) { - return; - } else if (_numOfLanes == 2) { - throw MlxRegException("Port is Splitted! please provide label port and lane, ex: " + convertToString(_labelPort) + "/2"); - } else if (_numOfLanes == 1) { - //TODO - 4x-1x - if (localPort) {} - //throw MlxRegException("Port is Splitted! please provide label port and lane, ex: " + convertToString(_labelPort) + "/4"); - }*/ } void MlxlinkCommander::labelToIBLocalPort() @@ -734,7 +719,9 @@ void MlxlinkCommander::labelToIBLocalPort() if (_userInput._splitProvided && _devID != DeviceQuantum && _devID != DeviceQuantum2) { throw MlxRegException("No split in IB!"); } - if ((labelPort > maxLocalPort() || (ibSplitReady && labelPort >= maxLocalPort()/2 )) || + u_int32_t maxLabelPort = _devID == DeviceQuantum2? maxLocalPort()/4 : + _devID == DeviceQuantum? maxLocalPort()/2 - 1 : maxLocalPort(); + if ((labelPort > maxLabelPort) || (_userInput._secondSplitProvided && _devID != DeviceQuantum2) || (_userInput._splitPort > 2)) { throw MlxRegException("Invalid port number!"); @@ -758,10 +745,13 @@ void MlxlinkCommander::labelToIBLocalPort() } if ((_devID == DeviceQuantum || _devID == DeviceQuantum2) && ibSplitReady) { string portStr = "Port " + to_string(_userInput._labelPort); - portStr = _devID == DeviceQuantum2 ? portStr + "/" + to_string(_userInput._splitPort) - : portStr; + string swSplitCmd = "module-type qsfp-split-2"; + if (_devID == DeviceQuantum2) { + portStr = portStr + "/" + to_string(_userInput._splitPort); + swSplitCmd = "port-type split-2"; + } throw MlxRegException("%s is not splitted physically from switch side, Use this command to split it physically:\n" - "interface ib module-type qsfp-split-2", portStr.c_str()); + "interface ib %s", portStr.c_str(), swSplitCmd.c_str()); } } @@ -1306,9 +1296,9 @@ void MlxlinkCommander::preparePowerAndCdrSection(bool valid) (_plugged && _cableMediaType != PASSIVE) ? powerClassStr : "N/A", ANSI_COLOR_RESET, true, valid); setPrintVal(_moduleInfoCmd, "CDR RX", _plugged ? rxCdrState : "N/A", - ANSI_COLOR_RESET, true, valid); + ANSI_COLOR_RESET, true, valid, true); setPrintVal(_moduleInfoCmd,"CDR TX", _plugged ? txCdrState : "N/A", - ANSI_COLOR_RESET, true, valid); + ANSI_COLOR_RESET, true, valid, true); setPrintVal(_moduleInfoCmd, "LOS Alarm", "N/A", ANSI_COLOR_RESET, true, valid); } @@ -1605,7 +1595,7 @@ void MlxlinkCommander::runningVersion() setPrintVal(_toolInfoCmd,"Firmware Version", _fwVersion, ANSI_COLOR_GREEN,true, !_prbsTestMode); setPrintVal(_toolInfoCmd,"amBER Version", AMBER_VERSION, ANSI_COLOR_GREEN, _productTechnology >= PRODUCT_16NM, !_prbsTestMode); - setPrintVal(_toolInfoCmd,"MSTFLINT Version", MSTFLINT_VERSION_STR, ANSI_COLOR_GREEN,true, !_prbsTestMode); + setPrintVal(_toolInfoCmd, PKG_NAME " Version", PKG_VER, ANSI_COLOR_GREEN,true, !_prbsTestMode); } void MlxlinkCommander::operatingInfoPage() @@ -1955,12 +1945,14 @@ void MlxlinkCommander::prepareBerInfo() setPrintVal(_berInfoCmd, "Time Since Last Clear [Min]", AmberField::getValueFromFields(_ppcntFields, "Time_since_last_clear_[Min]"), ANSI_COLOR_RESET, true, _linkUP); - setPrintVal(_berInfoCmd, "Symbol Errors", - AmberField::getValueFromFields(_ppcntFields, "Symbol_Errors"), - ANSI_COLOR_RESET, _protoActive == IB, _linkUP); - setPrintVal(_berInfoCmd, "Symbol BER", - AmberField::getValueFromFields(_ppcntFields, "Symbol_BER"), - ANSI_COLOR_RESET, _protoActive == IB, _linkUP); + if (_protoActive == IB) { + setPrintVal(_berInfoCmd, "Symbol Errors", + AmberField::getValueFromFields(_ppcntFields, "Symbol_Errors"), + ANSI_COLOR_RESET, true, _linkUP); + setPrintVal(_berInfoCmd, "Symbol BER", + AmberField::getValueFromFields(_ppcntFields, "Symbol_BER"), + ANSI_COLOR_RESET, true, _linkUP); + } setPrintVal(_berInfoCmd, "Effective Physical Errors", AmberField::getValueFromFields(_ppcntFields, "Effective_Errors"), ANSI_COLOR_RESET, true, _linkUP); @@ -2311,9 +2303,8 @@ string MlxlinkCommander::fecMaskToUserInputStr(u_int32_t fecCapMask) } } } - - validFecStr = validFecStr.empty()? "" : deleteLastChar(validFecStr); - + string auFec = _mlxlinkMaps->_fecModeMask[0].second + "(" + _mlxlinkMaps->_fecModeMask[0].first + ")"; + validFecStr = validFecStr.empty()? "" : (auFec + "/" + deleteLastChar(validFecStr)); return validFecStr; } @@ -3894,7 +3885,6 @@ u_int32_t MlxlinkCommander::fecToBit(const string &fec, const string &speedStrG) fecAdmin = it->first; } } - return fecAdmin; } @@ -3917,9 +3907,6 @@ u_int32_t MlxlinkCommander::getFecCapForCheck(const string &speedStr) void MlxlinkCommander::checkPplmCap() { - if (_userInput._pplmFec == "AU") { - return; - } string speedFec = _userInput._speedFec; string uiSpeed = _userInput._speedFec; if (_linkUP && _userInput._speedFec.empty()) { @@ -3940,10 +3927,20 @@ void MlxlinkCommander::checkPplmCap() } } if (!isIn(speedToCheck, supportedSpeeds)) { - throw MlxRegException("\nFEC speed %s is not valid", uiSpeed.c_str()); + string validSpeeds = ""; + if (!supportedSpeeds.empty()) { + validSpeeds = ", valid FEC speed configurations are ["; + for (auto it = _mlxlinkMaps->_fecPerSpeed.begin(); it != _mlxlinkMaps->_fecPerSpeed.end(); it++) { + if (isIn(it->first, supportedSpeeds)) { + validSpeeds += it->first + ","; + } + } + validSpeeds = !validSpeeds.empty()? deleteLastChar(validSpeeds) : validSpeeds; + validSpeeds = validSpeeds + "]"; + } + throw MlxRegException("\nFEC speed %s is not valid%s", uiSpeed.c_str(), validSpeeds.c_str()); } } - // Validate the FEC for the speed if (speedFec == "10g" || speedFec == "40g") { speedFec = "10g_40g"; @@ -3956,10 +3953,9 @@ void MlxlinkCommander::checkPplmCap() } _userInput._speedFec = speedFec; u_int32_t fecCap = getFecCapForCheck(_userInput._speedFec); - if (!(fecToBit(_userInput._pplmFec, _userInput._speedFec) & fecCap)) { + if (_userInput._pplmFec != "AU" && !(fecToBit(_userInput._pplmFec, _userInput._speedFec) & fecCap)) { string supportedFec = fecMaskToUserInputStr(fecCap); string validFecs = fecMaskToUserInputStr(BIT_MASK_ALL_DWORD); - string errorMsg = _userInput._pplmFec + " FEC is not supported in " + uiSpeed + " speed, "; if (validFecs.find(_userInput._pplmFec) == string::npos) { errorMsg = _userInput._pplmFec + " FEC configuration is not valid, "; diff --git a/mlxlink/modules/mlxlink_commander.h b/mlxlink/modules/mlxlink_commander.h index 6c1ca8d8..4849f69b 100644 --- a/mlxlink/modules/mlxlink_commander.h +++ b/mlxlink/modules/mlxlink_commander.h @@ -52,8 +52,12 @@ #ifdef MST_UL #define MLXLINK_EXEC "mstlink" +#define PKG_NAME "MSTFLINT" +#define PKG_VER MSTFLINT_VERSION_STR #else #define MLXLINK_EXEC "mlxlink" +#define PKG_NAME "MFT" +#define PKG_VER MFT_VERSION_STR #endif //------------------------------------------------------------ @@ -332,8 +336,7 @@ class MlxlinkCommander: public MlxlinkRegParser { void labelToIBLocalPort(); bool isIBSplitReady(); u_int32_t calculatePanelPort(bool ibSplitReady); - void checkWidthSplit(u_int32_t localPort); - void checkUnSplit(u_int32_t localPort); + void checkWidthSplit(); u_int32_t maxLocalPort(); void checkStrLength(const string &str); void getActualNumOfLanes(u_int32_t linkSpeedActive, bool extended); diff --git a/mlxlink/modules/mlxlink_ui.cpp b/mlxlink/modules/mlxlink_ui.cpp index 721c7af0..66243351 100644 --- a/mlxlink/modules/mlxlink_ui.cpp +++ b/mlxlink/modules/mlxlink_ui.cpp @@ -105,7 +105,7 @@ void MlxlinkUi::printSynopsisCommands() MlxlinkRecord::printFlagLine(PAOS_FLAG_SHORT, PAOS_FLAG, "port_state", "Configure Port State [UP(up)/DN(down)/TG(toggle)]"); MlxlinkRecord::printFlagLine(PTYS_FLAG_SHORT, PTYS_FLAG, "speeds", - "Configure Speeds [HDR,EDR,FDR10,FDR,QDR,DDR,SDR,400G_8X,200G_4X,100G_2X,50G_1X,100G,100G_4X,50G,50G_2X,25G,40X,10G,2.5G,1G]"); + "Configure Speeds [NDR,HDR,EDR,FDR10,FDR,QDR,DDR,SDR,400G_8X,200G_4X,100G_2X,50G_1X,100G,100G_4X,50G,50G_2X,25G,40X,10G,2.5G,1G]"); printf(IDENT); MlxlinkRecord::printFlagLine(PTYS_LINK_MODE_FORCE_FLAG_SHORT, PTYS_LINK_MODE_FORCE_FLAG, "", "Configure Link Mode Force (Disable AN)"); From 6114e83afef04fac9989a21d812ee97c66effba6 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Tue, 28 Dec 2021 16:40:35 +0200 Subject: [PATCH 010/184] [mstlink] Fixing formatting bugs and updating amber to 1.80 Description: -> Fixing rx prbs modes when set worng mode -> Fixing error message when device have no valid prbs Issue: 2824323 Issue: 2904985 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_amBER_collector.cpp | 4 ++-- mlxlink/modules/mlxlink_commander.cpp | 17 +++++++++++++++-- mlxlink/modules/mlxlink_enums.h | 2 +- mlxlink/modules/mlxlink_port_info.h | 1 - mlxlink/modules/mlxlink_ui.cpp | 2 +- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/mlxlink/modules/mlxlink_amBER_collector.cpp b/mlxlink/modules/mlxlink_amBER_collector.cpp index 79f57a47..d9475fa6 100644 --- a/mlxlink/modules/mlxlink_amBER_collector.cpp +++ b/mlxlink/modules/mlxlink_amBER_collector.cpp @@ -236,7 +236,7 @@ void MlxlinkAmBerCollector::init() _sheetsList[AMBER_SHEET_PORT_COUNTERS] = FIELDS_COUNT{35, 0, 35}; _sheetsList[AMBER_SHEET_TROUBLESHOOTING] = FIELDS_COUNT{2, 2, 0}; _sheetsList[AMBER_SHEET_PHY_OPERATION_INFO] = FIELDS_COUNT{18, 18, 15}; - _sheetsList[AMBER_SHEET_LINK_UP_INFO] = FIELDS_COUNT{6, 6, 0}; + _sheetsList[AMBER_SHEET_LINK_UP_INFO] = FIELDS_COUNT{9, 9, 0}; _sheetsList[AMBER_SHEET_LINK_DOWN_INFO] = FIELDS_COUNT{5, 5, 0}; _sheetsList[AMBER_SHEET_TEST_MODE_INFO] = FIELDS_COUNT{144, 144, 0}; _sheetsList[AMBER_SHEET_TEST_MODE_MODULE_INFO] = FIELDS_COUNT{110, 110, 0}; @@ -792,7 +792,7 @@ vector MlxlinkAmBerCollector::getSerdesHDR() sltpStatus.push_back(getFieldValue("status") ? "Valid" : "Invalid"); } - fillParamsToFields("Status", sltpStatus, fields); + fillParamsToFields("tx_status", sltpStatus, fields); fillParamsToFields("pre_2_tap", sltpParams[PRE_2_TAP], fields); fillParamsToFields("pre_tap", sltpParams[PRE_TAP], fields); fillParamsToFields("main_tap", sltpParams[MAIN_TAP], fields); diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index 6b699c2b..078b675b 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -3034,6 +3034,7 @@ string MlxlinkCommander::getSupportedPrbsModes(u_int32_t modeSelector) genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); u_int32_t capsMask = getFieldValue("prbs_modes_cap"); + capsMask = modeSelector == PRBS_RX? capsMask & 0xffe3fff : capsMask; string modeCapStr = ""; // Iterating over the supported modes according to capability mask // And preparing them in one string @@ -3483,8 +3484,20 @@ void MlxlinkCommander::checkPrbsRegsCap(const string &prbsReg, const string &lan if (invalidRateStr || !(laneRateCap & getFieldValue("lane_rate_cap"))) { string errStr = "Device does not support lane rate " + laneRateStr + " in physical test mode.\n"; - errStr += "Valid RX PRBS lane rates: " + getSupportedPrbsRates(PRBS_RX) + "\n"; - errStr += "Valid TX PRBS lane rates: " + getSupportedPrbsRates(PRBS_TX) + "\n"; + string rxRates = getSupportedPrbsRates(PRBS_RX); + string txRates = getSupportedPrbsRates(PRBS_TX); + if (rxRates.empty()) { + rxRates = "No Valid RX PRBS lane rate"; + } else { + rxRates = "Valid RX PRBS lane rates: " + rxRates; + } + errStr += rxRates + "\n"; + if (txRates.empty()) { + txRates = "No Valid TX PRBS lane rate"; + } else { + txRates = "Valid TX PRBS lane rates: " + txRates; + } + errStr += txRates + "\n"; errStr += "Default PRBS Lane Rate is EDR / 25GE / 50GE / 100GE (25.78125 Gb/s)"; throw MlxRegException(errStr); } diff --git a/mlxlink/modules/mlxlink_enums.h b/mlxlink/modules/mlxlink_enums.h index c09f8b1b..e60e0868 100644 --- a/mlxlink/modules/mlxlink_enums.h +++ b/mlxlink/modules/mlxlink_enums.h @@ -34,7 +34,7 @@ #define MLXLINK_ENUMS_H // Common definitions -#define AMBER_VERSION "1.78" +#define AMBER_VERSION "1.80" #define ACCESS_REG_PGUID "PGUID" #define ACCESS_REG_SPZR "SPZR" diff --git a/mlxlink/modules/mlxlink_port_info.h b/mlxlink/modules/mlxlink_port_info.h index 18db461a..91b01888 100644 --- a/mlxlink/modules/mlxlink_port_info.h +++ b/mlxlink/modules/mlxlink_port_info.h @@ -39,7 +39,6 @@ #define PPHCR_REG "PPHCR" #define PPCNT_REG "PPCNT" -#define PPCNT_HISTOGRAM_GRP 0x23 enum HISTOGRAM_TYPE { HIST_TYPE_AUTO, diff --git a/mlxlink/modules/mlxlink_ui.cpp b/mlxlink/modules/mlxlink_ui.cpp index 66243351..6332f07a 100644 --- a/mlxlink/modules/mlxlink_ui.cpp +++ b/mlxlink/modules/mlxlink_ui.cpp @@ -60,7 +60,7 @@ void MlxlinkUi::printSynopsisHeader() IDENT "SYNOPSIS:\n" IDENT2 MLXLINK_EXEC " [OPTIONS]\n\n" IDENT "DESCRIPTION:\n" - IDENT2 "The mstlink tool is used to check and debug link status and issues related to them.\n" + IDENT2 "The " MLXLINK_EXEC " tool is used to check and debug link status and issues related to them.\n" IDENT2 "The tool can be used on different links and cables (passive, active, transceiver and backplane).\n"); printf("\n"); printf(IDENT "OPTIONS:\n"); From 57aef98eb37b7be8179a2e268bd1c51f3b57a00e Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Sun, 2 Jan 2022 11:11:48 +0200 Subject: [PATCH 011/184] Fixing 400G 4X speed in show fec command Description: Fixing 400G 4X speed in show fec command Tested OS: Linux64 Tested devices: CX7 Tested flows: mlxlink show fec Known gaps (with RM ticket): NA Issue: 2912099 Change-Id: I05a05ca0ad552ee3bafdd3ffd1de9b792f847cfe Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_utils.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlxlink/modules/mlxlink_utils.cpp b/mlxlink/modules/mlxlink_utils.cpp index a8bcbd16..dca90796 100644 --- a/mlxlink/modules/mlxlink_utils.cpp +++ b/mlxlink/modules/mlxlink_utils.cpp @@ -229,10 +229,10 @@ string EthExtSupportedSpeeds2Str(u_int32_t int_mask) { string maskStr = ""; if (int_mask & ETH_LINK_SPEED_EXT_800GAUI_8) { - maskStr += "800G_8x,"; + maskStr += "800G_8X,"; } if (int_mask & ETH_LINK_SPEED_EXT_400GAUI_4) { - maskStr += "400G_4x,"; + maskStr += "400G_4X,"; } if (int_mask & ETH_LINK_SPEED_EXT_400GAUI_8) { maskStr += "400G_8X,"; From 5defa30a7576055a4083ff8bd8d22f9878c37c0a Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Mon, 3 Jan 2022 13:48:22 +0200 Subject: [PATCH 012/184] [mlxconfig] [ES] support for challenge and remote keep alive, RMCS only Description: mlxconfig shall support sending challenge and starting a keep alive session for remote tokens. new functionality was added to command line parser, and mlxconfig commands. this commit is for ES support. Tested OS: Linux Tested devices: BlackBird Tested flows: mlxconfig token, end_token_session, query_token_session, remote_token_keep_alive Known gaps (with RM ticket): N/A Issue: 2808445 --- flint/subcommands.cpp | 3 + fw_comps_mgr/fw_comps_mgr.cpp | 10 +- fw_comps_mgr/fw_comps_mgr.h | 1 + mlxconfig/mlxcfg_generic_commander.cpp | 5 + mlxconfig/mlxcfg_parser.cpp | 94 ++++- mlxconfig/mlxcfg_ui.cpp | 355 +++++++++++++++++- mlxconfig/mlxcfg_ui.h | 59 ++- mlxfwops/lib/fsctrl_ops.cpp | 4 +- mlxfwops/lib/mlxfwops_com.h | 3 +- reg_access/reg_access.c | 59 ++- reg_access/reg_access.h | 4 + .../prm/switch/ext/register_access_table.adb | 31 ++ tools_layouts/reg_access_switch_layouts.c | 273 +++++++++++++- tools_layouts/reg_access_switch_layouts.h | 215 ++++++++++- 14 files changed, 1083 insertions(+), 33 deletions(-) diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index b44c4903..4712b5f2 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -3392,6 +3392,9 @@ string QuerySubCommand::printSecurityAttrInfo(u_int32_t m) if (m & SMM_CRYTO_TO_COMMISSIONING) { attr += ", crypto-to-commissioning"; } + if (m & SMM_RMCS_TOKEN) { + attr += ", rmcs-token"; + } return attr; } diff --git a/fw_comps_mgr/fw_comps_mgr.cpp b/fw_comps_mgr/fw_comps_mgr.cpp index ebe36bd4..cdee73fd 100644 --- a/fw_comps_mgr/fw_comps_mgr.cpp +++ b/fw_comps_mgr/fw_comps_mgr.cpp @@ -1191,7 +1191,7 @@ void FwCompsMgr::GenerateHandle() _updateHandle = _lastFsmCtrl.update_handle & 0xffffff; } -const char* CompNames[] = { +const char* CompNames[] = { "NO_COMPONENT 1", "COMPID_BOOT_IMG", "COMPID_RUNTIME_IMG", @@ -1205,8 +1205,9 @@ const char* CompNames[] = { "COMPID_GEARBOX", "COMPID_CONGESTION_CONTROL", "COMPID_LINKX_PROPERTIES", - "COMPID_CRYPTO_TO_COMMISSIONING" -} ; + "COMPID_CRYPTO_TO_COMMISSIONING", + "COMPID_RMCS_TOKEN" +}; bool FwCompsMgr::RefreshComponentsStatus(comp_status_st* ComponentStatus) { @@ -1513,6 +1514,9 @@ const char* FwComponent::getCompIdStr(comps_ids_t compId) case COMPID_CRYPTO_TO_COMMISSIONING: return "COMPID_CRYPTO_TO_COMMISSIONING"; + case COMPID_RMCS_TOKEN: + return "COMPID_RMCS_TOKEN"; + default: return "UNKNOWN_COMPONENT"; } diff --git a/fw_comps_mgr/fw_comps_mgr.h b/fw_comps_mgr/fw_comps_mgr.h index a188006b..67eac173 100644 --- a/fw_comps_mgr/fw_comps_mgr.h +++ b/fw_comps_mgr/fw_comps_mgr.h @@ -165,6 +165,7 @@ class FwComponent { COMPID_CONGESTION_CONTROL = 0xB, COMPID_LINKX = 0xC, COMPID_CRYPTO_TO_COMMISSIONING = 0xD, + COMPID_RMCS_TOKEN = 0xE, COMPID_UNKNOWN = 0xff, } comps_ids_t; diff --git a/mlxconfig/mlxcfg_generic_commander.cpp b/mlxconfig/mlxcfg_generic_commander.cpp index 0c6899ee..6ce5f8df 100644 --- a/mlxconfig/mlxcfg_generic_commander.cpp +++ b/mlxconfig/mlxcfg_generic_commander.cpp @@ -120,6 +120,7 @@ enum OP {EQUAL, NOT_EQUAL}; const u_int8_t debugTokenId = 0x5; const u_int8_t csTokenId = 0x7; const u_int8_t btcTokenId = 0x8; +const u_int8_t rmcsTokenId = 0x10; const u_int32_t idMlnxId = 0x10e; void GenericCommander::supportsNVData() @@ -1377,6 +1378,10 @@ void GenericCommander::checkConfTlvs(const vector& tlvs, tlv->_id == btcTokenId) { csCompFound = true; compsId = FwComponent::COMPID_CRYPTO_TO_COMMISSIONING; + } else if (tlv->_tlvClass == NVFile && + tlv->_id == rmcsTokenId) { + csCompFound = true; + compsId = FwComponent::COMPID_RMCS_TOKEN; } else if (tlv->_tlvClass == 0x0 && tlv->_id == idMlnxId) { idMlnxCompFound = true; diff --git a/mlxconfig/mlxcfg_parser.cpp b/mlxconfig/mlxcfg_parser.cpp index c1ea4e62..9ba6a960 100644 --- a/mlxconfig/mlxcfg_parser.cpp +++ b/mlxconfig/mlxcfg_parser.cpp @@ -56,6 +56,8 @@ using namespace std; #define IDENT3 "\t\t" #define IDENT4 IDENT2 IDENT +#define MAX_SESSION_TIME_IN_MINUTES 10080 // 1 week = 7 * 24 hours * 60 minutes + static void printFlagLine(string flag_s, string flag_l, string param, string desc) { @@ -97,6 +99,7 @@ void MlxCfg::printHelp() printFlagLine("eng", "openssl_engine", "ENGINE NAME", "OpenSSL engine name"); printFlagLine("k", "openssl_key_id", "IDENTIFIER", "OpenSSL key identifier"); printFlagLine("t", "device_type", "switch/hca", "Specify the device type"); + printFlagLine("", "session_id", "", "Specify the session id for token keep alive session."); //print commands printf("\n"); @@ -116,6 +119,11 @@ void MlxCfg::printHelp() printf(IDENT2 "%-24s : %s\n", "xml2bin", "Generate binary configuration dump file from XML file. XML input file name and bin output file name must be specified. (*)"); printf(IDENT2 "%-24s : %s\n", "create_conf", "Generate configuration file from XML file. XML input file name and bin output file name must be specified. (*)"); printf(IDENT2 "%-24s : %s\n", "apply", "Apply a configuration file, that was created with create_conf command. bin input file name must be specified. (*)"); + printf(IDENT2 "%-24s : %s\n", "token", "Send a challenge request to a MST device. Token type must be specified."); + printf(IDENT2 "%-24s : %s\n", "remote_token_keep_alive", "Start a remote token session. Session id must be specified."); + printf(IDENT2 "%-24s : %s\n", "token_supported", "Query which tokens are supported on a MST device."); + printf(IDENT2 "%-24s : %s\n", "query_token_session", "Query the status of an active token session."); + printf(IDENT2 "%-24s : %s\n", "end_token_session", "End an active token session."); // print supported commands printf("\n"); @@ -359,8 +367,19 @@ Device_Type MlxCfg::getDeviceTypeFromString(string inStr){ } } +mlxCfgStatus MlxCfg::getNumberFromString(const char* str, u_int32_t& num) +{ + char* end = NULL; + num = strtoul(str, &end, 0); + if (*end != '\0') { + return err(true, "argument is not a number: %s", str); + } + return MLX_CFG_OK; +} + mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) { + mlxCfgStatus status = MLX_CFG_OK; int i = 1; for (; i < argc; i++) { string arg = argv[i]; @@ -473,6 +492,61 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) // hidden flag --force used to ignore parameter checks } else if (arg == "--force") { _mlxParams.force = true; + } else if (arg == "--session_id") { + if (++i == argc) { + return err(true, "missing session id"); + } + status = getNumberFromString(argv[i], _mlxParams.sessionId); + _mlxParams.isSessionIDGiven = true; + if (status != MLX_CFG_OK) { + return status; + } + } else if (arg == "token") { + if (++i == argc) { + return err(true, "missing token name"); + } + if (strcmp(argv[i], "RMCS") != 0) { + return err(true, "only RMCS token is supported"); + } + _mlxParams.cmd = Mc_TokenChallenge; + _mlxParams.tokenID = Mc_Token_RMCS; + } else if (arg == "token_supported") { + _mlxParams.cmd = Mc_TokenSupported; + } else if (arg == "query_token_session") { + _mlxParams.cmd = Mc_QueryTokenSession; + } else if (arg == "end_token_session") { + _mlxParams.cmd = Mc_EndTokenSession; + } else if (arg == "remote_token_keep_alive") { + if (++i == argc) { + return err(true, "missing session time"); + } + status = getNumberFromString(argv[i], _mlxParams.sessionTimeInSec); + if (status != MLX_CFG_OK) { + return status; + } + if (_mlxParams.sessionTimeInSec > MAX_SESSION_TIME_IN_MINUTES) { + return err(true, "requested session time is out of bounds, max session time is 1 week."); + } + _mlxParams.sessionTimeInSec *= 60; + _mlxParams.cmd = Mc_RemoteTokenKeepAlive; + } else if (arg == "--cycle_time") { + if (++i == argc) { + return err(true, "missing cycle time value"); + } + status = getNumberFromString(argv[i], _mlxParams.keepAliveSleepTimeBetweenCommands); + if (status != MLX_CFG_OK) { + return status; + } + _mlxParams.isSleepTimeBetweenCommandsInput = true; + } else if (arg == "--resend_time") { + if (++i == argc) { + return err(true, "missing resend time value"); + } + status = getNumberFromString(argv[i], _mlxParams.keepAliveSleepTimeOnCommandTO); + if (status != MLX_CFG_OK) { + return status; + } + _mlxParams.isSleepTimeOnCommandTOInput = true; } else { return err(true, "invalid argument: %s", arg.c_str()); } @@ -488,7 +562,10 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) if (i != argc && (_mlxParams.cmd == Mc_Reset)) { return err(true, "%s command expects no argument but %d argument received", "reset", argc - i); } - if ((_mlxParams.cmd == Mc_Set || _mlxParams.cmd == Mc_Clr_Sem || _mlxParams.cmd == Mc_Set_Raw || _mlxParams.cmd == Mc_Backup || _mlxParams.cmd == Mc_ShowConfs || _mlxParams.cmd == Mc_Apply) && _mlxParams.device.length() == 0) { + if ((_mlxParams.cmd == Mc_Set || _mlxParams.cmd == Mc_Clr_Sem || _mlxParams.cmd == Mc_Set_Raw || _mlxParams.cmd == Mc_Backup + || _mlxParams.cmd == Mc_ShowConfs || _mlxParams.cmd == Mc_Apply || _mlxParams.cmd == Mc_RemoteTokenKeepAlive + || _mlxParams.cmd == Mc_TokenChallenge || _mlxParams.cmd == Mc_TokenSupported || _mlxParams.cmd == Mc_QueryTokenSession + || _mlxParams.cmd == Mc_EndTokenSession) && _mlxParams.device.length() == 0) { return err(true, "%s command expects device to be specified.", _mlxParams.cmd == Mc_Set ? "set" : _mlxParams.cmd == Mc_Set_Raw ? @@ -496,7 +573,12 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) "get_raw" : _mlxParams.cmd == Mc_Clr_Sem ? "clear_semaphore" : _mlxParams.cmd == Mc_Backup ? "backup" : _mlxParams.cmd == Mc_Apply ? - "apply" : "show_confs"); + "apply" : _mlxParams.cmd == Mc_TokenChallenge ? + "token" : _mlxParams.cmd == Mc_TokenSupported ? + "token_supported" : _mlxParams.cmd == Mc_QueryTokenSession ? + "query_token_session" : _mlxParams.cmd == Mc_EndTokenSession ? + "end_token_session" : _mlxParams.cmd == Mc_EndTokenSession ? + "remote_token_keep_alive" : "show_confs"); } if (((_mlxParams.cmd == Mc_Set_Raw || _mlxParams.cmd == Mc_Get_Raw) && _mlxParams.rawTlvFile.size() == 0 )) { @@ -511,6 +593,14 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) return err(true, "raw TLV file can only be specified with set_raw command."); } + if ((_mlxParams.cmd == Mc_RemoteTokenKeepAlive && !_mlxParams.isSessionIDGiven) || + (_mlxParams.cmd != Mc_RemoteTokenKeepAlive && _mlxParams.isSessionIDGiven)) { + return err(true, "--session_id should be specified with remote_token_keep_alive command"); + } + if ((_mlxParams.isSleepTimeBetweenCommandsInput || _mlxParams.isSleepTimeOnCommandTOInput) && _mlxParams.cmd != Mc_RemoteTokenKeepAlive) { + return err(true, "sleep times for keep alive session can only be specified with remote_token_keep_alive command"); + } + if (_mlxParams.cmd == Mc_GenTLVsFile) { return extractNVOutputFile(argc - i, &(argv[i])); } diff --git a/mlxconfig/mlxcfg_ui.cpp b/mlxconfig/mlxcfg_ui.cpp index d0fc068c..0d713893 100644 --- a/mlxconfig/mlxcfg_ui.cpp +++ b/mlxconfig/mlxcfg_ui.cpp @@ -40,8 +40,11 @@ #include #include #include +#include #include +#include +#include #include "mlxcfg_ui.h" #include "mlxcfg_utils.h" @@ -1356,6 +1359,227 @@ mlxCfgStatus MlxCfg::apply() return rc; } + +mlxCfgStatus MlxCfg::remoteTokenKeepAlive() +{ + mlxCfgStatus status = MLX_CFG_OK; + mfile *mf = NULL; + + mf = mopen(_mlxParams.device.c_str()); + if (!mf) { + printf("-E- failed opening the device.\n"); + return MLX_CFG_ERROR; + } + + KeepAliveSession session(mf, _mlxParams.sessionId, _mlxParams.sessionTimeInSec); + + if (_mlxParams.isSleepTimeBetweenCommandsInput) { + session.setSleepTimeBetweenCommands(_mlxParams.keepAliveSleepTimeBetweenCommands); + } + if (_mlxParams.isSleepTimeOnCommandTOInput) { + session.setSleepTimeOnCommandTO(_mlxParams.keepAliveSleepTimeOnCommandTO); + } + + int session_status = session.startSession(); + if (session_status) { + status = MLX_CFG_ERROR; + } + else { + printf("Keep alive session has ended successfully.\n"); + } + + mclose(mf); + + return status; +} + +bool MlxCfg::runMTCQ(mfile* mf, struct reg_access_switch_mtcq_reg_ext* mtcq_reg) +{ + reg_access_status_t rc = ME_REG_ACCESS_OK; + + mft_signal_set_handling(1); + rc = reg_access_mtcq(mf, REG_ACCESS_METHOD_GET, mtcq_reg); + dealWithSignal(); + if (rc) { + printf("failed getting response from the device, error %d.\n", rc); + return false; + } + + return true; +} + +void MlxCfg::printArray(const u_int32_t arr[], int len) +{ + int i = 0; + + if (len < 0) { + throw MlxcfgException("Invalid array length was given.\n"); + } + + for (; i < len; ++i) { + printf("%08x", arr[i]); + } + printf("\n"); +} + +void MlxCfg::printHexArrayAsAscii(const u_int32_t arr[], int len) +{ + u_int8_t byteArray[4]; + int i = 0, j = 0; + + if (len < 0) { + throw MlxcfgException("Invalid array length was given.\n"); + } + + for (i = 0; i < len; ++i) { + + memcpy(byteArray, &arr[i], 4); + for (j = 3; j >= 0; --j) { + printf("%c", byteArray[j]); + } + } + printf("\n"); +} + +mlxCfgStatus MlxCfg::getChallenge() +{ + u_int32_t base_mac[2]; + + mfile *mf = mopen(_mlxParams.device.c_str()); + if (!mf) { + printf("-E- failed to open the device.\n"); + return MLX_CFG_ERROR; + } + + struct reg_access_switch_mtcq_reg_ext mtcq_reg; + memset(&mtcq_reg, 0, sizeof(mtcq_reg)); + mtcq_reg.token_opcode = _mlxParams.tokenID; + if (!runMTCQ(mf, &mtcq_reg)) { + return MLX_CFG_ERROR; + } + base_mac[0] = mtcq_reg.base_mac & 0xffffffff; + base_mac[1] = (mtcq_reg.base_mac >> 32) & 0xffffffff; + + printf("Token opcode: %x\n", mtcq_reg.token_opcode); + printf("Keypair uuid: "); + printArray(mtcq_reg.keypair_uuid, 4); + printf("Base mac: %08x%08x\n", base_mac[1], base_mac[0]); + printf("PSID: "); + printHexArrayAsAscii(mtcq_reg.psid, 4); + printf("FW version: %x%08x\n", mtcq_reg.fw_version_39_32, mtcq_reg.fw_version_31_0); + printf("Source address: "); + printArray(mtcq_reg.source_address, 4); + printf("Session id: %x\n", mtcq_reg.session_id); + printf("Challenge version: %x\n", mtcq_reg.challenge_version); + printf("Challenge: "); + printArray(mtcq_reg.challenge, 8); + + return MLX_CFG_OK; +} + +mlxCfgStatus MlxCfg::queryTokenSupport() +{ + mfile *mf = mopen(_mlxParams.device.c_str()); + if (!mf) { + printf("-E- failed opening the device.\n"); + return MLX_CFG_ERROR; + } + + tools_open_mcam mcam; + memset(&mcam, 0, sizeof(mcam)); + reg_access_status_t rc = ME_REG_ACCESS_OK; + rc = reg_access_mcam_reverse(mf, REG_ACCESS_METHOD_GET, &mcam); + if (rc) { + printf("failed getting response from the device, error %d.\n", rc); + } + + printf("CS tokens supported: %d\n", EXTRACT(mcam.mng_feature_cap_mask[1], 6, 1)); + printf("Debug FW tokens supported: %d\n", EXTRACT(mcam.mng_feature_cap_mask[1], 7, 1)); + + return MLX_CFG_OK; +} + +bool MlxCfg::runMDSR(mfile* mf, struct reg_access_switch_mdsr_reg_ext* mdsr_reg, reg_access_method_t method) +{ + reg_access_status_t rc = ME_REG_ACCESS_OK; + + mft_signal_set_handling(1); + rc = reg_access_mdsr(mf, method, mdsr_reg); + dealWithSignal(); + + if (rc) { + printf("failed getting response from the device, error %d.\n", rc); + return false; + } + + return true; +} + +mlxCfgStatus MlxCfg::queryTokenSession() +{ + mfile *mf = mopen(_mlxParams.device.c_str()); + if (!mf) { + printf("-E- failed opening the device.\n"); + return MLX_CFG_ERROR; + } + + struct reg_access_switch_mdsr_reg_ext mdsr_reg; + memset(&mdsr_reg, 0, sizeof(mdsr_reg)); + if (!runMDSR(mf, &mdsr_reg, REG_ACCESS_METHOD_GET)) { + return MLX_CFG_ERROR; + } + processMDSRData(mdsr_reg, true); + + return MLX_CFG_OK; +} + +void MlxCfg::processMDSRData(const struct reg_access_switch_mdsr_reg_ext& mdsr_reg, bool isQuery) +{ + static const char* additional_info_to_string[6] = {"No additional information available.", + "There is no debug session in progress.", + "FW is not secured, debug session cannot be ended.", + "Fail - Debug end request cannot be accepted.", + "Fail - Host is not allowed to query debug session.", + "Debug session active."}; + + if (mdsr_reg.status == 0) { + if (isQuery) { + printf("%s\n", additional_info_to_string[mdsr_reg.additional_info]); + } + else { + printf("Debug session ended successfully\n"); + } + } + else { + if (mdsr_reg.additional_info > 5) { + printf("-E- invalid code in info.\n"); + } + else { + printf("%s\n", additional_info_to_string[mdsr_reg.additional_info]); + } + } +} + +mlxCfgStatus MlxCfg::endTokenSession() +{ + mfile *mf = mopen(_mlxParams.device.c_str()); + if (!mf) { + printf("-E- failed opening the device.\n"); + return MLX_CFG_ERROR; + } + + struct reg_access_switch_mdsr_reg_ext mdsr_reg; + memset(&mdsr_reg, 0, sizeof(mdsr_reg)); + mdsr_reg.end = 1; + if (!runMDSR(mf, &mdsr_reg, REG_ACCESS_METHOD_SET)) { + return MLX_CFG_ERROR; + } + + processMDSRData(mdsr_reg, false); + + return MLX_CFG_OK; +} + mlxCfgStatus MlxCfg::execute(int argc, char *argv[]) { mlxCfgStatus rc = parseArgs(argc, argv); @@ -1427,7 +1651,21 @@ mlxCfgStatus MlxCfg::execute(int argc, char *argv[]) case Mc_Apply: ret = apply(); break; - + case Mc_RemoteTokenKeepAlive: + ret = remoteTokenKeepAlive(); + break; + case Mc_TokenChallenge: + ret = getChallenge(); + break; + case Mc_TokenSupported: + ret = queryTokenSupport(); + break; + case Mc_QueryTokenSession: + ret = queryTokenSession(); + break; + case Mc_EndTokenSession: + ret = endTokenSession(); + break; default: // should not reach here. return err(true, "invalid command."); @@ -1450,3 +1688,118 @@ int main(int argc, char *argv[]) } } +const char* KeepAliveSession::_mkdcErrorToString[5] = {"OK", "BAD_SESSION_ID", "BAD_KEEP_ALIVE_COUNTER", + "BAD_SOURCE_ADDRESS", "SESSION_TIMEOUT"}; + +const u_int32_t KeepAliveSession::_keepAliveTimestampInSec = 600; + +KeepAliveSession::KeepAliveSession(mfile *mf, u_int16_t sessionId, u_int32_t sessionTimeInSec): + _mf(mf), + _sessionId(sessionId), + _sessionTimeLeftInSec(sessionTimeInSec), + _SleepTimeOnCommandTO(5), + _SleepTimeBetweenCommands(300) +{ + memset(&_mkdc_reg, 0, sizeof(_mkdc_reg)); + _mkdc_reg.session_id = sessionId; + + srand(time(NULL)); + _mkdc_reg.current_keep_alive_counter = rand(); +} + +int KeepAliveSession::startSession() +{ + time_t timer; + u_int32_t sleepTimeInSec = 0; + u_int32_t sleepBetweenCommandsInSec = _SleepTimeBetweenCommands; + + if (sleepBetweenCommandsInSec >= _keepAliveTimestampInSec) { + printf("Specified cycle time cannot be longer than keep alive timestamp.\n"); + return -1; + } + + while (_sessionTimeLeftInSec > _keepAliveTimestampInSec) { + if (sleepBetweenCommandsInSec > (_sessionTimeLeftInSec - _keepAliveTimestampInSec)) { + sleepBetweenCommandsInSec = _sessionTimeLeftInSec - _keepAliveTimestampInSec; + } + sleepTimeInSec = sleepBetweenCommandsInSec; + timer = 0; + + msleep(sleepTimeInSec * 1000); + + _sessionTimeLeftInSec -= sleepBetweenCommandsInSec; + + runMKDC(_mf, &_mkdc_reg, timer); + + _sessionTimeLeftInSec -= timer; + if (processMKDCData(&_mkdc_reg) != 0) { + return -1; + } + } + + msleep(_sessionTimeLeftInSec * 1000); + + return 0; +} + +int KeepAliveSession::runMKDC(mfile* mf, reg_access_switch_mcdc_reg* mkdc_reg, time_t& timer) +{ + reg_access_status_t rc = ME_REG_ACCESS_OK; + time_t start = 0; + int status = 0; + + start = time(NULL); + mft_signal_set_handling(1); + rc = reg_access_mkdc(mf, REG_ACCESS_METHOD_GET, mkdc_reg); + dealWithSignal(); + timer = time(NULL) - start; + + while ((rc == ME_ICMD_STATUS_EXECUTE_TO) && ((u_int32_t)timer < _keepAliveTimestampInSec)) { + u_int32_t sleep_time_in_sec = _SleepTimeOnCommandTO; + + msleep(sleep_time_in_sec * 1000); + + mft_signal_set_handling(1); + rc = reg_access_mkdc(mf, REG_ACCESS_METHOD_GET, mkdc_reg); + dealWithSignal(); + + timer = time(NULL) - start; + } + + if (rc == ME_REG_ACCESS_REG_NOT_SUPP) { + printf("-E- MKDC access register is not supported.\n"); + status = -2; + } + else if (rc) { + printf("Error while using reg access MKDC, error code is %d\n", rc); + status = -1; + } + + return status; +} + +int KeepAliveSession::processMKDCData(reg_access_switch_mcdc_reg* mkdc_reg) +{ + if (mkdc_reg->error_code != 0) { + printf("-E- keep alive session failed. error code: %s\n", _mkdcErrorToString[mkdc_reg->error_code]); + return -1; + } + if (mkdc_reg->session_id != _sessionId) { + printf("-E- received wrong session id.\n"); + return -1; + } + + mkdc_reg->current_keep_alive_counter = mkdc_reg->next_keep_alive_counter; + + return 0; +} + +void KeepAliveSession::setSleepTimeOnCommandTO(u_int32_t sleepTime) +{ + _SleepTimeOnCommandTO = sleepTime; +} + +void KeepAliveSession::setSleepTimeBetweenCommands(u_int32_t sleepTime) +{ + _SleepTimeBetweenCommands = sleepTime; +} diff --git a/mlxconfig/mlxcfg_ui.h b/mlxconfig/mlxcfg_ui.h index 7169fab1..0ec5c9fa 100644 --- a/mlxconfig/mlxcfg_ui.h +++ b/mlxconfig/mlxcfg_ui.h @@ -62,9 +62,21 @@ typedef enum { Mc_XML2Bin, Mc_CreateConf, Mc_Apply, + Mc_RemoteTokenKeepAlive, + Mc_TokenChallenge, + Mc_TokenSupported, + Mc_QueryTokenSession, + Mc_EndTokenSession, Mc_UnknownCmd } mlxCfgCmd; +typedef enum { + Mc_Token_RMCS = 0, + Mc_Token_RMDT, + Mc_Token_CRCS, + Mc_Token_CRDT +} mlxCfgToken; + typedef enum { UNSUPPORTED_DEVICE = -1, HCA = 0, @@ -91,7 +103,8 @@ class MlxCfgParams MlxCfgParams() : device(), rawTlvFile(), NVInputFile(), NVOutputFile(), dbName(DB_NAME), privPemFile(), keyPairUUID(), opensslEngine(), opensslKeyId(), allAttrs(false), cmd(Mc_UnknownCmd), yes(false), - force(false), enableVerbosity(false) {} + force(false), enableVerbosity(false), isSleepTimeBetweenCommandsInput(false), + isSleepTimeOnCommandTOInput(false) {} ~MlxCfgParams() {} std::string device; @@ -110,7 +123,39 @@ class MlxCfgParams std::vector setParams; bool force;// ignore parameter checks bool enableVerbosity; + mlxCfgToken tokenID; + u_int32_t sessionId; + bool isSessionIDGiven; + u_int32_t sessionTimeInSec; + u_int32_t keepAliveSleepTimeBetweenCommands; + bool isSleepTimeBetweenCommandsInput; + u_int32_t keepAliveSleepTimeOnCommandTO; + bool isSleepTimeOnCommandTOInput; +}; + +class KeepAliveSession +{ +public: + KeepAliveSession(mfile *mf, u_int16_t sessionId, u_int32_t sessionTimeInSec); + int startSession(); + void setSleepTimeOnCommandTO(u_int32_t sleepTime); + void setSleepTimeBetweenCommands(u_int32_t sleepTime); + +private: + int runMKDC(mfile* mf, reg_access_switch_mcdc_reg* mkdc_reg, time_t& timer); + int processMKDCData(reg_access_switch_mcdc_reg* mkdc_reg); + + static const char* _mkdcErrorToString[5]; + + static const u_int32_t _keepAliveTimestampInSec; + + mfile* _mf; + u_int16_t _sessionId; + u_int32_t _sessionTimeLeftInSec; + reg_access_switch_mcdc_reg _mkdc_reg; + u_int32_t _SleepTimeOnCommandTO; + u_int32_t _SleepTimeBetweenCommands; }; class MlxCfg @@ -129,6 +174,7 @@ class MlxCfg void printOpening(const char *dev, int devIndex); void printConfHeader(bool showDefualt, bool showNew, bool showCurrent); Device_Type getDeviceTypeFromString(string inStr); + mlxCfgStatus getNumberFromString(const char* str, u_int32_t& num); mlxCfgStatus parseArgs(int argc, char *argv[]); //Helper functions for parse args mlxCfgStatus extractNVInputFile(int argc, char *argv[]); @@ -181,6 +227,17 @@ class MlxCfg mlxCfgStatus createConf(); mlxCfgStatus apply(); + mlxCfgStatus remoteTokenKeepAlive(); + mlxCfgStatus getChallenge(); + mlxCfgStatus queryTokenSupport(); + mlxCfgStatus queryTokenSession(); + mlxCfgStatus endTokenSession(); + void processMDSRData(const struct reg_access_switch_mdsr_reg_ext& mdsr_reg, bool isQuery); + bool runMDSR(mfile* mf, struct reg_access_switch_mdsr_reg_ext* mdsr_reg, reg_access_method_t method); + bool runMTCQ(mfile* mf, struct reg_access_switch_mtcq_reg_ext* mtcq_reg); + void printArray(const u_int32_t arr[], int len); + void printHexArrayAsAscii(const u_int32_t arr[], int len); + // static print functions static int printParam(string param, u_int32_t val); static int printValue(string strVal, u_int32_t val); diff --git a/mlxfwops/lib/fsctrl_ops.cpp b/mlxfwops/lib/fsctrl_ops.cpp index 13f9cf14..da824a0c 100644 --- a/mlxfwops/lib/fsctrl_ops.cpp +++ b/mlxfwops/lib/fsctrl_ops.cpp @@ -213,7 +213,9 @@ bool FsCtrlOperations::FsIntQuery() if (it->getType() == FwComponent::COMPID_CRYPTO_TO_COMMISSIONING) { _fsCtrlImgInfo.security_mode |= SMM_CRYTO_TO_COMMISSIONING; } - + if (it->getType() == FwComponent::COMPID_RMCS_TOKEN) { + _fsCtrlImgInfo.security_mode |= SMM_RMCS_TOKEN; + } } } diff --git a/mlxfwops/lib/mlxfwops_com.h b/mlxfwops/lib/mlxfwops_com.h index 1c6b8cc9..921c76db 100644 --- a/mlxfwops/lib/mlxfwops_com.h +++ b/mlxfwops/lib/mlxfwops_com.h @@ -258,7 +258,8 @@ typedef enum security_mode_mask { SMM_DEV_FW = 0x1 << 4, SMM_CS_TOKEN = 0x1 << 5, SMM_DBG_TOKEN = 0x1 << 6, - SMM_CRYTO_TO_COMMISSIONING = 0x1 << 7 + SMM_CRYTO_TO_COMMISSIONING = 0x1 << 7, + SMM_RMCS_TOKEN = 0x1 << 8 } security_mode_mask_t; typedef enum security_mode { diff --git a/reg_access/reg_access.c b/reg_access/reg_access.c index 3aa4f2ee..f27f3f3e 100644 --- a/reg_access/reg_access.c +++ b/reg_access/reg_access.c @@ -89,6 +89,8 @@ #define REG_ID_MCQI 0x9061 #define REG_ID_MCDA 0x9063 #define REG_ID_MQIS 0x9064 +#define REG_ID_MTCQ 0x9065 +#define REG_ID_MKDC 0x9066 #define REG_ID_MCAM 0x907f // TODO: get correct register ID for mfrl mfai #define REG_ID_MFRL 0x9028 @@ -98,6 +100,7 @@ #define REG_ID_MGPIR 0x9100 #define REG_ID_MDFCR 0x9101 #define REG_ID_MDRCR 0x9102 +#define REG_ID_MDSR 0x9110 #define REG_ID_MFSV 0x9115 #define REG_ID_MDDT 0x9160 @@ -583,6 +586,40 @@ reg_access_status_t reg_access_mcam(mfile *mf, reg_access_method_t method, struc REG_ACCCESS(mf, method, REG_ID_MCAM, mcam, mcam, tools_open); } +void swap_bytes(u_int8_t* lhs, u_int8_t* rhs) +{ + u_int8_t temp = 0; + temp = *lhs; + *lhs = *rhs; + *rhs = temp; +} + +void reverse_byte_array(u_int8_t* arr, int len) +{ + u_int8_t* lhs = arr; + u_int8_t* rhs = arr + len - 1; + + if (len < 2) { + return; + } + + for (; lhs < rhs; ++lhs, --rhs) { + swap_bytes(lhs, rhs); + } +} + +reg_access_status_t reg_access_mcam_reverse(mfile *mf, reg_access_method_t method, struct tools_open_mcam *mcam) +{ + reg_access_status_t rc = reg_access_mcam(mf, method, mcam); + +#if __BYTE_ORDER == __LITTLE_ENDIAN + reverse_byte_array(mcam->mng_access_reg_cap_mask, 16); + reverse_byte_array(mcam->mng_feature_cap_mask, 16); +#endif + + return rc; +} + /************************************ * Function: reg_access_mcda ************************************/ @@ -752,7 +789,27 @@ const char* reg_access_err2str(reg_access_status_t status) { return m_err2str(status); } - +/************************************ +* Function: reg_access_mtcq +************************************/ +reg_access_status_t reg_access_mtcq(mfile *mf, reg_access_method_t method, struct reg_access_switch_mtcq_reg_ext *mtcq) +{ + REG_ACCCESS(mf, method, REG_ID_MTCQ, mtcq, mtcq_reg_ext, reg_access_switch); +} +/************************************ +* Function: reg_access_mdsr +************************************/ +reg_access_status_t reg_access_mdsr(mfile *mf, reg_access_method_t method, struct reg_access_switch_mdsr_reg_ext *mdsr) +{ + REG_ACCCESS(mf, method, REG_ID_MDSR, mdsr, mdsr_reg_ext, reg_access_switch); +} +/************************************ +* Function: reg_access_mkdc +************************************/ +reg_access_status_t reg_access_mkdc(mfile *mf, reg_access_method_t method, struct reg_access_switch_mcdc_reg *mcdc) +{ + REG_ACCCESS(mf, method, REG_ID_MKDC, mcdc, mcdc_reg, reg_access_switch); +} /************************************ * Function: reg_access_mpegc ************************************/ diff --git a/reg_access/reg_access.h b/reg_access/reg_access.h index a2ccc899..03ff6e9a 100644 --- a/reg_access/reg_access.h +++ b/reg_access/reg_access.h @@ -103,6 +103,7 @@ reg_access_status_t reg_access_mfmc(mfile *mf, reg_access_method_t method, struc reg_access_status_t reg_access_mfpa_new(mfile *mf, reg_access_method_t method, struct tools_open_mfpa *mfpa); reg_access_status_t reg_access_mcam(mfile *mf, reg_access_method_t method, struct tools_open_mcam *mcam); +reg_access_status_t reg_access_mcam_reverse(mfile *mf, reg_access_method_t method, struct tools_open_mcam *mcam); reg_access_status_t reg_access_secure_host(mfile *mf, reg_access_method_t method, struct tools_open_mlock *mlock); /* * MCXX new burn commands @@ -119,6 +120,9 @@ reg_access_status_t reg_access_mcdd(mfile *mf, reg_access_method_t method, struc const char* reg_access_err2str(reg_access_status_t status); reg_access_status_t reg_access_mirc(mfile *mf, reg_access_method_t method, struct tools_open_mirc_reg *mirc); +reg_access_status_t reg_access_mkdc(mfile *mf, reg_access_method_t method, struct reg_access_switch_mcdc_reg *mcdc); +reg_access_status_t reg_access_mtcq(mfile *mf, reg_access_method_t method, struct reg_access_switch_mtcq_reg_ext *mtcq); +reg_access_status_t reg_access_mdsr(mfile *mf, reg_access_method_t method, struct reg_access_switch_mdsr_reg_ext *mtcq); reg_access_status_t reg_access_mpegc(mfile *mf, reg_access_method_t method, struct reg_access_hca_mpegc_reg *mpegc); #ifdef __cplusplus diff --git a/tools_layouts/adb/prm/switch/ext/register_access_table.adb b/tools_layouts/adb/prm/switch/ext/register_access_table.adb index 8c5a9db1..682dc3eb 100644 --- a/tools_layouts/adb/prm/switch/ext/register_access_table.adb +++ b/tools_layouts/adb/prm/switch/ext/register_access_table.adb @@ -1557,6 +1557,13 @@ + + + + + + + @@ -2023,6 +2030,25 @@ + + + + + + + + + + + + + + + + + + + @@ -7499,6 +7525,11 @@ + + + + + diff --git a/tools_layouts/reg_access_switch_layouts.c b/tools_layouts/reg_access_switch_layouts.c index c3c14af2..bdbc2e87 100644 --- a/tools_layouts/reg_access_switch_layouts.c +++ b/tools_layouts/reg_access_switch_layouts.c @@ -32,7 +32,7 @@ /*** - *** This file was generated at "2021-09-30 13:17:36" + *** This file was generated at "2021-10-26 16:49:12" *** by: *** > /mswg/release/tools/a-me/last_stable/adabe_plugins/adb2c/adb2pack.py --input adb/prm/switch/ext/reg_access_switch.adb --file-prefix reg_access_switch --prefix reg_access_switch_ --no-adb-utils ***/ @@ -502,6 +502,41 @@ void reg_access_switch_mddt_reg_payload_auto_ext_dump(const union reg_access_swi reg_access_switch_mddt_reg_payload_auto_ext_print(ptr_struct, fd, 0); } +void reg_access_switch_uint64_pack(const u_int64_t *ptr_struct, u_int8_t *ptr_buff) +{ + u_int32_t offset; + + offset = 0; + adb2c_push_integer_to_buff(ptr_buff, offset, 8, *ptr_struct); +} + +void reg_access_switch_uint64_unpack(u_int64_t *ptr_struct, const u_int8_t *ptr_buff) +{ + u_int32_t offset; + + offset = 0; + *ptr_struct = adb2c_pop_integer_from_buff(ptr_buff, offset, 8); +} + +void reg_access_switch_uint64_print(const u_int64_t *ptr_struct, FILE *fd, int indent_level) +{ + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "======== reg_access_switch_uint64 ========\n"); + + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "uint64 : " U64H_FMT "\n", (u_int64_t) *ptr_struct); +} + +unsigned int reg_access_switch_uint64_size(void) +{ + return REG_ACCESS_SWITCH_UINT64_SIZE; +} + +void reg_access_switch_uint64_dump(const u_int64_t *ptr_struct, FILE *fd) +{ + reg_access_switch_uint64_print(ptr_struct, fd, 0); +} + void reg_access_switch_icam_reg_ext_pack(const struct reg_access_switch_icam_reg_ext *ptr_struct, u_int8_t *ptr_buff) { u_int32_t offset; @@ -610,6 +645,59 @@ void reg_access_switch_icsr_ext_dump(const struct reg_access_switch_icsr_ext *pt reg_access_switch_icsr_ext_print(ptr_struct, fd, 0); } +void reg_access_switch_mcdc_reg_pack(const struct reg_access_switch_mcdc_reg *ptr_struct, u_int8_t *ptr_buff) +{ + u_int32_t offset; + + offset = 28; + adb2c_push_bits_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->error_code); + offset = 0; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->session_id); + offset = 32; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->current_keep_alive_counter); + offset = 64; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->next_keep_alive_counter); +} + +void reg_access_switch_mcdc_reg_unpack(struct reg_access_switch_mcdc_reg *ptr_struct, const u_int8_t *ptr_buff) +{ + u_int32_t offset; + + offset = 28; + ptr_struct->error_code = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 4); + offset = 0; + ptr_struct->session_id = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + offset = 32; + ptr_struct->current_keep_alive_counter = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + offset = 64; + ptr_struct->next_keep_alive_counter = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); +} + +void reg_access_switch_mcdc_reg_print(const struct reg_access_switch_mcdc_reg *ptr_struct, FILE *fd, int indent_level) +{ + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "======== reg_access_switch_mcdc_reg ========\n"); + + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "error_code : " UH_FMT "\n", ptr_struct->error_code); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "session_id : " UH_FMT "\n", ptr_struct->session_id); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "current_keep_alive_counter : " U32H_FMT "\n", ptr_struct->current_keep_alive_counter); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "next_keep_alive_counter : " U32H_FMT "\n", ptr_struct->next_keep_alive_counter); +} + +unsigned int reg_access_switch_mcdc_reg_size(void) +{ + return REG_ACCESS_SWITCH_MCDC_REG_SIZE; +} + +void reg_access_switch_mcdc_reg_dump(const struct reg_access_switch_mcdc_reg *ptr_struct, FILE *fd) +{ + reg_access_switch_mcdc_reg_print(ptr_struct, fd, 0); +} + void reg_access_switch_mddq_ext_pack(const struct reg_access_switch_mddq_ext *ptr_struct, u_int8_t *ptr_buff) { u_int32_t offset; @@ -846,6 +934,170 @@ void reg_access_switch_mddt_reg_ext_dump(const struct reg_access_switch_mddt_reg reg_access_switch_mddt_reg_ext_print(ptr_struct, fd, 0); } +void reg_access_switch_mdsr_reg_ext_pack(const struct reg_access_switch_mdsr_reg_ext *ptr_struct, u_int8_t *ptr_buff) +{ + u_int32_t offset; + + offset = 28; + adb2c_push_bits_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->status); + offset = 18; + adb2c_push_bits_to_buff(ptr_buff, offset, 6, (u_int32_t)ptr_struct->additional_info); + offset = 32; + adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->end); +} + +void reg_access_switch_mdsr_reg_ext_unpack(struct reg_access_switch_mdsr_reg_ext *ptr_struct, const u_int8_t *ptr_buff) +{ + u_int32_t offset; + + offset = 28; + ptr_struct->status = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 4); + offset = 18; + ptr_struct->additional_info = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 6); + offset = 32; + ptr_struct->end = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); +} + +void reg_access_switch_mdsr_reg_ext_print(const struct reg_access_switch_mdsr_reg_ext *ptr_struct, FILE *fd, int indent_level) +{ + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "======== reg_access_switch_mdsr_reg_ext ========\n"); + + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "status : " UH_FMT "\n", ptr_struct->status); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "additional_info : " UH_FMT "\n", ptr_struct->additional_info); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "end : " UH_FMT "\n", ptr_struct->end); +} + +unsigned int reg_access_switch_mdsr_reg_ext_size(void) +{ + return REG_ACCESS_SWITCH_MDSR_REG_EXT_SIZE; +} + +void reg_access_switch_mdsr_reg_ext_dump(const struct reg_access_switch_mdsr_reg_ext *ptr_struct, FILE *fd) +{ + reg_access_switch_mdsr_reg_ext_print(ptr_struct, fd, 0); +} + +void reg_access_switch_mtcq_reg_ext_pack(const struct reg_access_switch_mtcq_reg_ext *ptr_struct, u_int8_t *ptr_buff) +{ + u_int32_t offset; + int i; + + offset = 0; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->token_opcode); + for (i = 0; i < 4; ++i) { + offset = adb2c_calc_array_field_address(32, 32, i, 896, 1); + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->keypair_uuid[i]); + } + offset = 160; + adb2c_push_integer_to_buff(ptr_buff, offset, 8, ptr_struct->base_mac); + for (i = 0; i < 4; ++i) { + offset = adb2c_calc_array_field_address(224, 32, i, 896, 1); + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->psid[i]); + } + offset = 376; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->fw_version_39_32); + offset = 384; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->fw_version_31_0); + for (i = 0; i < 4; ++i) { + offset = adb2c_calc_array_field_address(416, 32, i, 896, 1); + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->source_address[i]); + } + offset = 560; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->session_id); + offset = 544; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->challenge_version); + for (i = 0; i < 8; ++i) { + offset = adb2c_calc_array_field_address(576, 32, i, 896, 1); + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->challenge[i]); + } +} + +void reg_access_switch_mtcq_reg_ext_unpack(struct reg_access_switch_mtcq_reg_ext *ptr_struct, const u_int8_t *ptr_buff) +{ + u_int32_t offset; + int i; + + offset = 0; + ptr_struct->token_opcode = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + for (i = 0; i < 4; ++i) { + offset = adb2c_calc_array_field_address(32, 32, i, 896, 1); + ptr_struct->keypair_uuid[i] = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + } + offset = 160; + ptr_struct->base_mac = adb2c_pop_integer_from_buff(ptr_buff, offset, 8); + for (i = 0; i < 4; ++i) { + offset = adb2c_calc_array_field_address(224, 32, i, 896, 1); + ptr_struct->psid[i] = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + } + offset = 376; + ptr_struct->fw_version_39_32 = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + offset = 384; + ptr_struct->fw_version_31_0 = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + for (i = 0; i < 4; ++i) { + offset = adb2c_calc_array_field_address(416, 32, i, 896, 1); + ptr_struct->source_address[i] = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + } + offset = 560; + ptr_struct->session_id = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + offset = 544; + ptr_struct->challenge_version = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); + for (i = 0; i < 8; ++i) { + offset = adb2c_calc_array_field_address(576, 32, i, 896, 1); + ptr_struct->challenge[i] = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + } +} + +void reg_access_switch_mtcq_reg_ext_print(const struct reg_access_switch_mtcq_reg_ext *ptr_struct, FILE *fd, int indent_level) +{ + int i; + + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "======== reg_access_switch_mtcq_reg_ext ========\n"); + + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "token_opcode : " UH_FMT "\n", ptr_struct->token_opcode); + for (i = 0; i < 4; ++i) { + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "keypair_uuid_%03d : " U32H_FMT "\n", i, ptr_struct->keypair_uuid[i]); + } + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "base_mac : " U64H_FMT "\n", ptr_struct->base_mac); + for (i = 0; i < 4; ++i) { + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "psid_%03d : " U32H_FMT "\n", i, ptr_struct->psid[i]); + } + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "fw_version_39_32 : " UH_FMT "\n", ptr_struct->fw_version_39_32); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "fw_version_31_0 : " U32H_FMT "\n", ptr_struct->fw_version_31_0); + for (i = 0; i < 4; ++i) { + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "source_address_%03d : " U32H_FMT "\n", i, ptr_struct->source_address[i]); + } + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "session_id : " UH_FMT "\n", ptr_struct->session_id); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "challenge_version : " UH_FMT "\n", ptr_struct->challenge_version); + for (i = 0; i < 8; ++i) { + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "challenge_%03d : " U32H_FMT "\n", i, ptr_struct->challenge[i]); + } +} + +unsigned int reg_access_switch_mtcq_reg_ext_size(void) +{ + return REG_ACCESS_SWITCH_MTCQ_REG_EXT_SIZE; +} + +void reg_access_switch_mtcq_reg_ext_dump(const struct reg_access_switch_mtcq_reg_ext *ptr_struct, FILE *fd) +{ + reg_access_switch_mtcq_reg_ext_print(ptr_struct, fd, 0); +} + void reg_access_switch_reg_access_switch_Nodes_pack(const union reg_access_switch_reg_access_switch_Nodes *ptr_struct, u_int8_t *ptr_buff) { reg_access_switch_icsr_ext_pack(&(ptr_struct->icsr_ext), ptr_buff); @@ -861,18 +1113,27 @@ void reg_access_switch_reg_access_switch_Nodes_print(const union reg_access_swit adb2c_add_indentation(fd, indent_level); fprintf(fd, "======== reg_access_switch_reg_access_switch_Nodes ========\n"); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "mddt_reg_ext:\n"); - reg_access_switch_mddt_reg_ext_print(&(ptr_struct->mddt_reg_ext), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); fprintf(fd, "icam_reg_ext:\n"); reg_access_switch_icam_reg_ext_print(&(ptr_struct->icam_reg_ext), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); + fprintf(fd, "mddq_ext:\n"); + reg_access_switch_mddq_ext_print(&(ptr_struct->mddq_ext), fd, indent_level + 1); + adb2c_add_indentation(fd, indent_level); fprintf(fd, "icsr_ext:\n"); reg_access_switch_icsr_ext_print(&(ptr_struct->icsr_ext), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); - fprintf(fd, "mddq_ext:\n"); - reg_access_switch_mddq_ext_print(&(ptr_struct->mddq_ext), fd, indent_level + 1); + fprintf(fd, "mdsr_reg_ext:\n"); + reg_access_switch_mdsr_reg_ext_print(&(ptr_struct->mdsr_reg_ext), fd, indent_level + 1); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "mcdc_reg:\n"); + reg_access_switch_mcdc_reg_print(&(ptr_struct->mcdc_reg), fd, indent_level + 1); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "mtcq_reg_ext:\n"); + reg_access_switch_mtcq_reg_ext_print(&(ptr_struct->mtcq_reg_ext), fd, indent_level + 1); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "mddt_reg_ext:\n"); + reg_access_switch_mddt_reg_ext_print(&(ptr_struct->mddt_reg_ext), fd, indent_level + 1); } unsigned int reg_access_switch_reg_access_switch_Nodes_size(void) diff --git a/tools_layouts/reg_access_switch_layouts.h b/tools_layouts/reg_access_switch_layouts.h index 6d3d786a..7c1fa81f 100644 --- a/tools_layouts/reg_access_switch_layouts.h +++ b/tools_layouts/reg_access_switch_layouts.h @@ -32,7 +32,7 @@ /*** - *** This file was generated at "2021-09-30 13:17:36" + *** This file was generated at "2021-10-26 16:49:12" *** by: *** > /mswg/release/tools/a-me/last_stable/adabe_plugins/adb2c/adb2pack.py --input adb/prm/switch/ext/reg_access_switch.adb --file-prefix reg_access_switch --prefix reg_access_switch_ --no-adb-utils ***/ @@ -75,9 +75,11 @@ struct reg_access_switch_device_info_ext { The first device should number 0 */ /* 0x0.0 - 0x0.7 */ u_int8_t device_index; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - The flash ID that the device is using. */ /* 0x0.16 - 0x0.23 */ u_int8_t flash_id; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - If set to '1', the fields related to the device are valid since the line-card is powered on and plugged and matching the INI ver sion. @@ -85,14 +87,17 @@ Note: this bit is not an indication to validity of the fields related to the specific FW capabilities and version. */ /* 0x0.28 - 0x0.28 */ u_int8_t lc_pwr_on; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - Thermal Shutdown. If set, the device was shut down due to thermal event. */ /* 0x0.29 - 0x0.29 */ u_int8_t thermal_sd; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - If set to '1', the device is the flash owner. Otherwise, a shared flash is used by this device (another device is the flash owner). */ /* 0x0.30 - 0x0.30 */ u_int8_t flash_owner; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - If set, the device uses a flash */ /* 0x0.31 - 0x0.31 */ u_int8_t uses_flash; @@ -101,6 +106,7 @@ flash is used by this device (another device is the flash owner). */ 1: Abir Gearbox */ /* 0x4.0 - 0x4.15 */ u_int16_t device_type; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ /* Description - Major FW version number. Valid only after the FW is burnt. Oth erwise, the value should be '0'. */ /* 0x4.16 - 0x4.31 */ @@ -110,6 +116,7 @@ erwise, the value should be '0'. */ burnt. Otherwise, the value should be '0'. */ /* 0x8.0 - 0x8.15 */ u_int16_t fw_sub_minor; +/*---------------- DWORD[2] (Offset 0x8) ----------------*/ /* Description - Minor FW version number. Valid only after the FW is burnt. Otherwise, the value should be '0'. */ /* 0x8.16 - 0x8.31 */ @@ -119,6 +126,7 @@ Otherwise, the value should be '0'. */ its PRM commands. */ /* 0xc.0 - 0xc.7 */ u_int8_t max_cmd_write_size_supp; +/*---------------- DWORD[3] (Offset 0xc) ----------------*/ /* Description - Maximum read size (in D-Words) that the device supports for its PRM commands. */ /* 0xc.8 - 0xc.15 */ @@ -137,10 +145,12 @@ struct reg_access_switch_prm_register_payload_ext { /* Description - Register ID */ /* 0x0.0 - 0x0.15 */ u_int16_t register_id; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - 0: Query 1: Write */ /* 0x0.22 - 0x0.23 */ u_int8_t method; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - Return code of the Downstream Device to the register that was sent. 0x0: OK - Operation was successfully executed @@ -166,6 +176,7 @@ struct reg_access_switch_slot_info_ext { mand */ /* 0x0.27 - 0x0.27 */ u_int8_t active; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - If set, the LC is powered on, matching the INI version and a new FW version can be burnt (if necessary) 0: Not ready @@ -174,11 +185,13 @@ new FW version can be burnt (if necessary) 3: Reserved */ /* 0x0.28 - 0x0.29 */ u_int8_t lc_ready; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - If set, Shift Register is valid (after being provisioned) and data can be sent from the switch ASIC to the line-card CPLD over Shift-Register. */ /* 0x0.30 - 0x0.30 */ u_int8_t sr_valid; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - If set, the INI file is ready and the card is provisioned */ /* 0x0.31 - 0x0.31 */ u_int8_t provisioned; @@ -187,6 +200,7 @@ Shift-Register. */ Valid only when active or lc_ready are '1'. */ /* 0x4.0 - 0x4.15 */ u_int16_t ini_file_version; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ /* Description - HW revision of the line-card as it appears in the current INI file. Valid only when active or lc_ready are '1'. */ /* 0x4.16 - 0x4.31 */ @@ -240,6 +254,15 @@ union reg_access_switch_mddt_reg_payload_auto_ext { struct reg_access_switch_crspace_access_payload_ext crspace_access_payload_ext; }; +/* Description - */ +/* Size in bytes - 8 */ +struct reg_access_switch_uint64 { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - */ + /* 0x0.0 - 0x4.31 */ + u_int64_t uint64; +}; + /* Description - */ /* Size in bytes - 24 */ struct reg_access_switch_icam_reg_ext { @@ -280,6 +303,36 @@ Range 1..256 */ u_int32_t data[256]; }; +/* Description - */ +/* Size in bytes - 44 */ +struct reg_access_switch_mcdc_reg { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - Indicates the successful completion of the instruction +or the reason it failed: +0: OK +1: BAD_SESSION_ID +2: BAD_KEEP_ALIVE_COUNTER +3: BAD_SOURCE_ADDRESS +4: SESSION_TIMEOUT +Other: Reserved. */ + /* 0x0.0 - 0x0.3 */ + u_int8_t error_code; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - Unique debug session identifier. */ + /* 0x0.16 - 0x0.31 */ + u_int16_t session_id; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ + /* Description - Running counter that states the current sequence +number of each keep-alive session. */ + /* 0x4.0 - 0x4.31 */ + u_int32_t current_keep_alive_counter; +/*---------------- DWORD[2] (Offset 0x8) ----------------*/ + /* Description - Running counter that states the expected next +sequence number of each keep-alive session. */ + /* 0x8.0 - 0x8.31 */ + u_int32_t next_keep_alive_counter; +}; + /* Description - */ /* Size in bytes - 48 */ struct reg_access_switch_mddq_ext { @@ -288,6 +341,7 @@ struct reg_access_switch_mddq_ext { 0: Reserved */ /* 0x0.0 - 0x0.3 */ u_int8_t slot_index; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - 0: Reserved 1: slot_info 2: device_info - If there are no devices on the slot, data_valid @@ -295,6 +349,7 @@ will be '0'. 3: slot_name - Name of the slot (string) */ /* 0x0.16 - 0x0.23 */ u_int8_t query_type; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - Slot info event enable When set to '1', each change in the MDDQ.slot_info.provi sioned / sr_valid / active / ready will generate an event. */ @@ -305,6 +360,7 @@ sioned / sr_valid / active / ready will generate an event. */ The first message number should be 0 */ /* 0x4.0 - 0x4.7 */ u_int8_t request_message_sequence; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ /* Description - Response message sequential number. For a specific request, the response message sequential num ber is the following one. @@ -316,6 +372,7 @@ In addition, the last message should be 0. */ For query_type = 1,2,3 this field is neglected. */ /* 0x8.0 - 0x8.7 */ u_int8_t query_index; +/*---------------- DWORD[2] (Offset 0x8) ----------------*/ /* Description - If set, the data in the data field is valid and contain the informa tion for the queried index. Note: This field is not reflecting any validity of the data while @@ -325,12 +382,12 @@ range index will lead to BAD_PARAM status of the register. */ u_int8_t data_valid; /*---------------- DWORD[4] (Offset 0x10) ----------------*/ /* Description - Properties of that field are based on query_type. -For slot information query_type data - see Table 530, -"slot_info Register Layout," on page 710 -For devices on slot query_type data - see Table 532, -"device_info Register Layout," on page 711 -For slot name query_type data - see Table 534, "slot_name -Register Layout," on page 712 */ +For slot information query_type data - see Table 537, +"slot_info Register Layout," on page 735 +For devices on slot query_type data - see Table 539, +"device_info Register Layout," on page 736 +For slot name query_type data - see Table 541, "slot_name +Register Layout," on page 737 */ /* 0x10.0 - 0x2c.31 */ union reg_access_switch_mddq_data_auto_ext data; }; @@ -342,6 +399,7 @@ struct reg_access_switch_mddt_reg_ext { /* Description - Device index */ /* 0x0.0 - 0x0.7 */ u_int8_t device_index; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - Slot index */ /* 0x0.8 - 0x0.11 */ u_int8_t slot_index; @@ -351,40 +409,135 @@ struct reg_access_switch_mddt_reg_ext { 2: CrSpace_access - [Internal] */ /* 0x4.0 - 0x4.1 */ u_int8_t type; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ /* Description - Write size in D-Words. */ /* 0x4.16 - 0x4.23 */ u_int8_t write_size; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ /* Description - Read size in D-Words. */ /* 0x4.24 - 0x4.31 */ u_int8_t read_size; /*---------------- DWORD[3] (Offset 0xc) ----------------*/ /* Description - Payload -For PRM Register type payload- See Table 522, "PRM -Register Payload Layout," on page 707 -For Command type payload - See Table 524, "Com -mand Payload Layout," on page 707 -For CrSpace type payload - See Table 526, "CrSpace -access Payload Layout," on page 708 */ +For PRM Register type payload- See Table 529, "PRM +Register Payload Layout," on page 732 +For Command type payload - See Table 531, "Com +mand Payload Layout," on page 732 +For CrSpace type payload - See Table 533, "CrSpace +access Payload Layout," on page 733 */ /* 0xc.0 - 0x10c.31 */ union reg_access_switch_mddt_reg_payload_auto_ext payload; }; +/* Description - */ +/* Size in bytes - 48 */ +struct reg_access_switch_mdsr_reg_ext { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - 0: The debug session ended successfully +1: Failed to execute the operation. See additional_info for +more details. +2: Debug session active +3-15: Reserved + +Note: Status might be '0' even when debug query is not +allowed and additional_info field will expose the reason. */ + /* 0x0.0 - 0x0.3 */ + u_int8_t status; +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - 0: No additional information available +1: There is no debug session in progress +2: FW is not secured, debug session cannot be ended +3: Fail - Debug end request cannot be accepted. +4: Fail - Host is not allowed to query debug session +5: Debug session active */ + /* 0x0.8 - 0x0.13 */ + u_int8_t additional_info; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ + /* Description - Set to '1' to end debug session. +Setting to '0' will not trigger any operation. */ + /* 0x4.31 - 0x4.31 */ + u_int8_t end; +}; + +/* Description - */ +/* Size in bytes - 112 */ +struct reg_access_switch_mtcq_reg_ext { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - The token which a challenge is generated for. +0: RMSC +1: RMDT + +Other: Reserved */ + /* 0x0.24 - 0x0.31 */ + u_int8_t token_opcode; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ + /* Description - The UUID of the key used to generate the challenge. */ + /* 0x4.0 - 0x10.31 */ + u_int32_t keypair_uuid[4]; +/*---------------- DWORD[5] (Offset 0x14) ----------------*/ + /* Description - Device base MAC address / unique identifier. */ + /* 0x14.0 - 0x18.31 */ + u_int64_t base_mac; +/*---------------- DWORD[7] (Offset 0x1c) ----------------*/ + /* Description - Device PSID */ + /* 0x1c.0 - 0x28.31 */ + u_int32_t psid[4]; +/*---------------- DWORD[11] (Offset 0x2c) ----------------*/ + /* Description - Device FW version */ + /* 0x2c.0 - 0x2c.7 */ + u_int8_t fw_version_39_32; +/*---------------- DWORD[12] (Offset 0x30) ----------------*/ + /* Description - Device FW version */ + /* 0x30.0 - 0x30.31 */ + u_int32_t fw_version_31_0; +/*---------------- DWORD[13] (Offset 0x34) ----------------*/ + /* Description - Source address of debug requester. DLID for Infini +band, ETH / IBg2 - TBD. +Valid only for RMCS/RMDT. */ + /* 0x34.0 - 0x40.31 */ + u_int32_t source_address[4]; +/*---------------- DWORD[17] (Offset 0x44) ----------------*/ + /* Description - Unique debug session identifier. +See details in REMOTE_DEBUG_KEEP_ALIVE. +Valid only for RMCS. */ + /* 0x44.0 - 0x44.15 */ + u_int16_t session_id; +/*---------------- DWORD[17] (Offset 0x44) ----------------*/ + /* Description - Version of the challenge format. */ + /* 0x44.24 - 0x44.31 */ + u_int8_t challenge_version; +/*---------------- DWORD[18] (Offset 0x48) ----------------*/ + /* Description - Random generated field. Used for randomness and +replay-protection. */ + /* 0x48.0 - 0x64.31 */ + u_int32_t challenge[8]; +}; + /* Description - */ /* Size in bytes - 1040 */ union reg_access_switch_reg_access_switch_Nodes { /*---------------- DWORD[0] (Offset 0x0) ----------------*/ - /* Description - */ - /* 0x0.0 - 0x10c.31 */ - struct reg_access_switch_mddt_reg_ext mddt_reg_ext; /* Description - */ /* 0x0.0 - 0x14.31 */ struct reg_access_switch_icam_reg_ext icam_reg_ext; /* Description - */ + /* 0x0.0 - 0x2c.31 */ + struct reg_access_switch_mddq_ext mddq_ext; + /* Description - */ /* 0x0.0 - 0x40c.31 */ struct reg_access_switch_icsr_ext icsr_ext; /* Description - */ /* 0x0.0 - 0x2c.31 */ - struct reg_access_switch_mddq_ext mddq_ext; + struct reg_access_switch_mdsr_reg_ext mdsr_reg_ext; + /* Description - */ + /* 0x0.0 - 0x28.31 */ + struct reg_access_switch_mcdc_reg mcdc_reg; + /* Description - */ + /* 0x0.0 - 0x6c.31 */ + struct reg_access_switch_mtcq_reg_ext mtcq_reg_ext; + /* Description - */ + /* 0x0.0 - 0x10c.31 */ + struct reg_access_switch_mddt_reg_ext mddt_reg_ext; }; @@ -445,6 +598,13 @@ void reg_access_switch_mddt_reg_payload_auto_ext_print(const union reg_access_sw unsigned int reg_access_switch_mddt_reg_payload_auto_ext_size(void); #define REG_ACCESS_SWITCH_MDDT_REG_PAYLOAD_AUTO_EXT_SIZE (0x104) void reg_access_switch_mddt_reg_payload_auto_ext_dump(const union reg_access_switch_mddt_reg_payload_auto_ext *ptr_struct, FILE *fd); +/* uint64 */ +void reg_access_switch_uint64_pack(const u_int64_t *ptr_struct, u_int8_t *ptr_buff); +void reg_access_switch_uint64_unpack(u_int64_t *ptr_struct, const u_int8_t *ptr_buff); +void reg_access_switch_uint64_print(const u_int64_t *ptr_struct, FILE *fd, int indent_level); +unsigned int reg_access_switch_uint64_size(void); +#define REG_ACCESS_SWITCH_UINT64_SIZE (0x8) +void reg_access_switch_uint64_dump(const u_int64_t *ptr_struct, FILE *fd); /* icam_reg_ext */ void reg_access_switch_icam_reg_ext_pack(const struct reg_access_switch_icam_reg_ext *ptr_struct, u_int8_t *ptr_buff); void reg_access_switch_icam_reg_ext_unpack(struct reg_access_switch_icam_reg_ext *ptr_struct, const u_int8_t *ptr_buff); @@ -459,6 +619,13 @@ void reg_access_switch_icsr_ext_print(const struct reg_access_switch_icsr_ext *p unsigned int reg_access_switch_icsr_ext_size(void); #define REG_ACCESS_SWITCH_ICSR_EXT_SIZE (0x410) void reg_access_switch_icsr_ext_dump(const struct reg_access_switch_icsr_ext *ptr_struct, FILE *fd); +/* mcdc_reg */ +void reg_access_switch_mcdc_reg_pack(const struct reg_access_switch_mcdc_reg *ptr_struct, u_int8_t *ptr_buff); +void reg_access_switch_mcdc_reg_unpack(struct reg_access_switch_mcdc_reg *ptr_struct, const u_int8_t *ptr_buff); +void reg_access_switch_mcdc_reg_print(const struct reg_access_switch_mcdc_reg *ptr_struct, FILE *fd, int indent_level); +unsigned int reg_access_switch_mcdc_reg_size(void); +#define REG_ACCESS_SWITCH_MCDC_REG_SIZE (0x2c) +void reg_access_switch_mcdc_reg_dump(const struct reg_access_switch_mcdc_reg *ptr_struct, FILE *fd); /* mddq_ext */ void reg_access_switch_mddq_ext_pack(const struct reg_access_switch_mddq_ext *ptr_struct, u_int8_t *ptr_buff); void reg_access_switch_mddq_ext_unpack(struct reg_access_switch_mddq_ext *ptr_struct, const u_int8_t *ptr_buff); @@ -473,6 +640,20 @@ void reg_access_switch_mddt_reg_ext_print(const struct reg_access_switch_mddt_re unsigned int reg_access_switch_mddt_reg_ext_size(void); #define REG_ACCESS_SWITCH_MDDT_REG_EXT_SIZE (0x110) void reg_access_switch_mddt_reg_ext_dump(const struct reg_access_switch_mddt_reg_ext *ptr_struct, FILE *fd); +/* mdsr_reg_ext */ +void reg_access_switch_mdsr_reg_ext_pack(const struct reg_access_switch_mdsr_reg_ext *ptr_struct, u_int8_t *ptr_buff); +void reg_access_switch_mdsr_reg_ext_unpack(struct reg_access_switch_mdsr_reg_ext *ptr_struct, const u_int8_t *ptr_buff); +void reg_access_switch_mdsr_reg_ext_print(const struct reg_access_switch_mdsr_reg_ext *ptr_struct, FILE *fd, int indent_level); +unsigned int reg_access_switch_mdsr_reg_ext_size(void); +#define REG_ACCESS_SWITCH_MDSR_REG_EXT_SIZE (0x30) +void reg_access_switch_mdsr_reg_ext_dump(const struct reg_access_switch_mdsr_reg_ext *ptr_struct, FILE *fd); +/* mtcq_reg_ext */ +void reg_access_switch_mtcq_reg_ext_pack(const struct reg_access_switch_mtcq_reg_ext *ptr_struct, u_int8_t *ptr_buff); +void reg_access_switch_mtcq_reg_ext_unpack(struct reg_access_switch_mtcq_reg_ext *ptr_struct, const u_int8_t *ptr_buff); +void reg_access_switch_mtcq_reg_ext_print(const struct reg_access_switch_mtcq_reg_ext *ptr_struct, FILE *fd, int indent_level); +unsigned int reg_access_switch_mtcq_reg_ext_size(void); +#define REG_ACCESS_SWITCH_MTCQ_REG_EXT_SIZE (0x70) +void reg_access_switch_mtcq_reg_ext_dump(const struct reg_access_switch_mtcq_reg_ext *ptr_struct, FILE *fd); /* reg_access_switch_Nodes */ void reg_access_switch_reg_access_switch_Nodes_pack(const union reg_access_switch_reg_access_switch_Nodes *ptr_struct, u_int8_t *ptr_buff); void reg_access_switch_reg_access_switch_Nodes_unpack(union reg_access_switch_reg_access_switch_Nodes *ptr_struct, const u_int8_t *ptr_buff); From 9f8a9973c8d07765d210ac42f3aa703a8dfeeba6 Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Mon, 1 Nov 2021 15:42:12 +0200 Subject: [PATCH 013/184] missing short name for --session_id option Description: added the -s short name option for --session_id, it was accepeted to use "-s" although "s" is also used for the set command Tested OS:Linux Tested devices:None Tested flows:mlxconfig -h Known gaps (with RM ticket): None Issue: 2844919 Change-Id: I283b11a4de8d869f02cbf0ebe817c47923f4b714 Signed-off-by: ashargorodsk --- mlxconfig/mlxcfg_parser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlxconfig/mlxcfg_parser.cpp b/mlxconfig/mlxcfg_parser.cpp index 9ba6a960..fd1241c7 100644 --- a/mlxconfig/mlxcfg_parser.cpp +++ b/mlxconfig/mlxcfg_parser.cpp @@ -99,7 +99,7 @@ void MlxCfg::printHelp() printFlagLine("eng", "openssl_engine", "ENGINE NAME", "OpenSSL engine name"); printFlagLine("k", "openssl_key_id", "IDENTIFIER", "OpenSSL key identifier"); printFlagLine("t", "device_type", "switch/hca", "Specify the device type"); - printFlagLine("", "session_id", "", "Specify the session id for token keep alive session."); + printFlagLine("s", "session_id", "", "Specify the session id for token keep alive session."); //print commands printf("\n"); From 648dbae232f39ca9acb3e18a4a016b38186cfe12 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Mon, 3 Jan 2022 14:28:03 +0200 Subject: [PATCH 014/184] Updated switches databases based on PRM 1_55_051_Nov07 Fixed typo mcdc -> mkdc Description: update mlxconfig + tools layout databases based on Nov7 PRM. Tested OS: Linux Tested devices:None Tested flows: compile the project to verify the DB is compatible with the code. Known gaps (with RM ticket): None Issue: None --- mlxconfig/mlxcfg_ui.cpp | 4 +- mlxconfig/mlxcfg_ui.h | 8 +- reg_access/reg_access.c | 4 +- reg_access/reg_access.h | 2 +- .../prm/switch/ext/register_access_table.adb | 26 ---- tools_layouts/reg_access_switch_layouts.c | 128 +++++++++--------- tools_layouts/reg_access_switch_layouts.h | 115 ++++++++-------- 7 files changed, 130 insertions(+), 157 deletions(-) diff --git a/mlxconfig/mlxcfg_ui.cpp b/mlxconfig/mlxcfg_ui.cpp index 0d713893..49d094d9 100644 --- a/mlxconfig/mlxcfg_ui.cpp +++ b/mlxconfig/mlxcfg_ui.cpp @@ -1742,7 +1742,7 @@ int KeepAliveSession::startSession() return 0; } -int KeepAliveSession::runMKDC(mfile* mf, reg_access_switch_mcdc_reg* mkdc_reg, time_t& timer) +int KeepAliveSession::runMKDC(mfile* mf, reg_access_switch_mkdc_reg_ext* mkdc_reg, time_t& timer) { reg_access_status_t rc = ME_REG_ACCESS_OK; time_t start = 0; @@ -1778,7 +1778,7 @@ int KeepAliveSession::runMKDC(mfile* mf, reg_access_switch_mcdc_reg* mkdc_reg, t return status; } -int KeepAliveSession::processMKDCData(reg_access_switch_mcdc_reg* mkdc_reg) +int KeepAliveSession::processMKDCData(reg_access_switch_mkdc_reg_ext* mkdc_reg) { if (mkdc_reg->error_code != 0) { printf("-E- keep alive session failed. error code: %s\n", _mkdcErrorToString[mkdc_reg->error_code]); diff --git a/mlxconfig/mlxcfg_ui.h b/mlxconfig/mlxcfg_ui.h index 0ec5c9fa..a0b54b68 100644 --- a/mlxconfig/mlxcfg_ui.h +++ b/mlxconfig/mlxcfg_ui.h @@ -143,17 +143,17 @@ class KeepAliveSession void setSleepTimeBetweenCommands(u_int32_t sleepTime); private: - int runMKDC(mfile* mf, reg_access_switch_mcdc_reg* mkdc_reg, time_t& timer); - int processMKDCData(reg_access_switch_mcdc_reg* mkdc_reg); + int runMKDC(mfile* mf, reg_access_switch_mkdc_reg_ext* mkdc_reg, time_t& timer); + int processMKDCData(reg_access_switch_mkdc_reg_ext* mkdc_reg); static const char* _mkdcErrorToString[5]; static const u_int32_t _keepAliveTimestampInSec; - + mfile* _mf; u_int16_t _sessionId; u_int32_t _sessionTimeLeftInSec; - reg_access_switch_mcdc_reg _mkdc_reg; + reg_access_switch_mkdc_reg_ext _mkdc_reg; u_int32_t _SleepTimeOnCommandTO; u_int32_t _SleepTimeBetweenCommands; }; diff --git a/reg_access/reg_access.c b/reg_access/reg_access.c index f27f3f3e..a657d3be 100644 --- a/reg_access/reg_access.c +++ b/reg_access/reg_access.c @@ -806,9 +806,9 @@ reg_access_status_t reg_access_mdsr(mfile *mf, reg_access_method_t method, struc /************************************ * Function: reg_access_mkdc ************************************/ -reg_access_status_t reg_access_mkdc(mfile *mf, reg_access_method_t method, struct reg_access_switch_mcdc_reg *mcdc) +reg_access_status_t reg_access_mkdc(mfile *mf, reg_access_method_t method, struct reg_access_switch_mkdc_reg_ext *mkdc) { - REG_ACCCESS(mf, method, REG_ID_MKDC, mcdc, mcdc_reg, reg_access_switch); + REG_ACCCESS(mf, method, REG_ID_MKDC, mkdc, mkdc_reg_ext, reg_access_switch); } /************************************ * Function: reg_access_mpegc diff --git a/reg_access/reg_access.h b/reg_access/reg_access.h index 03ff6e9a..2c18e849 100644 --- a/reg_access/reg_access.h +++ b/reg_access/reg_access.h @@ -120,7 +120,7 @@ reg_access_status_t reg_access_mcdd(mfile *mf, reg_access_method_t method, struc const char* reg_access_err2str(reg_access_status_t status); reg_access_status_t reg_access_mirc(mfile *mf, reg_access_method_t method, struct tools_open_mirc_reg *mirc); -reg_access_status_t reg_access_mkdc(mfile *mf, reg_access_method_t method, struct reg_access_switch_mcdc_reg *mcdc); +reg_access_status_t reg_access_mkdc(mfile *mf, reg_access_method_t method, struct reg_access_switch_mkdc_reg_ext *mkdc); reg_access_status_t reg_access_mtcq(mfile *mf, reg_access_method_t method, struct reg_access_switch_mtcq_reg_ext *mtcq); reg_access_status_t reg_access_mdsr(mfile *mf, reg_access_method_t method, struct reg_access_switch_mdsr_reg_ext *mtcq); reg_access_status_t reg_access_mpegc(mfile *mf, reg_access_method_t method, struct reg_access_hca_mpegc_reg *mpegc); diff --git a/tools_layouts/adb/prm/switch/ext/register_access_table.adb b/tools_layouts/adb/prm/switch/ext/register_access_table.adb index 682dc3eb..ba3363d1 100644 --- a/tools_layouts/adb/prm/switch/ext/register_access_table.adb +++ b/tools_layouts/adb/prm/switch/ext/register_access_table.adb @@ -1557,13 +1557,6 @@ - - - - - - - @@ -2088,12 +2081,6 @@ - - - - - - @@ -3044,19 +3031,6 @@ - - - - - - - - - - - - - diff --git a/tools_layouts/reg_access_switch_layouts.c b/tools_layouts/reg_access_switch_layouts.c index bdbc2e87..ebb79b28 100644 --- a/tools_layouts/reg_access_switch_layouts.c +++ b/tools_layouts/reg_access_switch_layouts.c @@ -32,7 +32,7 @@ /*** - *** This file was generated at "2021-10-26 16:49:12" + *** This file was generated at "2021-11-07 16:02:35" *** by: *** > /mswg/release/tools/a-me/last_stable/adabe_plugins/adb2c/adb2pack.py --input adb/prm/switch/ext/reg_access_switch.adb --file-prefix reg_access_switch --prefix reg_access_switch_ --no-adb-utils ***/ @@ -645,59 +645,6 @@ void reg_access_switch_icsr_ext_dump(const struct reg_access_switch_icsr_ext *pt reg_access_switch_icsr_ext_print(ptr_struct, fd, 0); } -void reg_access_switch_mcdc_reg_pack(const struct reg_access_switch_mcdc_reg *ptr_struct, u_int8_t *ptr_buff) -{ - u_int32_t offset; - - offset = 28; - adb2c_push_bits_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->error_code); - offset = 0; - adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->session_id); - offset = 32; - adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->current_keep_alive_counter); - offset = 64; - adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->next_keep_alive_counter); -} - -void reg_access_switch_mcdc_reg_unpack(struct reg_access_switch_mcdc_reg *ptr_struct, const u_int8_t *ptr_buff) -{ - u_int32_t offset; - - offset = 28; - ptr_struct->error_code = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 4); - offset = 0; - ptr_struct->session_id = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); - offset = 32; - ptr_struct->current_keep_alive_counter = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); - offset = 64; - ptr_struct->next_keep_alive_counter = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); -} - -void reg_access_switch_mcdc_reg_print(const struct reg_access_switch_mcdc_reg *ptr_struct, FILE *fd, int indent_level) -{ - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "======== reg_access_switch_mcdc_reg ========\n"); - - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "error_code : " UH_FMT "\n", ptr_struct->error_code); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "session_id : " UH_FMT "\n", ptr_struct->session_id); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "current_keep_alive_counter : " U32H_FMT "\n", ptr_struct->current_keep_alive_counter); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "next_keep_alive_counter : " U32H_FMT "\n", ptr_struct->next_keep_alive_counter); -} - -unsigned int reg_access_switch_mcdc_reg_size(void) -{ - return REG_ACCESS_SWITCH_MCDC_REG_SIZE; -} - -void reg_access_switch_mcdc_reg_dump(const struct reg_access_switch_mcdc_reg *ptr_struct, FILE *fd) -{ - reg_access_switch_mcdc_reg_print(ptr_struct, fd, 0); -} - void reg_access_switch_mddq_ext_pack(const struct reg_access_switch_mddq_ext *ptr_struct, u_int8_t *ptr_buff) { u_int32_t offset; @@ -981,6 +928,59 @@ void reg_access_switch_mdsr_reg_ext_dump(const struct reg_access_switch_mdsr_reg reg_access_switch_mdsr_reg_ext_print(ptr_struct, fd, 0); } +void reg_access_switch_mkdc_reg_ext_pack(const struct reg_access_switch_mkdc_reg_ext *ptr_struct, u_int8_t *ptr_buff) +{ + u_int32_t offset; + + offset = 28; + adb2c_push_bits_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->error_code); + offset = 0; + adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->session_id); + offset = 32; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->current_keep_alive_counter); + offset = 64; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->next_keep_alive_counter); +} + +void reg_access_switch_mkdc_reg_ext_unpack(struct reg_access_switch_mkdc_reg_ext *ptr_struct, const u_int8_t *ptr_buff) +{ + u_int32_t offset; + + offset = 28; + ptr_struct->error_code = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 4); + offset = 0; + ptr_struct->session_id = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + offset = 32; + ptr_struct->current_keep_alive_counter = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + offset = 64; + ptr_struct->next_keep_alive_counter = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); +} + +void reg_access_switch_mkdc_reg_ext_print(const struct reg_access_switch_mkdc_reg_ext *ptr_struct, FILE *fd, int indent_level) +{ + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "======== reg_access_switch_mkdc_reg_ext ========\n"); + + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "error_code : %s (" UH_FMT ")\n", (ptr_struct->error_code == 0 ? ("OK") : ((ptr_struct->error_code == 1 ? ("BAD_SESSION_ID") : ((ptr_struct->error_code == 2 ? ("BAD_KEEP_ALIVE_COUNTER") : ((ptr_struct->error_code == 3 ? ("BAD_SOURCE_ADDRESS") : ((ptr_struct->error_code == 4 ? ("SESSION_TIMEOUT") : ("unknown")))))))))), ptr_struct->error_code); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "session_id : " UH_FMT "\n", ptr_struct->session_id); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "current_keep_alive_counter : " U32H_FMT "\n", ptr_struct->current_keep_alive_counter); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "next_keep_alive_counter : " U32H_FMT "\n", ptr_struct->next_keep_alive_counter); +} + +unsigned int reg_access_switch_mkdc_reg_ext_size(void) +{ + return REG_ACCESS_SWITCH_MKDC_REG_EXT_SIZE; +} + +void reg_access_switch_mkdc_reg_ext_dump(const struct reg_access_switch_mkdc_reg_ext *ptr_struct, FILE *fd) +{ + reg_access_switch_mkdc_reg_ext_print(ptr_struct, fd, 0); +} + void reg_access_switch_mtcq_reg_ext_pack(const struct reg_access_switch_mtcq_reg_ext *ptr_struct, u_int8_t *ptr_buff) { u_int32_t offset; @@ -1113,27 +1113,27 @@ void reg_access_switch_reg_access_switch_Nodes_print(const union reg_access_swit adb2c_add_indentation(fd, indent_level); fprintf(fd, "======== reg_access_switch_reg_access_switch_Nodes ========\n"); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "mddt_reg_ext:\n"); + reg_access_switch_mddt_reg_ext_print(&(ptr_struct->mddt_reg_ext), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); fprintf(fd, "icam_reg_ext:\n"); reg_access_switch_icam_reg_ext_print(&(ptr_struct->icam_reg_ext), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); - fprintf(fd, "mddq_ext:\n"); - reg_access_switch_mddq_ext_print(&(ptr_struct->mddq_ext), fd, indent_level + 1); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "icsr_ext:\n"); - reg_access_switch_icsr_ext_print(&(ptr_struct->icsr_ext), fd, indent_level + 1); - adb2c_add_indentation(fd, indent_level); fprintf(fd, "mdsr_reg_ext:\n"); reg_access_switch_mdsr_reg_ext_print(&(ptr_struct->mdsr_reg_ext), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); - fprintf(fd, "mcdc_reg:\n"); - reg_access_switch_mcdc_reg_print(&(ptr_struct->mcdc_reg), fd, indent_level + 1); + fprintf(fd, "mkdc_reg_ext:\n"); + reg_access_switch_mkdc_reg_ext_print(&(ptr_struct->mkdc_reg_ext), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); fprintf(fd, "mtcq_reg_ext:\n"); reg_access_switch_mtcq_reg_ext_print(&(ptr_struct->mtcq_reg_ext), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); - fprintf(fd, "mddt_reg_ext:\n"); - reg_access_switch_mddt_reg_ext_print(&(ptr_struct->mddt_reg_ext), fd, indent_level + 1); + fprintf(fd, "mddq_ext:\n"); + reg_access_switch_mddq_ext_print(&(ptr_struct->mddq_ext), fd, indent_level + 1); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "icsr_ext:\n"); + reg_access_switch_icsr_ext_print(&(ptr_struct->icsr_ext), fd, indent_level + 1); } unsigned int reg_access_switch_reg_access_switch_Nodes_size(void) diff --git a/tools_layouts/reg_access_switch_layouts.h b/tools_layouts/reg_access_switch_layouts.h index 7c1fa81f..e991e805 100644 --- a/tools_layouts/reg_access_switch_layouts.h +++ b/tools_layouts/reg_access_switch_layouts.h @@ -303,36 +303,6 @@ Range 1..256 */ u_int32_t data[256]; }; -/* Description - */ -/* Size in bytes - 44 */ -struct reg_access_switch_mcdc_reg { -/*---------------- DWORD[0] (Offset 0x0) ----------------*/ - /* Description - Indicates the successful completion of the instruction -or the reason it failed: -0: OK -1: BAD_SESSION_ID -2: BAD_KEEP_ALIVE_COUNTER -3: BAD_SOURCE_ADDRESS -4: SESSION_TIMEOUT -Other: Reserved. */ - /* 0x0.0 - 0x0.3 */ - u_int8_t error_code; -/*---------------- DWORD[0] (Offset 0x0) ----------------*/ - /* Description - Unique debug session identifier. */ - /* 0x0.16 - 0x0.31 */ - u_int16_t session_id; -/*---------------- DWORD[1] (Offset 0x4) ----------------*/ - /* Description - Running counter that states the current sequence -number of each keep-alive session. */ - /* 0x4.0 - 0x4.31 */ - u_int32_t current_keep_alive_counter; -/*---------------- DWORD[2] (Offset 0x8) ----------------*/ - /* Description - Running counter that states the expected next -sequence number of each keep-alive session. */ - /* 0x8.0 - 0x8.31 */ - u_int32_t next_keep_alive_counter; -}; - /* Description - */ /* Size in bytes - 48 */ struct reg_access_switch_mddq_ext { @@ -382,12 +352,12 @@ range index will lead to BAD_PARAM status of the register. */ u_int8_t data_valid; /*---------------- DWORD[4] (Offset 0x10) ----------------*/ /* Description - Properties of that field are based on query_type. -For slot information query_type data - see Table 537, -"slot_info Register Layout," on page 735 -For devices on slot query_type data - see Table 539, -"device_info Register Layout," on page 736 -For slot name query_type data - see Table 541, "slot_name -Register Layout," on page 737 */ +For slot information query_type data - see Table 609, +"slot_info Register Layout," on page 750 +For devices on slot query_type data - see Table 611, +"device_info Register Layout," on page 751 +For slot name query_type data - see Table 613, "slot_name +Register Layout," on page 752 */ /* 0x10.0 - 0x2c.31 */ union reg_access_switch_mddq_data_auto_ext data; }; @@ -419,12 +389,12 @@ struct reg_access_switch_mddt_reg_ext { u_int8_t read_size; /*---------------- DWORD[3] (Offset 0xc) ----------------*/ /* Description - Payload -For PRM Register type payload- See Table 529, "PRM -Register Payload Layout," on page 732 -For Command type payload - See Table 531, "Com -mand Payload Layout," on page 732 -For CrSpace type payload - See Table 533, "CrSpace -access Payload Layout," on page 733 */ +For PRM Register type payload- See Table 601, "PRM +Register Payload Layout," on page 747 +For Command type payload - See Table 603, "Com +mand Payload Layout," on page 747 +For CrSpace type payload - See Table 605, "CrSpace +access Payload Layout," on page 748 */ /* 0xc.0 - 0x10c.31 */ union reg_access_switch_mddt_reg_payload_auto_ext payload; }; @@ -459,6 +429,35 @@ Setting to '0' will not trigger any operation. */ u_int8_t end; }; +/* Description - */ +/* Size in bytes - 44 */ +struct reg_access_switch_mkdc_reg_ext { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - Indicates the successful completion of the instruction +or the reason it failed: +0: OK +1: BAD_SESSION_ID +2: BAD_KEEP_ALIVE_COUNTER +3: BAD_SOURCE_ADDRESS +4: SESSION_TIMEOUT +Other values are Reserved. */ + /* 0x0.0 - 0x0.3 */ + u_int8_t error_code; + /* Description - Unique debug session identifier. */ + /* 0x0.16 - 0x0.31 */ + u_int16_t session_id; +/*---------------- DWORD[1] (Offset 0x4) ----------------*/ + /* Description - Running counter that states the current sequence +number of each keep-alive session. */ + /* 0x4.0 - 0x4.31 */ + u_int32_t current_keep_alive_counter; +/*---------------- DWORD[2] (Offset 0x8) ----------------*/ + /* Description - Running counter that states the expected next +sequence number of each keep-alive session. */ + /* 0x8.0 - 0x8.31 */ + u_int32_t next_keep_alive_counter; +}; + /* Description - */ /* Size in bytes - 112 */ struct reg_access_switch_mtcq_reg_ext { @@ -517,27 +516,27 @@ replay-protection. */ /* Size in bytes - 1040 */ union reg_access_switch_reg_access_switch_Nodes { /*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - */ + /* 0x0.0 - 0x10c.31 */ + struct reg_access_switch_mddt_reg_ext mddt_reg_ext; /* Description - */ /* 0x0.0 - 0x14.31 */ struct reg_access_switch_icam_reg_ext icam_reg_ext; /* Description - */ /* 0x0.0 - 0x2c.31 */ - struct reg_access_switch_mddq_ext mddq_ext; - /* Description - */ - /* 0x0.0 - 0x40c.31 */ - struct reg_access_switch_icsr_ext icsr_ext; - /* Description - */ - /* 0x0.0 - 0x2c.31 */ struct reg_access_switch_mdsr_reg_ext mdsr_reg_ext; /* Description - */ /* 0x0.0 - 0x28.31 */ - struct reg_access_switch_mcdc_reg mcdc_reg; + struct reg_access_switch_mkdc_reg_ext mkdc_reg_ext; /* Description - */ /* 0x0.0 - 0x6c.31 */ struct reg_access_switch_mtcq_reg_ext mtcq_reg_ext; /* Description - */ - /* 0x0.0 - 0x10c.31 */ - struct reg_access_switch_mddt_reg_ext mddt_reg_ext; + /* 0x0.0 - 0x2c.31 */ + struct reg_access_switch_mddq_ext mddq_ext; + /* Description - */ + /* 0x0.0 - 0x40c.31 */ + struct reg_access_switch_icsr_ext icsr_ext; }; @@ -619,13 +618,6 @@ void reg_access_switch_icsr_ext_print(const struct reg_access_switch_icsr_ext *p unsigned int reg_access_switch_icsr_ext_size(void); #define REG_ACCESS_SWITCH_ICSR_EXT_SIZE (0x410) void reg_access_switch_icsr_ext_dump(const struct reg_access_switch_icsr_ext *ptr_struct, FILE *fd); -/* mcdc_reg */ -void reg_access_switch_mcdc_reg_pack(const struct reg_access_switch_mcdc_reg *ptr_struct, u_int8_t *ptr_buff); -void reg_access_switch_mcdc_reg_unpack(struct reg_access_switch_mcdc_reg *ptr_struct, const u_int8_t *ptr_buff); -void reg_access_switch_mcdc_reg_print(const struct reg_access_switch_mcdc_reg *ptr_struct, FILE *fd, int indent_level); -unsigned int reg_access_switch_mcdc_reg_size(void); -#define REG_ACCESS_SWITCH_MCDC_REG_SIZE (0x2c) -void reg_access_switch_mcdc_reg_dump(const struct reg_access_switch_mcdc_reg *ptr_struct, FILE *fd); /* mddq_ext */ void reg_access_switch_mddq_ext_pack(const struct reg_access_switch_mddq_ext *ptr_struct, u_int8_t *ptr_buff); void reg_access_switch_mddq_ext_unpack(struct reg_access_switch_mddq_ext *ptr_struct, const u_int8_t *ptr_buff); @@ -647,6 +639,13 @@ void reg_access_switch_mdsr_reg_ext_print(const struct reg_access_switch_mdsr_re unsigned int reg_access_switch_mdsr_reg_ext_size(void); #define REG_ACCESS_SWITCH_MDSR_REG_EXT_SIZE (0x30) void reg_access_switch_mdsr_reg_ext_dump(const struct reg_access_switch_mdsr_reg_ext *ptr_struct, FILE *fd); +/* mkdc_reg_ext */ +void reg_access_switch_mkdc_reg_ext_pack(const struct reg_access_switch_mkdc_reg_ext *ptr_struct, u_int8_t *ptr_buff); +void reg_access_switch_mkdc_reg_ext_unpack(struct reg_access_switch_mkdc_reg_ext *ptr_struct, const u_int8_t *ptr_buff); +void reg_access_switch_mkdc_reg_ext_print(const struct reg_access_switch_mkdc_reg_ext *ptr_struct, FILE *fd, int indent_level); +unsigned int reg_access_switch_mkdc_reg_ext_size(void); +#define REG_ACCESS_SWITCH_MKDC_REG_EXT_SIZE (0x2c) +void reg_access_switch_mkdc_reg_ext_dump(const struct reg_access_switch_mkdc_reg_ext *ptr_struct, FILE *fd); /* mtcq_reg_ext */ void reg_access_switch_mtcq_reg_ext_pack(const struct reg_access_switch_mtcq_reg_ext *ptr_struct, u_int8_t *ptr_buff); void reg_access_switch_mtcq_reg_ext_unpack(struct reg_access_switch_mtcq_reg_ext *ptr_struct, const u_int8_t *ptr_buff); From 68f12a46adc04ef6619022b917ce56a51ed7a7fb Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Mon, 3 Jan 2022 14:40:15 +0200 Subject: [PATCH 015/184] [mlxconfig] remote_token_keep_alive command succeeded while we run with wrong session id on wrong device (pci device) Description: Fixed keep alive session loop - sending MKDC reg first, then sleep. Added check for IB device in challenge and keep alive session commands. Tested OS: Linux Tested devices: Blackbird Tested flows: remote token keep alive Known gaps (with RM ticket): N/A Issue: 2842006 --- mlxconfig/mlxcfg_parser.cpp | 10 ++-- mlxconfig/mlxcfg_ui.cpp | 116 ++++++++++++++++++++++-------------- mlxconfig/mlxcfg_ui.h | 12 +++- 3 files changed, 86 insertions(+), 52 deletions(-) diff --git a/mlxconfig/mlxcfg_parser.cpp b/mlxconfig/mlxcfg_parser.cpp index fd1241c7..539ffb84 100644 --- a/mlxconfig/mlxcfg_parser.cpp +++ b/mlxconfig/mlxcfg_parser.cpp @@ -119,10 +119,10 @@ void MlxCfg::printHelp() printf(IDENT2 "%-24s : %s\n", "xml2bin", "Generate binary configuration dump file from XML file. XML input file name and bin output file name must be specified. (*)"); printf(IDENT2 "%-24s : %s\n", "create_conf", "Generate configuration file from XML file. XML input file name and bin output file name must be specified. (*)"); printf(IDENT2 "%-24s : %s\n", "apply", "Apply a configuration file, that was created with create_conf command. bin input file name must be specified. (*)"); - printf(IDENT2 "%-24s : %s\n", "token", "Send a challenge request to a MST device. Token type must be specified."); - printf(IDENT2 "%-24s : %s\n", "remote_token_keep_alive", "Start a remote token session. Session id must be specified."); - printf(IDENT2 "%-24s : %s\n", "token_supported", "Query which tokens are supported on a MST device."); - printf(IDENT2 "%-24s : %s\n", "query_token_session", "Query the status of an active token session."); + printf(IDENT2 "%-24s : %s\n", "token", "Send a challenge request. Token type must be specified."); + printf(IDENT2 "%-24s : %s\n", "remote_token_keep_alive", "Start a remote token session for a specified time. time in minutes and session id must be specified."); + printf(IDENT2 "%-24s : %s\n", "token_supported", "Query which tokens are supported."); + printf(IDENT2 "%-24s : %s\n", "query_token_session", "Query the status of a token session."); printf(IDENT2 "%-24s : %s\n", "end_token_session", "End an active token session."); // print supported commands @@ -525,7 +525,7 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) return status; } if (_mlxParams.sessionTimeInSec > MAX_SESSION_TIME_IN_MINUTES) { - return err(true, "requested session time is out of bounds, max session time is 1 week."); + return err(true, "requested session time is out of bounds, max session time is 1 week (10080 minutes)."); } _mlxParams.sessionTimeInSec *= 60; _mlxParams.cmd = Mc_RemoteTokenKeepAlive; diff --git a/mlxconfig/mlxcfg_ui.cpp b/mlxconfig/mlxcfg_ui.cpp index 49d094d9..a787abc5 100644 --- a/mlxconfig/mlxcfg_ui.cpp +++ b/mlxconfig/mlxcfg_ui.cpp @@ -1361,7 +1361,7 @@ mlxCfgStatus MlxCfg::apply() mlxCfgStatus MlxCfg::remoteTokenKeepAlive() -{ +{ mlxCfgStatus status = MLX_CFG_OK; mfile *mf = NULL; @@ -1371,6 +1371,10 @@ mlxCfgStatus MlxCfg::remoteTokenKeepAlive() return MLX_CFG_ERROR; } + if ((mf->flags & MDEVS_IB) == 0) { //not IB device + return err(true, "specified device is not an IB device.\n"); + } + KeepAliveSession session(mf, _mlxParams.sessionId, _mlxParams.sessionTimeInSec); if (_mlxParams.isSleepTimeBetweenCommandsInput) { @@ -1380,8 +1384,8 @@ mlxCfgStatus MlxCfg::remoteTokenKeepAlive() session.setSleepTimeOnCommandTO(_mlxParams.keepAliveSleepTimeOnCommandTO); } - int session_status = session.startSession(); - if (session_status) { + keepAliveStatus sessionStatus = session.runSession(); + if (sessionStatus != KEEP_ALIVE_OK) { status = MLX_CFG_ERROR; } else { @@ -1450,7 +1454,11 @@ mlxCfgStatus MlxCfg::getChallenge() printf("-E- failed to open the device.\n"); return MLX_CFG_ERROR; } - + + if ((mf->flags & MDEVS_IB) == 0) { //not IB device + return err(true, "specified device is not an IB device.\n"); + } + struct reg_access_switch_mtcq_reg_ext mtcq_reg; memset(&mtcq_reg, 0, sizeof(mtcq_reg)); mtcq_reg.token_opcode = _mlxParams.tokenID; @@ -1697,7 +1705,7 @@ KeepAliveSession::KeepAliveSession(mfile *mf, u_int16_t sessionId, u_int32_t ses _mf(mf), _sessionId(sessionId), _sessionTimeLeftInSec(sessionTimeInSec), - _SleepTimeOnCommandTO(5), + _SleepTimeOnCommandTO(1), _SleepTimeBetweenCommands(300) { memset(&_mkdc_reg, 0, sizeof(_mkdc_reg)); @@ -1707,42 +1715,50 @@ KeepAliveSession::KeepAliveSession(mfile *mf, u_int16_t sessionId, u_int32_t ses _mkdc_reg.current_keep_alive_counter = rand(); } -int KeepAliveSession::startSession() +keepAliveStatus KeepAliveSession::runSession() { - time_t timer; + time_t mkdcRunTime; u_int32_t sleepTimeInSec = 0; u_int32_t sleepBetweenCommandsInSec = _SleepTimeBetweenCommands; if (sleepBetweenCommandsInSec >= _keepAliveTimestampInSec) { - printf("Specified cycle time cannot be longer than keep alive timestamp.\n"); - return -1; + return err(true, "Specified cycle time must be shorter than %d seconds.", _keepAliveTimestampInSec); } - while (_sessionTimeLeftInSec > _keepAliveTimestampInSec) { - if (sleepBetweenCommandsInSec > (_sessionTimeLeftInSec - _keepAliveTimestampInSec)) { - sleepBetweenCommandsInSec = _sessionTimeLeftInSec - _keepAliveTimestampInSec; + if (_sessionTimeLeftInSec < _keepAliveTimestampInSec) { + return err(true, "Specified session time must be longer than %d minutes.", _keepAliveTimestampInSec / 60); + } + + while (_sessionTimeLeftInSec >= _keepAliveTimestampInSec) { + mkdcRunTime = 0; + if (runMKDC(_mf, &_mkdc_reg, mkdcRunTime) != KEEP_ALIVE_OK) { + return KEEP_ALIVE_ERROR; } - sleepTimeInSec = sleepBetweenCommandsInSec; - timer = 0; + if (processMKDCData(&_mkdc_reg) != KEEP_ALIVE_OK) { + return KEEP_ALIVE_ERROR; + } + _sessionTimeLeftInSec -= mkdcRunTime; - msleep(sleepTimeInSec * 1000); + if (_sessionTimeLeftInSec > _keepAliveTimestampInSec) { + if (sleepBetweenCommandsInSec > (_sessionTimeLeftInSec - _keepAliveTimestampInSec)) { + //* sleep until last MKDC is needed (which is when _keepAliveTimestampInSec seconds are left for the session) + sleepBetweenCommandsInSec = _sessionTimeLeftInSec - _keepAliveTimestampInSec; + } + } + else { + //* sleep until session time ends + sleepBetweenCommandsInSec = _sessionTimeLeftInSec; + } + sleepTimeInSec = sleepBetweenCommandsInSec; + msleep(sleepTimeInSec * 1000); _sessionTimeLeftInSec -= sleepBetweenCommandsInSec; - - runMKDC(_mf, &_mkdc_reg, timer); - - _sessionTimeLeftInSec -= timer; - if (processMKDCData(&_mkdc_reg) != 0) { - return -1; - } } - msleep(_sessionTimeLeftInSec * 1000); - - return 0; + return KEEP_ALIVE_OK; } -int KeepAliveSession::runMKDC(mfile* mf, reg_access_switch_mkdc_reg_ext* mkdc_reg, time_t& timer) +keepAliveStatus KeepAliveSession::runMKDC(mfile* mf, reg_access_switch_mkdc_reg_ext* mkdc_reg, time_t& timer) { reg_access_status_t rc = ME_REG_ACCESS_OK; time_t start = 0; @@ -1753,45 +1769,41 @@ int KeepAliveSession::runMKDC(mfile* mf, reg_access_switch_mkdc_reg_ext* mkdc_re rc = reg_access_mkdc(mf, REG_ACCESS_METHOD_GET, mkdc_reg); dealWithSignal(); timer = time(NULL) - start; - + while ((rc == ME_ICMD_STATUS_EXECUTE_TO) && ((u_int32_t)timer < _keepAliveTimestampInSec)) { u_int32_t sleep_time_in_sec = _SleepTimeOnCommandTO; - + msleep(sleep_time_in_sec * 1000); - + mft_signal_set_handling(1); - rc = reg_access_mkdc(mf, REG_ACCESS_METHOD_GET, mkdc_reg); + rc = reg_access_mkdc(mf, REG_ACCESS_METHOD_GET, mkdc_reg); dealWithSignal(); - + timer = time(NULL) - start; } - + if (rc == ME_REG_ACCESS_REG_NOT_SUPP) { - printf("-E- MKDC access register is not supported.\n"); - status = -2; + return err(true, "MKDC access register is not supported."); } else if (rc) { - printf("Error while using reg access MKDC, error code is %d\n", rc); - status = -1; + return err(true, "cannot access MKDC register, error code is %d."); } - return status; + return KEEP_ALIVE_OK; } -int KeepAliveSession::processMKDCData(reg_access_switch_mkdc_reg_ext* mkdc_reg) +keepAliveStatus KeepAliveSession::processMKDCData(reg_access_switch_mkdc_reg_ext* mkdc_reg) { if (mkdc_reg->error_code != 0) { - printf("-E- keep alive session failed. error code: %s\n", _mkdcErrorToString[mkdc_reg->error_code]); - return -1; + return err(true, "keep alive session failed. error code: %s.", _mkdcErrorToString[mkdc_reg->error_code]); } - if (mkdc_reg->session_id != _sessionId) { - printf("-E- received wrong session id.\n"); - return -1; + if (mkdc_reg->session_id != _sessionId) { + return err(true, "received wrong session id."); } mkdc_reg->current_keep_alive_counter = mkdc_reg->next_keep_alive_counter; - return 0; + return KEEP_ALIVE_OK; } void KeepAliveSession::setSleepTimeOnCommandTO(u_int32_t sleepTime) @@ -1803,3 +1815,19 @@ void KeepAliveSession::setSleepTimeBetweenCommands(u_int32_t sleepTime) { _SleepTimeBetweenCommands = sleepTime; } + +keepAliveStatus KeepAliveSession::err(bool report, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + char errBuff[MAX_ERR_STR_LEN] = {0}; + + if (vsnprintf(errBuff, MAX_ERR_STR_LEN, fmt, args) >= MAX_ERR_STR_LEN) { + strcpy(&errBuff[MAX_ERR_STR_LEN - 5], "..."); + } + if (report) { + fprintf(stdout, PRE_ERR_MSG " %s\n", errBuff); + } + va_end(args); + return KEEP_ALIVE_ERROR; +} \ No newline at end of file diff --git a/mlxconfig/mlxcfg_ui.h b/mlxconfig/mlxcfg_ui.h index a0b54b68..fa2d0b50 100644 --- a/mlxconfig/mlxcfg_ui.h +++ b/mlxconfig/mlxcfg_ui.h @@ -83,6 +83,11 @@ typedef enum { Switch = 1 } Device_Type; +typedef enum { + KEEP_ALIVE_OK, + KEEP_ALIVE_ERROR +} keepAliveStatus; + typedef struct QueryOutputItem { string mlxconfigName; u_int32_t nextVal; @@ -138,13 +143,14 @@ class KeepAliveSession public: KeepAliveSession(mfile *mf, u_int16_t sessionId, u_int32_t sessionTimeInSec); - int startSession(); + keepAliveStatus runSession(); void setSleepTimeOnCommandTO(u_int32_t sleepTime); void setSleepTimeBetweenCommands(u_int32_t sleepTime); private: - int runMKDC(mfile* mf, reg_access_switch_mkdc_reg_ext* mkdc_reg, time_t& timer); - int processMKDCData(reg_access_switch_mkdc_reg_ext* mkdc_reg); + keepAliveStatus runMKDC(mfile* mf, reg_access_switch_mkdc_reg_ext* mkdc_reg, time_t& timer); + keepAliveStatus processMKDCData(reg_access_switch_mkdc_reg_ext* mkdc_reg); + keepAliveStatus err(bool report, const char *fmt, ...); static const char* _mkdcErrorToString[5]; From ee6385829f13cf1d091dad51889797d427bdf6a0 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Mon, 3 Jan 2022 17:08:32 +0200 Subject: [PATCH 016/184] [mlxconfig] Fix remote tokens command names Description: changed token challenge command name. Added flags for session time for keep alive and token type for token challenge. Tested OS: Linux Tested devices: N/A Tested flows: token challenge, remote token keep alive Known gaps (with RM ticket): N/A Issue: 2856085 --- mlxconfig/mlxcfg_parser.cpp | 136 ++++++++++++++++++++---------------- mlxconfig/mlxcfg_ui.cpp | 2 +- mlxconfig/mlxcfg_ui.h | 13 ++-- 3 files changed, 86 insertions(+), 65 deletions(-) diff --git a/mlxconfig/mlxcfg_parser.cpp b/mlxconfig/mlxcfg_parser.cpp index 539ffb84..e02adcc1 100644 --- a/mlxconfig/mlxcfg_parser.cpp +++ b/mlxconfig/mlxcfg_parser.cpp @@ -100,6 +100,8 @@ void MlxCfg::printHelp() printFlagLine("k", "openssl_key_id", "IDENTIFIER", "OpenSSL key identifier"); printFlagLine("t", "device_type", "switch/hca", "Specify the device type"); printFlagLine("s", "session_id", "", "Specify the session id for token keep alive session."); + printFlagLine("st", "session_time", "", "Specify session time for token keep alive session."); + printFlagLine("tkn", "token_type", "", "Specify token type."); //print commands printf("\n"); @@ -119,8 +121,8 @@ void MlxCfg::printHelp() printf(IDENT2 "%-24s : %s\n", "xml2bin", "Generate binary configuration dump file from XML file. XML input file name and bin output file name must be specified. (*)"); printf(IDENT2 "%-24s : %s\n", "create_conf", "Generate configuration file from XML file. XML input file name and bin output file name must be specified. (*)"); printf(IDENT2 "%-24s : %s\n", "apply", "Apply a configuration file, that was created with create_conf command. bin input file name must be specified. (*)"); - printf(IDENT2 "%-24s : %s\n", "token", "Send a challenge request. Token type must be specified."); - printf(IDENT2 "%-24s : %s\n", "remote_token_keep_alive", "Start a remote token session for a specified time. time in minutes and session id must be specified."); + printf(IDENT2 "%-24s : %s\n", "challenge_request", "Send a token challenge request to the device. Token type must be specified."); + printf(IDENT2 "%-24s : %s\n", "remote_token_keep_alive", "Start a remote token session for a specified time. session id must be specified."); printf(IDENT2 "%-24s : %s\n", "token_supported", "Query which tokens are supported."); printf(IDENT2 "%-24s : %s\n", "query_token_session", "Query the status of a token session."); printf(IDENT2 "%-24s : %s\n", "end_token_session", "End an active token session."); @@ -441,18 +443,66 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) return err(true, "missing OpenSSL key identifier"); } _mlxParams.opensslKeyId = argv[i]; + } else if ((arg == "-tkn") || (arg == "--token_type")) { + if (++i == argc) { + return err(true, "missing token name"); + } + if (strcmp(argv[i], "RMCS") != 0) { + return err(true, "only RMCS token is supported"); + } + _mlxParams.tokenID = Mc_Token_RMCS; + } else if (arg == "--cycle_time") { + if (++i == argc) { + return err(true, "missing cycle time value"); + } + status = getNumberFromString(argv[i], _mlxParams.keepAliveSleepTimeBetweenCommands); + if (status != MLX_CFG_OK) { + return status; + } + _mlxParams.isSleepTimeBetweenCommandsInput = true; + } else if (arg == "--resend_time") { + if (++i == argc) { + return err(true, "missing resend time value"); + } + status = getNumberFromString(argv[i], _mlxParams.keepAliveSleepTimeOnCommandTO); + if (status != MLX_CFG_OK) { + return status; + } + _mlxParams.isSleepTimeOnCommandTOInput = true; + } else if ((arg == "-s") || (arg == "--session_id")) { + if (++i == argc) { + return err(true, "missing session id"); + } + status = getNumberFromString(argv[i], _mlxParams.sessionId); + _mlxParams.isSessionIDGiven = true; + if (status != MLX_CFG_OK) { + return status; + } + } else if ((arg == "-st") || (arg == "--session_time")) { + if (++i == argc) { + return err(true, "missing session time value"); + } + status = getNumberFromString(argv[i], _mlxParams.sessionTimeInSec); + if (status != MLX_CFG_OK) { + return status; + } + if (_mlxParams.sessionTimeInSec > MAX_SESSION_TIME_IN_MINUTES) { + return err(true, "requested session time is out of bounds, max session time is 1 week (10080 minutes)."); + } + _mlxParams.sessionTimeInSec *= 60; + _mlxParams.isSessionTimeGiven = true; + // hidden flag --force used to ignore parameter checks + } else if (arg == "--force") { + _mlxParams.force = true; } else if (arg == "set" || arg == "s") { _mlxParams.cmd = Mc_Set; break; - } else if (arg == "query" || arg == "q") { _mlxParams.cmd = Mc_Query; break; - } else if (arg == "reset" || arg == "r") { _mlxParams.cmd = Mc_Reset; break; - } else if (arg == "clear_semaphore") { _mlxParams.cmd = Mc_Clr_Sem; break; @@ -489,64 +539,21 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) } else if (arg == "show_confs" || arg == "i") { _mlxParams.cmd = Mc_ShowConfs; break; - // hidden flag --force used to ignore parameter checks - } else if (arg == "--force") { - _mlxParams.force = true; - } else if (arg == "--session_id") { - if (++i == argc) { - return err(true, "missing session id"); - } - status = getNumberFromString(argv[i], _mlxParams.sessionId); - _mlxParams.isSessionIDGiven = true; - if (status != MLX_CFG_OK) { - return status; - } - } else if (arg == "token") { - if (++i == argc) { - return err(true, "missing token name"); - } - if (strcmp(argv[i], "RMCS") != 0) { - return err(true, "only RMCS token is supported"); - } - _mlxParams.cmd = Mc_TokenChallenge; - _mlxParams.tokenID = Mc_Token_RMCS; + } else if (arg == "challenge_request") { + _mlxParams.cmd = Mc_ChallengeRequest; + break; } else if (arg == "token_supported") { _mlxParams.cmd = Mc_TokenSupported; + break; } else if (arg == "query_token_session") { _mlxParams.cmd = Mc_QueryTokenSession; + break; } else if (arg == "end_token_session") { _mlxParams.cmd = Mc_EndTokenSession; + break; } else if (arg == "remote_token_keep_alive") { - if (++i == argc) { - return err(true, "missing session time"); - } - status = getNumberFromString(argv[i], _mlxParams.sessionTimeInSec); - if (status != MLX_CFG_OK) { - return status; - } - if (_mlxParams.sessionTimeInSec > MAX_SESSION_TIME_IN_MINUTES) { - return err(true, "requested session time is out of bounds, max session time is 1 week (10080 minutes)."); - } - _mlxParams.sessionTimeInSec *= 60; _mlxParams.cmd = Mc_RemoteTokenKeepAlive; - } else if (arg == "--cycle_time") { - if (++i == argc) { - return err(true, "missing cycle time value"); - } - status = getNumberFromString(argv[i], _mlxParams.keepAliveSleepTimeBetweenCommands); - if (status != MLX_CFG_OK) { - return status; - } - _mlxParams.isSleepTimeBetweenCommandsInput = true; - } else if (arg == "--resend_time") { - if (++i == argc) { - return err(true, "missing resend time value"); - } - status = getNumberFromString(argv[i], _mlxParams.keepAliveSleepTimeOnCommandTO); - if (status != MLX_CFG_OK) { - return status; - } - _mlxParams.isSleepTimeOnCommandTOInput = true; + break; } else { return err(true, "invalid argument: %s", arg.c_str()); } @@ -564,7 +571,7 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) } if ((_mlxParams.cmd == Mc_Set || _mlxParams.cmd == Mc_Clr_Sem || _mlxParams.cmd == Mc_Set_Raw || _mlxParams.cmd == Mc_Backup || _mlxParams.cmd == Mc_ShowConfs || _mlxParams.cmd == Mc_Apply || _mlxParams.cmd == Mc_RemoteTokenKeepAlive - || _mlxParams.cmd == Mc_TokenChallenge || _mlxParams.cmd == Mc_TokenSupported || _mlxParams.cmd == Mc_QueryTokenSession + || _mlxParams.cmd == Mc_ChallengeRequest || _mlxParams.cmd == Mc_TokenSupported || _mlxParams.cmd == Mc_QueryTokenSession || _mlxParams.cmd == Mc_EndTokenSession) && _mlxParams.device.length() == 0) { return err(true, "%s command expects device to be specified.", _mlxParams.cmd == Mc_Set ? @@ -573,8 +580,8 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) "get_raw" : _mlxParams.cmd == Mc_Clr_Sem ? "clear_semaphore" : _mlxParams.cmd == Mc_Backup ? "backup" : _mlxParams.cmd == Mc_Apply ? - "apply" : _mlxParams.cmd == Mc_TokenChallenge ? - "token" : _mlxParams.cmd == Mc_TokenSupported ? + "apply" : _mlxParams.cmd == Mc_ChallengeRequest ? + "challenge_request" : _mlxParams.cmd == Mc_TokenSupported ? "token_supported" : _mlxParams.cmd == Mc_QueryTokenSession ? "query_token_session" : _mlxParams.cmd == Mc_EndTokenSession ? "end_token_session" : _mlxParams.cmd == Mc_EndTokenSession ? @@ -593,13 +600,22 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) return err(true, "raw TLV file can only be specified with set_raw command."); } + if ((_mlxParams.cmd == Mc_ChallengeRequest && (_mlxParams.tokenID == Mc_Token_Unknown)) || + (_mlxParams.cmd != Mc_ChallengeRequest && (_mlxParams.tokenID != Mc_Token_Unknown))) { + return err(true, "-tkn/--token_type must be specified with challenge_request command"); + } + if ((_mlxParams.cmd == Mc_RemoteTokenKeepAlive && !_mlxParams.isSessionIDGiven) || (_mlxParams.cmd != Mc_RemoteTokenKeepAlive && _mlxParams.isSessionIDGiven)) { - return err(true, "--session_id should be specified with remote_token_keep_alive command"); + return err(true, "-s/--session_id should be specified with remote_token_keep_alive command"); } - if ((_mlxParams.isSleepTimeBetweenCommandsInput || _mlxParams.isSleepTimeOnCommandTOInput) && _mlxParams.cmd != Mc_RemoteTokenKeepAlive) { + if ((_mlxParams.isSleepTimeBetweenCommandsInput || _mlxParams.isSleepTimeOnCommandTOInput) + && _mlxParams.cmd != Mc_RemoteTokenKeepAlive) { return err(true, "sleep times for keep alive session can only be specified with remote_token_keep_alive command"); } + if (_mlxParams.isSessionTimeGiven && _mlxParams.cmd != Mc_RemoteTokenKeepAlive) { + return err(true, "session time for keep alive session can only be specified with remote_token_keep_alive command"); + } if (_mlxParams.cmd == Mc_GenTLVsFile) { return extractNVOutputFile(argc - i, &(argv[i])); diff --git a/mlxconfig/mlxcfg_ui.cpp b/mlxconfig/mlxcfg_ui.cpp index a787abc5..9efb40f5 100644 --- a/mlxconfig/mlxcfg_ui.cpp +++ b/mlxconfig/mlxcfg_ui.cpp @@ -1662,7 +1662,7 @@ mlxCfgStatus MlxCfg::execute(int argc, char *argv[]) case Mc_RemoteTokenKeepAlive: ret = remoteTokenKeepAlive(); break; - case Mc_TokenChallenge: + case Mc_ChallengeRequest: ret = getChallenge(); break; case Mc_TokenSupported: diff --git a/mlxconfig/mlxcfg_ui.h b/mlxconfig/mlxcfg_ui.h index fa2d0b50..ac3efeb2 100644 --- a/mlxconfig/mlxcfg_ui.h +++ b/mlxconfig/mlxcfg_ui.h @@ -63,7 +63,7 @@ typedef enum { Mc_CreateConf, Mc_Apply, Mc_RemoteTokenKeepAlive, - Mc_TokenChallenge, + Mc_ChallengeRequest, Mc_TokenSupported, Mc_QueryTokenSession, Mc_EndTokenSession, @@ -74,7 +74,8 @@ typedef enum { Mc_Token_RMCS = 0, Mc_Token_RMDT, Mc_Token_CRCS, - Mc_Token_CRDT + Mc_Token_CRDT, + Mc_Token_Unknown } mlxCfgToken; typedef enum { @@ -108,8 +109,11 @@ class MlxCfgParams MlxCfgParams() : device(), rawTlvFile(), NVInputFile(), NVOutputFile(), dbName(DB_NAME), privPemFile(), keyPairUUID(), opensslEngine(), opensslKeyId(), allAttrs(false), cmd(Mc_UnknownCmd), yes(false), - force(false), enableVerbosity(false), isSleepTimeBetweenCommandsInput(false), - isSleepTimeOnCommandTOInput(false) {} + force(false), enableVerbosity(false), tokenID(Mc_Token_Unknown), sessionId(0), + isSessionIDGiven(false), sessionTimeInSec(600), isSessionTimeGiven(false), + keepAliveSleepTimeBetweenCommands(0), isSleepTimeBetweenCommandsInput(false), + keepAliveSleepTimeOnCommandTO(0), isSleepTimeOnCommandTOInput(false) {} + ~MlxCfgParams() {} std::string device; @@ -132,6 +136,7 @@ class MlxCfgParams u_int32_t sessionId; bool isSessionIDGiven; u_int32_t sessionTimeInSec; + bool isSessionTimeGiven; u_int32_t keepAliveSleepTimeBetweenCommands; bool isSleepTimeBetweenCommandsInput; u_int32_t keepAliveSleepTimeOnCommandTO; From 06606f27b0633957e438245703e840d1bacace8f Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Mon, 3 Jan 2022 17:13:10 +0200 Subject: [PATCH 017/184] [mlxconfig] token_supported command prints wrong data Description: Fixed MCAM parsing in mlxconfig token_supported command Tested OS: Linux Tested devices: BB Tested flows: token_supported Known gaps (with RM ticket): N/A Issue: 2856648 --- mlxconfig/mlxcfg_ui.cpp | 20 ++++++++------------ reg_access/reg_access.c | 34 ---------------------------------- reg_access/reg_access.h | 1 - 3 files changed, 8 insertions(+), 47 deletions(-) diff --git a/mlxconfig/mlxcfg_ui.cpp b/mlxconfig/mlxcfg_ui.cpp index 9efb40f5..b35800a2 100644 --- a/mlxconfig/mlxcfg_ui.cpp +++ b/mlxconfig/mlxcfg_ui.cpp @@ -1405,8 +1405,7 @@ bool MlxCfg::runMTCQ(mfile* mf, struct reg_access_switch_mtcq_reg_ext* mtcq_reg) rc = reg_access_mtcq(mf, REG_ACCESS_METHOD_GET, mtcq_reg); dealWithSignal(); if (rc) { - printf("failed getting response from the device, error %d.\n", rc); - return false; + return err(true, "failed getting response from the device, error %d.", rc); } return true; @@ -1496,13 +1495,13 @@ mlxCfgStatus MlxCfg::queryTokenSupport() tools_open_mcam mcam; memset(&mcam, 0, sizeof(mcam)); reg_access_status_t rc = ME_REG_ACCESS_OK; - rc = reg_access_mcam_reverse(mf, REG_ACCESS_METHOD_GET, &mcam); + rc = reg_access_mcam(mf, REG_ACCESS_METHOD_GET, &mcam); if (rc) { - printf("failed getting response from the device, error %d.\n", rc); + return err(true, "failed getting response from the device, error %d.", rc); } - printf("CS tokens supported: %d\n", EXTRACT(mcam.mng_feature_cap_mask[1], 6, 1)); - printf("Debug FW tokens supported: %d\n", EXTRACT(mcam.mng_feature_cap_mask[1], 7, 1)); + printf("CS tokens supported: %d\n", EXTRACT(mcam.mng_feature_cap_mask[2], 6, 1)); + printf("Debug FW tokens supported: %d\n", EXTRACT(mcam.mng_feature_cap_mask[2], 7, 1)); return MLX_CFG_OK; } @@ -1516,8 +1515,7 @@ bool MlxCfg::runMDSR(mfile* mf, struct reg_access_switch_mdsr_reg_ext* mdsr_reg, dealWithSignal(); if (rc) { - printf("failed getting response from the device, error %d.\n", rc); - return false; + return err(true, "failed getting response from the device, error %d.", rc); } return true; @@ -1527,8 +1525,7 @@ mlxCfgStatus MlxCfg::queryTokenSession() { mfile *mf = mopen(_mlxParams.device.c_str()); if (!mf) { - printf("-E- failed opening the device.\n"); - return MLX_CFG_ERROR; + return err(true, "failed opening the device."); } struct reg_access_switch_mdsr_reg_ext mdsr_reg; @@ -1572,8 +1569,7 @@ mlxCfgStatus MlxCfg::endTokenSession() { mfile *mf = mopen(_mlxParams.device.c_str()); if (!mf) { - printf("-E- failed opening the device.\n"); - return MLX_CFG_ERROR; + return err(true, "failed opening the device."); } struct reg_access_switch_mdsr_reg_ext mdsr_reg; diff --git a/reg_access/reg_access.c b/reg_access/reg_access.c index a657d3be..549dbd12 100644 --- a/reg_access/reg_access.c +++ b/reg_access/reg_access.c @@ -586,40 +586,6 @@ reg_access_status_t reg_access_mcam(mfile *mf, reg_access_method_t method, struc REG_ACCCESS(mf, method, REG_ID_MCAM, mcam, mcam, tools_open); } -void swap_bytes(u_int8_t* lhs, u_int8_t* rhs) -{ - u_int8_t temp = 0; - temp = *lhs; - *lhs = *rhs; - *rhs = temp; -} - -void reverse_byte_array(u_int8_t* arr, int len) -{ - u_int8_t* lhs = arr; - u_int8_t* rhs = arr + len - 1; - - if (len < 2) { - return; - } - - for (; lhs < rhs; ++lhs, --rhs) { - swap_bytes(lhs, rhs); - } -} - -reg_access_status_t reg_access_mcam_reverse(mfile *mf, reg_access_method_t method, struct tools_open_mcam *mcam) -{ - reg_access_status_t rc = reg_access_mcam(mf, method, mcam); - -#if __BYTE_ORDER == __LITTLE_ENDIAN - reverse_byte_array(mcam->mng_access_reg_cap_mask, 16); - reverse_byte_array(mcam->mng_feature_cap_mask, 16); -#endif - - return rc; -} - /************************************ * Function: reg_access_mcda ************************************/ diff --git a/reg_access/reg_access.h b/reg_access/reg_access.h index 2c18e849..05d47f18 100644 --- a/reg_access/reg_access.h +++ b/reg_access/reg_access.h @@ -103,7 +103,6 @@ reg_access_status_t reg_access_mfmc(mfile *mf, reg_access_method_t method, struc reg_access_status_t reg_access_mfpa_new(mfile *mf, reg_access_method_t method, struct tools_open_mfpa *mfpa); reg_access_status_t reg_access_mcam(mfile *mf, reg_access_method_t method, struct tools_open_mcam *mcam); -reg_access_status_t reg_access_mcam_reverse(mfile *mf, reg_access_method_t method, struct tools_open_mcam *mcam); reg_access_status_t reg_access_secure_host(mfile *mf, reg_access_method_t method, struct tools_open_mlock *mlock); /* * MCXX new burn commands From ed71fd85d52b1e6453b2e8fd40c33f60da9e7f26 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Mon, 3 Jan 2022 18:46:05 +0200 Subject: [PATCH 018/184] [mlxconfig] support for RMDT token for un-managed switches Description: Added RMDT token support in: 1) mlxconfig --token_type argument 2) mlxconfig challenge_request command 3) mlxconfig apply command Tested OS: Linux Tested devices: un-managed BB Tested flows: in mlxconfig 1) create tlvs 2) create xml from tlvs 3) get challenge from fw using challenge_request command 4) create binary from xml 5) apply token to the switch over IB 6) burn debug fw on the switch Known gaps (with RM ticket): N/A Issue: 2859746 --- flint/subcommands.cpp | 3 +++ fw_comps_mgr/fw_comps_mgr.cpp | 6 +++++- fw_comps_mgr/fw_comps_mgr.h | 1 + mlxconfig/mlxcfg_generic_commander.cpp | 5 +++++ mlxconfig/mlxcfg_parser.cpp | 18 ++++++++++++++---- mlxconfig/mlxcfg_ui.h | 1 + mlxfwops/lib/fsctrl_ops.cpp | 3 +++ mlxfwops/lib/mlxfwops_com.h | 3 ++- 8 files changed, 34 insertions(+), 6 deletions(-) diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index 4712b5f2..66f21789 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -3395,6 +3395,9 @@ string QuerySubCommand::printSecurityAttrInfo(u_int32_t m) if (m & SMM_RMCS_TOKEN) { attr += ", rmcs-token"; } + if (m & SMM_RMDT_TOKEN) { + attr += ", rmdt-token"; + } return attr; } diff --git a/fw_comps_mgr/fw_comps_mgr.cpp b/fw_comps_mgr/fw_comps_mgr.cpp index cdee73fd..ec1375a6 100644 --- a/fw_comps_mgr/fw_comps_mgr.cpp +++ b/fw_comps_mgr/fw_comps_mgr.cpp @@ -1206,7 +1206,8 @@ const char* CompNames[] = { "COMPID_CONGESTION_CONTROL", "COMPID_LINKX_PROPERTIES", "COMPID_CRYPTO_TO_COMMISSIONING", - "COMPID_RMCS_TOKEN" + "COMPID_RMCS_TOKEN", + "COMPID_RMDT_TOKEN" }; bool FwCompsMgr::RefreshComponentsStatus(comp_status_st* ComponentStatus) @@ -1517,6 +1518,9 @@ const char* FwComponent::getCompIdStr(comps_ids_t compId) case COMPID_RMCS_TOKEN: return "COMPID_RMCS_TOKEN"; + case COMPID_RMDT_TOKEN: + return "COMPID_RMDT_TOKEN"; + default: return "UNKNOWN_COMPONENT"; } diff --git a/fw_comps_mgr/fw_comps_mgr.h b/fw_comps_mgr/fw_comps_mgr.h index 67eac173..b2ac69f2 100644 --- a/fw_comps_mgr/fw_comps_mgr.h +++ b/fw_comps_mgr/fw_comps_mgr.h @@ -166,6 +166,7 @@ class FwComponent { COMPID_LINKX = 0xC, COMPID_CRYPTO_TO_COMMISSIONING = 0xD, COMPID_RMCS_TOKEN = 0xE, + COMPID_RMDT_TOKEN = 0xF, COMPID_UNKNOWN = 0xff, } comps_ids_t; diff --git a/mlxconfig/mlxcfg_generic_commander.cpp b/mlxconfig/mlxcfg_generic_commander.cpp index 6ce5f8df..0c49ba39 100644 --- a/mlxconfig/mlxcfg_generic_commander.cpp +++ b/mlxconfig/mlxcfg_generic_commander.cpp @@ -121,6 +121,7 @@ const u_int8_t debugTokenId = 0x5; const u_int8_t csTokenId = 0x7; const u_int8_t btcTokenId = 0x8; const u_int8_t rmcsTokenId = 0x10; +const u_int8_t rmdtTokenId = 0x11; const u_int32_t idMlnxId = 0x10e; void GenericCommander::supportsNVData() @@ -1382,6 +1383,10 @@ void GenericCommander::checkConfTlvs(const vector& tlvs, tlv->_id == rmcsTokenId) { csCompFound = true; compsId = FwComponent::COMPID_RMCS_TOKEN; + } else if (tlv->_tlvClass == NVFile && + tlv->_id == rmdtTokenId) { + csCompFound = true; + compsId = FwComponent::COMPID_RMDT_TOKEN; } else if (tlv->_tlvClass == 0x0 && tlv->_id == idMlnxId) { idMlnxCompFound = true; diff --git a/mlxconfig/mlxcfg_parser.cpp b/mlxconfig/mlxcfg_parser.cpp index e02adcc1..e887b1d2 100644 --- a/mlxconfig/mlxcfg_parser.cpp +++ b/mlxconfig/mlxcfg_parser.cpp @@ -379,6 +379,16 @@ mlxCfgStatus MlxCfg::getNumberFromString(const char* str, u_int32_t& num) return MLX_CFG_OK; } +mlxCfgToken MlxCfg::getTokenType(const char* tokenStr) +{ + mlxCfgToken tokenType = Mc_Token_Unknown; + + if (strcmp(tokenStr, "RMCS") == 0) tokenType = Mc_Token_RMCS; + if (strcmp(tokenStr, "RMDT") == 0) tokenType = Mc_Token_RMDT; + + return tokenType; +} + mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) { mlxCfgStatus status = MLX_CFG_OK; @@ -445,12 +455,12 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) _mlxParams.opensslKeyId = argv[i]; } else if ((arg == "-tkn") || (arg == "--token_type")) { if (++i == argc) { - return err(true, "missing token name"); + return err(true, "missing token type"); } - if (strcmp(argv[i], "RMCS") != 0) { - return err(true, "only RMCS token is supported"); + _mlxParams.tokenID = getTokenType(argv[i]); + if (_mlxParams.tokenID == Mc_Token_Unknown) { + return err(true, "invalid token type"); } - _mlxParams.tokenID = Mc_Token_RMCS; } else if (arg == "--cycle_time") { if (++i == argc) { return err(true, "missing cycle time value"); diff --git a/mlxconfig/mlxcfg_ui.h b/mlxconfig/mlxcfg_ui.h index ac3efeb2..9031bffc 100644 --- a/mlxconfig/mlxcfg_ui.h +++ b/mlxconfig/mlxcfg_ui.h @@ -248,6 +248,7 @@ class MlxCfg bool runMTCQ(mfile* mf, struct reg_access_switch_mtcq_reg_ext* mtcq_reg); void printArray(const u_int32_t arr[], int len); void printHexArrayAsAscii(const u_int32_t arr[], int len); + mlxCfgToken getTokenType(const char* tokenStr); // static print functions static int printParam(string param, u_int32_t val); diff --git a/mlxfwops/lib/fsctrl_ops.cpp b/mlxfwops/lib/fsctrl_ops.cpp index da824a0c..51f1afe4 100644 --- a/mlxfwops/lib/fsctrl_ops.cpp +++ b/mlxfwops/lib/fsctrl_ops.cpp @@ -216,6 +216,9 @@ bool FsCtrlOperations::FsIntQuery() if (it->getType() == FwComponent::COMPID_RMCS_TOKEN) { _fsCtrlImgInfo.security_mode |= SMM_RMCS_TOKEN; } + if (it->getType() == FwComponent::COMPID_RMDT_TOKEN) { + _fsCtrlImgInfo.security_mode |= SMM_RMDT_TOKEN; + } } } diff --git a/mlxfwops/lib/mlxfwops_com.h b/mlxfwops/lib/mlxfwops_com.h index 921c76db..07bc3a90 100644 --- a/mlxfwops/lib/mlxfwops_com.h +++ b/mlxfwops/lib/mlxfwops_com.h @@ -259,7 +259,8 @@ typedef enum security_mode_mask { SMM_CS_TOKEN = 0x1 << 5, SMM_DBG_TOKEN = 0x1 << 6, SMM_CRYTO_TO_COMMISSIONING = 0x1 << 7, - SMM_RMCS_TOKEN = 0x1 << 8 + SMM_RMCS_TOKEN = 0x1 << 8, + SMM_RMDT_TOKEN = 0x1 << 9 } security_mode_mask_t; typedef enum security_mode { From a64d76fa0da5b3d977967b6420f78c7471eee4f4 Mon Sep 17 00:00:00 2001 From: Oded Burstein Date: Tue, 4 Jan 2022 11:16:25 +0200 Subject: [PATCH 019/184] prevent accesing ICMD GW in livefish --- mtcr_ul/Makefile.am | 2 +- mtcr_ul/mtcr_ul_icmd_cif.c | 58 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/mtcr_ul/Makefile.am b/mtcr_ul/Makefile.am index b4f4be27..17626ed0 100644 --- a/mtcr_ul/Makefile.am +++ b/mtcr_ul/Makefile.am @@ -31,7 +31,7 @@ #-- # Makefile.am -- Process this file with automake to produce Makefile.in -AM_CPPFLAGS = -I$(top_srcdir)/include/mtcr_ul -I$(top_srcdir)/common +AM_CPPFLAGS = -I$(top_srcdir)/include/mtcr_ul -I$(top_srcdir)/common -I$(top_srcdir)/dev_mgt pkglib_LIBRARIES = libmtcr_ul.a diff --git a/mtcr_ul/mtcr_ul_icmd_cif.c b/mtcr_ul/mtcr_ul_icmd_cif.c index b4b946fb..fbd5c9aa 100644 --- a/mtcr_ul/mtcr_ul_icmd_cif.c +++ b/mtcr_ul/mtcr_ul_icmd_cif.c @@ -47,6 +47,7 @@ #endif #include "mtcr_mem_ops.h" +#include "tools_dev_types.h" #define ICMD_QUERY_CAP_CMD_ID 0x8400 #define ICMD_QUERY_CAP_CMD_SZ 0x8 @@ -1114,12 +1115,69 @@ void icmd_get_dma_support(mfile *mf) } +static int is_pci_device(mfile* mf) +{ + return (mf->flags & MDEVS_I2CM) + || (mf->flags & (MDEVS_CABLE | MDEVS_LINKX_CHIP)) + || (mf->flags & MDEVS_SOFTWARE); +} + +static int is_livefish_device(mfile *mf) +{ + // Make sure to update this table both in mtcr.c & mtcr_ul_com.c ! + static u_int32_t live_fish_ids[][2] = { + {DeviceConnectX4_HwId, DeviceConnectX4_HwId}, + {DeviceConnectX4LX_HwId, DeviceConnectX4LX_HwId}, + {DeviceConnectX5_HwId, DeviceConnectX5_HwId}, + {DeviceConnectX6_HwId, DeviceConnectX6_HwId}, + {DeviceConnectX6DX_HwId, DeviceConnectX6DX_HwId}, + {DeviceConnectX6LX_HwId, DeviceConnectX6LX_HwId}, + {DeviceConnectX7_HwId, DeviceConnectX7_HwId}, + {DeviceBlueField3_HwId, DeviceBlueField3_HwId}, + {DeviceBlueField2_HwId, DeviceBlueField2_HwId}, + {DeviceBlueField_HwId, DeviceBlueField_HwId}, + {DeviceSwitchIB_HwId, DeviceSwitchIB_HwId}, + {DeviceSpectrum_HwId, DeviceSpectrum_HwId}, + {DeviceSwitchIB2_HwId, DeviceSwitchIB2_HwId}, + {DeviceQuantum_HwId, DeviceQuantum_HwId}, + {DeviceQuantum2_HwId, DeviceQuantum2_HwId}, + {DeviceSpectrum2_HwId, DeviceSpectrum2_HwId}, + {DeviceSpectrum3_HwId, DeviceSpectrum3_HwId}, + {DeviceSpectrum4_HwId, DeviceSpectrum4_HwId}, + {0, 0 } + }; + int i = 0; + unsigned int hwdevid = 0; + if (mf->tp == MST_SOFTWARE) { + return 1; + } + int rc = mread4(mf, 0xf0014, &hwdevid); + hwdevid &= 0xffff;//otherwise, BF A1 will fail in the searching (0x00010211) + if (rc == 4) { + while (live_fish_ids[i][0] != 0) { + if (live_fish_ids[i][0] == hwdevid) { + return (mf->dinfo->pci.dev_id == live_fish_ids[i][1]); + } + i++; + } + } + return 0; +} + int icmd_open(mfile *mf) { if (mf->icmd.icmd_opened) { return ME_OK; } +#ifndef __FreeBSD__ + // Currently livefish check is supported for PCI devices & devices that map to CR. + // ICMD is not supported while in livefish (GW is locked). + if ((is_pci_device(mf) || (mf->flags & MDEVS_TAVOR_CR)) && is_livefish_device(mf)) { + return ME_ICMD_NOT_SUPPORTED; + } +#endif + mf->icmd.took_semaphore = 0; mf->icmd.ib_semaphore_lock_supported = 0; // attempt to open via CR-Space From 506abcba1ce3ffc09f7eebb48774fb2691a2c894 Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Mon, 3 Jan 2022 19:46:04 +0200 Subject: [PATCH 020/184] fail downaload files from mellanox server Description: The parser was looking for a number followed by a whitespace. in some OS giving just a number would count as pass but in the case of WINPE (and also windows arm) not getting the full parse raised the error flag. code was updated to expect a number only. (trailing whitespace are still acceptable based on testing) Tested OS: linux (apps-104), windows ARM(winqa-arm-014) Tested devices:None Tested flows: run the command "mlxfwmanager --download C:\tmp" with the following outputs: 3 - pass a - invalid 3a - invalid a3 - invalid 3 - pass 3 - invalid Known gaps (with RM ticket): None Issue: 2883937 Change-Id: I4e8a4552abe8a0b3e42575f6ec12d372f93bb2f3 Signed-off-by: Tomer Tubi --- mlxfwupdate/mlxfwmanager.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mlxfwupdate/mlxfwmanager.cpp b/mlxfwupdate/mlxfwmanager.cpp index b00a257a..d2a4fe82 100644 --- a/mlxfwupdate/mlxfwmanager.cpp +++ b/mlxfwupdate/mlxfwmanager.cpp @@ -2256,17 +2256,16 @@ int handleDownloadRequest(ServerRequest *srq, CmdLineParams &cmd_params, config_ currentMenu->generateMenu(cmd_params, filterOPtions); if (currentMenu->isValid(cmd_params, filterOPtions)) { std::istringstream iss(getline()); - iss >> choice >> std::ws; + iss.clear(); + iss >> choice; if (!iss.eof()) { sleep(1); invalid = true; } - #if !defined(__FreeBSD__) && !(defined(_MSC_VER) && defined(_ARM64_)) if (iss.fail()) { sleep(1); invalid = true; } - #endif print_out("\n"); } else { aNewmenu = currentMenu->getNextMenu(cmd_params, filterOPtions); From 3ceb4a4c520838063a874b49b16ba90e3a329a8b Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Mon, 22 Nov 2021 16:46:44 +0200 Subject: [PATCH 021/184] Wrong error message for CX3 Burn when device in livefish Description: IsSecurityVersionViolated method in base class shouldn't use errmsg to comply with flint flow Tested OS: Linux Tested devices: Cx3Pro Tested flows: Flint burn Known gaps (with RM ticket): N/A Issue: 2864397 Change-Id: Ie7fee9f788328265dc469c0bd1c6795ea5471719 Signed-off-by: ashargorodsk --- mlxfwops/lib/fw_ops.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 606987a9..0154ca10 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -2503,7 +2503,7 @@ bool FwOperations::IsLifeCycleValidInLivefish(chip_type_t) bool FwOperations::IsSecurityVersionViolated(u_int32_t) { - return errmsg("IsSecurityVersionViolated not supported."); + return false; } #if !defined(UEFI_BUILD) && !defined(NO_OPEN_SSL) From f28d051509c2fdf75cdc1f37a245a55da59c6842 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Tue, 23 Nov 2021 10:34:03 +0200 Subject: [PATCH 022/184] Fixing Spectrum4,BF3 to be treated as 7nm (new GW) Description: Tested OS: N/A Tested devices: N/A Tested flows: N/A Known gaps (with RM ticket): N/A Issue: None Change-Id: I8c52aaa860766d3fdf1e294b010bc93c6e2a3179 Signed-off-by: ashargorodsk --- mflash/mflash_dev_capability.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mflash/mflash_dev_capability.c b/mflash/mflash_dev_capability.c index 04c1592e..7b5a3522 100644 --- a/mflash/mflash_dev_capability.c +++ b/mflash/mflash_dev_capability.c @@ -147,11 +147,9 @@ int is_icmdif_supported(mflash *mfl, MfError *status, int *is7NmSuppported) case DeviceConnectX5: case DeviceBlueField: case DeviceBlueField2: - case DeviceBlueField3: case DeviceQuantum: case DeviceSpectrum2: case DeviceSpectrum3: - case DeviceSpectrum4: case DeviceConnectX6: case DeviceConnectX6DX: case DeviceConnectX6LX: @@ -159,8 +157,10 @@ int is_icmdif_supported(mflash *mfl, MfError *status, int *is7NmSuppported) case DeviceGearBoxManager: *is7NmSuppported = 0; return 1; - case DeviceConnectX7: case DeviceQuantum2: + case DeviceSpectrum4: + case DeviceConnectX7: + case DeviceBlueField3: *is7NmSuppported = 1; return 1; default: From 8b943be499842ae45347e35d0419afc5c9e26fed Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Tue, 23 Nov 2021 11:16:55 +0200 Subject: [PATCH 023/184] Reverting part of commit e7fa24c4fdc3e2c118401f447c5981225c34b795 Description: Previously query didn't work on encrypted image/flash so we had to skip it in case of encrypted image/flash Now we can revert this skip since query is supported for encrypted image/flash Tested OS: Linux Tested devices: BB Tested flows: flint burn; flint -ocr burn Known gaps (with RM ticket): N/A Issue: None Change-Id: Ib645fa60c895c4eb187e67f26856bea66a53876f Signed-off-by: ashargorodsk --- mlxfwops/lib/fw_ops.cpp | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 0154ca10..44c16cb0 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -697,35 +697,31 @@ FwOperations* FwOperations::FwOperationsCreate(void *fwHndl, void *info, char *p return FwOperationsCreate(fwParams); } -bool FwOperations::imageDevOperationsCreate(fw_ops_params_t& devParams, fw_ops_params_t& imgParams, FwOperations **devFwOps, FwOperations **imgFwOps, bool ignoreSecurityAttributes, bool ignoreDToc) +bool FwOperations::imageDevOperationsCreate(fw_ops_params_t& devParams, fw_ops_params_t& imgParams, + FwOperations **devFwOps, FwOperations **imgFwOps, + bool ignoreSecurityAttributes, bool ignoreDToc) { *imgFwOps = FwOperationsCreate(imgParams); if (!(*imgFwOps)) { return false; } - bool is_encrypted = false; - if (!(*imgFwOps)->isEncrypted(is_encrypted)) { - return false; - } - if (!is_encrypted) { - if ((*imgFwOps)->FwType() == FIT_FS2) { - devParams.canSkipFwCtrl = true; - *devFwOps = FwOperationsCreate(devParams); - if (!(*devFwOps)) { - return false; - } - return true; - } - - fw_info_t imgQuery; - memset(&imgQuery, 0, sizeof(fw_info_t)); - if (!(*imgFwOps)->FwQuery(&imgQuery, true, false, true, ignoreDToc)) { + if ((*imgFwOps)->FwType() == FIT_FS2) { + devParams.canSkipFwCtrl = true; + *devFwOps = FwOperationsCreate(devParams); + if (!(*devFwOps)) { return false; } - if (imgQuery.fs3_info.security_mode == SM_NONE && ignoreSecurityAttributes == false) { - devParams.noFwCtrl = true; - } + return true; + } + + fw_info_t imgQuery; + memset(&imgQuery, 0, sizeof(fw_info_t)); + if (!(*imgFwOps)->FwQuery(&imgQuery, true, false, true, ignoreDToc)) { + return false; + } + if (imgQuery.fs3_info.security_mode == SM_NONE && ignoreSecurityAttributes == false) { + devParams.noFwCtrl = true; } *devFwOps = FwOperationsCreate(devParams); From 6b750c0756bd468188dd5da742809e2a87a72e5f Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Tue, 4 Jan 2022 13:09:13 +0200 Subject: [PATCH 024/184] [flint|mlxfwops] Calling QuerySecurityFeatures() in case of flash instead of livefish only Description: The original use case was for BB in livefish mode, but we want to support the cases where the secured BB is "opened", meaning token is applied and CR-space is open, dev-secure back-door Also we now support the case where secured CX6DX/CX6LX not in livefish mode are "opened" so we can read life-cycle via CR-space Tested OS: Linux Tested devices: BB Tested flows: flint query; flint -ocr query Known gaps (with RM ticket): N/A Issue: None --- flint/subcommands.cpp | 4 ++-- mlxfwops/lib/fs4_ops.cpp | 51 +++++++++++++++++++++++----------------- mlxfwops/lib/fs4_ops.h | 2 +- mlxfwops/lib/fw_ops.cpp | 4 ++-- mlxfwops/lib/fw_ops.h | 2 +- 5 files changed, 35 insertions(+), 28 deletions(-) diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index 66f21789..344609c4 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -3684,8 +3684,8 @@ FlintStatus QuerySubCommand::printInfo(const fw_info_t& fwInfo, bool fullQuery) } } else { // No fw control - if (ops->IsSecureBootSupported()) { - if (ops->IsLifeCycleValidInLivefish(fwInfo.fw_info.chip_type)) { + if (ops->IsSecureBootSupported()) { // CX6DX onwards + if (ops->IsLifeCycleAccessible(fwInfo.fw_info.chip_type)) { printf("Image Boot Status: %d\n", fwInfo.fs3_info.global_image_status); diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 78aa4c77..df3c952a 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -931,7 +931,7 @@ bool Fs4Operations::encryptedFwQuery(fw_info_t *fwInfo, bool readRom, bool quick memcpy(&(fwInfo->fs3_info), &(_fs3ImgInfo.ext_info), sizeof(fs3_info_t)); fwInfo->fw_type = FwType(); - if (dm_is_livefish_mode(getMfileObj()) == 1) { + if (_ioAccess->is_flash()) { if (!QuerySecurityFeatures()) { return false; } @@ -977,36 +977,43 @@ bool Fs4Operations::FwQuery(fw_info_t *fwInfo, bool readRom, bool isStripedImage return true; } -bool Fs4Operations::IsLifeCycleValidInLivefish(chip_type_t chip_type) +bool Fs4Operations::IsLifeCycleAccessible(chip_type_t chip_type) { - bool isValid; - - switch (chip_type) - { - case CT_BLUEFIELD2: - case CT_CONNECTX6DX: - case CT_CONNECTX6LX: - isValid = false; - break; - default: - isValid = true; - break; + DPRINTF(("Fs4Operations::IsLifeCycleAccessible\n")); + bool res = true; + if (IsLifeCycleSupported()) { + if (dm_is_livefish_mode(getMfileObj())) { + switch (chip_type) + { + case CT_BLUEFIELD2: + case CT_CONNECTX6DX: + case CT_CONNECTX6LX: + // HW bug - life-cycle CR-space is blocked in livefish mode on these devices + res = false; + break; + default: + break; + } + } + } + else { + res = false; } - return isValid; + DPRINTF(("Fs4Operations::IsLifeCycleAccessible res = %s\n", res ? "TRUE" : "FALSE")); + return res; } bool Fs4Operations::QuerySecurityFeatures() { - DPRINTF(("Fs4Operations::QuerySecurityFeatures\n")); - CRSpaceRegisters crSpaceReg(getMfileObj(), _fwImgInfo.ext_info.chip_type); - + DPRINTF(("Fs4Operations::QuerySecurityFeatures _fwImgInfo.ext_info.chip_type = %d\n", _fwImgInfo.ext_info.chip_type)); try { - if (_signatureMngr->IsLifeCycleSupported() && IsLifeCycleValidInLivefish(_fwImgInfo.ext_info.chip_type)) { + if (IsLifeCycleAccessible(_fwImgInfo.ext_info.chip_type)) { + CRSpaceRegisters crSpaceReg(getMfileObj(), _fwImgInfo.ext_info.chip_type); _fs3ImgInfo.ext_info.life_cycle = crSpaceReg.getLifeCycle(); - - if (_fs3ImgInfo.ext_info.life_cycle == GA_SECURED) { - _fs3ImgInfo.ext_info.global_image_status = crSpaceReg.getGlobalImageStatus(); + + if (_fs3ImgInfo.ext_info.life_cycle == GA_SECURED) { + _fs3ImgInfo.ext_info.global_image_status = crSpaceReg.getGlobalImageStatus(); _fs3ImgInfo.ext_info.device_security_version_access_method = GW; _fs3ImgInfo.ext_info.device_security_version_gw = crSpaceReg.getSecurityVersion(); diff --git a/mlxfwops/lib/fs4_ops.h b/mlxfwops/lib/fs4_ops.h index beee5eb8..a0e5fc81 100644 --- a/mlxfwops/lib/fs4_ops.h +++ b/mlxfwops/lib/fs4_ops.h @@ -110,7 +110,7 @@ class Fs4Operations : public Fs3Operations { bool DoAfterBurnJobs(const u_int32_t magic_patter[], ExtBurnParams& burnParams, Flash *flash_access, u_int32_t new_image_start, u_int32_t log2_chunk_size); virtual void FwCleanUp(); - bool IsLifeCycleValidInLivefish(chip_type_t chip_type); + bool IsLifeCycleAccessible(chip_type_t chip_type); bool IsSecurityVersionViolated(u_int32_t image_security_version); protected: diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 44c16cb0..7335ba00 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -2492,9 +2492,9 @@ bool FwOperations::VerifyBranchFormat(const char* vsdString) return false; } -bool FwOperations::IsLifeCycleValidInLivefish(chip_type_t) +bool FwOperations::IsLifeCycleAccessible(chip_type_t) { - return errmsg("IsLifeCycleValidInLivefish not supported."); + return errmsg("IsLifeCycleAccessible not supported."); } bool FwOperations::IsSecurityVersionViolated(u_int32_t) diff --git a/mlxfwops/lib/fw_ops.h b/mlxfwops/lib/fw_ops.h index da294f45..fa9a8445 100644 --- a/mlxfwops/lib/fw_ops.h +++ b/mlxfwops/lib/fw_ops.h @@ -258,7 +258,7 @@ class MLXFWOP_API FwOperations : public FlintErrMsg { static FwVersion createFwVersion(u_int16_t fw_ver0, u_int16_t fw_ver1, u_int16_t fw_ver2); static FwVersion createRunningFwVersion(const fw_info_com_t*); static int getFileSignature(const char *fname); - virtual bool IsLifeCycleValidInLivefish(chip_type_t chip_type); + virtual bool IsLifeCycleAccessible(chip_type_t chip_type); virtual bool IsSecurityVersionViolated(u_int32_t image_security_version); #ifndef UEFI_BUILD static bool CheckPemKeySize(const string privPemFileStr, u_int32_t& keySize); From 9302f2cc21b2cd698d3f06566d99d8663247c13c Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Thu, 9 Dec 2021 12:52:06 +0200 Subject: [PATCH 025/184] Fixing error message in case using hw set command with flint_ext Description: hw set command isn't supported on flint_ext so we fixed the error message accordingly Tested OS: Linux Tested devices: CX6 Tested flows: flint_ext -d /dev/mst/mt4123_pciconf0 -ocr hw set Known gaps (with RM ticket): N/A Issue: 2888565 Change-Id: I0d78699cc59fd181837d34e654138bb0f6a8986a Signed-off-by: ashargorodsk --- flint/subcommands.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index 344609c4..c863c835 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -5290,15 +5290,14 @@ HwSubCommand:: ~HwSubCommand() bool HwSubCommand::verifyParams() { #ifdef EXTERNAL - if (_flintParams.cmd_params.size() != 1) { - reportErr(true, FLINT_CMD_ARGS_ERROR2, _name.c_str(), 1, (int)_flintParams.cmd_params.size()); - return false; - } - if (_flintParams.cmd_params[0] != "query") { reportErr(true, FLINT_INVALID_OPTION_ERROR, _flintParams.cmd_params[0].c_str(), _name.c_str(), "query"); return false; } + if (_flintParams.cmd_params.size() != 1) { + reportErr(true, FLINT_CMD_ARGS_ERROR2, _name.c_str(), 1, (int)_flintParams.cmd_params.size()); + return false; + } #else if (_flintParams.cmd_params.size() > 2 || _flintParams.cmd_params.size() == 0) { reportErr(true, FLINT_CMD_ARGS_ERROR2, _name.c_str(), 2, (int)_flintParams.cmd_params.size()); From d3adeaad0f77ab1454c5d94cc9c03f6408273ce8 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Wed, 15 Dec 2021 19:53:42 +0200 Subject: [PATCH 026/184] enable writing word to image (ww command) Description: Until now we had ww command limited to devices, now it's enabled for images as well Motivation - boot-record encryption issue for Carmel Tested OS: Linux Tested devices: CX6 Tested flows: flint_oem -i carmel.bin ww 0x4f0 0x0000149b flint_oem -ocr -d /dev/mst/mt4123_pciconf0 ww 0x0 0x0 Known gaps (with RM ticket): N/A Issue: 2897873 Change-Id: Ifb8ffcac1e23212a1a4f0d8b9270874f62f60852 Signed-off-by: ashargorodsk --- flint/subcommands.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index c863c835..81f455a1 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -5603,7 +5603,7 @@ WwSubCommand::WwSubCommand() _paramExp = "addr - address of word\n" "data - value of word"; _example = FLINT_NAME " -d " MST_DEV_EXAMPLE1 " ww 0x10008 0x5a445a44"; - _v = Wtv_Dev; + _v = Wtv_Dev_Or_Img; _maxCmdParamNum = 2; _minCmdParamNum = 2; _cmdType = SC_Ww; @@ -5642,7 +5642,7 @@ FlintStatus WwSubCommand::executeCommand() delete[] addrStr; delete[] dataStr; data = __cpu_to_be32(data); - if (!((Flash*)_io)->write(addr, data)) { + if (!_io->write(addr, &data, 0x4)) { reportErr(true, FLINT_FLASH_WRITE_ERROR, _io->err()); return FLINT_FAILED; } From c174ebcb369ba6962740f3ffc88af991c020711c Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Thu, 16 Dec 2021 17:58:00 +0200 Subject: [PATCH 027/184] No power_boot_partial_reset_enable field for CX7/BF3 Description: Tested OS: N/A Tested devices: N/A Tested flows: N/A Known gaps (with RM ticket): N/A Issue: None Change-Id: I8cb1c7fdb6840fc59c6a5445f1dcb407cb364d6e Signed-off-by: ashargorodsk --- mflash/mflash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mflash/mflash.c b/mflash/mflash.c index f100856a..6b8abfec 100644 --- a/mflash/mflash.c +++ b/mflash/mflash.c @@ -2705,6 +2705,8 @@ int mf_set_reset_flash_on_warm_reboot(mflash *mfl) case DeviceSwitchIB2: case DeviceQuantum: case DeviceQuantum2: + case DeviceConnectX7: + case DeviceBlueField3: return MFE_OK; case DeviceSpectrum: case DeviceConnectX4: @@ -2715,11 +2717,9 @@ int mf_set_reset_flash_on_warm_reboot(mflash *mfl) set_reset_bit_offset = 1; break; case DeviceConnectX6: - case DeviceConnectX7: case DeviceConnectX6DX: case DeviceConnectX6LX: case DeviceBlueField2: - case DeviceBlueField3: case DeviceSpectrum2: case DeviceSpectrum3: case DeviceSpectrum4: From 8954429ad40cd3556466471b47194d72850a99a1 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Tue, 4 Jan 2022 13:41:55 +0200 Subject: [PATCH 028/184] [Production Burn][Flint] fails when device in livefish mode [no fw image] Description: Flint was looking for image start to determine whether the device is encrypted in case of production burn. In this case no magic patterns are found on this device, thus an error is returned. There's no need to look for image start in case of devices, only if querying an image. Tested OS: Linux Tested devices: BB, Carmel Tested flows: Flint query Known gaps (with RM ticket): N/A Issue: 2899590 --- mlxfwops/lib/fs4_ops.cpp | 67 ++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index df3c952a..9f040197 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -133,58 +133,48 @@ bool Fs4Operations::IsEncryptedDevice(bool& is_encrypted) //* Determine if encrypted by reading ITOC header magic-pattern bool Fs4Operations::IsEncryptedImage(bool& is_encrypted) { + DPRINTF(("Fs4Operations::IsEncryptedImage\n")); struct image_layout_itoc_header itocHeader; u_int8_t buffer[TOC_HEADER_SIZE]; - u_int32_t image_start[CNTX_START_POS_SIZE] = {0}; - u_int32_t image_num = 0; is_encrypted = false; - //* Check if valid image exists - FindAllImageStart(_ioAccess, image_start, &image_num, _fs4_magic_pattern); - - if (image_num == 1) { - _fwImgInfo.imgStart = image_start[0]; - DPRINTF(("Fs4Operations::IsEncryptedImage - _fwImgInfo.imgStart = 0x%x\n", _fwImgInfo.imgStart)); + if (!_is_hw_ptrs_initialized) { + if (!initHwPtrs(true)) { + DPRINTF(("Fs4Operations::IsEncryptedImage HW pointers not found")); + return false; + } + } - u_int32_t itoc_header_addr = _fwImgInfo.imgStart + _itoc_ptr; - READBUF((*_ioAccess), itoc_header_addr, buffer, TOC_HEADER_SIZE, "ITOC Header"); + READBUF((*_ioAccess), _itoc_ptr, buffer, TOC_HEADER_SIZE, "ITOC Header"); + image_layout_itoc_header_unpack(&itocHeader, buffer); + if (!CheckTocSignature(&itocHeader, ITOC_ASCII)) { // Check first location of ITOC header magic-pattern + _itoc_ptr += FS4_DEFAULT_SECTOR_SIZE; + READBUF((*_ioAccess), _itoc_ptr, buffer, TOC_HEADER_SIZE, "ITOC Header"); image_layout_itoc_header_unpack(&itocHeader, buffer); - if (!CheckTocSignature(&itocHeader, ITOC_ASCII)) { // Check first location of ITOC header magic-pattern - itoc_header_addr += FS4_DEFAULT_SECTOR_SIZE; - READBUF((*_ioAccess), itoc_header_addr, buffer, TOC_HEADER_SIZE, "ITOC Header"); - image_layout_itoc_header_unpack(&itocHeader, buffer); - if (!CheckTocSignature(&itocHeader, ITOC_ASCII)) { // Check second location of ITOC header magic-pattern - is_encrypted = true; - } + if (!CheckTocSignature(&itocHeader, ITOC_ASCII)) { // Check second location of ITOC header magic-pattern + is_encrypted = true; } - } - else { - DPRINTF(("Fs4Operations::IsEncryptedImage No valid image found --> not encrypted")); - } + } + return true; } bool Fs4Operations::isEncrypted(bool& is_encrypted) { - bool rc = false; - - //* Init HW pointers - if (!_is_hw_ptrs_initialized) { - if (!initHwPtrs(true)) { - DPRINTF(("Fs4Operations::IsEncryptedImage HW pointers not found")); - return false; - } - } + DPRINTF(("Fs4Operations::isEncrypted\n")); + bool res = false; if (_ioAccess->is_flash()) { - rc = IsEncryptedDevice(is_encrypted); + DPRINTF(("Fs4Operations::isEncrypted call IsEncryptedDevice\n")); + res = IsEncryptedDevice(is_encrypted); } else { - rc = IsEncryptedImage(is_encrypted); + DPRINTF(("Fs4Operations::isEncrypted call IsEncryptedImage\n")); + res = IsEncryptedImage(is_encrypted); } - DPRINTF(("Fs4Operations::isEncrypted res = %s, rc = %d\n", is_encrypted ? "TRUE" : "FALSE", rc)); - return rc; + DPRINTF(("Fs4Operations::isEncrypted is_encrypted = %s, res = %s\n", is_encrypted ? "TRUE" : "FALSE", res ? "TRUE" : "FALSE")); + return res; } bool Fs4Operations::CheckTocSignature(struct image_layout_itoc_header *itoc_header, u_int32_t first_signature) @@ -916,6 +906,11 @@ bool Fs4Operations::parseDevData(bool readRom, bool quickQuery, bool verbose) { bool Fs4Operations::encryptedFwQuery(fw_info_t *fwInfo, bool readRom, bool quickQuery, bool ignoreDToc, bool verbose) { + if (!initHwPtrs(true)) { + DPRINTF(("Fs4Operations::IsEncryptedImage HW pointers not found")); + return false; + } + if (!encryptedFwReadImageInfoSection()) { return errmsg("%s", err()); } @@ -3645,6 +3640,10 @@ bool Fs4Operations::storeSecureBootSignaturesInSection(vector boot_sig } bool Fs4Operations::initHwPtrs(bool isVerify) { + if (!getImgStart()) { // Set _fwImgInfo.imgStart with the image start address + return false; + } + if (!getExtendedHWAravaPtrs((VerifyCallBack)NULL, _ioAccess, false, isVerify)) { return errmsg("initHwPtrs: HW pointers not found.\n"); } From 5d04bae3fe66743374db3f76a267cd7521e48465 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Mon, 20 Dec 2021 12:55:12 +0200 Subject: [PATCH 029/184] Fixing new gw write status register function Description: Only in case of bytes_num=2 we write 2 to data_size field in flash gw, but there are scenarios where bytes_num=1 so we left the data_size=0x0 so the write failed Tested OS: Linux Tested devices: Carmel Tested flows: flint hw set/query Known gaps (with RM ticket): N/A Issue: 2901723 Change-Id: I4a428adc8b509b808105257bcebeb999fd683b12 Signed-off-by: ashargorodsk --- mflash/mflash_new_gw.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mflash/mflash_new_gw.c b/mflash/mflash_new_gw.c index b1f6bc21..7cec0916 100644 --- a/mflash/mflash_new_gw.c +++ b/mflash/mflash_new_gw.c @@ -268,9 +268,8 @@ int new_gw_spi_write_status_reg(mflash *mfl, u_int32_t status_reg, u_int8_t writ } // push status reg to upper bytes status_reg = status_reg << ((bytes_num == 2) ? 16 : 24); - if (bytes_num == 2) { - gw_cmd = MERGE(gw_cmd, 2, HBO_MSIZE, HBS_NEW_GW_MSIZE); - } + gw_cmd = MERGE(gw_cmd, bytes_num, HBO_MSIZE, HBS_NEW_GW_MSIZE); + DPRINTF(("new_gw_spi_write_status_reg: gw_cmd=%08x status_reg=%08x\n", gw_cmd, status_reg)); rc = new_gw_exec_cmd_set(mfl, gw_cmd, &status_reg, 1, (u_int32_t*)NULL, "Write-Status-Register"); // wait for flash to write the register if (mfl->attr.vendor == FV_S25FLXXXX && mfl->attr.type == FMT_S25FLXXXL) { // New CYPRESS From 1486d31c740f9da9a138c8ad954d074c71b45b2b Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Tue, 4 Jan 2022 13:49:44 +0200 Subject: [PATCH 030/184] [flint] can't perform swreset on QTM2 inband devices Description: swreset is being done in the flash class object, but for secured BB no flash access object is being created. Moved the swreset logic to fw_ops, mfile for low-lever swreset logic will be created according to the concrete object (fsctrl or fs4/3 etc). Tested OS: linux Tested devices: BB (managed, un-managed, pci, ib) Tested flows: flint swreset Known gaps (with RM ticket): N/A Issue: 2900662 --- flint/subcommands.cpp | 58 ++++++++++++++++++++++++++++++++++ flint/subcommands.h | 2 +- mflash/mflash.c | 24 -------------- mflash/mflash.h | 3 +- mflash/mflash_dev_capability.c | 41 ------------------------ mflash/mflash_dev_capability.h | 1 - mlxfwops/lib/flint_io.cpp | 12 ------- mlxfwops/lib/flint_io.h | 8 ----- mlxfwops/lib/fs4_ops.cpp | 2 +- mlxfwops/lib/fw_ops.cpp | 20 +++++++++--- 10 files changed, 76 insertions(+), 95 deletions(-) diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index 81f455a1..e33f5bd4 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -4024,18 +4024,76 @@ bool SwResetSubCommand::verifyParams() FlintStatus SwResetSubCommand::executeCommand() { + mfile* mf = NULL; + dm_dev_id_t devid_type; + u_int32_t devid, revid; + if (preFwOps() == FLINT_FAILED) { return FLINT_FAILED; } + + mf = _fwOps->getMfileObj(); + int rc = dm_get_device_id(mf, &devid_type, &devid, &revid); + if (rc != 0) { + reportErr(true, "can't get device Id.\n"); + return FLINT_FAILED; + } + (void)devid; + (void)revid; + + if (!IsDeviceSupported(devid_type)) { + return FLINT_FAILED; + } + printf("-I- Sending reset command to device %s ...\n", _flintParams.device.c_str()); if (!_fwOps->FwSwReset()) { reportErr(true, FLINT_SWRESET_ERROR, _fwOps->err()); return FLINT_FAILED; } printf("-I- Reset command accepted by the device.\n"); + return FLINT_SUCCESS; } +bool SwResetSubCommand::IsDeviceSupported(dm_dev_id_t dev_id) +{ + switch (dev_id) { + case DeviceInfiniScaleIV: + case DeviceSwitchX: + case DeviceSwitchIB: + case DeviceSwitchIB2: + case DeviceQuantum: + case DeviceQuantum2: + return true; + case DeviceConnectX2: + case DeviceConnectX3: + case DeviceConnectX3Pro: + case DeviceConnectIB: + case DeviceSpectrum: + case DeviceConnectX4: + case DeviceConnectX4LX: + case DeviceConnectX5: + case DeviceBlueField: + case DeviceBlueField2: + case DeviceBlueField3: + case DeviceConnectX6: + case DeviceConnectX6DX: + case DeviceConnectX6LX: + case DeviceConnectX7: + case DeviceSpectrum2: + case DeviceSpectrum3: + case DeviceSpectrum4: + case DeviceSecureHost: + case DeviceGearBox: + case DeviceGearBoxManager: + reportErr(true, "The device type %d is not supported.\n", dev_id); + return false; + default: + reportErr(true, "Unknown device type - %d.\n", dev_id); + return false; + } +} + /*********************** * Class: BromSubCommand **********************/ diff --git a/flint/subcommands.h b/flint/subcommands.h index 5bf40c6b..379c7a89 100644 --- a/flint/subcommands.h +++ b/flint/subcommands.h @@ -362,7 +362,7 @@ class ImageReactivationSubCommand : public SubCommand class SwResetSubCommand : public SubCommand { private: - + bool IsDeviceSupported(dm_dev_id_t dev_id); public: SwResetSubCommand(); ~SwResetSubCommand(); diff --git a/mflash/mflash.c b/mflash/mflash.c index 6b8abfec..bacf509f 100644 --- a/mflash/mflash.c +++ b/mflash/mflash.c @@ -2399,30 +2399,6 @@ int mf_get_attr(mflash *mfl, flash_attr *attr) return MFE_OK; } -int mf_sw_reset(mflash *mfl) -{ - MfError status; - int supports_sw_reset = is_supports_sw_reset(mfl, &status); - if (status != MFE_OK) { - return status; - } - if (!supports_sw_reset) { - return MFE_UNSUPPORTED_DEVICE; - } - if (msw_reset(mfl->mf)) { - if (errno == EPERM) { - return MFE_CMD_SUPPORTED_INBAND_ONLY; - } else if (errno == OP_NOT_SUPPORTED) { - return MFE_MANAGED_SWITCH_NOT_SUPPORTED; - } else { - - return MFE_ERROR; - } - } - - return MFE_OK; -} - const char* mf_err2str(int err_code) { diff --git a/mflash/mflash.h b/mflash/mflash.h index 6bf0be14..227335de 100644 --- a/mflash/mflash.h +++ b/mflash/mflash.h @@ -183,8 +183,7 @@ int mf_cr_read(mflash *mfl, u_int32_t cr_addr, u_int32_t *data); int mf_cr_write(mflash *mfl, u_int32_t cr_addr, u_int32_t data); int mf_update_boot_addr(mflash *mfl, u_int32_t boot_addr); -// Software reset the target device. Currently supported for InfiniScale4 switch via IB interface only. -int mf_sw_reset(mflash *mfl); + // // mf_get_attr(): Returns the flash_attr struct // diff --git a/mflash/mflash_dev_capability.c b/mflash/mflash_dev_capability.c index 7b5a3522..3a090bfa 100644 --- a/mflash/mflash_dev_capability.c +++ b/mflash/mflash_dev_capability.c @@ -170,44 +170,3 @@ int is_icmdif_supported(mflash *mfl, MfError *status, int *is7NmSuppported) } } -//When (*status != MFE_OK) return value is undefined -int is_supports_sw_reset(mflash *mfl, MfError *status) -{ - *status = MFE_OK; - - switch (mfl->dm_dev_id) { - case DeviceInfiniScaleIV: - case DeviceSwitchX: - case DeviceSwitchIB: - case DeviceSwitchIB2: - case DeviceQuantum: - case DeviceQuantum2: - return 1; - case DeviceConnectX2: - case DeviceConnectX3: - case DeviceConnectX3Pro: - case DeviceConnectIB: - case DeviceSpectrum: - case DeviceConnectX4: - case DeviceConnectX4LX: - case DeviceConnectX5: - case DeviceBlueField: - case DeviceBlueField2: - case DeviceBlueField3: - case DeviceConnectX6: - case DeviceConnectX6DX: - case DeviceConnectX6LX: - case DeviceConnectX7: - case DeviceSpectrum2: - case DeviceSpectrum3: - case DeviceSpectrum4: - case DeviceSecureHost: - case DeviceGearBox: - case DeviceGearBoxManager: - return 0; - default: - *status = MFE_UNSUPPORTED_DEVICE; - fprintf(stderr, "The device type %d is not supported.\n", mfl->dm_dev_id); - return 0; - } -} diff --git a/mflash/mflash_dev_capability.h b/mflash/mflash_dev_capability.h index f317f902..a9ff4f31 100644 --- a/mflash/mflash_dev_capability.h +++ b/mflash/mflash_dev_capability.h @@ -57,7 +57,6 @@ int is_four_byte_address_needed(mflash *mfl, MfError *status); int is_flash_enable_needed(mflash *mfl, MfError *status); int is_icmdif_supported(mflash *mfl, MfError *status, int* is7NmSuppported); -int is_supports_sw_reset(mflash *mfl, MfError *status); #endif /* USER_MFLASH_MFLASH_DEV_CAPABILITY_H_ */ diff --git a/mlxfwops/lib/flint_io.cpp b/mlxfwops/lib/flint_io.cpp index bae2e111..608e4a3b 100644 --- a/mlxfwops/lib/flint_io.cpp +++ b/mlxfwops/lib/flint_io.cpp @@ -807,18 +807,6 @@ bool Flash::disable_hw_access(u_int64_t key) } -bool Flash::sw_reset() -{ - int rc = mf_sw_reset(_mfl); - if (rc != MFE_OK) { - if (rc == MFE_UNSUPPORTED_DEVICE) { - return errmsg("operation supported only for InfiniScale4 switch, SwitchX and SwitchIB over IB interface"); - } - return errmsg("%s (%s)", errno == 0 ? "" : strerror(errno), mf_err2str(rc)); - } - return true; -} - bool Flash::get_attr(ext_flash_attr_t& attr) { diff --git a/mlxfwops/lib/flint_io.h b/mlxfwops/lib/flint_io.h index 9a368b13..6203ead2 100644 --- a/mlxfwops/lib/flint_io.h +++ b/mlxfwops/lib/flint_io.h @@ -143,7 +143,6 @@ class MLXFWOP_API FBase : public FlintErrMsg { virtual bool set_flash_utilization(bool, int) = 0; virtual int get_flash_working_mode() = 0; - virtual bool sw_reset() = 0; virtual bool set_no_flash_verify(bool) = 0; virtual u_int32_t get_sector_size() = 0; @@ -326,11 +325,6 @@ class MLXFWOP_API FImage : public FBase { check_uefi_build(); return false; } - virtual bool sw_reset() - { - check_uefi_build(); - return false; - } virtual bool set_no_flash_verify(bool) { check_uefi_build(); @@ -453,8 +447,6 @@ class MLXFWOP_API Flash : public FBase { u_int8_t get_cr_space_locked() { return _cr_space_locked; } bool get_ignore_cache_replacment() { return _ignore_cache_replacement; } - virtual bool sw_reset(); - virtual bool set_no_flash_verify(bool val); static void get_flash_list(char *flash_list, int buffer_size) { return mf_flash_list(flash_list, buffer_size); } diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 9f040197..85d5e782 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -907,7 +907,7 @@ bool Fs4Operations::parseDevData(bool readRom, bool quickQuery, bool verbose) { bool Fs4Operations::encryptedFwQuery(fw_info_t *fwInfo, bool readRom, bool quickQuery, bool ignoreDToc, bool verbose) { if (!initHwPtrs(true)) { - DPRINTF(("Fs4Operations::IsEncryptedImage HW pointers not found")); + DPRINTF(("Fs4Operations::encryptedFwQuery HW pointers not found")); return false; } diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 7335ba00..1b93ee1c 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -59,6 +59,12 @@ #endif //NO_OPEN_SSL #endif //UEFI_BUILD +#ifndef __WIN__ + #define OP_NOT_SUPPORTED EOPNOTSUPP +#else // __WIN__ + #define OP_NOT_SUPPORTED EINVAL +#endif // __WIN__ + #define BAD_CRC_MSG "Bad CRC." extern const char *g_sectNames[]; @@ -1452,12 +1458,16 @@ bool FwOperations::CheckFwVersion(FwOperations &imageOps, bool FwOperations::FwSwReset() { - if (!_ioAccess->is_flash()) { - return errmsg("operation supported only for switch devices: InfiniScaleIV SwitchX and SwitchIB over an IB interface"); - } - if (!_ioAccess->sw_reset()) { - return errmsg("%s", _ioAccess->err()); + if (msw_reset(getMfileObj())) { + if (errno == EPERM) { + return errmsg("operation supported only for IB switches."); + } else if (errno == OP_NOT_SUPPORTED) { + return errmsg("operation supported only for un-managed switches."); + } else { + return errmsg("operation failed, errno - %d.", errno); + } } + return true; } From 759c481f689fe8b87cde2ec53d2d28eaf6b86269 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Thu, 30 Dec 2021 17:20:47 +0200 Subject: [PATCH 031/184] Fixing using uninitilized chip_type to determine if HCA device Description: Tested OS: Linux Tested devices: Carmel Tested flows: flint query full Known gaps (with RM ticket): N/A Issue: None Change-Id: I0858ead5a525a0d238c37ba13c74808203f4751d Signed-off-by: ashargorodsk --- mlxfwops/lib/fsctrl_ops.cpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/mlxfwops/lib/fsctrl_ops.cpp b/mlxfwops/lib/fsctrl_ops.cpp index 51f1afe4..86fcccd7 100644 --- a/mlxfwops/lib/fsctrl_ops.cpp +++ b/mlxfwops/lib/fsctrl_ops.cpp @@ -154,6 +154,12 @@ bool FsCtrlOperations::FsIntQuery() strcpy(_fwImgInfo.ext_info.product_ver, fwQuery.product_ver); } + // get chip type and device sw id + const u_int32_t *swId = (u_int32_t*) NULL; + if (!getInfoFromHwDevid(fwQuery.hw_dev_id, _fwImgInfo.ext_info.chip_type, &swId)) { + return false; + } + // Copy version_string to fw version and VSD to branch ver, only for switches fw version if (!IS_HCA(_fwImgInfo.ext_info.chip_type)) { ExtractSwitchFWVersion(fwQuery); @@ -161,10 +167,6 @@ bool FsCtrlOperations::FsIntQuery() // if nextBootFwVer, only fw version is needed and chip type, return. if (nextBootFwVer) { - const u_int32_t *swId = (u_int32_t*)NULL; - if (!getInfoFromHwDevid(fwQuery.hw_dev_id, _fwImgInfo.ext_info.chip_type, &swId)) { - return false; - } return true; } @@ -183,11 +185,7 @@ bool FsCtrlOperations::FsIntQuery() _hwDevId = fwQuery.hw_dev_id; _fwImgInfo.ext_info.dev_rev = fwQuery.rev_id; _fwImgInfo.ext_info.is_failsafe = true; - // get chip type and device sw id, from device/image - const u_int32_t *swId = (u_int32_t*) NULL; - if (!getInfoFromHwDevid(fwQuery.hw_dev_id, _fwImgInfo.ext_info.chip_type, &swId)) { - return false; - } + _fsCtrlImgInfo.security_mode = (security_mode_t) (SMM_MCC_EN | ((fwQuery.security_type.debug_fw == 1) ? SMM_DEBUG_FW : 0) | @@ -514,12 +512,6 @@ bool FsCtrlOperations::VerifyAllowedParams(ExtBurnParams &burnParams, bool isSec bool FsCtrlOperations::_createImageOps(FwOperations** imageOps) { - std::vector compsMap; - if (!_fwCompsAccess->getFwComponents(compsMap, false)) { - - return errmsg("Failed to get the FW Components MAP, err[%d]", _fwCompsAccess->getLastError()); - } - u_int32_t imageSize = 0; if (!ReadBootImage(NULL, &imageSize)) { return errmsg("Failed to get boot image size"); From ed1b0d10f65c871a1b0bf5a46eea05acc2c4c9d4 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Tue, 4 Jan 2022 14:26:18 +0200 Subject: [PATCH 032/184] [flint] Fixing DMA fallback to be executed on all operations Description: Previously fallback was enabled for burn(write) only, now it's enabled for any access using MCC flow Tested OS: Linux Tested devices: Carmel Tested flows: flint rb Known gaps (with RM ticket): N/A Issue: 2911585 --- fw_comps_mgr/fw_comps_mgr.cpp | 75 ++++++++++++--------- fw_comps_mgr/fw_comps_mgr.h | 22 ++++-- fw_comps_mgr/fw_comps_mgr_direct_access.cpp | 8 +-- fw_comps_mgr/fw_comps_mgr_dma_access.cpp | 17 ++--- 4 files changed, 72 insertions(+), 50 deletions(-) diff --git a/fw_comps_mgr/fw_comps_mgr.cpp b/fw_comps_mgr/fw_comps_mgr.cpp index ec1375a6..a71d475e 100644 --- a/fw_comps_mgr/fw_comps_mgr.cpp +++ b/fw_comps_mgr/fw_comps_mgr.cpp @@ -660,9 +660,28 @@ bool FwCompsMgr::accessComponent(u_int32_t offset, u_int32_t size, u_int32_t data[], access_type_t access, - ProgressCallBackAdvSt *progressFuncAdv) + ProgressCallBackAdvSt *progressFuncAdv, + controlFsmArgs* lastFsmCommandArgs) { bool bRes = _accessObj->accessComponent(_updateHandle, offset, size, data, access, _currComponentStr, progressFuncAdv); + if (!bRes && lastFsmCommandArgs != NULL && isDMAAccess()) { + printf("\nBurning with DMA has failed, switching to Register-Access burn.\n"); + bRes = fallbackToRegisterAccess(); + + if (bRes) { + if (!controlFsm(FSM_CMD_CANCEL, FSMST_LOCKED)) { + DPRINTF(("Cancel instruction to FW component has failed!\n")); + return false; + } + if (!controlFsm(lastFsmCommandArgs->command, lastFsmCommandArgs->expectedState, lastFsmCommandArgs->size, + lastFsmCommandArgs->currentState, lastFsmCommandArgs->progressFuncAdv, lastFsmCommandArgs->reg_access_timeout)) { + DPRINTF(("FSM reinitialize for fallback has failed!\n")); + return false; + } + + bRes = _accessObj->accessComponent(_updateHandle, offset, size, data, access, _currComponentStr, progressFuncAdv); + } + } setLastFirmwareError(_accessObj->getLastFirmwareError()); setLastRegisterAccessStatus(_accessObj->getLastRegisterAccessStatus()); @@ -674,7 +693,7 @@ bool FwCompsMgr::isDMAAccess() return (dynamic_cast(_accessObj) != NULL); } -bool FwCompsMgr::fallbackToDirectAccess() +bool FwCompsMgr::fallbackToRegisterAccess() { bool bRes = false; AbstractComponentAccess* newAccessObj = NULL; @@ -1290,8 +1309,10 @@ bool FwCompsMgr::readComponent(FwComponent::comps_ids_t compType, FwComponent& f return false; } _currComponentStr = FwComponent::getCompIdStr(compType); - if (!accessComponent(0, compSize, (u_int32_t *)(data.data()), MCDA_READ_COMP, progressFuncAdv)) { - //_lastError = FWCOMPS_READ_COMP_FAILED; + controlFsmArgs fsmReadCommand; + fsmReadCommand.command = readPending ? FSM_CMD_READ_PENDING_COMPONENT : FSM_CMD_READ_COMPONENT; + fsmReadCommand.expectedState = FSMST_UPLOAD; + if (!accessComponent(0, compSize, (u_int32_t *)(data.data()), MCC_READ_COMP, progressFuncAdv, &fsmReadCommand)) { return false; } if (!controlFsm(FSM_CMD_RELEASE_UPDATE_HANDLE)) { @@ -1374,7 +1395,7 @@ bool FwCompsMgr::burnComponents(std::vector& comps, _currCompQuery = &(_compsQueryMap[component]); if (!_currCompQuery->valid) { _lastError = FWCOMPS_COMP_NOT_SUPPORTED; - DPRINTF(("MCC/MCDA flow for component %x is not supported!\n", component)); + DPRINTF(("MCC flow for component %d is not supported!\n", component)); return false; } _componentIndex = _currCompQuery->comp_status.component_index; @@ -1383,29 +1404,15 @@ bool FwCompsMgr::burnComponents(std::vector& comps, return false; } _currComponentStr = FwComponent::getCompIdStr(comps[i].getType()); - if (!accessComponent(0, comps[i].getSize(), (u_int32_t *)(comps[i].getData().data()), MCDA_WRITE_COMP, progressFuncAdv)) { - bool bRes = false; - if (isDMAAccess()) { - printf("\nBurning with DMA has failed, switching to Direct Access burn.\n"); - bRes = fallbackToDirectAccess(); - - if (bRes) { - if (!controlFsm(FSM_CMD_CANCEL, FSMST_LOCKED)) { - DPRINTF(("Cancel instruction to FW component has failed!\n")); - return false; - } - if (!controlFsm(FSM_CMD_UPDATE_COMPONENT, FSMST_DOWNLOAD, comps[i].getSize(), FSMST_INITIALIZE, progressFuncAdv)) { - DPRINTF(("Initializing downloading FW component has failed!\n")); - return false; - } - - bRes = accessComponent(0, comps[i].getSize(), (u_int32_t *)(comps[i].getData().data()), MCDA_WRITE_COMP, progressFuncAdv); - } - } - if (!bRes) { - DPRINTF(("Downloading FW component has failed!\n")); - return false; - } + controlFsmArgs fsmUpdateCommand; + fsmUpdateCommand.command = FSM_CMD_UPDATE_COMPONENT; + fsmUpdateCommand.expectedState = FSMST_DOWNLOAD; + fsmUpdateCommand.size = comps[i].getSize(); + fsmUpdateCommand.currentState = FSMST_INITIALIZE; + fsmUpdateCommand.progressFuncAdv = progressFuncAdv; + if (!accessComponent(0, comps[i].getSize(), (u_int32_t *)(comps[i].getData().data()), MCC_WRITE_COMP, progressFuncAdv, &fsmUpdateCommand)) { + DPRINTF(("Downloading FW component has failed!\n")); + return false; } if (!controlFsm(FSM_CMD_VERIFY_COMPONENT, FSMST_LOCKED, 0, FSMST_NA, progressFuncAdv)) { DPRINTF(("Verifying FW component has failed!\n")); @@ -2102,13 +2109,17 @@ bool FwCompsMgr::readBlockFromComponent(FwComponent::comps_ids_t compId, if (!controlFsm(FSM_CMD_LOCK_UPDATE_HANDLE, FSMST_LOCKED)) { return false; } + controlFsmArgs fsmReadCommand; + fsmReadCommand.command = FSM_CMD_READ_PENDING_COMPONENT; + fsmReadCommand.expectedState = FSMST_UPLOAD; if (!controlFsm(FSM_CMD_READ_PENDING_COMPONENT, FSMST_UPLOAD)) { + fsmReadCommand.command = FSM_CMD_READ_COMPONENT; if (!controlFsm(FSM_CMD_READ_COMPONENT, FSMST_UPLOAD)) { _lastError = FWCOMPS_READ_COMP_FAILED; return false; } } - if (!accessComponent(offset, size, (u_int32_t *)(data.data()), MCDA_READ_COMP)) { + if (!accessComponent(offset, size, (u_int32_t *)(data.data()), MCC_READ_COMP, NULL, &fsmReadCommand)) { return false; } if (!controlFsm(FSM_CMD_RELEASE_UPDATE_HANDLE)) { @@ -2116,9 +2127,9 @@ bool FwCompsMgr::readBlockFromComponent(FwComponent::comps_ids_t compId, } } else { - _lastError = FWCOMPS_READ_COMP_NOT_SUPPORTED; - DPRINTF(("readBlockFromComponent : RD EN is 0 for component index %u compId %s \n", _componentIndex, FwComponent::getCompIdStr(compId))); - return false; + _lastError = FWCOMPS_READ_COMP_NOT_SUPPORTED; + DPRINTF(("readBlockFromComponent : RD EN is 0 for component index %u compId %s \n", _componentIndex, FwComponent::getCompIdStr(compId))); + return false; } return true; } diff --git a/fw_comps_mgr/fw_comps_mgr.h b/fw_comps_mgr/fw_comps_mgr.h index b2ac69f2..7a20b35a 100644 --- a/fw_comps_mgr/fw_comps_mgr.h +++ b/fw_comps_mgr/fw_comps_mgr.h @@ -131,8 +131,8 @@ typedef struct { } comp_query_st; typedef enum { - MCDA_READ_COMP = 0x0, - MCDA_WRITE_COMP + MCC_READ_COMP = 0x0, + MCC_WRITE_COMP } access_type_t; typedef struct mac_guid { @@ -403,6 +403,15 @@ class FwCompsMgr { FSMST_NA = 0xFF, } fsm_state_t; + typedef struct { + fsm_command_t command; + fsm_state_t expectedState = FSMST_NA; + u_int32_t size = 0; + fsm_state_t currentState = FSMST_NA; + ProgressCallBackAdvSt *progressFuncAdv = (ProgressCallBackAdvSt*)NULL; + u_int32_t reg_access_timeout = 0; + } controlFsmArgs; + typedef enum { MCC_ERRCODE_OK = 0x0, MCC_ERRCODE_ERROR = 0x1, @@ -453,7 +462,8 @@ class FwCompsMgr { u_int32_t size, u_int32_t data[], access_type_t access, - ProgressCallBackAdvSt *progressFuncAdv = (ProgressCallBackAdvSt *)NULL); + ProgressCallBackAdvSt *progressFuncAdv = (ProgressCallBackAdvSt *)NULL, + controlFsmArgs* lastFsmCommandArgs = NULL); bool queryComponentStatus(u_int32_t componentIndex, comp_status_st *query); @@ -463,9 +473,9 @@ class FwCompsMgr { component_version_st *cmpVer); bool controlFsm(fsm_command_t command, - fsm_state_t expStatus = FSMST_NA, + fsm_state_t expectedState = FSMST_NA, u_int32_t size = 0, - fsm_state_t currState = FSMST_NA, + fsm_state_t currentState = FSMST_NA, ProgressCallBackAdvSt *progressFuncAdv = (ProgressCallBackAdvSt *)NULL, u_int32_t reg_access_timeout = 0); @@ -500,7 +510,7 @@ class FwCompsMgr { bool extractMacsGuids(fwInfoT *fwQuery); void extractRomInfo(mgirReg *mgir, fwInfoT *fwQuery); bool isDMAAccess(); - bool fallbackToDirectAccess(); + bool fallbackToRegisterAccess(); std::vector _compsQueryMap; bool _refreshed; diff --git a/fw_comps_mgr/fw_comps_mgr_direct_access.cpp b/fw_comps_mgr/fw_comps_mgr_direct_access.cpp index 50a662d3..3ede8411 100644 --- a/fw_comps_mgr/fw_comps_mgr_direct_access.cpp +++ b/fw_comps_mgr/fw_comps_mgr_direct_access.cpp @@ -66,9 +66,9 @@ bool DirectComponentAccess::accessComponent(u_int32_t updateHandle, u_int32_t of char stage[MAX_MSG_SIZE] = { 0 }; int progressPercentage = -1; if (progressFuncAdv && progressFuncAdv->func) { - snprintf(stage, MAX_MSG_SIZE, "%s %s component", (access == MCDA_READ_COMP) ? "Reading" : "Writing", currComponentStr); + snprintf(stage, MAX_MSG_SIZE, "%s %s component", (access == MCC_READ_COMP) ? "Reading" : "Writing", currComponentStr); } - int maxDataSize = mget_max_reg_size(_mf, (access == MCDA_READ_COMP) ? MACCESS_REG_METHOD_GET : MACCESS_REG_METHOD_SET) + int maxDataSize = mget_max_reg_size(_mf, (access == MCC_READ_COMP) ? MACCESS_REG_METHOD_GET : MACCESS_REG_METHOD_SET) - sizeof(accessData); if (maxDataSize > MAX_REG_DATA) { maxDataSize = MAX_REG_DATA; @@ -78,7 +78,7 @@ bool DirectComponentAccess::accessComponent(u_int32_t updateHandle, u_int32_t of } std::vector dataToRW(maxDataSize, 0); while (leftSize > 0) { - DPRINTF(("0x%x bytes left to %s\n", leftSize, access == MCDA_READ_COMP ? "read" : "burn")); + DPRINTF(("0x%x bytes left to %s\n", leftSize, access == MCC_READ_COMP ? "read" : "burn")); memset(&accessData, 0, sizeof(mcdaReg)); memcpy(accessData.data, dataToRW.data(), sizeof(accessData.data)); @@ -87,7 +87,7 @@ bool DirectComponentAccess::accessComponent(u_int32_t updateHandle, u_int32_t of accessData.size = leftSize > maxDataSize ? maxDataSize : leftSize; mft_signal_set_handling(1); - if (access == MCDA_READ_COMP) { + if (access == MCC_READ_COMP) { reg_access_status_t rc = reg_access_mcda(_mf, REG_ACCESS_METHOD_GET, &accessData); _manager->deal_with_signal(); if (rc) { diff --git a/fw_comps_mgr/fw_comps_mgr_dma_access.cpp b/fw_comps_mgr/fw_comps_mgr_dma_access.cpp index 2cad525b..6fdda19a 100644 --- a/fw_comps_mgr/fw_comps_mgr_dma_access.cpp +++ b/fw_comps_mgr/fw_comps_mgr_dma_access.cpp @@ -111,7 +111,7 @@ bool DMAComponentAccess::prepareParameters(u_int32_t updateHandle, mcddReg* acce accessData->mailbox_page_phys_addr_lsb = EXTRACT64(mailbox_page.dma_address, 0, 32); accessData->mailbox_page_phys_addr_msb = EXTRACT64(mailbox_page.dma_address, 32, 32); int currentOffset = data_size - leftSize; - if (access == MCDA_WRITE_COMP) { + if (access == MCC_WRITE_COMP) { u_int32_t* data_ptr = (u_int32_t*)page.virtual_address; for (int i = 0; i < accessData->size / 4; i++) { *data_ptr = ___my_swab32(data[(currentOffset) / 4 + i]); @@ -173,6 +173,7 @@ bool DMAComponentAccess::isBMESet(mfile* mf) { } #endif + DPRINTF(("DMAComponentAccess::isBMESet res = %s\n", res ? "TRUE" : "FALSE")); return res; } @@ -219,10 +220,10 @@ bool DMAComponentAccess::accessComponent(u_int32_t updateHandle, u_int32_t offse int nMaximumSleepTime = 0; tools_open_mcdd_descriptor mailboxVirtPtr_1; if (progressFuncAdv && progressFuncAdv->func) { - snprintf(stage, MAX_MSG_SIZE, "%s %s component", (access == MCDA_READ_COMP) ? "Reading" : "Writing", currComponentStr); + snprintf(stage, MAX_MSG_SIZE, "%s %s component", (access == MCC_READ_COMP) ? "Reading" : "Writing", currComponentStr); } //updateHandle &= ~0xff000000; - DPRINTF(("DMAComponentAccess::AccessComponent BEGIN size %d access %s\n", data_size, (access == MCDA_READ_COMP) ? "READ" : "WRITE")); + DPRINTF(("DMAComponentAccess::AccessComponent BEGIN size %d access %s\n", data_size, (access == MCC_READ_COMP) ? "READ" : "WRITE")); mcddReg accessData; mtcr_page_addresses page = _allocatedListVect[CurrentPage]; mtcr_page_addresses mailboxPage = _allocatedListVect[FMPT_MAILBOX_PAGE]; @@ -230,19 +231,19 @@ bool DMAComponentAccess::accessComponent(u_int32_t updateHandle, u_int32_t offse int maxDataSize = data_size > PAGE_SIZE ? PAGE_SIZE : data_size; memset(&accessData, 0, TOOLS_OPEN_MCDD_REG_SIZE); - if (access == MCDA_READ_COMP) { + if (access == MCC_READ_COMP) { memset(data , 0, data_size); } prepareParameters(updateHandle, &accessData, offset + (data_size - leftSize), data, data_size, access, leftSize, page, mailboxPage); int nIteration = 0; while (leftSize > 0) { - DPRINTF(("0x%x bytes left to %s\n", leftSize, access == MCDA_READ_COMP ? "read" : "burn")); + DPRINTF(("0x%x bytes left to %s\n", leftSize, access == MCC_READ_COMP ? "read" : "burn")); memset((u_int8_t*)mailboxPage.virtual_address, 0, TOOLS_OPEN_MCDD_DESCRIPTOR_SIZE); memset(&mailboxVirtPtr_1, 0, TOOLS_OPEN_MCDD_DESCRIPTOR_SIZE);//set zero before each transaction maxDataSize = leftSize > PAGE_SIZE ? PAGE_SIZE : leftSize; mft_signal_set_handling(1); - reg_access_status_t rc = reg_access_mcdd(_mf, (access == MCDA_READ_COMP) ? REG_ACCESS_METHOD_GET : REG_ACCESS_METHOD_SET, &accessData); + reg_access_status_t rc = reg_access_mcdd(_mf, (access == MCC_READ_COMP) ? REG_ACCESS_METHOD_GET : REG_ACCESS_METHOD_SET, &accessData); _manager->deal_with_signal(); if (rc) { DPRINTF(("CRITICAL : DMAComponentAccess::AccessComponent reg_access_mcdd ERROR: %#x\n", rc)); @@ -252,7 +253,7 @@ bool DMAComponentAccess::accessComponent(u_int32_t updateHandle, u_int32_t offse } //if we write a data, meawhile use a time for prepare next data page - if (access == MCDA_WRITE_COMP) { + if (access == MCC_WRITE_COMP) { leftSize -= maxDataSize; if (leftSize > 0) { @@ -309,7 +310,7 @@ bool DMAComponentAccess::accessComponent(u_int32_t updateHandle, u_int32_t offse } // read the data from FW (from page.virtual_address -> to 'data' array) - if (access == MCDA_READ_COMP) { + if (access == MCC_READ_COMP) { DPRINTF(("READ mailboxVirtPtr->status = %d\r\n", mailboxVirtPtr_1.status)); readFromDataPage(&accessData, page, data, data_size, leftSize); leftSize -= maxDataSize; From 4d6ace69caf49fdea469455db478634514c52b35 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Tue, 4 Jan 2022 14:29:03 +0200 Subject: [PATCH 033/184] Fixing build issue caused by 82cd74812ac87b355d13d16437227db43440e146 Description: Tested OS: PPC Tested devices: N/A Tested flows: compilation Known gaps (with RM ticket): N/A Issue: None --- fw_comps_mgr/fw_comps_mgr.cpp | 8 ++++---- fw_comps_mgr/fw_comps_mgr.h | 18 ++++++++++-------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/fw_comps_mgr/fw_comps_mgr.cpp b/fw_comps_mgr/fw_comps_mgr.cpp index a71d475e..a76c5d75 100644 --- a/fw_comps_mgr/fw_comps_mgr.cpp +++ b/fw_comps_mgr/fw_comps_mgr.cpp @@ -661,7 +661,7 @@ bool FwCompsMgr::accessComponent(u_int32_t offset, u_int32_t data[], access_type_t access, ProgressCallBackAdvSt *progressFuncAdv, - controlFsmArgs* lastFsmCommandArgs) + control_fsm_args_t* lastFsmCommandArgs) { bool bRes = _accessObj->accessComponent(_updateHandle, offset, size, data, access, _currComponentStr, progressFuncAdv); if (!bRes && lastFsmCommandArgs != NULL && isDMAAccess()) { @@ -1309,7 +1309,7 @@ bool FwCompsMgr::readComponent(FwComponent::comps_ids_t compType, FwComponent& f return false; } _currComponentStr = FwComponent::getCompIdStr(compType); - controlFsmArgs fsmReadCommand; + control_fsm_args_t fsmReadCommand; fsmReadCommand.command = readPending ? FSM_CMD_READ_PENDING_COMPONENT : FSM_CMD_READ_COMPONENT; fsmReadCommand.expectedState = FSMST_UPLOAD; if (!accessComponent(0, compSize, (u_int32_t *)(data.data()), MCC_READ_COMP, progressFuncAdv, &fsmReadCommand)) { @@ -1404,7 +1404,7 @@ bool FwCompsMgr::burnComponents(std::vector& comps, return false; } _currComponentStr = FwComponent::getCompIdStr(comps[i].getType()); - controlFsmArgs fsmUpdateCommand; + control_fsm_args_t fsmUpdateCommand; fsmUpdateCommand.command = FSM_CMD_UPDATE_COMPONENT; fsmUpdateCommand.expectedState = FSMST_DOWNLOAD; fsmUpdateCommand.size = comps[i].getSize(); @@ -2109,7 +2109,7 @@ bool FwCompsMgr::readBlockFromComponent(FwComponent::comps_ids_t compId, if (!controlFsm(FSM_CMD_LOCK_UPDATE_HANDLE, FSMST_LOCKED)) { return false; } - controlFsmArgs fsmReadCommand; + control_fsm_args_t fsmReadCommand; fsmReadCommand.command = FSM_CMD_READ_PENDING_COMPONENT; fsmReadCommand.expectedState = FSMST_UPLOAD; if (!controlFsm(FSM_CMD_READ_PENDING_COMPONENT, FSMST_UPLOAD)) { diff --git a/fw_comps_mgr/fw_comps_mgr.h b/fw_comps_mgr/fw_comps_mgr.h index 7a20b35a..3c725184 100644 --- a/fw_comps_mgr/fw_comps_mgr.h +++ b/fw_comps_mgr/fw_comps_mgr.h @@ -403,14 +403,16 @@ class FwCompsMgr { FSMST_NA = 0xFF, } fsm_state_t; - typedef struct { + typedef struct control_fsm_args { + control_fsm_args() : command(FSM_CMD_UNDEFINED), expectedState(FSMST_NA), size(0), + currentState(FSMST_NA), progressFuncAdv(NULL), reg_access_timeout(0) {} fsm_command_t command; - fsm_state_t expectedState = FSMST_NA; - u_int32_t size = 0; - fsm_state_t currentState = FSMST_NA; - ProgressCallBackAdvSt *progressFuncAdv = (ProgressCallBackAdvSt*)NULL; - u_int32_t reg_access_timeout = 0; - } controlFsmArgs; + fsm_state_t expectedState; + u_int32_t size; + fsm_state_t currentState; + ProgressCallBackAdvSt *progressFuncAdv; + u_int32_t reg_access_timeout; + } control_fsm_args_t; typedef enum { MCC_ERRCODE_OK = 0x0, @@ -463,7 +465,7 @@ class FwCompsMgr { u_int32_t data[], access_type_t access, ProgressCallBackAdvSt *progressFuncAdv = (ProgressCallBackAdvSt *)NULL, - controlFsmArgs* lastFsmCommandArgs = NULL); + control_fsm_args_t* lastFsmCommandArgs = NULL); bool queryComponentStatus(u_int32_t componentIndex, comp_status_st *query); From 11e67d046fab425e283ea5c55372a6049e581f50 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Tue, 4 Jan 2022 15:37:44 +0200 Subject: [PATCH 034/184] [flint] fw-update signature ignored MAIN CRCs for Carmel onwards Description: Since we sign before we encrypt in case of Carmel onwards, it means that we sign the image with MAIN CRCs but eventually those CRCs are overwritten with auth-tag as part of the encryption flow, so this signature can't be authenticated by FW To resolve it we decided to ignore MAIN CRCs for fw-update signature Tested OS: Linux Tested devices: Carmel Tested flows: flint sign Known gaps (with RM ticket): N/A Issue: 2906797 --- mlxfwops/lib/fs3_ops.cpp | 27 ++++++++++++++---- mlxfwops/lib/fs3_ops.h | 3 +- mlxfwops/lib/fs4_ops.cpp | 61 +++++++++++++++++++++++++++++++++++++++- mlxfwops/lib/fs4_ops.h | 4 ++- 4 files changed, 86 insertions(+), 9 deletions(-) diff --git a/mlxfwops/lib/fs3_ops.cpp b/mlxfwops/lib/fs3_ops.cpp index 377a61f5..6ed6e403 100644 --- a/mlxfwops/lib/fs3_ops.cpp +++ b/mlxfwops/lib/fs3_ops.cpp @@ -2847,6 +2847,24 @@ u_int32_t Fs3Operations::getImageSize() return _fs3ImgInfo.sizeOfImgData - _fwImgInfo.imgStart; } +bool Fs3Operations::GetImageDataForSign(MlxSign::SHAType shaType, vector& img) +{ + if (!FwExtract4MBImage(img, true)) { + return false; + } + + if (shaType == MlxSign::SHA256) { + MaskItocSectionAndEntry(FS3_IMAGE_SIGNATURE_256, img); + } else if (shaType == MlxSign::SHA512) { + MaskItocSectionAndEntry(FS3_IMAGE_SIGNATURE_256, img); + MaskItocSectionAndEntry(FS3_IMAGE_SIGNATURE_512, img); + } else { + return errmsg("Unexpected type of SHA"); + } + + return true; +} + bool Fs3Operations::FwExtract4MBImage(vector& img, bool maskMagicPatternAndDevToc, bool verbose, bool ignoreImageStart) { @@ -2871,7 +2889,7 @@ bool Fs3Operations::FwExtract4MBImage(vector& img, bool maskMagicPatte return true; } -void Fs3Operations::maskIToCSection(u_int32_t itocType, vector& img) +void Fs3Operations::MaskItocSectionAndEntry(u_int32_t itocType, vector& img) { for (int i = 0; i < _fs3ImgInfo.numOfItocs; i++) { if (_fs3ImgInfo.tocArr[i].toc_entry.type == itocType) { @@ -3072,16 +3090,13 @@ bool Fs3Operations::FwCalcSHA(MlxSign::SHAType shaType, vector& sha, v MlxSignSHA *mlxSignSHA = NULL; FwInit(); _imageCache.clear(); - if (!FwExtract4MBImage(img, true)) { + if (!GetImageDataForSign(shaType, img)) { return false; } if (shaType == MlxSign::SHA256) { - maskIToCSection(FS3_IMAGE_SIGNATURE_256, img); mlxSignSHA = new MlxSignSHA256(); } else if (shaType == MlxSign::SHA512) { - maskIToCSection(FS3_IMAGE_SIGNATURE_256, img); - maskIToCSection(FS3_IMAGE_SIGNATURE_512, img); mlxSignSHA = new MlxSignSHA512(); } else { return errmsg("Unexpected type of SHA"); @@ -3563,7 +3578,7 @@ bool Fs3Operations::CalcHMAC(const vector& key, vector& dige } //mask hmac itoc entry and section - maskIToCSection(FS3_HMAC, data); + MaskItocSectionAndEntry(FS3_HMAC, data); //mask magic pattern (First 16 bytes): for (unsigned int i = 0; i < 16; i++) { diff --git a/mlxfwops/lib/fs3_ops.h b/mlxfwops/lib/fs3_ops.h index a5031288..9b571744 100644 --- a/mlxfwops/lib/fs3_ops.h +++ b/mlxfwops/lib/fs3_ops.h @@ -122,6 +122,7 @@ class Fs3Operations : public FwOperations { const char *uuid, PrintCallBack printFunc = (PrintCallBack)NULL); virtual bool FwExtract4MBImage(vector& img, bool maskMagicPatternAndDevToc, bool verbose = false, bool ignoreImageStart = false); + virtual bool GetImageDataForSign(MlxSign::SHAType shaType, vector& img); virtual bool FwSetPublicKeys(char *fname, PrintCallBack callBackFunc = (PrintCallBack)NULL); virtual bool FwSetForbiddenVersions(char *fname, PrintCallBack callBackFunc = (PrintCallBack)NULL); virtual bool FwCalcMD5(u_int8_t md5sum[16]); @@ -290,7 +291,7 @@ class Fs3Operations : public FwOperations { virtual bool reburnItocSection(PrintCallBack callBackFunc, bool burnFailsafe = true); virtual u_int32_t getImageSize(); virtual void maskDevToc(vector& img); - virtual void maskIToCSection(u_int32_t itocType, vector& img); + virtual void MaskItocSectionAndEntry(u_int32_t itocType, vector& img); // this class is for sorting the itoc array by ascending absolute flash_addr used in FwShiftDevData class TocComp { public: diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 85d5e782..35fc9b58 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -463,6 +463,65 @@ bool Fs4Operations::verifyTocHeader(u_int32_t tocAddr, bool isDtoc, VerifyCallBa return true; } +/* + This function responsible on remove every 4B of CRC from MAIN section + Some special cases and how we handle them (aligned to FW behavior): + 1. Complete line is 0x0 (including the 4B CRC) --> handle it the same as other line, remove the last 4B + 2. Leftover (not a complete line at the end) --> keep it as is +*/ +void Fs4Operations::RemoveCRCsFromMainSection(vector& img) { + //* Get MAIN section ITOC entry + struct fs4_toc_info *main_itoc_entry = NULL; + fs4_toc_info *itoc_entries = _fs4ImgInfo.itocArr.tocArr; + for (int i = 0; i < _fs4ImgInfo.itocArr.numOfTocs; i++) { + if (itoc_entries[i].toc_entry.type == FS3_MAIN_CODE) { + main_itoc_entry = &(itoc_entries[i]); + break; + } + } + + u_int32_t main_addr = main_itoc_entry->toc_entry.flash_addr << 2; // addr in entry is in DW + u_int32_t main_size = main_itoc_entry->toc_entry.size << 2; // size in entry is in DW + + vector tmp_img; + tmp_img.reserve(img.size()); + + //* Copying image data before MAIN section + tmp_img.insert(tmp_img.end(), img.begin(), img.begin() + main_addr); + + //* Copying MAIN section without CRCs + const u_int32_t MAIN_LINE_SIZE = 68; // Line in MAIN is 64B data + 4B crc + const u_int32_t MAIN_LINE_DATA_ONLY_SIZE = MAIN_LINE_SIZE - 4; + for (u_int32_t ii = 0; ii < main_size; ii += MAIN_LINE_SIZE) { + u_int32_t line_start_addr = main_addr + ii; + if (ii + MAIN_LINE_SIZE > main_size) { + // In case last line isn't a full line there will be no CRC + tmp_img.insert(tmp_img.end(), img.begin() + line_start_addr, img.begin() + main_addr + main_size); + } + else { + tmp_img.insert(tmp_img.end(), img.begin() + line_start_addr, img.begin() + line_start_addr + MAIN_LINE_DATA_ONLY_SIZE); + } + } + + //* Copying image data after MAIN section + tmp_img.insert(tmp_img.end(), img.begin() + main_addr + main_size, img.end()); + + img = tmp_img; +} + +bool Fs4Operations::GetImageDataForSign(MlxSign::SHAType shaType, vector& img) { + if (!Fs3Operations::GetImageDataForSign(shaType, img)) { + return false; + } + + //* In case of security version 2 (Carmel onwards) we'll ignore MAIN CRCs for fw-update signature + if (getSecureBootSignVersion() == VERSION_2) { + RemoveCRCsFromMainSection(img); + } + + return true; +} + bool Fs4Operations::FwExtract4MBImage(vector& img, bool maskMagicPatternAndDevToc, bool verbose, bool ignoreImageStart) { @@ -3247,7 +3306,7 @@ u_int32_t Fs4Operations::getImageSize() return _fwImgInfo.lastImageAddr - _fwImgInfo.imgStart; } -void Fs4Operations::maskIToCSection(u_int32_t itocType, vector& img) +void Fs4Operations::MaskItocSectionAndEntry(u_int32_t itocType, vector& img) { for (int i = 0; i < _fs4ImgInfo.itocArr.numOfTocs; i++) { if (_fs4ImgInfo.itocArr.tocArr[i].toc_entry.type == itocType) { diff --git a/mlxfwops/lib/fs4_ops.h b/mlxfwops/lib/fs4_ops.h index a0e5fc81..9f1bcd54 100644 --- a/mlxfwops/lib/fs4_ops.h +++ b/mlxfwops/lib/fs4_ops.h @@ -89,6 +89,7 @@ class Fs4Operations : public Fs3Operations { virtual bool storeSecureBootSignaturesInSection(vector boot_signature, vector critical_sections_signature = vector(), vector non_critical_sections_signature = vector()); virtual bool FwExtract4MBImage(vector& img, bool maskMagicPatternAndDevToc, bool verbose = false, bool ignoreImageStart = false); + virtual bool GetImageDataForSign(MlxSign::SHAType shaType, vector& img); virtual bool IsSecureBootSupported(); virtual bool IsCableQuerySupported(); virtual bool IsLifeCycleSupported(); @@ -242,7 +243,7 @@ class Fs4Operations : public Fs3Operations { bool CheckDTocArray(); u_int32_t getImageSize(); void maskDevToc(vector& img); - void maskIToCSection(u_int32_t itocType, vector& img); + void MaskItocSectionAndEntry(u_int32_t itocType, vector& img); bool Fs4UpdateSignatureSection(vector sha256Buff, vector &newSectionData); bool isDTocSection(fs3_section_t sect_type, bool& isDtoc); @@ -259,6 +260,7 @@ class Fs4Operations : public Fs3Operations { bool QuerySecurityFeatures(); bool IsEncryptedDevice(bool& is_encrypted); bool IsEncryptedImage(bool& is_encrypted); + void RemoveCRCsFromMainSection(vector& img); // Members Fs4ImgInfo _fs4ImgInfo; From b2cfe40c451040f200621db7510c6e5eef58eb61 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Tue, 4 Jan 2022 16:40:59 +0200 Subject: [PATCH 035/184] [mic/flint] mic save the image size in image_info.burn_image_size instead of address 16MB flint use image_info.burn_image_size for burn and read-image of encrypted devices Description: Tested OS:Linux Tested devices:BB Tested flows:burn,query,ri Known gaps (with RM ticket): Issue:2813610 --- mlxfwops/lib/fs3_ops.cpp | 16 +++-- mlxfwops/lib/fs3_ops.h | 1 + mlxfwops/lib/fs4_ops.cpp | 98 ++++++++++++++++++++++++---- mlxfwops/lib/fs4_ops.h | 3 + mlxfwops/lib/mlxfwops_com.h | 2 + tools_layouts/image_layout_layouts.c | 26 +++++--- tools_layouts/image_layout_layouts.h | 24 ++++--- 7 files changed, 132 insertions(+), 38 deletions(-) diff --git a/mlxfwops/lib/fs3_ops.cpp b/mlxfwops/lib/fs3_ops.cpp index 6ed6e403..6f18e9b5 100644 --- a/mlxfwops/lib/fs3_ops.cpp +++ b/mlxfwops/lib/fs3_ops.cpp @@ -281,7 +281,7 @@ bool Fs3Operations::GetMfgInfo(u_int8_t *buff) bool Fs3Operations::GetImageInfo(u_int8_t *buff) { DPRINTF(("Fs3Operations::GetImageInfo\n")); - struct cibfw_image_info image_info; + struct image_layout_image_info image_info; int IIMajor, IIMinor; // TODO: adrianc: use the version fields once they are available in tools layouts GET_IMAGE_INFO_VERSION(buff, IIMajor, IIMinor); @@ -289,8 +289,8 @@ bool Fs3Operations::GetImageInfo(u_int8_t *buff) if (!CHECK_IMAGE_INFO_VERSION(IIMajor)) { return errmsg(MLXFW_UNKNOWN_SECT_VER_ERR, "Unknown IMAGE_INFO format version (%d.%d).", IIMajor, IIMinor); } - cibfw_image_info_unpack(&image_info, buff); - // cibfw_image_info_dump(&image_info, stdout); + image_layout_image_info_unpack(&image_info, buff); + //image_layout_image_info_dump(&image_info, stdout); _fwImgInfo.ext_info.image_info_minor_version = image_info.minor_version; _fwImgInfo.ext_info.image_info_major_version = image_info.major_version; @@ -299,7 +299,7 @@ bool Fs3Operations::GetImageInfo(u_int8_t *buff) _fwImgInfo.ext_info.fw_ver[1] = image_info.FW_VERSION.MINOR; _fwImgInfo.ext_info.fw_ver[2] = image_info.FW_VERSION.SUBMINOR; - _fwImgInfo.ext_info.isfu_major = image_info.isfu.major; + _fwImgInfo.ext_info.isfu_major = image_info.module_versions.mad.major; _fwImgInfo.ext_info.mic_ver[0] = image_info.mic_version.MAJOR; _fwImgInfo.ext_info.mic_ver[1] = image_info.mic_version.MINOR; @@ -309,6 +309,8 @@ bool Fs3Operations::GetImageInfo(u_int8_t *buff) _fwImgInfo.ext_info.fw_rel_date[1] = (u_int16_t)image_info.FW_VERSION.Month; _fwImgInfo.ext_info.fw_rel_date[2] = (u_int16_t)image_info.FW_VERSION.Year; + _fwImgInfo.ext_info.burn_image_size = image_info.burn_image_size; + // assuming number of supported_hw_id < MAX_NUM_SUPP_HW_IDS memcpy(_fwImgInfo.supportedHwId, image_info.supported_hw_id, sizeof(image_info.supported_hw_id)); _fwImgInfo.supportedHwIdNum = (sizeof(image_info.supported_hw_id)) / sizeof(image_info.supported_hw_id[0]); @@ -1252,12 +1254,12 @@ bool Fs3Operations::FsBurnAux(FwOperations *imgops, ExtBurnParams& burnParams) } // modify it: std::vector imageInfoSect = imageInfoToc->section_data; - struct cibfw_image_info image_info; - cibfw_image_info_unpack(&image_info, &imageInfoSect[0]); + struct image_layout_image_info image_info; + image_layout_image_info_unpack(&image_info, &imageInfoSect[0]); if (burnParams.vsdSpecified) { strncpy(image_info.vsd, burnParams.userVsd, VSD_LEN); } - cibfw_image_info_pack(&image_info, &imageInfoSect[0]); + image_layout_image_info_pack(&image_info, &imageInfoSect[0]); if (burnParams.useDevImgInfo) { // update PSID, name and description in image info struct tools_open_image_info tools_image_info; diff --git a/mlxfwops/lib/fs3_ops.h b/mlxfwops/lib/fs3_ops.h index 9b571744..103c2f6f 100644 --- a/mlxfwops/lib/fs3_ops.h +++ b/mlxfwops/lib/fs3_ops.h @@ -38,6 +38,7 @@ #include "reg_access/reg_access.h" #include +#include #include #include // #include "flint_base.h" diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 35fc9b58..e94e2666 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -110,6 +110,7 @@ bool Fs4Operations::CheckSignatures(u_int32_t a[], u_int32_t b[], int n) bool Fs4Operations::IsEncryptedDevice(bool& is_encrypted) { + DPRINTF(("Fs4Operations::IsEncryptedDevice\n")); is_encrypted = false; if (_signatureMngr->IsLifeCycleSupported() && _signatureMngr->IsEncryptionSupported()) { @@ -921,6 +922,40 @@ bool Fs4Operations::FwVerify(VerifyCallBack verifyCallBackFunc, bool isStripedIm return Fs3Operations::FwVerify(verifyCallBackFunc, isStripedImage, showItoc, ignoreDToc); } +bool Fs4Operations::GetImageInfo(u_int8_t *buff) +{ + DPRINTF(("Fs4Operations::GetImageInfo call Fs3Operations::GetImageInfo\n")); + bool success = Fs3Operations::GetImageInfo(buff); + + //* Fix burn_image_size if required (required only for BB first FW release) + if (success && !_ioAccess->is_flash()/*image*/) { + DPRINTF(("Fs4Operations::GetImageInfo check if fix burn_image_size is required\n")); + bool is_encrypted_image; + if (!IsEncryptedImage(is_encrypted_image)){ + return false; + } + if (is_encrypted_image && _fwImgInfo.ext_info.burn_image_size == 0){ + DPRINTF(("Fs4Operations::GetImageInfo read burn_image_size from the address 16MB\n")); + //* Read burn_image_size from the address 16MB ("outside" the range that we burn) + u_int32_t burn_image_size; + u_int8_t *buff; + //* Choosing the correct io to read from + FBase* io = _ioAccess; + if (_encrypted_image_io_access) { + io = _encrypted_image_io_access; // If encrypted image was given we'll read from it + } + + READALLOCBUF((*io), ENCRYPTED_IMAGE_LAST_ADDR_LOCATION_IN_BYTES, buff, 4, "IMAGE_LAST_ADDR"); // Reading DWORD from addr 16MB + burn_image_size = ((u_int32_t*)buff)[0]; + TOCPU1(burn_image_size); + free(buff); + _fwImgInfo.ext_info.burn_image_size = burn_image_size; + } + } + return true; + +} + bool Fs4Operations::encryptedFwReadImageInfoSection() { //* Read IMAGE_INFO section u_int32_t image_info_section_addr = _hmac_start_ptr + _fwImgInfo.imgStart; @@ -965,6 +1000,7 @@ bool Fs4Operations::parseDevData(bool readRom, bool quickQuery, bool verbose) { bool Fs4Operations::encryptedFwQuery(fw_info_t *fwInfo, bool readRom, bool quickQuery, bool ignoreDToc, bool verbose) { + DPRINTF(("Fs4Operations::encryptedFwQuery\n")); if (!initHwPtrs(true)) { DPRINTF(("Fs4Operations::encryptedFwQuery HW pointers not found")); return false; @@ -1126,8 +1162,49 @@ bool Fs4Operations::CheckFs4ImgSize(Fs4Operations& imageOps, bool useImageDevDat return true; } + +bool Fs4Operations::getEncryptedImageSize(u_int32_t *imageSize){ + DPRINTF(("Fs4Operations::getEncryptedImageSize\n")); + fw_info_t fwInfo; + if (!encryptedFwQuery(&fwInfo, false, false)) { + return errmsg("%s", err()); + } + *imageSize = fwInfo.fw_info.burn_image_size; + return true; +} + +bool Fs4Operations::FwReadEncryptedData(void *image, u_int32_t imageSize, bool verbose){ + DPRINTF(("Fs4Operations::FwReadEncryptedData\n")); + vector data; + data.resize(imageSize); + if (!(*_ioAccess).read(_fwImgInfo.imgStart, data.data(), imageSize, verbose)) { + return errmsg("%s - read error (%s)\n", "Image", (*_ioAccess).err()); + } + memcpy(image, data.data(), imageSize); + return true; +} + + bool Fs4Operations::FwReadData(void *image, u_int32_t *imageSize, bool verbose) { + + //* Read encrypted data + bool is_encrypted = false; + DPRINTF(("Fs4Operations::FwReadData\n")); + if (!isEncrypted(is_encrypted)) { + return errmsg(getErrorCode(), "%s", err()); + } + if (is_encrypted) { + if (image == NULL) { + bool result = getEncryptedImageSize(imageSize); + DPRINTF(("Fs4Operations::FwReadData imageSize=0x%x result=%s\n", *imageSize, result ? "true" : "false")); + return result; + } else { + return FwReadEncryptedData(image, *imageSize, verbose); + } + } + + //* Read non-encrypted data struct QueryOptions queryOptions; if (!imageSize) { return errmsg("bad parameter is given to FwReadData\n"); @@ -1897,17 +1974,16 @@ bool Fs4Operations::FwExtractEncryptedImage(vector& img, bool maskMagi } //* Get image size - u_int8_t *buff; - READALLOCBUF((*io), ENCRYPTED_IMAGE_LAST_ADDR_LOCATION_IN_BYTES, buff, 4, "IMAGE_LAST_ADDR"); // Reading DWORD from addr 16MB - u_int32_t image_last_addr = ((u_int32_t*)buff)[0]; - TOCPU1(image_last_addr); - u_int32_t image_size = image_last_addr - image_start; - free(buff); - - //* Read image from _fwImgInfo.imgStart to image_size (_fwImgInfo.imgStart expected to be zero) - DPRINTF(("Fs4Operations::FwExtractEncryptedImage - Reading image from 0x%x to 0x%x\n", image_start, image_start + image_size)); - img.resize(image_size); - if (!(*io).read(image_start, img.data(), image_size, verbose)) { + fw_info_t fwInfo; + if (!encryptedFwQuery(&fwInfo, false, false, true)) { + return errmsg("%s", err()); + } + u_int32_t burn_image_size = fwInfo.fw_info.burn_image_size; + + //* Read image from _fwImgInfo.imgStart to burn_image_size (_fwImgInfo.imgStart expected to be zero) + DPRINTF(("Fs4Operations::FwExtractEncryptedImage - Reading 0x%x bytes from address 0x%x\n", burn_image_size, image_start)); + img.resize(burn_image_size); + if (!(*io).read(image_start, img.data(), burn_image_size, verbose)) { return errmsg("%s - read error (%s)\n", "image", (*io).err()); } diff --git a/mlxfwops/lib/fs4_ops.h b/mlxfwops/lib/fs4_ops.h index 9f1bcd54..f453ce44 100644 --- a/mlxfwops/lib/fs4_ops.h +++ b/mlxfwops/lib/fs4_ops.h @@ -113,6 +113,7 @@ class Fs4Operations : public Fs3Operations { virtual void FwCleanUp(); bool IsLifeCycleAccessible(chip_type_t chip_type); bool IsSecurityVersionViolated(u_int32_t image_security_version); + bool GetImageInfo(u_int8_t *buff); protected: struct fs4_toc_info { @@ -201,6 +202,8 @@ class Fs4Operations : public Fs3Operations { bool Fs4UpdateItocInfo(struct fs4_toc_info *curr_toc, u_int32_t NewSectSize, std::vector& newSectionData); bool FwReadData(void *image, u_int32_t *imageSize, bool verbose = false); + bool getEncryptedImageSize(u_int32_t *imageSize); + bool FwReadEncryptedData(void *image, u_int32_t imageSize, bool verbose); bool CreateDtoc(vector& img, u_int8_t* SectionData, u_int32_t section_size, u_int32_t flash_data_addr, fs3_section_t section, u_int32_t tocEntryAddr, CRCTYPE CRC); bool Fs4RemoveSectionAux(fs3_section_t sectionType); diff --git a/mlxfwops/lib/mlxfwops_com.h b/mlxfwops/lib/mlxfwops_com.h index 07bc3a90..fd213685 100644 --- a/mlxfwops/lib/mlxfwops_com.h +++ b/mlxfwops/lib/mlxfwops_com.h @@ -471,6 +471,8 @@ typedef struct fw_info_com { char branch_ver[BRANCH_LEN + 1]; char running_branch_ver[BRANCH_LEN + 1]; u_int8_t encrypted_fw; + u_int32_t burn_image_size; //! Be aware! This field is backward compatible starting from BB/CX-7 + //! Use this field only for encrypted images } fw_info_com_t; typedef struct fw_info_ext { diff --git a/tools_layouts/image_layout_layouts.c b/tools_layouts/image_layout_layouts.c index 00d78962..3e4d6122 100755 --- a/tools_layouts/image_layout_layouts.c +++ b/tools_layouts/image_layout_layouts.c @@ -32,7 +32,7 @@ /*** - *** This file was generated at "2021-10-25 13:11:03" + *** This file was generated at "2021-11-08 14:11:31" *** by: *** > /mswg/release/tools/a-me/last_stable/adabe_plugins/adb2c/adb2pack.py --input adb/image_layout/image_layout.adb --file-prefix image_layout --prefix image_layout_ --no-adb-utils ***/ @@ -1363,6 +1363,8 @@ void image_layout_image_info_pack(const struct image_layout_image_info *ptr_stru } offset = 2368; adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->ini_file_num); + offset = 2400; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->burn_image_size); offset = 3200; image_layout_version_vector_pack(&(ptr_struct->version_vector), ptr_buff + offset / 8); for (i = 0; i < 16; ++i) { @@ -1452,6 +1454,8 @@ void image_layout_image_info_unpack(struct image_layout_image_info *ptr_struct, } offset = 2368; ptr_struct->ini_file_num = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + offset = 2400; + ptr_struct->burn_image_size = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); offset = 3200; image_layout_version_vector_unpack(&(ptr_struct->version_vector), ptr_buff + offset / 8); for (i = 0; i < 16; ++i) { @@ -1543,6 +1547,8 @@ void image_layout_image_info_print(const struct image_layout_image_info *ptr_str adb2c_add_indentation(fd, indent_level); fprintf(fd, "ini_file_num : " U32H_FMT "\n", ptr_struct->ini_file_num); adb2c_add_indentation(fd, indent_level); + fprintf(fd, "burn_image_size : " U32H_FMT "\n", ptr_struct->burn_image_size); + adb2c_add_indentation(fd, indent_level); fprintf(fd, "version_vector:\n"); image_layout_version_vector_print(&(ptr_struct->version_vector), fd, indent_level + 1); fprintf(fd, "prod_ver : \"%s\"\n", ptr_struct->prod_ver); @@ -1822,27 +1828,27 @@ void image_layout_image_layout_Nodes_print(const union image_layout_image_layout adb2c_add_indentation(fd, indent_level); fprintf(fd, "======== image_layout_image_layout_Nodes ========\n"); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "hashes_table:\n"); + image_layout_hashes_table_print(&(ptr_struct->hashes_table), fd, indent_level + 1); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "itoc_entry:\n"); + image_layout_itoc_entry_print(&(ptr_struct->itoc_entry), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); fprintf(fd, "itoc_header:\n"); image_layout_itoc_header_print(&(ptr_struct->itoc_header), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); + fprintf(fd, "device_info:\n"); + image_layout_device_info_print(&(ptr_struct->device_info), fd, indent_level + 1); + adb2c_add_indentation(fd, indent_level); fprintf(fd, "tools_area:\n"); image_layout_tools_area_print(&(ptr_struct->tools_area), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); - fprintf(fd, "itoc_entry:\n"); - image_layout_itoc_entry_print(&(ptr_struct->itoc_entry), fd, indent_level + 1); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "hashes_table:\n"); - image_layout_hashes_table_print(&(ptr_struct->hashes_table), fd, indent_level + 1); - adb2c_add_indentation(fd, indent_level); fprintf(fd, "image_info:\n"); image_layout_image_info_print(&(ptr_struct->image_info), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); fprintf(fd, "hw_pointers_carmel:\n"); image_layout_hw_pointers_carmel_print(&(ptr_struct->hw_pointers_carmel), fd, indent_level + 1); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "device_info:\n"); - image_layout_device_info_print(&(ptr_struct->device_info), fd, indent_level + 1); } unsigned int image_layout_image_layout_Nodes_size(void) diff --git a/tools_layouts/image_layout_layouts.h b/tools_layouts/image_layout_layouts.h index e7aeeef1..343e007a 100755 --- a/tools_layouts/image_layout_layouts.h +++ b/tools_layouts/image_layout_layouts.h @@ -32,7 +32,7 @@ /*** - *** This file was generated at "2021-10-25 13:11:03" + *** This file was generated at "2021-11-08 14:11:31" *** by: *** > /mswg/release/tools/a-me/last_stable/adabe_plugins/adb2c/adb2pack.py --input adb/image_layout/image_layout.adb --file-prefix image_layout --prefix image_layout_ --no-adb-utils ***/ @@ -642,6 +642,10 @@ For Golan A0, first entry should be 0x1ff /* Description - */ /* 0x128.0 - 0x128.31 */ u_int32_t ini_file_num; +/*---------------- DWORD[75] (Offset 0x12c) ----------------*/ + /* Description - */ + /* 0x12c.0 - 0x12c.31 */ + u_int32_t burn_image_size; /*---------------- DWORD[100] (Offset 0x190) ----------------*/ /* Description - */ /* 0x190.0 - 0x1bc.31 */ @@ -817,27 +821,27 @@ struct image_layout_tools_area { /* Size in bytes - 2064 */ union image_layout_image_layout_Nodes { /*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - */ + /* 0x0.0 - 0x80c.31 */ + struct image_layout_hashes_table hashes_table; + /* Description - */ + /* 0x0.0 - 0x1c.31 */ + struct image_layout_itoc_entry itoc_entry; /* Description - */ /* 0x0.0 - 0x1c.31 */ struct image_layout_itoc_header itoc_header; /* Description - */ + /* 0x0.0 - 0x1fc.31 */ + struct image_layout_device_info device_info; + /* Description - */ /* 0x0.0 - 0x3c.31 */ struct image_layout_tools_area tools_area; /* Description - */ - /* 0x0.0 - 0x1c.31 */ - struct image_layout_itoc_entry itoc_entry; - /* Description - */ - /* 0x0.0 - 0x80c.31 */ - struct image_layout_hashes_table hashes_table; - /* Description - */ /* 0x0.0 - 0x3fc.31 */ struct image_layout_image_info image_info; /* Description - */ /* 0x0.0 - 0x7c.31 */ struct image_layout_hw_pointers_carmel hw_pointers_carmel; - /* Description - */ - /* 0x0.0 - 0x1fc.31 */ - struct image_layout_device_info device_info; }; From 96e9aab174eeadbabc6b314a0c1d5136f3056e76 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Tue, 4 Jan 2022 16:45:23 +0200 Subject: [PATCH 036/184] [flint] ITOC hash in HTOC is wrong after flint sign/rsa_sign Description: Calling READBUF macro in flint with size of dwords instead of bytes Tested OS: Linux Tested devices: N/A Tested flows: flint_oem -i carmel_signed.bin --private_key /swgwork/denysv/keys/private4k.pem --public_key /swgwork/denysv/keys/public4k.pub --key_uuid 443b6f24111311eabd95000000000000 rsa_sign Known gaps (with RM ticket): N/A Issue: 2863502 --- mlxfwops/lib/fs4_ops.cpp | 10 +++++----- mlxfwops/lib/fs4_ops.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index e94e2666..ffc5ebaa 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -2770,13 +2770,13 @@ bool Fs4Operations::Fs4ReburnSection(u_int32_t newSectionAddr, return true; } -bool Fs4Operations::calcHashOnItoc(vector& hash) { +bool Fs4Operations::calcHashOnItoc(vector& hash, u_int32_t itoc_addr) { //* Get ITOC data as vector of bytes #if !defined(NO_OPEN_SSL) && !defined(NO_DYNAMIC_ENGINE) //mlxSignSHA is only available with OPEN_SSL vector itoc_data; u_int32_t itoc_size = _fs4ImgInfo.itocArr.numOfTocs * TOC_ENTRY_SIZE + TOC_HEADER_SIZE; itoc_data.resize(itoc_size); - READBUF((*_ioAccess), _itoc_ptr, (u_int32_t*)&itoc_data[0], itoc_size / 4, "Reading ITOC data"); + READBUF((*_ioAccess), itoc_addr, (u_int32_t*)&itoc_data[0], itoc_size, "Reading ITOC data"); //* Calculate SHA MlxSignSHA512 mlxSignSHA; @@ -2862,7 +2862,7 @@ bool Fs4Operations::reburnDTocSection(PrintCallBack callBackFunc) } memset(&p[tocSize] - IMAGE_LAYOUT_ITOC_ENTRY_SIZE, FS3_END, IMAGE_LAYOUT_ITOC_ENTRY_SIZE); - PRINT_PROGRESS(callBackFunc, (char *)"Updating TOC section - "); + PRINT_PROGRESS(callBackFunc, (char *)"Updating DTOC section - "); bool rc = writeImage((ProgressCallBack)NULL, tocAddr, p, tocSize, true, true); delete[] p; if (!rc) { @@ -2897,7 +2897,7 @@ bool Fs4Operations::reburnITocSection(PrintCallBack callBackFunc, bool isFailSaf } memset(&p[tocSize] - IMAGE_LAYOUT_ITOC_ENTRY_SIZE, FS3_END, IMAGE_LAYOUT_ITOC_ENTRY_SIZE); - PRINT_PROGRESS(callBackFunc, (char *)"Updating TOC section - "); + PRINT_PROGRESS(callBackFunc, (char *)"Updating ITOC section - "); bool rc = writeImage((ProgressCallBack)NULL, newITocAddr, p, tocSize, true, true); delete[] p; if (!rc) { @@ -2919,7 +2919,7 @@ bool Fs4Operations::reburnITocSection(PrintCallBack callBackFunc, bool isFailSaf if (getSecureBootSignVersion() == VERSION_2) { //* Calculate SHA-512 on ITOC vector hash; - if (!calcHashOnItoc(hash)) { + if (!calcHashOnItoc(hash, newITocAddr)) { return errmsg("Failed to calculate ITOC hash"); } if (!updateHashInHashesTable(FS3_ITOC, hash)) { diff --git a/mlxfwops/lib/fs4_ops.h b/mlxfwops/lib/fs4_ops.h index f453ce44..3c0d3fa5 100644 --- a/mlxfwops/lib/fs4_ops.h +++ b/mlxfwops/lib/fs4_ops.h @@ -258,7 +258,7 @@ class Fs4Operations : public Fs3Operations { bool GetSectionSizeAndOffset(fs3_section_t sectType, u_int32_t& size, u_int32_t& offset); SecureBootSignVersion getSecureBootSignVersion(); - bool calcHashOnItoc(vector& hash); + bool calcHashOnItoc(vector& hash, u_int32_t itoc_addr); bool updateHashInHashesTable(fs3_section_t section_type, vector hash); bool QuerySecurityFeatures(); bool IsEncryptedDevice(bool& is_encrypted); From b138bcd109e261bb77bf916f45d3bec91a605f2c Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Sat, 18 Dec 2021 23:03:11 +0200 Subject: [PATCH 037/184] fixing ww command in case of device Description: Wrong usage in write function parameters Tested OS: Linux Tested devices: CX6 Tested flows: flint ww Known gaps (with RM ticket): N/A Issue: 2899772 Change-Id: I39b56057501d3febbf95c771cf39e1a76f619201 Signed-off-by: ashargorodsk --- flint/subcommands.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index e33f5bd4..f42c6959 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -5700,9 +5700,18 @@ FlintStatus WwSubCommand::executeCommand() delete[] addrStr; delete[] dataStr; data = __cpu_to_be32(data); - if (!_io->write(addr, &data, 0x4)) { - reportErr(true, FLINT_FLASH_WRITE_ERROR, _io->err()); - return FLINT_FAILED; + // TODO - align below write function for Flash and FImage classes + if (_io->is_flash()) { + if (!((Flash*)_io)->write(addr, data)) { + reportErr(true, FLINT_FLASH_WRITE_ERROR, _io->err()); + return FLINT_FAILED; + } + } + else { + if (!_io->write(addr, &data, 0x4)) { + reportErr(true, FLINT_FLASH_WRITE_ERROR, _io->err()); + return FLINT_FAILED; + } } return FLINT_SUCCESS; } From d76add5d1646867d87a81f2635aab29dddff62ca Mon Sep 17 00:00:00 2001 From: ssela Date: Sat, 13 Nov 2021 22:35:42 +0200 Subject: [PATCH 038/184] Added a validation check and error message. Description: Sign and rsa_sign commands with --openssl_key_id flag may not be called with type=public. Also may not use --private_key flag with --openssl_key_id, --openssl_engine flags. Added a validation check and error message if needed. Tested OS:N/A Tested devices:N/A Tested flows:N/A Known gaps (with RM ticket):N/A Issue:2449104 2449099 Change-Id: I0676a1af0998c0ea8cc596d9494944dfe38fbf22 Signed-off-by: ashargorodsk --- flint/subcommands.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index f42c6959..39e27965 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -1609,7 +1609,14 @@ bool SignSubCommand::verifyParams() reportErr(true, "To Sign the image with OpenSSL you must provide the engine and the key identifier.\n"); return false; } - return true; + if (_flintParams.openssl_key_id.find("type=public", 0) != std::string::npos) { + reportErr(true, "The Sign command with --openssl_key_id flag does not accept public keys\n"); + return false; + } + if (_flintParams.privkey_specified) { + reportErr(true, "The Sign command does not accept --private_key flag with the following flags: --openssl_engine, --openssl_key_id\n"); + return false; + } } else if (_flintParams.hsm_specified) { if (_flintParams.uuid_specified == false) { @@ -1624,7 +1631,6 @@ bool SignSubCommand::verifyParams() reportErr(true, HSM_PASSWORD_MISSING); return false; } - return true; } else { if (_flintParams.privkey_specified ^ _flintParams.uuid_specified) { @@ -1649,8 +1655,8 @@ bool SignSubCommand::verifyParams() (int)_flintParams.cmd_params.size()); return false; } - return true; } + return true; } /*********************** @@ -1962,8 +1968,16 @@ bool SignRSASubCommand::verifyParams() reportErr(true, "To create secure boot signature with OpenSSL you must provide uuid string.\n"); return false; } - if (_flintParams.openssl_engine.empty()) { - reportErr(true, "To create secure boot signature with OpenSSL you must provide the URI string.\n"); + if (_flintParams.openssl_engine.empty() || _flintParams.openssl_key_id.empty()) { + reportErr(true, "To Sign the image with OpenSSL you must provide the engine and the key identifier.\n"); + return false; + } + if (_flintParams.openssl_key_id.find("type=public", 0) != std::string::npos) { + reportErr(true, "The rsa_sign command with --openssl_key_id flag does not accept public keys\n"); + return false; + } + if (_flintParams.privkey_specified) { + reportErr(true, "The Sign command does not accept --private_key flag with the following flags: --openssl_engine, --openssl_key_id\n"); return false; } return true; From e8e9d7a626176a5fe3a8e4cc75f2f2e29d463a50 Mon Sep 17 00:00:00 2001 From: Oded Burstein Date: Tue, 4 Jan 2022 16:07:51 +0200 Subject: [PATCH 039/184] BF3 | added missing life_cycle query implementation for BF3 Description: added the correct life_cycle address & size for BF3 according to ADB. Tested OS: linux Tested devices: BF3 Tested flows: flint, mlxburn Known gaps (with RM ticket): n/a Issue: 2916843 Change-Id: Ic3a362c6221dbe94228e2715bac57ce059151771 Signed-off-by: ashargorodsk --- mlxfwops/lib/fw_ops.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 1b93ee1c..7c12f0a6 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -2563,7 +2563,8 @@ life_cycle_t CRSpaceRegisters::getLifeCycle() bitLen = 2; break; case CT_CONNECTX7: - case CT_QUANTUM2: + case CT_QUANTUM2: + case CT_BLUEFIELD3: lifeCycleAddress = 0xf0000; firstBit = 4; bitLen = 2; From 7cc67552af393ac94ba5571e56d0e1901d865da0 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Tue, 4 Jan 2022 16:24:38 +0200 Subject: [PATCH 040/184] direct access to flash will clear gcm_en bit for BB/Carmel onwards devices Description: In some cases gcm_en bit is 0x1, so before accessing the flash we need to disable it in order to not stuck the flash GW Specific scenario: ROM failed on secure-boot signature authentication, so device want to livefish. ROM didn't clear the gcm_en bit and afterwards we tried to query the device and the device got stuck. Tested OS: Linux Tested devices: Carmel Tested flows: burn image with wrong secure-boot signature, reboot, flint query Known gaps (with RM ticket): N/A Issue: 2919025 Change-Id: If01170649d14964f27413b0f39eec151a55133dd Signed-off-by: ashargorodsk --- mflash/mflash.c | 34 +++++++++++++++++++++++++++++++++- mflash/mflash_pack_layer.h | 2 ++ mlxfwops/lib/fs4_ops.cpp | 2 +- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/mflash/mflash.c b/mflash/mflash.c index bacf509f..4c27d297 100644 --- a/mflash/mflash.c +++ b/mflash/mflash.c @@ -1366,6 +1366,15 @@ int is4_flash_lock(mflash *mfl, int lock_state) return MFE_OK; } +int disable_gcm(mflash *mfl) +{ + u_int32_t data = 0; + MREAD4(mfl->gcm_en_addr, &data); + data = MERGE(data, 0, 0, 1); + MWRITE4(mfl->gcm_en_addr, data); + + return 0; +} int disable_cache_replacement(mflash *mfl) { @@ -1386,6 +1395,27 @@ int restore_cache_replacemnt(mflash *mfl) return MFE_OK; } +int sixth_gen_flash_lock(mflash *mfl, int lock_state) +{ + int rc = 0; + if (lock_state == 1) { // lock the flash + rc = is4_flash_lock(mfl, lock_state); + CHECK_RC(rc); + rc = disable_gcm(mfl); + CHECK_RC(rc); + rc = disable_cache_replacement(mfl); + CHECK_RC(rc); + rc = gw_wait_ready(mfl, "WAIT TO BUSY"); + CHECK_RC(rc); + } else { // unlock the flash + rc = restore_cache_replacemnt(mfl); + CHECK_RC(rc); + rc = is4_flash_lock(mfl, lock_state); + CHECK_RC(rc); + } + return MFE_OK; +} + int connectib_flash_lock(mflash *mfl, int lock_state) { int rc = 0; @@ -1673,8 +1703,9 @@ int sx_flash_init_direct_access(mflash *mfl, flash_params_t *flash_params) int sixth_gen_init_direct_access(mflash *mfl, flash_params_t *flash_params) { mfl->cache_repacement_en_addr = HCR_NEW_GW_CACHE_REPLACEMNT_EN_ADDR; + mfl->gcm_en_addr = HCR_NEW_GW_GCM_EN_ADDR; - mfl->f_lock = connectib_flash_lock; + mfl->f_lock = sixth_gen_flash_lock; return gen6_flash_init_com(mfl, flash_params, 0); } @@ -2223,6 +2254,7 @@ int mf_open_fw(mflash *mfl, flash_params_t *flash_params, int num_of_banks) mfl->gw_cmd = HCR_FLASH_CMD; mfl->gw_addr = HCR_FLASH_ADDR; mfl->cache_repacement_en_addr = HCR_CACHE_REPLACEMNT_EN_ADDR; + mfl->gcm_en_addr = 0xffffffff; // Relevant to devices with new flash GW only mfl->cache_rep_offset = HCR_FLASH_CACHE_REPLACEMENT_OFFSET; mfl->cache_rep_cmd = HCR_FLASH_CACHE_REPLACEMENT_CMD; if (mfl->access_type == MFAT_MFILE) { diff --git a/mflash/mflash_pack_layer.h b/mflash/mflash_pack_layer.h index bf86f749..55014b37 100644 --- a/mflash/mflash_pack_layer.h +++ b/mflash/mflash_pack_layer.h @@ -247,6 +247,7 @@ struct mflash { int cputUtilizationApplied; int cpuPercent; u_int32_t cache_repacement_en_addr; + u_int32_t gcm_en_addr; u_int32_t gw_addr; u_int32_t gw_data; u_int32_t gw_cmd; @@ -280,6 +281,7 @@ enum CntxCrConstants { HCR_FLASH_DATA = 0xf0410, HCR_CACHE_REPLACEMNT_EN_ADDR = 0xf0420, HCR_NEW_GW_CACHE_REPLACEMNT_EN_ADDR = 0xf0480, + HCR_NEW_GW_GCM_EN_ADDR = 0xf0440, HCR_FLASH_GEARBOX_CMD = 0x2000, HCR_FLASH_GEARBOX_ADDR = 0x2004, HCR_FLASH_GEARBOX_CACHE_REPLACEMENT_OFFSET = 0x2008, diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index ffc5ebaa..70ded5b9 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -156,7 +156,7 @@ bool Fs4Operations::IsEncryptedImage(bool& is_encrypted) if (!CheckTocSignature(&itocHeader, ITOC_ASCII)) { // Check second location of ITOC header magic-pattern is_encrypted = true; } - } + } return true; } From 184ab0bd43fc7b26e527137d12e6271c636327c7 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Tue, 21 Dec 2021 10:38:38 +0200 Subject: [PATCH 041/184] signing encrypted BB image was broken Description: In case of signing encrypted BB image we need to read the burn_image_size from the encrypted image instead of the non-encrypted image Tested OS: Linux Tested devices: BB Tested flows: flint_oem -i bb_encrypted.bin --private_key /.autodirect/fwgwork/SMV/utils/dev_keys/private4k.pem --public_key /.autodirect/fwgwork/SMV/utils/dev_keys/public4k.pub --key_uuid 5dd6108a040811ec9f1a000000000000 --nonencrypted_image bb.bin rsa_sign Known gaps (with RM ticket): N/A Issue: 2903003 Change-Id: Ia7440723f2a9eb7b0dae6b1dc6963aefc03030e4 Signed-off-by: ashargorodsk --- mlxfwops/lib/fs4_ops.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 70ded5b9..c9a3b485 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -931,10 +931,10 @@ bool Fs4Operations::GetImageInfo(u_int8_t *buff) if (success && !_ioAccess->is_flash()/*image*/) { DPRINTF(("Fs4Operations::GetImageInfo check if fix burn_image_size is required\n")); bool is_encrypted_image; - if (!IsEncryptedImage(is_encrypted_image)){ + if (!IsEncryptedImage(is_encrypted_image)) { return false; } - if (is_encrypted_image && _fwImgInfo.ext_info.burn_image_size == 0){ + if ((is_encrypted_image || _encrypted_image_io_access) && _fwImgInfo.ext_info.burn_image_size == 0) { DPRINTF(("Fs4Operations::GetImageInfo read burn_image_size from the address 16MB\n")); //* Read burn_image_size from the address 16MB ("outside" the range that we burn) u_int32_t burn_image_size; From 40a5008f257a87d83c5ff7917625e0236dd26c86 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Wed, 5 Jan 2022 12:24:38 +0200 Subject: [PATCH 042/184] Alignment of whitespaces, new-lines, etc. Description: Tested OS: Tested devices: Tested flows: Known gaps (with RM ticket): Issue: None --- flint/subcommands.cpp | 21 +++++++++++-------- fw_comps_mgr/fw_comps_mgr.cpp | 1 + fw_comps_mgr/fw_comps_mgr_abstract_access.cpp | 4 +++- fw_comps_mgr/fw_comps_mgr_abstract_access.h | 4 +++- mlxfwops/lib/fs3_ops.cpp | 1 + mlxfwops/lib/fs4_ops.cpp | 5 +++-- mlxfwops/lib/fsctrl_ops.cpp | 2 +- mlxfwops/lib/fuse_gw.cpp | 3 +-- mlxfwops/lib/fw_ops.cpp | 2 ++ mlxfwops/lib/fw_ops.h | 1 + 10 files changed, 28 insertions(+), 16 deletions(-) diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index 39e27965..86a82b7a 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -1881,6 +1881,7 @@ FlintStatus SignRSASubCommand::executeCommand() reportErr(true, IMAGE_SIGN_TYPE_ERROR); return FLINT_FAILED; } + if (_flintParams.openssl_engine_usage_specified) { #if !defined(NO_OPEN_SSL) && !defined(NO_DYNAMIC_ENGINE) //* Init openssl engine for signing @@ -3842,6 +3843,7 @@ FlintStatus QuerySubCommand::executeCommand() if (preFwOps() == FLINT_FAILED) { return FLINT_FAILED; } + fw_info_t fwInfo; FwOperations *ops; bool fullQuery = false; @@ -3967,6 +3969,7 @@ FlintStatus VerifySubCommand::executeCommand() reportErr(true, FLINT_CMD_VERIFY_ERROR_1); return FLINT_FAILED; } + FwOperations *ops; bool showItoc = (_flintParams.cmd_params.size() == 1) ? true : false; //check on what we are wroking @@ -4646,7 +4649,7 @@ SmgSubCommand::SmgSubCommand() "Use -uid flag to set the desired GUIDs, intended for production use only."; _flagLong = "smg"; _flagShort = ""; - _param = "[guids_num= step_size=]"; + _param = "guids_num= step_size="; _paramExp = "guids_num: (optional) number of GUIDs to be allocated per physical port\n" "step_size: (optional) step size between GUIDs\n" "Note: guids_num/step_size values can be specified per port or for both ports"; @@ -4764,7 +4767,7 @@ SetVpdSubCommand::SetVpdSubCommand() _extendedDesc = "Set Read-only VPD, Set VPD in the given FS3/FS4 image, intended for production use only."; _flagLong = "set_vpd"; _flagShort = ""; - _param = "[vpd file]"; + _param = ""; _paramExp = "vpd file: bin file containing the vpd data"; _example = FLINT_NAME " -i fw_image.bin set_vpd vpd.bin" #ifndef __WIN__ @@ -4805,7 +4808,7 @@ SetPublicKeysSubCommand::SetPublicKeysSubCommand() _extendedDesc = "Set Public Keys in the given FS3/FS4 image."; _flagLong = "set_public_keys"; _flagShort = ""; - _param = "[public keys binary file]"; + _param = ""; _paramExp = "public keys file: bin file containing the public keys data"; _example = FLINT_NAME " -i fw_image.bin set_public_keys publickeys.bin"; _v = Wtv_Img; @@ -4993,7 +4996,7 @@ DcSubCommand::DcSubCommand() " Existence of this section depends on the version of the image generation tool."; _flagLong = "dc"; _flagShort = ""; - _param = "[out-file]"; + _param = ""; _paramExp = "file: (optional) filename to write the dumped configuration to. If not given," " the data is printed to screen"; _example = FLINT_NAME " -d " MST_DEV_EXAMPLE1 " dc"; @@ -5047,7 +5050,7 @@ DhSubCommand::DhSubCommand() "This command would fail if the image does not contain a Hash file."; _flagLong = "dh"; _flagShort = ""; - _param = "[out-file]"; + _param = ""; _paramExp = "file - (optional) filename to write the dumped tracer hash file to. If not given," " the data is printed to screen"; _example = FLINT_NAME " -d " MST_DEV_EXAMPLE1 " dh hash.csv"; @@ -5102,7 +5105,7 @@ SetKeySubCommand::SetKeySubCommand() _extendedDesc = "Set/Update the HW access key which is used to enable/disable access to HW."; _flagLong = "set_key"; _flagShort = ""; - _param = "[key]"; + _param = ""; _paramExp = "key: (optional) The new key you intend to set (in hex)."; _example = FLINT_NAME " -d " MST_DEV_EXAMPLE1 " set_key 1234deaf5678"; _v = Wtv_Dev; @@ -5212,7 +5215,7 @@ HwAccessSubCommand::HwAccessSubCommand() _extendedDesc = "Enable/disable the access to the HW."; _flagLong = "hw_access"; _flagShort = ""; - _param = " [key]"; + _param = "[enable/disable] "; _paramExp = ": Specify if you intend to disable or enable the HW access.\n" "You will be asked to type a key when you try to enable HW access.\n" "key: The key you intend to use for enabling the HW access, or disabling it in 5th Gen devices.\n" @@ -5326,7 +5329,7 @@ HwSubCommand::HwSubCommand() _extendedDesc = "Access HW info and flash attributes."; _flagLong = "hw"; _flagShort = ""; - _param = " [ATTR=VAL]"; + _param = "[query/set] "; _paramExp = "query: query HW info\n" "set [ATTR=VAL]: set flash attribure\n" "Supported attributes:\n" @@ -5966,7 +5969,7 @@ RbSubCommand::RbSubCommand() _extendedDesc = "Read a data block from the flash and write it to a file or to screen."; _flagLong = "rb"; _flagShort = ""; - _param = " [out-file]"; + _param = " "; _paramExp = "addr - address of block\n" "size - size of data to read in bytes\n" "file - filename to write the block (raw binary). If not given, the data is printed to screen"; diff --git a/fw_comps_mgr/fw_comps_mgr.cpp b/fw_comps_mgr/fw_comps_mgr.cpp index a76c5d75..23d6eccf 100644 --- a/fw_comps_mgr/fw_comps_mgr.cpp +++ b/fw_comps_mgr/fw_comps_mgr.cpp @@ -1924,6 +1924,7 @@ unsigned char* FwCompsMgr::getLastErrMsg() return (unsigned char*)"LinkX activation failed"; } } + case FWCOMPS_MCC_REJECTED_INCOMPATIBLE_FLASH: return (unsigned char*)"The image does not support the device's flash type"; diff --git a/fw_comps_mgr/fw_comps_mgr_abstract_access.cpp b/fw_comps_mgr/fw_comps_mgr_abstract_access.cpp index 725aa12c..fabcb373 100644 --- a/fw_comps_mgr/fw_comps_mgr_abstract_access.cpp +++ b/fw_comps_mgr/fw_comps_mgr_abstract_access.cpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2013 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -28,6 +29,7 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. + * */ #include "fw_comps_mgr_abstract_access.h" diff --git a/fw_comps_mgr/fw_comps_mgr_abstract_access.h b/fw_comps_mgr/fw_comps_mgr_abstract_access.h index 54b8a95b..e35bea84 100644 --- a/fw_comps_mgr/fw_comps_mgr_abstract_access.h +++ b/fw_comps_mgr/fw_comps_mgr_abstract_access.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2013 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -28,6 +29,7 @@ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. + * */ #ifndef USER_MLXFWOPS_LIB_FW_ABSTRACT_COMP_ACCESS_H_ diff --git a/mlxfwops/lib/fs3_ops.cpp b/mlxfwops/lib/fs3_ops.cpp index 6f18e9b5..70eaf250 100644 --- a/mlxfwops/lib/fs3_ops.cpp +++ b/mlxfwops/lib/fs3_ops.cpp @@ -1452,6 +1452,7 @@ bool Fs3Operations::FwSetMFG(fs3_uid_t baseGuid, PrintCallBack callBackFunc) if (!_ioAccess->is_flash() && !VerifyImageAfterModifications()) { return false; } + return true; } diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index c9a3b485..2566a58a 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -1001,6 +1001,7 @@ bool Fs4Operations::parseDevData(bool readRom, bool quickQuery, bool verbose) { bool Fs4Operations::encryptedFwQuery(fw_info_t *fwInfo, bool readRom, bool quickQuery, bool ignoreDToc, bool verbose) { DPRINTF(("Fs4Operations::encryptedFwQuery\n")); + if (!initHwPtrs(true)) { DPRINTF(("Fs4Operations::encryptedFwQuery HW pointers not found")); return false; @@ -1187,7 +1188,7 @@ bool Fs4Operations::FwReadEncryptedData(void *image, u_int32_t imageSize, bool v bool Fs4Operations::FwReadData(void *image, u_int32_t *imageSize, bool verbose) { - + //* Read encrypted data bool is_encrypted = false; DPRINTF(("Fs4Operations::FwReadData\n")); @@ -3030,7 +3031,6 @@ bool Fs4Operations::VerifyImageAfterModifications() { bool Fs4Operations::Fs3UpdateSection(void *new_info, fs3_section_t sect_type, bool is_sect_failsafe, CommandType cmd_type, PrintCallBack callBackFunc) { - (void) cmd_type; struct fs4_toc_info *curr_toc = (fs4_toc_info *)NULL; struct fs4_toc_info *old_toc = (fs4_toc_info *)NULL; std::vector newSection; @@ -3852,6 +3852,7 @@ bool Fs4Operations::signForSecureBootUsingHSM(const char *public_key_file, const if (!initHwPtrs()) { return errmsg("signForSecureBootUsingHSM failed - Error: HW pointers not found"); } + SecureBootSignVersion secure_boot_version = getSecureBootSignVersion(); if (!storePublicKeyInSection(public_key_file, uuid)) { diff --git a/mlxfwops/lib/fsctrl_ops.cpp b/mlxfwops/lib/fsctrl_ops.cpp index 86fcccd7..737a57f1 100644 --- a/mlxfwops/lib/fsctrl_ops.cpp +++ b/mlxfwops/lib/fsctrl_ops.cpp @@ -1002,4 +1002,4 @@ bool FsCtrlOperations::IsSecurityVersionViolated(u_int32_t image_security_versio // Check violation of security-version return (imageSecurityVersion < deviceEfuseSecurityVersion); -} +} \ No newline at end of file diff --git a/mlxfwops/lib/fuse_gw.cpp b/mlxfwops/lib/fuse_gw.cpp index ba5de5d6..2b0ff81a 100755 --- a/mlxfwops/lib/fuse_gw.cpp +++ b/mlxfwops/lib/fuse_gw.cpp @@ -474,5 +474,4 @@ u_int32_t SecurityVersionFuse::countSetBits(u_int32_t num){ num >>= 1; } return count; -} - +} \ No newline at end of file diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 7c12f0a6..82e585ff 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -59,12 +59,14 @@ #endif //NO_OPEN_SSL #endif //UEFI_BUILD + #ifndef __WIN__ #define OP_NOT_SUPPORTED EOPNOTSUPP #else // __WIN__ #define OP_NOT_SUPPORTED EINVAL #endif // __WIN__ + #define BAD_CRC_MSG "Bad CRC." extern const char *g_sectNames[]; diff --git a/mlxfwops/lib/fw_ops.h b/mlxfwops/lib/fw_ops.h index fa9a8445..5adf369b 100644 --- a/mlxfwops/lib/fw_ops.h +++ b/mlxfwops/lib/fw_ops.h @@ -260,6 +260,7 @@ class MLXFWOP_API FwOperations : public FlintErrMsg { static int getFileSignature(const char *fname); virtual bool IsLifeCycleAccessible(chip_type_t chip_type); virtual bool IsSecurityVersionViolated(u_int32_t image_security_version); + #ifndef UEFI_BUILD static bool CheckPemKeySize(const string privPemFileStr, u_int32_t& keySize); #endif From 6ad644b209ce07702091cd26515b686bbdf37ab2 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Wed, 5 Jan 2022 15:21:08 +0200 Subject: [PATCH 043/184] Fixing Fs4Operations::IsEncryptedImage to not modify _toc_ptr member Description: When check for second ITOC header magic-pattern we shouldn't modify the _toc_ptr member Tested OS: Linux Tested devices: Carmel Tested flows: flint -i q Known gaps (with RM ticket): N/A Issue: None Change-Id: Idf73a4377c734fc22dc60ec5c1836a995b1e5549 Signed-off-by: Matan Eliyahu --- mlxfwops/lib/fs4_ops.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 2566a58a..2728d5e1 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -150,8 +150,7 @@ bool Fs4Operations::IsEncryptedImage(bool& is_encrypted) READBUF((*_ioAccess), _itoc_ptr, buffer, TOC_HEADER_SIZE, "ITOC Header"); image_layout_itoc_header_unpack(&itocHeader, buffer); if (!CheckTocSignature(&itocHeader, ITOC_ASCII)) { // Check first location of ITOC header magic-pattern - _itoc_ptr += FS4_DEFAULT_SECTOR_SIZE; - READBUF((*_ioAccess), _itoc_ptr, buffer, TOC_HEADER_SIZE, "ITOC Header"); + READBUF((*_ioAccess), _itoc_ptr + FS4_DEFAULT_SECTOR_SIZE, buffer, TOC_HEADER_SIZE, "ITOC Header"); image_layout_itoc_header_unpack(&itocHeader, buffer); if (!CheckTocSignature(&itocHeader, ITOC_ASCII)) { // Check second location of ITOC header magic-pattern is_encrypted = true; From c1c4ef7d0276b1d40e742eb77dacb9dde343d209 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Wed, 5 Jan 2022 16:12:09 +0200 Subject: [PATCH 044/184] Align ITOC/DTOC section types according to Flash App note doc Description: N/A Tested OS: Linux Tested devices: Carmel Tested flows: flint v Known gaps (with RM ticket): N/A Issue: 2196017 Change-Id: I98cff86bcfbfd120a8222db4e3c711760bbff12b Signed-off-by: Matan Eliyahu --- mlxfwops/lib/bluefiled_signature_manager.cpp | 2 +- mlxfwops/lib/flint_base.h | 101 ++++++++-------- mlxfwops/lib/fs3_ops.cpp | 116 ++++++++++--------- mlxfwops/lib/fs4_ops.cpp | 2 +- 4 files changed, 119 insertions(+), 102 deletions(-) diff --git a/mlxfwops/lib/bluefiled_signature_manager.cpp b/mlxfwops/lib/bluefiled_signature_manager.cpp index b8ab1593..5a1f1b7c 100644 --- a/mlxfwops/lib/bluefiled_signature_manager.cpp +++ b/mlxfwops/lib/bluefiled_signature_manager.cpp @@ -65,7 +65,7 @@ bool BluefieldFwOperationsSignatureManager::AddSignature(mfile* mf, Fs3Operation // burn the HMAC digest u_int32_t sectionSize = 0x0; u_int32_t sectionOffset = 0x0; - if (!imageOps->GetSectionSizeAndOffset(FS3_HMAC, sectionSize, sectionOffset)) { + if (!imageOps->GetSectionSizeAndOffset(FS3_HMAC_DIGEST, sectionSize, sectionOffset)) { return errmsg("Could not retrieve HMAC section size and offset"); } diff --git a/mlxfwops/lib/flint_base.h b/mlxfwops/lib/flint_base.h index f3edc433..d4ad819b 100644 --- a/mlxfwops/lib/flint_base.h +++ b/mlxfwops/lib/flint_base.h @@ -259,56 +259,65 @@ enum SectionType { * array. It is recommended to leave the unused part of the iTOC section blank (that is, 0xff in all unused bytes)\;All other values Reserved \; */ typedef enum fs3_section { - FS3_BOOT_CODE = 0x1, - FS3_PCI_CODE = 0x2, - FS3_MAIN_CODE = 0x3, - FS3_PCIE_LINK_CODE = 0x4, - FS3_IRON_PREP_CODE = 0x5, + FS3_BOOT_CODE = 0x1, + FS3_PCI_CODE = 0x2, + FS3_MAIN_CODE = 0x3, + FS3_PCIE_LINK_CODE = 0x4, + FS3_IRON_PREP_CODE = 0x5, FS3_POST_IRON_BOOT_CODE = 0x6, - FS3_UPGRADE_CODE = 0x7, - FS3_HW_BOOT_CFG = 0x8, - FS3_HW_MAIN_CFG = 0x9, - FS3_PHY_UC_CODE = 0xa, - FS3_PHY_UC_CONSTS = 0xb, - FS3_PHY_UC_CMD = 0xc, - FS4_BOOT3_CODE = 0xf, - FS3_IMAGE_INFO = 0x10, - FS3_FW_BOOT_CFG = 0x11, - FS3_FW_MAIN_CFG = 0x12, - FS3_ROM_CODE = 0x18, - FS3_RESET_INFO = 0x20, - FS3_DBG_FW_INI = 0x30, - // FS3_DBG_LOG_MAP = 0x30 - in practice its unused and DBG_FW_INI is found in that section instead - FS3_DBG_FW_PARAMS = 0x32, - FS3_FW_ADB = 0x33, + FS3_UPGRADE_CODE = 0x7, + FS3_HW_BOOT_CFG = 0x8, + FS3_HW_MAIN_CFG = 0x9, + FS3_PHY_UC_CODE = 0xa, + FS3_PHY_UC_CONSTS = 0xb, + FS3_PCIE_PHY_UC_CODE = 0xc, + FS3_CCIR_INFRA_CODE = 0xd, + FS3_CCIR_ALGO_CODE = 0xe, + FS4_BOOT3_CODE = 0xf, + FS3_IMAGE_INFO = 0x10, + FS3_FW_BOOT_CFG = 0x11, + FS3_FW_MAIN_CFG = 0x12, + FS3_APU_KERNEL = 0x14, + FS3_APU_APPS = 0x15, + FS3_ROM_CODE = 0x18, + FS3_RESET_INFO = 0x20, + FS3_DBG_FW_INI = 0x30, + FS3_DBG_FW_PARAMS = 0x32, + FS3_FW_ADB = 0x33, + FS4_GB_FW_CODE = 0x34, + FS4_TILE_FW_CODE = 0x35, + FS4_FW_TILE_INI = 0x36, + FS4_HW_TILE_INI = 0x37, FS3_IMAGE_SIGNATURE_256 = 0xa0, - FS3_PUBLIC_KEYS_2048 = 0xa1, - FS3_FORBIDDEN_VERSIONS = 0xa2, + FS3_PUBLIC_KEYS_2048 = 0xa1, + FS3_FORBIDDEN_VERSIONS = 0xa2, FS3_IMAGE_SIGNATURE_512 = 0xa3, - FS3_PUBLIC_KEYS_4096 = 0xa4, - FS3_HMAC = 0xa5, - FS4_RSA_PUBLIC_KEY = 0xa6, + FS3_PUBLIC_KEYS_4096 = 0xa4, + FS3_HMAC_DIGEST = 0xa5, + FS4_RSA_PUBLIC_KEY = 0xa6, FS4_RSA_4096_SIGNATURES = 0xa7, - FS3_MFG_INFO = 0xe0, - FS3_DEV_INFO = 0xe1, - FS3_NV_DATA1 = 0xe2, - FS3_VPD_R0 = 0xe3, - FS3_NV_DATA2 = 0xe4, - FS3_FW_NV_LOG = 0xe5, - FS3_NV_DATA0 = 0xe6, // replaces FS3_NV_DATA1 - FS3_CRDUMP_MASK_DATA = 0xe9, - FS4_PART_TYPE_FW_INTERNAL_USAGE = 0xea, - FS4_PART_TYPE_PROGRAMMABLE_HW_FW1 = 0xeb, - FS4_PART_TYPE_PROGRAMMABLE_HW_FW2 = 0xec, - FS4_LC_INI1_TABLE = 0xef, - FS4_LC_INI2_TABLE = 0xf0, - FS4_LC_INI_NV_DATA = 0xf1, - FS4_HASHES_TABLE = 0xfa, - FS4_HW_PTR = 0xfb, - FS4_TOOLS_AREA = 0xfc, - FS3_ITOC = 0xfd, - FS3_DTOC = 0xfe, - FS3_END = 0xff, + FS3_MFG_INFO = 0xe0, + FS3_DEV_INFO = 0xe1, + FS3_NV_DATA1 = 0xe2, + FS3_VPD_R0 = 0xe3, + FS3_NV_DATA2 = 0xe4, + FS3_FW_NV_LOG = 0xe5, + FS3_NV_DATA0 = 0xe6, // replaces FS3_NV_DATA1 + FS4_DEV_INFO1 = 0xe7, + FS4_DEV_INFO2 = 0xe8, + FS3_CRDUMP_MASK_DATA = 0xe9, + FS4_FW_INTERNAL_USAGE = 0xea, + FS4_PROGRAMMABLE_HW_FW1 = 0xeb, + FS4_PROGRAMMABLE_HW_FW2 = 0xec, + FS4_LC_INI1_TABLE = 0xef, + FS4_LC_INI2_TABLE = 0xf0, + FS4_LC_INI_NV_DATA = 0xf1, + FS4_HASHES_TABLE = 0xfa, + FS4_HW_PTR = 0xfb, + FS4_TOOLS_AREA = 0xfc, + FS3_ITOC = 0xfd, + FS3_DTOC = 0xfe, + FS3_END = 0xff, } fs3_section_t; enum CommandType { diff --git a/mlxfwops/lib/fs3_ops.cpp b/mlxfwops/lib/fs3_ops.cpp index 70eaf250..ed8a05d9 100644 --- a/mlxfwops/lib/fs3_ops.cpp +++ b/mlxfwops/lib/fs3_ops.cpp @@ -83,57 +83,65 @@ const u_int32_t Fs3Operations::_itocSignature[4] = { }; const Fs3Operations::SectionInfo Fs3Operations::_fs3SectionsInfoArr[] = { - {FS3_END, "END"}, - {FS3_ITOC, "ITOC_HEADER"}, - - {FS3_BOOT_CODE, "BOOT_CODE"}, - {FS3_PCI_CODE, "PCI_CODE"}, - {FS3_MAIN_CODE, "MAIN_CODE"}, - {FS3_PCIE_LINK_CODE, "PCIE_LINK_CODE"}, - {FS3_IRON_PREP_CODE, "IRON_PREP_CODE"}, - {FS3_POST_IRON_BOOT_CODE, "POST_IRON_BOOT_CODE"}, - {FS3_UPGRADE_CODE, "UPGRADE_CODE"}, - {FS3_HW_BOOT_CFG, "HW_BOOT_CFG"}, - {FS3_HW_MAIN_CFG, "HW_MAIN_CFG"}, - {FS3_PHY_UC_CODE, "PHY_UC_CODE"}, - {FS3_PHY_UC_CONSTS, "PHY_UC_CONSTS"}, - {FS3_PHY_UC_CMD, "PHY_UC_CMD"}, - {FS4_BOOT3_CODE, "BOOT3_CODE"}, - {FS3_IMAGE_INFO, "IMAGE_INFO"}, - {FS3_FW_BOOT_CFG, "FW_BOOT_CFG"}, - {FS3_FW_MAIN_CFG, "FW_MAIN_CFG"}, - {FS3_ROM_CODE, "ROM_CODE"}, - {FS3_RESET_INFO, "FS3_RESET_INFO"}, - {FS3_DBG_FW_INI, "DBG_FW_INI"}, - {FS3_DBG_FW_PARAMS, "DBG_FW_PARAMS"}, - {FS3_FW_ADB, "FW_ADB"}, - {FS3_IMAGE_SIGNATURE_256, "IMAGE_SIGNATURE_256"}, - {FS3_PUBLIC_KEYS_2048, "PUBLIC_KEYS_2048"}, - {FS3_PUBLIC_KEYS_4096, "PUBLIC_KEYS_4096"}, - {FS3_FORBIDDEN_VERSIONS, "FORBIDDEN_VERSIONS"}, - {FS3_IMAGE_SIGNATURE_512, "IMAGE_SIGNATURE_512"}, - {FS3_CRDUMP_MASK_DATA, "CRDUMP_MASK_DATA"}, - {FS3_HMAC, "HMAC"}, - {FS3_MFG_INFO, MFG_INFO}, - {FS3_DEV_INFO, "DEV_INFO"}, - {FS3_NV_DATA1, "NV_DATA"}, - {FS3_VPD_R0, "VPD_R0"}, - {FS3_NV_DATA2, "NV_DATA"}, - {FS3_NV_DATA0, "NV_DATA"}, - {FS3_FW_NV_LOG, "FW_NV_LOG"}, - {FS3_NV_DATA0, "NV_DATA"}, - {FS4_PART_TYPE_FW_INTERNAL_USAGE , "PART_TYPE_FW_INTERNAL_USAGE"}, - {FS4_PART_TYPE_PROGRAMMABLE_HW_FW1, "FS4_PART_TYPE_PROGRAMMABLE_HW_FW"}, - {FS4_PART_TYPE_PROGRAMMABLE_HW_FW2, "FS4_PART_TYPE_PROGRAMMABLE_HW_FW"}, - {FS4_LC_INI1_TABLE, "FS4_LC_INI1_TABLE"}, - {FS4_LC_INI2_TABLE, "FS4_LC_INI2_TABLE"}, - {FS4_LC_INI_NV_DATA, "FS4_LC_INI_NV_DATA"}, - {FS3_DTOC, "DTOC_HEADER"}, - {FS4_HW_PTR, "HW_POINTERS"}, - {FS4_TOOLS_AREA, "TOOLS_AREA"}, - {FS4_RSA_PUBLIC_KEY, "FS4_RSA_PUBLIC_KEY"}, - {FS4_RSA_4096_SIGNATURES, "FS4_RSA_4096_SIGNATURES"}, - {FS4_HASHES_TABLE, "HASHES_TABLE"} + {FS3_END, "END"}, + {FS3_ITOC, "ITOC_HEADER"}, + {FS3_BOOT_CODE, "BOOT_CODE"}, + {FS3_PCI_CODE, "PCI_CODE"}, + {FS3_MAIN_CODE, "MAIN_CODE"}, + {FS3_PCIE_LINK_CODE, "PCIE_LINK_CODE"}, + {FS3_IRON_PREP_CODE, "IRON_PREP_CODE"}, + {FS3_POST_IRON_BOOT_CODE, "POST_IRON_BOOT_CODE"}, + {FS3_UPGRADE_CODE, "UPGRADE_CODE"}, + {FS3_HW_BOOT_CFG, "HW_BOOT_CFG"}, + {FS3_HW_MAIN_CFG, "HW_MAIN_CFG"}, + {FS3_PHY_UC_CODE, "PHY_UC_CODE"}, + {FS3_PHY_UC_CONSTS, "PHY_UC_CONSTS"}, + {FS3_PCIE_PHY_UC_CODE, "PCIE_PHY_UC_CODE"}, + {FS3_CCIR_INFRA_CODE, "CCIR_INFRA_CODE"}, + {FS3_CCIR_ALGO_CODE, "CCIR_ALGO_CODE"}, + {FS4_BOOT3_CODE, "BOOT3_CODE"}, + {FS3_IMAGE_INFO, "IMAGE_INFO"}, + {FS3_FW_BOOT_CFG, "FW_BOOT_CFG"}, + {FS3_FW_MAIN_CFG, "FW_MAIN_CFG"}, + {FS3_APU_KERNEL, "APU_KERNEL"}, + {FS3_APU_APPS, "APU_APPS"}, + {FS3_ROM_CODE, "ROM_CODE"}, + {FS3_RESET_INFO, "RESET_INFO"}, + {FS3_DBG_FW_INI, "DBG_FW_INI"}, + {FS3_DBG_FW_PARAMS, "DBG_FW_PARAMS"}, + {FS3_FW_ADB, "FW_ADB"}, + {FS4_GB_FW_CODE, "GB_FW_CODE"}, + {FS4_TILE_FW_CODE, "TILE_FW_CODE"}, + {FS4_FW_TILE_INI, "FW_TILE_INI"}, + {FS4_HW_TILE_INI, "HW_TILE_INI"}, + {FS3_IMAGE_SIGNATURE_256, "IMAGE_SIGNATURE_256"}, + {FS3_PUBLIC_KEYS_2048, "PUBLIC_KEYS_2048"}, + {FS3_PUBLIC_KEYS_4096, "PUBLIC_KEYS_4096"}, + {FS3_FORBIDDEN_VERSIONS, "FORBIDDEN_VERSIONS"}, + {FS3_IMAGE_SIGNATURE_512, "IMAGE_SIGNATURE_512"}, + {FS3_CRDUMP_MASK_DATA, "CRDUMP_MASK_DATA"}, + {FS3_HMAC_DIGEST, "HMAC_DIGEST"}, + {FS3_MFG_INFO, MFG_INFO}, + {FS3_DEV_INFO, DEV_INFO}, + {FS3_NV_DATA1, "NV_DATA"}, + {FS3_VPD_R0, "VPD_R0"}, + {FS3_NV_DATA2, "NV_DATA"}, + {FS3_FW_NV_LOG, "FW_NV_LOG"}, + {FS3_NV_DATA0, "NV_DATA"}, + {FS4_DEV_INFO1, "DEV_INFO1"}, + {FS4_DEV_INFO2, "DEV_INFO2"}, + {FS4_FW_INTERNAL_USAGE, "FW_INTERNAL_USAGE"}, + {FS4_PROGRAMMABLE_HW_FW1, "PROGRAMMABLE_HW_FW"}, + {FS4_PROGRAMMABLE_HW_FW2, "PROGRAMMABLE_HW_FW"}, + {FS4_LC_INI1_TABLE, "LC_INI1_TABLE"}, + {FS4_LC_INI2_TABLE, "LC_INI2_TABLE"}, + {FS4_LC_INI_NV_DATA, "LC_INI_NV_DATA"}, + {FS3_DTOC, "DTOC_HEADER"}, + {FS4_HW_PTR, "HW_POINTERS"}, + {FS4_TOOLS_AREA, "TOOLS_AREA"}, + {FS4_RSA_PUBLIC_KEY, "RSA_PUBLIC_KEY"}, + {FS4_RSA_4096_SIGNATURES, "RSA_4096_SIGNATURES"}, + {FS4_HASHES_TABLE, "HASHES_TABLE"} }; bool Fs3Operations::Fs3UpdateImgCache(u_int8_t *buff, u_int32_t addr, u_int32_t size) @@ -3271,7 +3279,7 @@ bool Fs3Operations::CheckItocArray() bool Fs3Operations::IsCriticalSection(u_int8_t sect_type) { - if (sect_type != FS3_PCIE_LINK_CODE && sect_type != FS3_PHY_UC_CMD && sect_type != FS3_HW_BOOT_CFG) + if (sect_type != FS3_PCIE_LINK_CODE && sect_type != FS3_PCIE_PHY_UC_CODE && sect_type != FS3_HW_BOOT_CFG) return false; return true; } @@ -3581,7 +3589,7 @@ bool Fs3Operations::CalcHMAC(const vector& key, vector& dige } //mask hmac itoc entry and section - MaskItocSectionAndEntry(FS3_HMAC, data); + MaskItocSectionAndEntry(FS3_HMAC_DIGEST, data); //mask magic pattern (First 16 bytes): for (unsigned int i = 0; i < 16; i++) { @@ -3591,7 +3599,7 @@ bool Fs3Operations::CalcHMAC(const vector& key, vector& dige //Remove the HMAC section from the end of the buffer u_int32_t hmacSectionSize = 0x0; u_int32_t hmacSectionOffset = 0x0; - if (!GetSectionSizeAndOffset(FS3_HMAC, hmacSectionSize, hmacSectionOffset)) { + if (!GetSectionSizeAndOffset(FS3_HMAC_DIGEST, hmacSectionSize, hmacSectionOffset)) { return errmsg("HMAC section is not found\n"); } diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 2728d5e1..9e9d9030 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -4143,7 +4143,7 @@ bool Fs4Operations::getCriticalNonCriticalSections(vector& critical, v bool Fs4Operations::IsCriticalSection(u_int8_t sect_type) { - if (sect_type != FS3_PCIE_LINK_CODE && sect_type != FS3_PHY_UC_CMD && sect_type != FS3_HW_BOOT_CFG) + if (sect_type != FS3_PCIE_LINK_CODE && sect_type != FS3_PCIE_PHY_UC_CODE && sect_type != FS3_HW_BOOT_CFG) return false; return true; } From a62169d024746c7961e20d7ee9789121bc28aed0 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Wed, 5 Jan 2022 18:19:41 +0200 Subject: [PATCH 045/184] Support 4 new DTOC certificates section types Description: N/A Tested OS: Linux Tested devices: Carmel Tested flows: flint -i v Known gaps (with RM ticket): N/A Issue: 2919316 Change-Id: I55791aefc2a9f12de4511fdb4b6e4cc31473b65b Signed-off-by: Matan Eliyahu --- mlxfwops/lib/flint_base.h | 4 ++++ mlxfwops/lib/fs3_ops.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/mlxfwops/lib/flint_base.h b/mlxfwops/lib/flint_base.h index d4ad819b..7ed968d8 100644 --- a/mlxfwops/lib/flint_base.h +++ b/mlxfwops/lib/flint_base.h @@ -309,9 +309,13 @@ typedef enum fs3_section { FS4_FW_INTERNAL_USAGE = 0xea, FS4_PROGRAMMABLE_HW_FW1 = 0xeb, FS4_PROGRAMMABLE_HW_FW2 = 0xec, + FS4_DIGITAL_CERT_PTR = 0xed, + FS4_DIGITAL_CERT_RW = 0xee, FS4_LC_INI1_TABLE = 0xef, FS4_LC_INI2_TABLE = 0xf0, FS4_LC_INI_NV_DATA = 0xf1, + FS4_CERT_CHAIN_0 = 0xf2, + FS4_DIGITAL_CACERT_RW = 0xf3, FS4_HASHES_TABLE = 0xfa, FS4_HW_PTR = 0xfb, FS4_TOOLS_AREA = 0xfc, diff --git a/mlxfwops/lib/fs3_ops.cpp b/mlxfwops/lib/fs3_ops.cpp index ed8a05d9..6347d2de 100644 --- a/mlxfwops/lib/fs3_ops.cpp +++ b/mlxfwops/lib/fs3_ops.cpp @@ -133,9 +133,13 @@ const Fs3Operations::SectionInfo Fs3Operations::_fs3SectionsInfoArr[] = { {FS4_FW_INTERNAL_USAGE, "FW_INTERNAL_USAGE"}, {FS4_PROGRAMMABLE_HW_FW1, "PROGRAMMABLE_HW_FW"}, {FS4_PROGRAMMABLE_HW_FW2, "PROGRAMMABLE_HW_FW"}, + {FS4_DIGITAL_CERT_PTR, "DIGITAL_CERT_PTR"}, + {FS4_DIGITAL_CERT_RW, "DIGITAL_CERT_RW"}, {FS4_LC_INI1_TABLE, "LC_INI1_TABLE"}, {FS4_LC_INI2_TABLE, "LC_INI2_TABLE"}, {FS4_LC_INI_NV_DATA, "LC_INI_NV_DATA"}, + {FS4_CERT_CHAIN_0, "CERT_CHAIN_0"}, + {FS4_DIGITAL_CACERT_RW, "DIGITAL_CACERT_RW"}, {FS3_DTOC, "DTOC_HEADER"}, {FS4_HW_PTR, "HW_POINTERS"}, {FS4_TOOLS_AREA, "TOOLS_AREA"}, From 565076fa7468ee3389321655603a3ceca80af2a9 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Thu, 6 Jan 2022 15:28:28 +0200 Subject: [PATCH 046/184] Fix production burn flow to burn VPD section as well in case of encrypted image Description: Fixing Fs4Operations::burnEncryptedImage call to parseDevData with quickquery=false Tested OS: Linux Tested devices: Carmel Tested flows: production burn Known gaps (with RM ticket): N/A Issue: 2922291 Change-Id: I2b1cc419efc8ac8a962b99a10f9502ef85f8526a Signed-off-by: Matan Eliyahu --- mlxfwops/lib/fs4_ops.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 9e9d9030..8139d275 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -2073,7 +2073,7 @@ bool Fs4Operations::burnEncryptedImage(FwOperations* imageOps, ExtBurnParams& bu } //* Parse DTOC and its sections - ((Fs4Operations*)imageOps)->parseDevData(); + ((Fs4Operations*)imageOps)->parseDevData(true, false); //* DTOC sanity check if (!((Fs4Operations*)imageOps)->CheckDTocArray()) { From 468703b4bc79d200b369124dc7f2601caf902007 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Thu, 6 Jan 2022 11:22:12 +0200 Subject: [PATCH 047/184] Fixing cable features Description: Fixing show_module and --cables flags while accessing Buffalo ports Issue: 2921059 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_cables_commander.cpp | 3 +++ mlxlink/modules/mlxlink_cables_commander.h | 1 + mlxlink/modules/mlxlink_commander.cpp | 4 ++++ mlxlink/modules/mlxlink_commander.h | 1 + 4 files changed, 9 insertions(+) diff --git a/mlxlink/modules/mlxlink_cables_commander.cpp b/mlxlink/modules/mlxlink_cables_commander.cpp index 178356ee..d4c5c5c8 100644 --- a/mlxlink/modules/mlxlink_cables_commander.cpp +++ b/mlxlink/modules/mlxlink_cables_commander.cpp @@ -35,6 +35,7 @@ MlxlinkCablesCommander::MlxlinkCablesCommander(Json::Value &jsonRoot): _jsonRoot(jsonRoot) { _moduleNumber = 0; + _slotIndex = 0; _sfp51Paging = false; _passiveQsfp = false; _localPort = 0; @@ -52,6 +53,7 @@ void MlxlinkCablesCommander::readMCIA(u_int32_t page, u_int32_t size, string regName = "MCIA"; resetParser(regName); updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); updateField("size", size); updateField("page_number", page); updateField("device_address", offset); @@ -81,6 +83,7 @@ void MlxlinkCablesCommander::writeMCIA(u_int32_t page, u_int32_t size, string regName = "MCIA"; resetParser(regName); updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); updateField("size", dataSize); updateField("page_number", page); updateField("device_address", offset); diff --git a/mlxlink/modules/mlxlink_cables_commander.h b/mlxlink/modules/mlxlink_cables_commander.h index 0dfcff26..91caa195 100644 --- a/mlxlink/modules/mlxlink_cables_commander.h +++ b/mlxlink/modules/mlxlink_cables_commander.h @@ -153,6 +153,7 @@ class MlxlinkCablesCommander :public MlxlinkRegParser{ u_int16_t getStatusBit(u_int32_t channel, u_int16_t val, u_int32_t statusMask); u_int32_t _moduleNumber; + u_int32_t _slotIndex; u_int32_t _cableIdentifier; bool _sfp51Paging; bool _passiveQsfp; diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index 078b675b..0284fc03 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -63,6 +63,7 @@ MlxlinkCommander::MlxlinkCommander() : _userInput() _moduleTemp = "N/A"; _cableMediaType = 0; _moduleNumber = 0; + _slotIndex = 0; _uniqueCmds = 0; _networkCmds = 0; _activeSpeed = 0; @@ -522,6 +523,7 @@ void MlxlinkCommander::labeltoDSlocalPort() if ((getFieldValue("label_port") == port) && (getFieldValue("slot_num") == lineCard)) { _localPort = localPort; + _slotIndex = lineCard; isLocalPortValid = true; break; } @@ -1428,6 +1430,7 @@ void MlxlinkCommander::showModuleInfo() string regName = "PMAOS"; resetParser(regName); updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); u_int32_t oper_status = getFieldValue("oper_status"); @@ -4420,6 +4423,7 @@ void MlxlinkCommander::initCablesCommander() _cablesCommander->_gvmiAddress = _gvmiAddress; _cablesCommander->_mlxlinkLogger = _mlxlinkLogger; _cablesCommander->_moduleNumber = _moduleNumber; + _cablesCommander->_slotIndex = _slotIndex; _cablesCommander->_localPort = _localPort; _cablesCommander->_numOfLanes = _numOfLanes; _cablesCommander->_cableIdentifier = _cableIdentifier; diff --git a/mlxlink/modules/mlxlink_commander.h b/mlxlink/modules/mlxlink_commander.h index 4849f69b..dd750b22 100644 --- a/mlxlink/modules/mlxlink_commander.h +++ b/mlxlink/modules/mlxlink_commander.h @@ -559,6 +559,7 @@ class MlxlinkCommander: public MlxlinkRegParser { u_int32_t _protoAdminEx; u_int32_t _productTechnology; u_int32_t _moduleNumber; + u_int32_t _slotIndex; u_int32_t _linkSpeed; string _extAdbFile; string _device; From b46f8e623d3402e265bcad5afd9dd8c57c983d5f Mon Sep 17 00:00:00 2001 From: Oded Burstein Date: Mon, 10 Jan 2022 18:45:11 +0200 Subject: [PATCH 048/184] fixed compilation issue for freebsd --- mtcr_ul/mtcr_ul_icmd_cif.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mtcr_ul/mtcr_ul_icmd_cif.c b/mtcr_ul/mtcr_ul_icmd_cif.c index fbd5c9aa..3ab3ba36 100644 --- a/mtcr_ul/mtcr_ul_icmd_cif.c +++ b/mtcr_ul/mtcr_ul_icmd_cif.c @@ -44,10 +44,11 @@ #include "packets_common.h" #ifndef __FreeBSD__ #include "mtcr_ib_res_mgt.h" +#include "tools_dev_types.h" #endif #include "mtcr_mem_ops.h" -#include "tools_dev_types.h" + #define ICMD_QUERY_CAP_CMD_ID 0x8400 #define ICMD_QUERY_CAP_CMD_SZ 0x8 @@ -1115,6 +1116,7 @@ void icmd_get_dma_support(mfile *mf) } +#ifndef __FreeBSD__ static int is_pci_device(mfile* mf) { return (mf->flags & MDEVS_I2CM) @@ -1122,6 +1124,7 @@ static int is_pci_device(mfile* mf) || (mf->flags & MDEVS_SOFTWARE); } + static int is_livefish_device(mfile *mf) { // Make sure to update this table both in mtcr.c & mtcr_ul_com.c ! @@ -1163,6 +1166,7 @@ static int is_livefish_device(mfile *mf) } return 0; } +#endif int icmd_open(mfile *mf) { From 8fbaf482fad67a643a2cc66ec68c7847db7a9f93 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Mon, 10 Jan 2022 11:03:36 +0200 Subject: [PATCH 049/184] Skip MAIN CRCs removal in case MAIN doesn't exist for fw update sign flow Description: In case of minimized image we don't have MAIN section, so we need to skip RemoveCRCsFromMainSection Tested OS: N/A Tested devices: N/A Tested flows: N/A Known gaps (with RM ticket): N/A Issue: 2928610 Change-Id: I5033eb48ea9ce0b0e8c6fd24f586320ddbf0c02e Signed-off-by: Matan Eliyahu --- mlxfwops/lib/fs4_ops.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 8139d275..9275d562 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -471,7 +471,7 @@ bool Fs4Operations::verifyTocHeader(u_int32_t tocAddr, bool isDtoc, VerifyCallBa */ void Fs4Operations::RemoveCRCsFromMainSection(vector& img) { //* Get MAIN section ITOC entry - struct fs4_toc_info *main_itoc_entry = NULL; + struct fs4_toc_info* main_itoc_entry = NULL; fs4_toc_info *itoc_entries = _fs4ImgInfo.itocArr.tocArr; for (int i = 0; i < _fs4ImgInfo.itocArr.numOfTocs; i++) { if (itoc_entries[i].toc_entry.type == FS3_MAIN_CODE) { @@ -479,6 +479,9 @@ void Fs4Operations::RemoveCRCsFromMainSection(vector& img) { break; } } + if (main_itoc_entry == NULL) { + return; + } u_int32_t main_addr = main_itoc_entry->toc_entry.flash_addr << 2; // addr in entry is in DW u_int32_t main_size = main_itoc_entry->toc_entry.size << 2; // size in entry is in DW From 490733c24ec3bef337e7e7301a274e808285423a Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Tue, 11 Jan 2022 17:36:21 +0200 Subject: [PATCH 050/184] Fix switch case in mf_update_boot_addr function Description: This caused the false warning message in case of burning (not via MCC) Carmel/BB devices "-W- Failed to update FW boot address , power cycle the device in order to load the new FW" Tested OS: Linux Tested devices: Carmel Tested flows: production burn Known gaps (with RM ticket): N/A Issue: 2916128 Change-Id: I70d3aeb8b8f0fc15bc63aba562a89309a78dc8ac Signed-off-by: Matan Eliyahu --- mflash/mflash.c | 2 ++ mlxfwops/lib/fw_ops.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mflash/mflash.c b/mflash/mflash.c index 4c27d297..81868a92 100644 --- a/mflash/mflash.c +++ b/mflash/mflash.c @@ -2786,10 +2786,12 @@ int mf_update_boot_addr(mflash *mfl, u_int32_t boot_addr) case DeviceQuantum2: boot_cr_space_address = 0xf1000; offset_in_address = 0; + break; case DeviceConnectX7: case DeviceBlueField3: boot_cr_space_address = 0xf2000; offset_in_address = 0; + break; default: return MFE_UNSUPPORTED_DEVICE; } diff --git a/mlxfwops/lib/fw_ops.h b/mlxfwops/lib/fw_ops.h index 5adf369b..fc88b74e 100644 --- a/mlxfwops/lib/fw_ops.h +++ b/mlxfwops/lib/fw_ops.h @@ -413,7 +413,6 @@ class MLXFWOP_API FwOperations : public FlintErrMsg { #define FS3_IND_ADDR 0x24 #define FS4_IND_ADDR 0x10 #define ARR_SIZE(arr) sizeof(arr) / sizeof(arr[0]) - #define RESTORING_MSG "Restoring signature" struct FwImgInfo { fw_info_com_t ext_info; From a9c24d95454811a81d9a4a4246495f02f9fde7e1 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Tue, 11 Jan 2022 17:33:56 +0200 Subject: [PATCH 051/184] Fixing encrypted image burning progress percentage (not via MCC) Description: Tested OS: Linux Tested devices: Carmel Tested flows: production burn Known gaps (with RM ticket): N/A Issue: None Change-Id: I1f13cbf9ca05de785dbd8cafd2a6ef45a5f284f6 Signed-off-by: Matan Eliyahu --- mlxfwops/lib/fs4_ops.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 9275d562..06136123 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -2120,7 +2120,7 @@ bool Fs4Operations::burnEncryptedImage(FwOperations* imageOps, ExtBurnParams& bu } //* Get image size without signature - total_img_size += imgBuff.size() - FS3_FW_SIGNATURE_SIZE; + total_img_size += imgBuff.size(); DPRINTF(("Fs4Operations::burnEncryptedImage - image size to burn = 0x%x\n", (u_int32_t)imgBuff.size())); //* Burn @@ -2141,6 +2141,7 @@ bool Fs4Operations::burnEncryptedImage(FwOperations* imageOps, ExtBurnParams& bu { return errmsg("Failed to burn encrypted image\n"); } + alreadyWrittenSz += imgBuff.size() - FS3_FW_SIGNATURE_SIZE; if (burnParams.useImgDevData) { //* Burning DTOC @@ -2204,6 +2205,8 @@ bool Fs4Operations::burnEncryptedImage(FwOperations* imageOps, ExtBurnParams& bu { return errmsg("Failed to burn encrypted image signature\n"); } + alreadyWrittenSz += FS3_FW_SIGNATURE_SIZE; + return DoAfterBurnJobs(_fs4_magic_pattern, burnParams, (Flash*)(this->_ioAccess), new_image_start_addr, log2_chunk_size); } From 339499b0bf54d77cdca7b02b5a30e3b06eb3472d Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Thu, 13 Jan 2022 14:49:23 +0200 Subject: [PATCH 052/184] remove shebang line from mstfwtrace.py script should run from python wrapper which decide on what python version to run --- tracers/fwtrace/mstfwtrace.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tracers/fwtrace/mstfwtrace.py b/tracers/fwtrace/mstfwtrace.py index 5243ac3f..bf732d7b 100755 --- a/tracers/fwtrace/mstfwtrace.py +++ b/tracers/fwtrace/mstfwtrace.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python -# -- -# # Copyright (c) 2019-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # This software is available to you under a choice of one of two @@ -30,7 +27,6 @@ # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - # -- From df7903c2312be64fe183161e43101d9f019df526 Mon Sep 17 00:00:00 2001 From: Benjamin Drung Date: Tue, 3 Jan 2017 20:01:35 +0100 Subject: [PATCH 053/184] Fix man page errors lintian found some issues with the man pages. Fix the reported issue, but do not start the needed full adjustment of the formatting. Bug: https://github.com/Mellanox/mstflint/issues/38 Signed-off-by: Benjamin Drung --- man/mstarchive.1 | 2 +- man/mstconfig.1 | 72 +++++++++++----------- man/mstcongestion.1 | 2 +- man/mstflint.1 | 138 ++++++++++++++++++++---------------------- man/mstfwmanager.1 | 2 +- man/mstfwreset.1 | 2 +- man/mstfwtrace.1 | 2 +- man/mstlink.1 | 30 ++++----- man/mstmcra.1 | 2 +- man/mstmread.1 | 2 +- man/mstmtserver.1 | 15 +---- man/mstmwrite.1 | 2 +- man/mstprivhost.1 | 2 +- man/mstreg.1 | 2 +- man/mstregdump.1 | 25 ++++---- man/mstresourcedump.1 | 2 +- man/mstvpd.1 | 2 +- 17 files changed, 141 insertions(+), 163 deletions(-) diff --git a/man/mstarchive.1 b/man/mstarchive.1 index 42d5ed30..82ec2947 100644 --- a/man/mstarchive.1 +++ b/man/mstarchive.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTARCHIVE "1" "March 2020" "mstarchive NAME" "User Commands" .SH NAME -mstarchive \- manual page for mstarchive NAME +mstarchive \- generate MFA2 archives .SH DESCRIPTION NAME .IP diff --git a/man/mstconfig.1 b/man/mstconfig.1 index 2acc37b7..302673b6 100644 --- a/man/mstconfig.1 +++ b/man/mstconfig.1 @@ -1,14 +1,14 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTCONFIG, "1" "March 2020" "mstconfig, mstflint 4.14.0, built on Mar 3 2020, 14:01:56. Git SHA Hash: N/A" "User Commands" .SH NAME -mstconfig, \- manual page for mstconfig, mstflint 4.14.0, built on Mar 3 2020, 14:01:56. Git SHA Hash: N/A +mstconfig \- set or query non-volatile configurable options for Mellanox HCAs .SH DESCRIPTION .IP -NAME: +NAME .IP mstconfig .IP -SYNOPSIS: +SYNOPSIS .IP mstconfig [Options] [Parameters] .IP @@ -20,78 +20,78 @@ create and burn a new firmware. OPTIONS: .TP \fB\-d\fR|\-\-dev -: Perform operation for a specified MST device. +Perform operation for a specified MST device. .TP \fB\-b\fR|\-\-db -: Use a specific database file. +Use a specific database file. .TP \fB\-f\fR|\-\-file -: raw configuration file. +raw configuration file. .TP \fB\-h\fR|\-\-help -: Display help message. +Display help message. .TP \fB\-v\fR|\-\-version -: Display version info. +Display version info. .TP \fB\-e\fR|\-\-enable_verbosity -: Show default and current configurations. +Show default and current configurations. .TP \fB\-y\fR|\-\-yes -: Answer yes in prompt. +Answer yes in prompt. .TP \fB\-a\fR|\-\-all_attrs -: Show all attributes in the XML template +Show all attributes in the XML template .TP \fB\-p\fR|\-\-private_key -: pem file for private key +pem file for private key .TP \fB\-u\fR|\-\-key_uuid -: keypair uuid -.IP -COMMANDS: +keypair uuid +.SH +COMMANDS .TP clear_semaphore -: clear the tool semaphore. +clear the tool semaphore. .TP i[show_confs] -: display information about all configurations. +display information about all configurations. .TP q[uery] -: query supported configurations. +query supported configurations. .TP r[eset] -: reset all configurations to their default value. +reset all configurations to their default value. .TP s[et] -: set configurations to a specific device. +set configurations to a specific device. .TP set_raw -: set raw configuration file.(only Connect\-IB/Connect\-X4/LX.) +set raw configuration file.(only Connect\-IB/Connect\-X4/LX.) .TP backup -: backup configurations to a file (only Connect\-IB/Connect\-X4/LX.). Use set_raw command to restore file. +backup configurations to a file (only Connect\-IB/Connect\-X4/LX.). Use set_raw command to restore file. .TP gen_tlvs_file -: Generate List of all TLVs. TLVs output file name must be specified. (*) +Generate List of all TLVs. TLVs output file name must be specified. (*) .TP g[en_xml_template] -: Generate XML template. TLVs input file name and XML output file name must be specified. (*) +Generate XML template. TLVs input file name and XML output file name must be specified. (*) .TP xml2raw -: Generate Raw file from XML file. XML input file name and raw output file name must be specified. (*) +Generate Raw file from XML file. XML input file name and raw output file name must be specified. (*) .TP raw2xml -: Generate XML file from Raw file. raw input file name and XML output file name must be specified. (*) +Generate XML file from Raw file. raw input file name and XML output file name must be specified. (*) .TP xml2bin -: Generate Bin file from XML file. XML input file name and bin output file name must be specified. (*) +Generate Bin file from XML file. XML input file name and bin output file name must be specified. (*) .TP create_conf -: Generate Configuration file from XML file. XML input file name and bin output file name must be specified. (*) +Generate Configuration file from XML file. XML input file name and bin output file name must be specified. (*) .TP apply -: Apply a Configuration file. bin input file name must be specified. (*) +Apply a Configuration file. bin input file name must be specified. (*) .IP (*) These commands do not require MST device .IP @@ -100,16 +100,16 @@ To show supported configurations by device type, run show_confs command Examples: .TP To query configurations -: mstconfig \fB\-d\fR 04:00.0 query +mstconfig \fB\-d\fR 04:00.0 query .TP To set configuration -: mstconfig \fB\-d\fR 04:00.0 set SRIOV_EN=1 NUM_OF_VFS=16 WOL_MAGIC_EN_P1=1 +mstconfig \fB\-d\fR 04:00.0 set SRIOV_EN=1 NUM_OF_VFS=16 WOL_MAGIC_EN_P1=1 .TP To set raw configuration -: mstconfig \fB\-d\fR 05:00.0 \fB\-f\fR conf_file set_raw +mstconfig \fB\-d\fR 05:00.0 \fB\-f\fR conf_file set_raw .TP To reset configuration -: mstconfig \fB\-d\fR 04:00.0 reset +mstconfig \fB\-d\fR 04:00.0 reset .IP Supported devices: .IP @@ -119,13 +119,13 @@ Supported devices: Note: query device to view supported configurations by Firmware. .SH "SEE ALSO" The full documentation for -.B mstconfig, +.B mstconfig is maintained as a Texinfo manual. If the .B info and -.B mstconfig, +.B mstconfig programs are properly installed at your site, the command .IP -.B info mstconfig, +.B info mstconfig .PP should give you access to the complete manual. diff --git a/man/mstcongestion.1 b/man/mstcongestion.1 index bcab5b36..3fc0b45b 100644 --- a/man/mstcongestion.1 +++ b/man/mstcongestion.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTCONGESTION, "1" "March 2020" "mstcongestion, mstflint 4.14.0, built on Mar 3 2020, 14:02:45. Git SHA Hash: N/A" "User Commands" .SH NAME -mstcongestion, \- manual page for mstcongestion, mstflint 4.14.0, built on Mar 3 2020, 14:02:45. Git SHA Hash: N/A +mstcongestion \- utility for configuring Mellanox device's receive congestion handling .SH DESCRIPTION NAME .IP diff --git a/man/mstflint.1 b/man/mstflint.1 index 28addcf5..b604e02f 100644 --- a/man/mstflint.1 +++ b/man/mstflint.1 @@ -1,15 +1,14 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTFLINT, "1" "March 2020" "mstflint, mstflint 4.14.0, built on Mar 3 2020, 14:02:39. Git SHA Hash: N/A" "User Commands" .SH NAME -mstflint, \- manual page for mstflint, mstflint 4.14.0, built on Mar 3 2020, 14:02:39. Git SHA Hash: N/A +mstflint \- Flash Interface .SH DESCRIPTION NAME -.IP -MstFlint \- Flash Interface -.PP +mstflint \- Flash Interface +.SH SYNOPSIS .IP -MstFlint [OPTIONS] [Parameters] +mstflint [OPTIONS] [Parameters] .IP [\-d|\-\-device ] [\-i|\-\-image ] [\-\-latest_fw] [\-\-ir] [\-h|\-\-help] [\-\-hh] [\-y|\-\-yes] [\-\-no] [\-\-guid ] [\-\-guids ] [\-\-mac ] @@ -27,17 +26,15 @@ DESCRIPTION .IP flint is a FW (firmware) burning and flash memory operations tool for Mellanox Infiniband HCAs,Ethernet NIC cards, and switch devices. -.PP +.SH OPTIONS -.IP -MstFlint [OPTIONS] [Parameters] .TP \fB\-d\fR|\-\-device -: Device flash is connected to. +Device flash is connected to. Commands affected: all .TP \fB\-i\fR|\-\-image -: Binary image file. +Binary image file. Commands affected: burn, verify .TP \fB\-\-latest_fw\fR @@ -47,32 +44,32 @@ Commands affected: burn, verify : Commands affected: burn .TP \fB\-h\fR|\-\-help -: Prints this message and exits +Prints this message and exits .TP \fB\-\-hh\fR -: Prints extended command help +Prints extended command help .TP \fB\-y\fR|\-\-yes -: Non interactive mode \- assume answer "yes" to +Non interactive mode \- assume answer "yes" to all questions. Commands affected: all .TP \fB\-\-no\fR -: Non interactive mode \- assume answer "no" to +Non interactive mode \- assume answer "no" to all questions. Commands affected: all .TP \fB\-\-guid\fR -: GUID base value. 4 GUIDs are automatically +GUID base value. 4 GUIDs are automatically assigned to the following values: .TP guid \-> node GUID -.IP +.TP guid+1 \-> port1 guid+2 \-> port2 guid+3 \-> system image GUID. -.IP +.TP Note: port2 guid will be assigned even for a single port HCA \- The HCA ignores this value. @@ -80,11 +77,11 @@ value. Commands affected: burn, sg .TP \fB\-\-guids\fR -: 4 GUIDs must be specified here. +4 GUIDs must be specified here. The specified GUIDs are assigned to the following fields, respectively: node, port1, port2 and system image GUID. -.IP +.TP Note: port2 guid must be specified even for a single port HCA \- The HCA ignores this value. @@ -93,7 +90,7 @@ It can be set to 0x0. Commands affected: burn, sg .TP \fB\-\-mac\fR -: MAC address base value. 2 MACs are +MAC address base value. 2 MACs are automatically assigned to the following values: .TP @@ -106,25 +103,25 @@ mac+1 Commands affected: burn, sg .TP \fB\-\-macs\fR -: 2 MACs must be specified here. +2 MACs must be specified here. The specified MACs are assigned to port1, port2, respectively. Commands affected: burn, sg -.IP +.TP Note: \fB\-mac\fR/\-macs flags are applicable only for Mellanox .IP Technologies ethernet products. .TP \fB\-\-uid\fR -: ConnectIB/SwitchIB only. Derive and set the +ConnectIB/SwitchIB only. Derive and set the device UIDs (GUIDs, MACs, WWNs). UIDs are derived from the given base UID according to Mellanox Methodology Commands affected: burn, sg .TP \fB\-\-blank_guids\fR -: Burn the image with blank GUIDs and MACs +Burn the image with blank GUIDs and MACs (where applicable). These values can be set later using the "sg" command (see details below). @@ -132,7 +129,7 @@ below). Commands affected: burn .TP \fB\-\-clear_semaphore\fR -: Force clear the flash semaphore on the +Force clear the flash semaphore on the device. No command is allowed when this flag is used. @@ -142,7 +139,7 @@ application is currently using the flash. Exercise caution. .TP \fB\-\-qq\fR -: Run a quick query. When specified, flint will +Run a quick query. When specified, flint will not perform full image integrity checks during the query operation. This may shorten execution time when running over slow @@ -160,15 +157,15 @@ fetched Commands affected: query .TP \fB\-\-nofs\fR -: Burn image in a non failsafe manner. +Burn image in a non failsafe manner. .TP \fB\-\-allow_rom_change\fR -: Allow burning/removing a ROM to/from FW image +Allow burning/removing a ROM to/from FW image when product version is present. Use only if you know what you are doing .TP \fB\-\-override_cache_replacement\fR -: On SwitchX/ConnectIB devices: +On SwitchX/ConnectIB devices: Allow accessing the flash even if the cache replacement mode is enabled. NOTE: This flag is intended for advanced @@ -177,74 +174,74 @@ Running in this mode may cause the firmware to hang. .TP \fB\-\-no_flash_verify\fR -: Do not verify each write on the flash. +Do not verify each write on the flash. .TP \fB\-\-use_fw\fR -: Flash access will be done using FW +Flash access will be done using FW (ConnectX\-3/ConnectX\-3Pro only). .TP \fB\-s\fR|\-\-silent -: Do not print burn progress flyer. +Do not print burn progress flyer. Commands affected: burn .TP \fB\-\-vsd\fR -: Write this string, of up to 208 characters, +Write this string, of up to 208 characters, to VSD when burn. .TP \fB\-\-use_image_ps\fR -: Burn vsd as appears in the given image \- do +Burn vsd as appears in the given image \- do not keep existing VSD on flash. Commands affected: burn .TP \fB\-\-use_image_guids\fR -: Burn (guids/macs) as appears in the given +Burn (guids/macs) as appears in the given image. Commands affected: burn .TP \fB\-\-use_image_rom\fR -: Do not save the ROM which exists in the +Do not save the ROM which exists in the device. Commands affected: burn .TP \fB\-\-use_dev_rom\fR -: Save the ROM which exists in the device. +Save the ROM which exists in the device. Commands affected: burn .TP \fB\-\-ignore_dev_data\fR -: Do not attempt to take device data sections +Do not attempt to take device data sections from device(sections will be taken from the image. FS3 Only). Commands affected: burn .TP \fB\-\-no_fw_ctrl\fR -: Do not attempt to work with the FW Ctrl +Do not attempt to work with the FW Ctrl update commands .TP \fB\-\-dual_image\fR -: Make the burn process burn two images on +Make the burn process burn two images on flash (previously default algorithm). Current default failsafe burn process burns a single image (in alternating locations). Commands affected: burn .TP \fB\-\-striped_image\fR -: Use this flag to indicate that the given +Use this flag to indicate that the given image file is in a "striped image" format. Commands affected: query verify .TP \fB\-\-banks\fR -: Set the number of attached flash devices +Set the number of attached flash devices (banks) .TP \fB\-\-log\fR -: Print the burning status to the specified log +Print the burning status to the specified log file .HP \fB\-\-flash_params\fR -: Use the given parameters to access the flash -.IP +Use the given parameters to access the flash +.TP instead of reading them from the flash. Supported parameters: Type: The type of the flash, such @@ -257,47 +254,47 @@ size.num_of_flashes: the number of the flashes connected to the device. .TP \fB\-v\fR|\-\-version -: Version info. +Version info. .TP \fB\-\-private_key\fR -: path to PEM formatted private key to be used +path to PEM formatted private key to be used by the sign command .TP \fB\-\-key_uuid\fR -: UUID matching the given private key to be +UUID matching the given private key to be used by the sign command .TP \fB\-\-private_key2\fR -: path to PEM formatted private key to be used +path to PEM formatted private key to be used by the sign command .TP \fB\-\-hmac_key\fR -: path to file containing key (For FS4 image +path to file containing key (For FS4 image only). .TP \fB\-\-key_uuid2\fR -: UUID matching the given private key to be +UUID matching the given private key to be used by the sign command .PP COMMANDS SUMMARY .TP burn|b \fB\-ir\fR -: Burn flash. Use "\-ir burn" flag to perform +Burn flash. Use "\-ir burn" flag to perform .IP image reactivation prior burning. .TP query|q [full] -: Query misc. flash/firmware characteristics, +Query misc. flash/firmware characteristics, .IP use "full" to get more information. .TP verify|v [showitoc] -: Verify entire flash, use "showitoc" to see +Verify entire flash, use "showitoc" to see .IP ITOC headers in FS3/FS4 image only. .TP swreset -: SW reset the target switch device.This +SW reset the target switch device.This .IP command is supported only in the In\-Band access method. @@ -306,13 +303,13 @@ brom : Burn the specified ROM file on the flash. .TP drom -: Remove the ROM section from the flash. +Remove the ROM section from the flash. .TP rrom : Read the ROM section from the flash. .TP bb -: Burn Block \- Burns the given image as is. No +Burn Block \- Burns the given image as is. No .IP checks are done. .TP @@ -334,7 +331,7 @@ in the FW image .TP set_key [key] : Set/Update the HW access key which is used to -.IP +.TP enable/disable access to HW. The key can be provided in the command line or interactively typed after the command is @@ -344,7 +341,7 @@ the device is reset. .TP hw_access [key] : Enable/disable the access to the HW. -.IP +.TP The key can be provided in the command line or interactively typed after the command is given @@ -353,7 +350,7 @@ hw query : Query HW info and flash attributes. .TP erase|e -: Erases sector. +Erases sector. .TP rw : Read one dword from flash @@ -378,13 +375,13 @@ rb [out\-file] : Read a data block from flash .TP clear_semaphore -: Clear flash semaphore. +Clear flash semaphore. .TP qrom -: query ROM image. +query ROM image. .TP checksum|cs -: perform MD5 checksum on FW. +perform MD5 checksum on FW. .IP timestamp|ts [timestamp] [FW version] : FW time stamping. @@ -407,28 +404,27 @@ binary_compare|bc .IP given BIN file. If there is a silent mode, no progress is displayed. -.PP +.SH RETURN VALUES .TP 0 -: Successful completion. +Successful completion. .TP 1 -: An error has occurred. +An error has occurred. .TP 7 -: For burn command \- FW already updated \- burn -.IP +For burn command \- FW already updated \- burn was aborted. .SH "SEE ALSO" The full documentation for -.B mstflint, +.B mstflint is maintained as a Texinfo manual. If the .B info and -.B mstflint, +.B mstflint programs are properly installed at your site, the command .IP -.B info mstflint, +.B info mstflint .PP should give you access to the complete manual. diff --git a/man/mstfwmanager.1 b/man/mstfwmanager.1 index 02560361..bef0171b 100644 --- a/man/mstfwmanager.1 +++ b/man/mstfwmanager.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTFWMANAGER "1" "March 2020" "mstfwmanager 1.0, mstflint 4.14.0, built on Mar 3 2020, 14:02:20. Git SHA Hash: N/A" "User Commands" .SH NAME -mstfwmanager \- manual page for mstfwmanager 1.0, mstflint 4.14.0, built on Mar 3 2020, 14:02:20. Git SHA Hash: N/A +mstfwmanager \- Mellanox Firmware Manager .SH DESCRIPTION NAME .IP diff --git a/man/mstfwreset.1 b/man/mstfwreset.1 index d5d813b4..4f0893a1 100644 --- a/man/mstfwreset.1 +++ b/man/mstfwreset.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTFWRESET "1" "March 2020" "mstfwreset 1.0.0, mstflint 4.14.0, built on Mar 03 2020, 14:01:10. Git SHA Hash: N/A" "User Commands" .SH NAME -mstfwreset \- manual page for mstfwreset 1.0.0, mstflint 4.14.0, built on Mar 03 2020, 14:01:10. Git SHA Hash: N/A +mstfwreset \- Query and perform reset operation on the device .SH DESCRIPTION usage: mstfwreset \fB\-\-device\fR DEVICE [\-\-level {0,3,4,5}] [\-\-type {0,1}] [\-\-yes] .IP diff --git a/man/mstfwtrace.1 b/man/mstfwtrace.1 index 4b3e3782..2fd63938 100644 --- a/man/mstfwtrace.1 +++ b/man/mstfwtrace.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTFWTRACE, "1" "March 2020" "mstfwtrace, mstflint 4.14.0, built on Mar 03 2020, 14:01:10. Git SHA Hash: N/A" "User Commands" .SH NAME -mstfwtrace, \- manual page for mstfwtrace, mstflint 4.14.0, built on Mar 03 2020, 14:01:10. Git SHA Hash: N/A +mstfwtrace \- Extracts and prints trace messages generated by the firmware of 5th generation devices .SH DESCRIPTION usage: mstfwtrace \fB\-d\fR|\-\-device DEVICE [options] .SS "optional arguments:" diff --git a/man/mstlink.1 b/man/mstlink.1 index 161a832c..b7713b02 100644 --- a/man/mstlink.1 +++ b/man/mstlink.1 @@ -1,23 +1,16 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTLINK, "1" "March 2020" "mstlink, mstflint 4.14.0, built on Mar 3 2020, 14:03:31. Git SHA Hash: N/A" "User Commands" .SH NAME -mstlink, \- manual page for mstlink, mstflint 4.14.0, built on Mar 3 2020, 14:03:31. Git SHA Hash: N/A -.SH DESCRIPTION -.IP -NAME: -.IP -mstlink -.IP -SYNOPSIS: -.IP +mstlink \- check and debug link status and issues related to them +.SH +SYNOPSIS mstlink [OPTIONS] -.IP -DESCRIPTION: -.IP -The mstlink tool is used to check and debug link status and issues related to them. +.SH +DESCRIPTION +The mlxlink tool is used to check and debug link status and issues related to them. The tool can be used on different links and cables (passive, active, transceiver and backplane). -.IP -OPTIONS: +.SH +OPTIONS .TP \fB\-h\fR |\-\-help : Display help message. @@ -136,8 +129,8 @@ COMMANDS: .TP \fB\-\-twisted_pair_force_mode\fR : Twisted Pair Force Mode [MA(Master)/SL(Slave)] -.IP -Examples: +.SH +EXAMPLES .TP get info of , : @@ -179,7 +172,8 @@ mstlink \fB\-d\fR \fB\-p\fR \fB\-\-test_mode\fR TU .IP Configure Transmitter Parameters (on lane, to database): .IP -mstlink \fB\-d\fR \fB\-p\fR \fB\-\-serdes_tx\fR ,,,,, (\fB\-\-serdes_tx_lane\fR ) (\fB\-\-database\fR) +mstlink \fB\-d\fR \fB\-p\fR (\fB\-\-serdes_tx_lane\fR ) (\fB\-\-database\fR) \\ + \fB\-\-serdes_tx\fR ,,,,, .SH "SEE ALSO" The full documentation for .B mstlink, diff --git a/man/mstmcra.1 b/man/mstmcra.1 index 407a68e0..42fcfc63 100644 --- a/man/mstmcra.1 +++ b/man/mstmcra.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTMCRA "1" "March 2020" "mstmcra Mellanox Configuration Registers Access tool" "User Commands" .SH NAME -mstmcra \- manual page for mstmcra Mellanox Configuration Registers Access tool +mstmcra \- Mellanox Configuration Registers Access tool .SH DESCRIPTION .IP Mellanox Configuration Registers Access tool diff --git a/man/mstmread.1 b/man/mstmread.1 index 82152dad..cc5fefe4 100644 --- a/man/mstmread.1 +++ b/man/mstmread.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTMREAD "1" "March 2020" "mstmread " "User Commands" .SH NAME -mstmread \- manual page for mstmread +mstmread \- Mellanox Read Configuration Register Tool .SH DESCRIPTION mstmread .SH "SEE ALSO" diff --git a/man/mstmtserver.1 b/man/mstmtserver.1 index 6eb737ac..cf495274 100644 --- a/man/mstmtserver.1 +++ b/man/mstmtserver.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTMTSERVER "1" "March 2020" .SH NAME -mstmtserver +mstmtserver \- mstflint mst mt server .SH DESCRIPTION Usage: .IP @@ -15,15 +15,4 @@ mstmtserver [switches] \fB\-h[elp]\fR \- Print help message. .HP \fB\-v[ersion]\fR \- Print version. -.SH "SEE ALSO" -The full documentation for -.B mstmtserver -is maintained as a Texinfo manual. If the -.B info -and -.B mstmtserver -programs are properly installed at your site, the command -.IP -info mstmtserver -.PP -should give you access to the complete manual. + diff --git a/man/mstmwrite.1 b/man/mstmwrite.1 index 22f6b7c5..110a6d17 100644 --- a/man/mstmwrite.1 +++ b/man/mstmwrite.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTMWRITE "1" "March 2020" "mstmwrite " "User Commands" .SH NAME -mstmwrite \- manual page for mstmwrite +mstmwrite \- Mellanox Write Configuration Register Tool .SH DESCRIPTION mstmwrite .SH "SEE ALSO" diff --git a/man/mstprivhost.1 b/man/mstprivhost.1 index d50b0964..2c8b3ec2 100644 --- a/man/mstprivhost.1 +++ b/man/mstprivhost.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTPRIVHOST "1" "March 2020" "mstprivhost 1.0.0, mstflint 4.14.0, built on Mar 03 2020, 14:01:10. Git SHA Hash: N/A" "User Commands" .SH NAME -mstprivhost \- manual page for mstprivhost 1.0.0, mstflint 4.14.0, built on Mar 03 2020, 14:01:10. Git SHA Hash: N/A +mstprivhost \- privilege modification tool .SH DESCRIPTION usage: mstprivhost [\-h] [\-v] \fB\-\-device\fR DEVICE [\-\-disable_rshim] .IP diff --git a/man/mstreg.1 b/man/mstreg.1 index 1f1c8db6..8276064b 100644 --- a/man/mstreg.1 +++ b/man/mstreg.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTREG, "1" "March 2020" "mstreg, mstflint 4.14.0, built on Mar 3 2020, 14:03:18. Git SHA Hash: N/A" "User Commands" .SH NAME -mstreg, \- manual page for mstreg, mstflint 4.14.0, built on Mar 3 2020, 14:03:18. Git SHA Hash: N/A +mstreg \- Expose supported access registers .SH DESCRIPTION .IP NAME: diff --git a/man/mstregdump.1 b/man/mstregdump.1 index 2c6ac14b..546b9f95 100644 --- a/man/mstregdump.1 +++ b/man/mstregdump.1 @@ -1,34 +1,33 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTREGDUMP, "1" "March 2020" "mstregdump, mstflint 4.14.0, built on Mar 3 2020, 14:02:48. Git SHA Hash: N/A" "User Commands" .SH NAME -mstregdump, \- manual page for mstregdump, mstflint 4.14.0, built on Mar 3 2020, 14:02:48. Git SHA Hash: N/A -.SH DESCRIPTION -.IP -Mellanox mstregdump utility, dumps device internal configuration data -Usage: mstregdump [\-full] [i2c\-slave] [\-v[ersion] [\-h[elp]]] +mstdump \- Mellanox mstdump utility, dumps device internal configuration data +.SH SYNOPSIS +mstregdump [\-full] [i2c\-slave] [\-v[ersion] [\-h[elp]]] +.SH OPTIONS .TP \fB\-full\fR -: Dump more expanded list of addresses -Note : be careful when using this flag, None safe addresses might be read. +Dump more expanded list of addresses +Note: be careful when using this flag, None safe addresses might be read. .TP \fB\-v\fR | \fB\-\-version\fR -: Display version info +Display version info .TP \fB\-h\fR | \fB\-\-help\fR -: Print this help message +Print this help message .IP -Example : +.SH EXAMPLE .IP mstregdump 0b:00.0 .SH "SEE ALSO" The full documentation for -.B mstregdump, +.B mstregdump is maintained as a Texinfo manual. If the .B info and -.B mstregdump, +.B mstregdump programs are properly installed at your site, the command .IP -.B info mstregdump, +.B info mstregdump .PP should give you access to the complete manual. diff --git a/man/mstresourcedump.1 b/man/mstresourcedump.1 index 0dc3c6ab..7d06cd21 100644 --- a/man/mstresourcedump.1 +++ b/man/mstresourcedump.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH MSTRESOURCEDUMP, "1" "March 2020" "mstresourcedump, mstflint 4.14.0, built on Mar 03 2020, 14:01:10. Git SHA Hash: N/A" "User Commands" .SH NAME -mstresourcedump, \- manual page for mstresourcedump, mstflint 4.14.0, built on Mar 03 2020, 14:01:10. Git SHA Hash: N/A +mstresourcedump \- dump resource information .SH DESCRIPTION usage: mstresourcedump [\-h] [\-v] {dump,query} ... .SS "optional arguments:" diff --git a/man/mstvpd.1 b/man/mstvpd.1 index 30f640d3..1af3051d 100644 --- a/man/mstvpd.1 +++ b/man/mstvpd.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.41.1. .TH USAGE: "1" "March 2020" "Usage: mstvpd [-m|-n|-r] [-t ##] [-- keyword ...]" "User Commands" .SH NAME -Usage: \- manual page for Usage: mstvpd [-m|-n|-r] [-t ##] [-- keyword ...] +mstvpd \- Mellanox VPD read tool .SH SYNOPSIS .B mstvpd [\fI-m|-n|-r\fR] [\fI-t ##\fR] \fI \fR[\fI-- keyword \fR...] From c7609daa84b2f021942a4d3e7da65e3cc71ca031 Mon Sep 17 00:00:00 2001 From: Oded Burstein Date: Mon, 17 Jan 2022 14:02:07 +0200 Subject: [PATCH 054/184] fixed bug in mtcr reg access smp fallback Issue: 2937605 --- mtcr_ul/mtcr_ul_com.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mtcr_ul/mtcr_ul_com.c b/mtcr_ul/mtcr_ul_com.c index 73a462a9..314c59c1 100644 --- a/mtcr_ul/mtcr_ul_com.c +++ b/mtcr_ul/mtcr_ul_com.c @@ -2883,6 +2883,7 @@ int maccess_reg_ul(mfile *mf, // Fallback - Attempting SMP as last resort. if (supports_reg_access_smp(mf)) { + class_to_use = MAD_CLASS_REG_ACCESS; rc = mreg_send_raw(mf, reg_id, reg_method, reg_data, reg_size, r_size_reg, w_size_reg, reg_status); } else { return ME_REG_ACCESS_NOT_SUPPORTED; From 25bb5ed1f5856b60a90458dd92a8a622545e25dc Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Sun, 30 Jan 2022 16:40:21 +0200 Subject: [PATCH 055/184] port PRM changes based on Jan 2022 PRM release Switch V1.55.60 - Jan 27 Adapters V0.57_DraftE Jan 26 Description: updated mlxconfig databases and relevant tool layouts. Issue: 2948432 --- mlxconfig/mlxconfig_dbs/mlxconfig_host.db | Bin 455680 -> 477184 bytes .../adb/prm/hca/ext/register_access_table.adb | 385 ++-- .../prm/switch/ext/register_access_table.adb | 1807 ++++++++++------- tools_layouts/reg_access_hca_layouts.c | 2 +- tools_layouts/reg_access_hca_layouts.h | 128 +- tools_layouts/reg_access_switch_layouts.c | 24 + tools_layouts/reg_access_switch_layouts.h | 72 +- 7 files changed, 1394 insertions(+), 1024 deletions(-) diff --git a/mlxconfig/mlxconfig_dbs/mlxconfig_host.db b/mlxconfig/mlxconfig_dbs/mlxconfig_host.db index 828a91ca98bf0582f3310c7bfdd8f86423ca1e61..5bd02fc51e302856feafd9ce11e68c13c3c0f324 100644 GIT binary patch delta 64247 zcmb@v2V7J~_cwme%)Ps-U}XVO$|6-M(h(6A5f!CLvFnP0N>o6wYs6iODNmy2MkYm# zrdOkqWRsW}P48-YPfYKCL&z(DW>Y3AKcEjfbHf#>r97Zqg zb$rF?(N16eZeDr7wMf(G9@iYe4p#->D%WVh39dxI7+0XCY5%x5;C=M~w@w3CJr-bM zDnM`~z<@ps(85azZye$u^JhAH+hV!tu=fw4iv#oo8>?I4Y^-16TwXK3);X`fZoYOH zZ|pYfeF7}=ti$K@jv;`oqg<|@(J3(jXp^KNJ|mZKGphbJNn`a z4g6Q;VMEBG{Y}rY`7De1u-CL5`~muuze+pVW}ZaTsW+wa8QkDIxJx@gYt26P>9$X` zDCDO7De7Oe1ozS=`71HuP7_Xt8kW==I4*0en`Jpyg$zpBsN@NSPe9*_LcemfY2Uk z{0qj)Gy??66q7#H1G=>WofXD&ndr4&53;564YE7067S!`!iLK}A1jN=4k6h!b{@y_ zCgr1wMWy&=c|l1rIoVB`9m((y7>ersNBhO)H&`MjrLaMGGrl*EV8xY1&dFn)Mdbxk zHIqH9p)bz*7b`zSZ9JZb@=y(bJvH`)7JMSrn=yP66GtDl40P&m^LUVHm@HCR={V>3 z+yZawm1eLFc-Gzf66b3)G_j7P_5M78mFAXJ6yz4l7R#@2<`-)R`D(4ti4SyL=`yja zuO+ZoGLsEu>!KbJ$Ch%x?v=%33iKO6dsxir$?ev3wg8zwA$Hzu1RASAUmy~;>cInE z0U9IgqunGMl<`{uDUH9#Z^hWWocBz}{mFmZ#E#dE@a~v^+O-Krc3d|xVy7O%_`-dT zMg8azbMeq2^o+S}XpHe?k})yd+&MJRe1E9F^`Ar|HwN?P&J^n33lpNDex;lWa*jP= zMrI{+Uma}tCEHk4V}r=`a6f7{>$5`Wn0Z-NDE(~SnRS3JFt=nUa>g6fmGc$yO1ilz zI|;+zt*91$k-A#><+vtUuM9CFqHJVVtwS-g-=h!A1H=1Kp85Llfi%nfb9e+@Xoltl z(`++4C!Ov#m*xzm$>!}jG1kvwjF?mu_~1_FVD!29XHE=#VGbM-LtmN`Mhv#@i!j3E z^U@8LV5WDPSC5FL-R7es2GKR<*CP_?UUR_6aJtjX85wEa8*N0TqZG%A!p)0EE*Jkc zTdbYNsC(>;tmgiT!9Kg9jPP_Do4dRzNjM(S2cTBIm9aiMP9rBD0NG;B0C{Jm5#~*u zEH)g_`xBYBRYudb=8?)6M%?_PaV4vGgW|`v6($~BQ4{tX2PKjjH(|jE_x9*$z zO0e~TuCE-uQ+_4b{A*dP&wVG~&Je0Dq2`3;u|D^otV^boD`M#$bMK0ERBTRK>A--QgzG@6P9v0DZd2_s>4Aa%?)0489_pXi5M;5N z$6Wr+X-TV+5|i`6F2-QNsHeIhbUE5SOcX5rgv1wuL5@*AF`4#iiUwfO*`z;gB_()m# z_=2LdJ}{=Bd}em;=)(Llu96w{5ZRlq89B+`-t2)YoXqw;SHI@Wb2@e9!W#5zqXVV( zW`Cl)94l)VFP1f_S=CVAR8xJTduL{!>|ohCCpxuQm7%L&QK+uld@o(~)R=V6| z4xqEg-sJy-!FO^=Krf1mR~-lpdxQPq@`lawKBQh_tOeA{4LZrYPV}IYClo{4WrrQ zrkm*~Ggu;WgdVt;Xu!buX89df8z_ z#9{GsCH5CnXRwvMd!Y0>-JtOc*eh%}-2f@WB<>2RGB<9xisqOO*VaInpVOYNm`$&f zmBvgJKlHQsnRjn+h}Az*Z?UtMS!SIv|Ic7&r}KfC*d6sdCH7Ngni{ zo^w0Dyv(09N6Bfkj@D_kjy6ymT|%4aO1heM&<%7e-9`JzLl4m*dXk=_BlIf0Meozc z^aXuOKhf{>4`a;Ad|4kBzy?5^i(-S>5S9joY6Qz;<5>|aV^i2nRs|(%5o=(}*&5c& zS}_SPXC}LfZ7*flvs>7mY%jZy?Pmws6YN=b7^C-1_8$9)ea^mNKeFH0-<-IG`|#e} zpZDisJdzLMi9D4L1~=z;VlZbD%hrAyMh}Pyj;O64Q_6} zW42AUa0AWJJpCNhkDwKg5=r5tH)}VmWVa}ItAe*Fc)NmkD0ruWcPY4A!MhdQqu^cz z_bJ$^;5`c7ui$xVdomyOpI9r%4KyDOj#xg@Tm|PF8S=f>RZo zrl8WEX@=k!;o>LzNHjFD?!YwQP>rhN@g@g8^Q&+puSMLrB1!)olg z$x?KwIh|jfJ$=j{wmQU3Us?Pyf2+X{w6&(Kb!kSB;TLCP)m3t}m|qLouD05_WO3apx@3UiH{|Rm zD{AVh>l^6`b8qWFDltd3VP)fG>dJYgy6Su?t`Rgt-C6i-b+z&;b+z$o^GI7Lg`3~C zg;BcMt38Yg%priY%o4z*W<6k=xe4%U^KQVq%){*t8fbps9!?p6VGxHWsH@IqtE<5p z)z!k<)z!+bQCAz=ZN9fLyvM7uKN+pn*f+Emi(EZ%cm1NyE!WhOkGuB;_KC@I1u)Db zTODTDMLyhUek7JY?ihYgWyV^mSIc0iQA^h#GQ55Ux8M2EbjdFs-1Mj zjk>R{4b^x)d!8D#p?D*fyEB(|*58yx)X;g`%~Oc2tT+4YT1|E4rMvD&f9X98ZHNYQ zkc;+fUuYtEk0q45GFO;i?0KNua{Hw0puiBrNbKj8lBiPo48Jg}Em zcP@GmD)oBvKM#Ei^?U8ZU(&kH`3H8AZ-T}%SR1{fy{9E?$sM4(5?tI&J9sy9G4tbt zKcl$jn}=|xnHN8LH#M7CkG)`m2p;K|Vq!nh8P1dUzXI?EnimC zboQLNJj@t?IdksQu6ffTQvFzzwJOobLNc-Q7YY#BuN!@h)(B%zoY>>X!o(eZY;bou z^oT`iEDGaw0MlEhxVm)?dht(2-8&NM82KVUM(Z?>Adr`Yl(Vwj(;PB zQ_s%%Z+}PByL0lp$2s-soP12@WH)Dgd+@TvpLxR1D=Q z602o*u(x>+J{&^wwfu!Gx&6f92`q&^G9Ugu(rQBRglsB;EtVjgUY%fM%E}ik!IsB zo4Q4GWiZklez2dI9)%9w{G%am{|Tk}{w`fNr~O(C?s@C4H-YCC|8`$WKkY#cf3IkN zQ5+Rf9bHB@(PQ)_>&+6_WVQ@qmWLf>-|+63V-5Ufen=$U!$Tp5%om%k+_F7_vdrhU zhh}C686jOSEnD4CbJ`ol1B~#lCo39ioi%l*JxenkJAwo2Q;pnI8=XhD2=SktY~-AH zc1n-my&=RpE8WP)lM^aWFgeYf9sOyOIdw;{RfHR1ax@>lg7s(g&J}-OM1#$X|6WOh zO!{X9#hR=B5fo$g{`V`2?)>{-ojP=Cq-1f456181I+V>M@r_QcG(=toh|3JBr9|GJF1OI76fgQ)sfpq|ms@E$QM%B((I1rN`L`SCM5%)NP&=i_99JmWaVbsLJOK_& zQS{kRDLWcHl(b1o+N6ub_;9Kbo#8Y+NC}Xn1V~Z>Bq;%s?h>|v6w$0?L{c&$-K!*| z`xNvjsH8@EK;e%lcu+wlLDHiNe@sCoL6Q<6NePgo1V~b%BOO&~UQ_UO1>aEcP4VJD zx?mxFrS85~@EZlcRq#6nl^{t@ zLE}4oF)K1X@xJsuQHCd^Cw)XIa$yS4%HdPe+}d947{v0iR6`r-4tfJR&0y#(>)3WE zBi};h$mSRDogyic!n-FL$z7aAEWO<_po^t^u=RCHw7%?RW+JSBVtut&GmP95NnN!R z(UtUlv4kjrjtVgMQ2JCnNEA-x;vJ$0>znaLo}5vA9z@PLuUfh@{p$`!k#s~vF^Z?d zqD)?16wQ*@E^cJx7}5k|It<{_2&xpk#kH`1uE2!z+CiQ38kQ?xz|>eH3gr>Ur&+?8 zezo|P;ll?-Z%%{hS&_{t(YPet7&k>ttlDofjzQj2eEwQG!jmVBkX z(z87Yy)S;qqW)rA3ORjU&8|HANR{6VVNIo5#okn^>=~zVgUx`lI}M9t+?L!x-sqYj z;?po&3&izl(1^#2>FH3I$BEa|p)-#avoh!wpOvnBd#=jNDSBmskv^13OQ^&%cqljo z6^rdz)B=SUh5{X!o- zLb+dS=3(`Ohg5sMuO4+8MJ{g7d6o_bo3i`qgOpSCG%Hhqcq@m3?L~d{81<;SX72I@ z&L#ELHECkV2sKg4i;eE=M;y@+ej~^T?kw?K0_;4xr1GYntoYCNE-Wn-xM9 zaTL$FRlDN8F*K06m-)qIVJNQDGR3Y!^21UK%j6{SX+FJ3rJj4o(uHJ9wkKx=iCzU1 zBudBAgH$Pe3g|Ve@O)T6J&DRaKTN<&G+kU(2yQh^EG?pMXsU1))63nb_@!nA28FEE zMtbuvDWSa`6{JJjyA~Y*J~s+uv4alMw;(*ig4k%bn03JL@+G%JJXpxD;V)pSEfOoD zDT1oRHS#h?AA^9UfdZiDE7X{ z{Y3BA3|~JzKLt}+4d=T9^x|O^PrwmSU;cqZI^zA6y@Gat1K=r7+0J> zrbt{D$O5NG=UegQA{aG`DhqQf5Ln=xnO&4S)j6p$zcSxBCcm^|yvymDWzWkRfDg^m z3QoB*qz3W7QxdAmXn-|ksQhr6*tMGVGjrDaCac21N&_`Qnr!5UVXP@#xVlN&dL3g= z_ze@4Z*X~yqa%>@k4QYLfM*vk+ci^UmC*s3;rYFcY}B!sEZyGK_&W9&^V3A`J**ZY zT#fEdan19DPN#J0HrJl28g86wII(;NU8=j%T~(sCl$sP%vDSnltISP(YaHN8x6wFm{ zw1RmGj!`gQ!LbUCQ*gY31#-Z0D%RL^aL!_g6r+e==$bEnn@t;RHGZjifq@|_#TFkZ zO{Npp-Ijr_YR{^vP;h&ySGCO=dze;ho5Aedx~s-jD|*eQPkOmWxfa^<^U>z+DFu^y zi1#m`em$^oHq5JaF0NW#zkHeKa|oGk7)iEfHJH`NN|C{sJM%jQSqEH7~3?+>kpk@zj$%|N{mQ+ zcNlW-k3g0ZXR>o@m*;bGfg&V1v(nAvmj;A(-6Mf=fu8nQIzh#Cv&lcWbgWax5EbT5 zE2*q-k8~~Qs(j_i%CGoul~*p&|A&>IT-&&8`Dyd-e_Qvmp#R@>AAm@tQ+4-_ie(x* zL@sR^M#X&H-OaVwV2*Aj969Qq4lgC+4YO}k8c zNc$WzP7yW0F?2t@!!#BNX>Bpv%cs5lcL`u{*`Q z3aDRe#F|P^kN{IHw!zh4hFNpUm;qrtBu5L0(m#WQ+aMs<6=*(9l0~zb- zC0JN*FJfhVy@-w3#lI?vA+}7Rfyl+`ML6r`MRevPkqE|mcnKEP%Zpf9A1`8Keq!$t zHo#aMX{3gWqeoc3Ze60IUN2ra!s7f^$`N8{Wg4%7J@OyQ*2*wSMoHeWT=I@!@!cA- zi9Ji`aoBT5Vi1J5%1;i0o4YmH^YS2?xoS?*e8tYEpc%G2LyN^X_2j3!{9KLV`GwTM zm)eWOiwh}SOpUh0o9V~xG9Uv3C8djdojp!hc|1$yI9=&^ys>MXt`HcfAtD5Y+WIM$ z?7P>KuQNpU|Ynz`l7I+Xp4%Zyt_7fJJ;W49{RHW zJufqZMxLPRto#IOumvYj3tM{vwX#hT^+66cb_1-+h(q|`D+*!kUeM)mKcKFhJteQu zeh;un6!A?(wXhFyjij&SU9^q;JkSV%x!^=x4#eSeECn+}cVb2N?Sx)UTtu|fR^~=@ z>n;lP9Bro|=+sI#iNxC|P!z4B0~xZ#1GNT3LuwzueiaKP?*yZ;v2-?z#qW# z_yX-peu>t=Z{!d^K z19j#6Q(PnHYjtPvAJx^ue^*y4|JU4e-9W3Z#~C9dx{0Li6vcF#IJ%7nbEf-x5w7=^ zNIZC=dSK}Nyof~)_99l@p^zAx9*IaqwAM-M;rW_ty4bfJn%!sO-|aAcd?7~dKofi_ zYIjg#&L6UEq99Fc&uL$g55;MFX*>dp7t?wu!PnD0@T$K--@u0+$l_TpjJ1o{2AFI2 zu&3DvVpy794-1C4Elm$H?()XxzODDSaCpqRVs)*V{68menuqc$WK3{j?l>9TT2fh- zm+#CiEG)@W(zNz)A0EXD3yLQ?E2fnqsyLbcIg64)|DHujrQ>H&(wKG@C7qF?ApGq_ z))|bQl_-<(vnWHEE=n_W`-p#K0B>R8m{Mo)Xy=%`(TH+L;rhA6RNnnuVwyOHJVvMU zfODT^@ZfWanS9{6#GyP^^v=}%c{0OVo~Z{gZg>f)+((R3gg#zEIu8^LnR*~tt9m1o zM~I#Bevmk#a^RXokb}ibNaem>B#rm=BI&%J7s=qEUL=!8Dx}v?K3Fa@jK*mQ^B&jP z$DR$LqmSG0e0K@;A-%=n);-Ow1ecyS-6V}Ir%6bck8}>V)idfMj7H|Rc&aakJ+tFK zw3@lQtLZC#UT+!Tx$8ez%bB~IcLu+6869M9n*bZ`=eh54TF#iehxgH#Ep*W0_Vo`> z4-$v2B)cc{3djJ=?IV_$WTwfX9iX*n_}iV-IsYQB{}he=-|HaF^VHXD!kva+R3dI;k~#Fi!Q*M8Y-m(ASa3!-8uR_6;X62FcYPIpfu|`a$ zxnXsr`SLgM^vV_ACc$T&{B1flmL^yNa-zQYo#UmZxd=YHz^U=0I00r2k;O zdxieMdY8`@X`8fKEf3Dt1MF*r(2VCR_>KG}v3L(9!KS%)AC@&M&sT`e!gB{2Q3yb< z-wT%Zuef}#6wbIVk%5eNR|L|)hr3ayOy=XNALi9jr|1IS~S+TIeaC= z;63~W{xODnh91Imn7R3-eoVVW9NTDwCf_GnkJLGGD@uwA@>F;+Eezm8PHf~zI=PX9 ztOIx!+-qAXz=9C~zAkpRQJ{qonF##ge<(17ET_GieCk!MUfsM-zDhEA$9nmurrzAN zkpdB*E;dE6fRJ7?r7RFOk))i=z?oZKT13zvki_cUP~t0Z282-0)4rH`@&)oyUkrnn znNc?}B$^FikcDv#2%SX#u`QYf8+KK|5_qhGDB!dg(oenM zC%(Z8Mjw@O_f`tbpxzSis>7+2PVaa7o|a9^vw~2!R|YMm>jFU3-TmQe5>gtlyEM z_W|&f2+s=#VC1L4p74V-h_HN2JVd|w#@b8Ni-B6ng(CMk2w6)GQFl@QD7}fu(}Ksy z)A2O?^h3nDr(tGF6xq+vGu;yG*|}2ZG^A?LUnD$;K1g~N!EW*PiMitNLVVxxEEK@~ z&(fN1ageo@hA1XI20?x5bM(9pe@@g98VA0+Xek_?yI+D8I>}S{GEB;pBVK$9X7syXp;W^3`&&s<|!u}S`q>*B& zyo~VRGbt1)=V?#n_9hLw_zHMQenxO_4Z99e3wAz{Z{&|*26l*?Tl9STT~ys}8Aktz zUiB9LQ@YURI*U%fiq~(qjHbUu|2vQ*T2$U)$wFMoraLSd*6=JNCl`|G=BFveMnkfV zTzOaW45cx&{6mk^Ppucq8MKXqeQ&|kp-1p^iAr(lqR{e|rsN^g!( zH<1b|`=GAugSxU0>dHQ-7pSKb6jasM3l(0ZV6lQF3aS7^eUide0HR*5@CpSh6`ZW# z6a}X?tIIS6RRp50A`o>IfvC?`^f?MvDL7xj1qv=yuvWnf6kMcWy@Cx2E>&=ug3A?L zq2Njd*BP<0H8-f6s};OP!8;V(r{FybisN6wH#tqTeNETGKNS8AgtIAP&o}flO%^wO z3nyfynDQM|;|k9;-(d#PY*Fz8WQJM7_z`n@rWpGp9Cb6qcR#`rIbE#&i7vA>X-v=v ztqGH>Mt6;KSBam0rl)+}mF_wA1Q|rxk}jV5h0Nxe*-I9$@;FvpaIHFa`l zO1z`4zAoXU6|11Me)6iq++tWl=P$0Ws+Jb569JOaB``C)wr*ZM0_v&|J^Af6~*876{Kj=-c_8rT>zZs79^{1GbAzW4WJaw+#jiW6?>f z=k;zZfP5CZFYr%JmR7|@;`i=sTirx?wf^)yWnG3-we4&2SjVYX`aEC>9$Zv_Sb7+li=C%- z6eX=n8Rj_kplgGXDBTZb{}lN|dTC{kKSe&Z9VtcbfjybM+~*^X1~R|!)60D-T;GwC z<48_QX-Ra~d&&aXK0;J#lE%hUxOR<}gqCpd1@2|ys~~m(HHpdnSvxg)-tCW#Cwfbo zd#UFdJG+Ml$|bW0;tRBoA=6KW`Qa$*&c?#u{s{Y>XK)ukgq$9=3^lUlA{X``BoBxX z2!Tovv!BFd87Rb)lm+SK=#yX$@uKfjAbuexK1JF3&pAe(D1Hh`4h))+^pkkvDLDJT z6;Iuw52dd}_b5wF)OQn%Sy&8Lz=&Nd-M`C}zwSJi@#u)}M;iJ0=O#VBAHt%2KElXD z14dc=gfq$#t3*OS z_8<7OAMA$!*%e|`5W6+PmFZq?&r)%G*xK9m@63TETyd6QQ5wp0^WraqM1C0SJL^RM z!J{KxJze9g$uYMcUdB@$eqwxJ-&-~K+o=a#Bg7%2E1G02blBcuw5i3e$%jybJ9XD` z_j=(I!G6(QN$v~9j$qbF>qJ=y+fQpn&rtTdcMlMD*YlAW4!3BB@!BK0tD=R8_#x~S zU)RVMY*SY?D;F1rvv{#M%Rrz(C^O8@ezl7uiLAhm0(R}|Q$YS6A4$ya+5u`W;1j|jTUgKJ?c^8F04S6PU?+Qwf*CGP6;UtHLB zn?C)&J+|so{@Y_ipY*?f+>tvv~=@}iWBweEJlnDmfrUCA!2VSO z_M#r>=RZWu$prIHABF(n0I_fwtAM=wu)NqkeY06_sakKD!~#Uta5ffhf#fMHP>A8| zLD(s_RD!-RhmC+9iceOJ`EU_S^D*smuI z+k?FbXCu6b&dMYbN%Ot;7PiKVSlQ(Y!A`yFQ;c!2IUvv~o-u!s)I!O~X^S_GWnb{2}AijY0y;#DaiMh zr06V43NJm2lFG}^qNMT3XHnAmv_8D~jI1;G%(D_@a_3o;p?t2iuBZY{DJX=Y8++oC zdC9rN6kc{NF_l-IPHgtRpT?)2PW2Mg`HXXk8GQD+#7tgwE)m91Z_)Fe6?vsjSxOdu z7A2*brJqGgWd&zZ(%7uCDCunJSrqL0IE#|Wu0D%0l-=dW2chM>1uCn+o_JWo2a4Q} z$S)`3oM)+Q!a1}wHv1e}I%^bLkj3!!a~@@~YtEq!WxMU;Mj5zIgg4b|Wk@wp z_?NSVOfUnct*k@He#@G5mgn z(i=9h=zdrk468VNKX%0YBODK~K~M~EiQycIf2MzIg9O!5q9D;~c(Pt5ZdGcYTd`c|3mPbVW z0`&O-Mi90%&u^Ru?MUrjYgj%PTc4eaYF103;}hW+XX!7le9sbM%*XxnqADNzFJ?Sy z@we!2BZH%2Zz<0**5la|;^N+KqJKA87#>-hSY=A25*${KcIK0 zCBSN9yKoaK&#vfW|Y$C!FJ;7w#4pjbky=>bZ9uwj^CA z-WkWDvXFya!!Xn63S4GE>AY9_4AQ`KNTc`A8>}zOfs}I@+l`@?47;)5FCei7v(iv_8Ky$=*duWiajmO|Yqt{#Vy+aSNaGcAe?NxphtCdINX0f^L+u_|B@se)>BGk>h z)(kR=aOW@Pa|Xs<%t zl#4gV>CuKfu_i;TpTGwBRLPLQn}dz;h;HIYsSyyv1=58C8zI=-Q@0$aM?f`)hxD}b zXCA^EBh4rO$}-*rHeO^+WTSkV@z!{ZU>Ql8cyDBYJTT|KNoR2A79+_PB@OjAbVTjb zM(nrh3KE5uSA(Mrnih#sF%-mY`sj`dRt2p^NhGT(Ad$p-dBSTI;0bY(Csd&0Kdr>( z!9m_sUrt7W%hJ`>s%Tv1YXnKu*MBSl<46Umdk$#0&8p&R(KNr9OM`Jt@OJLf7VKud${Q|q|Mt>L|DPGyMwDXD|yT zQzQ)r&q)^(2eUNVEH(^g(bkU=j0kB#bzIA$9rR&{5d|~Lvf33m4Z*px>dYNM1>&c{ za0@*l!sA#5JtL;Zu@I{>#0Zf))%NIe&r;1mBTOE&a7`Ti6WT@MzBusjwc>*~FxmG+ z!OeOUy)Sm}K{39SmwtRM{noLU1@S8S3D*HI69?~w_2)-<8GxsMiK%;8u=P9dBoJY{ znLmTMd5?TrMX=Byb@rc9UJTTRY51$rT-tTo@FNFp7Av%Vpo5)=3R`w1W zEr&Pq>-Z78q{*2VXBl7wVuzyGlFaPUbZLkY2LT%7s~%1pMV~f(pmkH25hUB@!cmrfOutlA zwCNGp61J*MkA}7Dx;8yhzkG<1Et1>y{$|I6eXXmrj1m;Yd}M#P8TtcGfV)m4w(IEz zHio4~h)wN!fLPzI`_e<=(sn(S9u<$Y>si)A@+m%(y8wPkdQdnv>S@-4@kVYJ(JtyY z>V2*IlZ-5RuG2G92aA0h_2iCKYz{2mRjb(F*ibQhHJgMD6`nn7*kpbK^YZoKdu_OfL*UO6`cFKz`j^e`kkV>(1 z9m6qLi4|i0g;<2k#i0wK$lP@yYzSo%9}KkBcsN=3wa4AK%Ybv=uR>Ah_|rf-pW zemy33q3~&jo-|R6XvQ?1AQm*UL9uZKK7*K_tyd4SMcB}5r|qvGM{z-3lFcjXi%Xl? znr>v*_-uyLDLVVuEi}uurls5-Ge|mkmM>2~74+Pd$@z{3QKl{xWj)ku@KT%6y)VEn z)`0L-SW@MYB0}1_9F@f<&X3Cxh-sm+$@d5kQQm|P55JH!w?{CG}HK^mZ@Uv#n2F^2>lY) z3RCsP@=_^!Udn#d-4QJnp6@omwiO`70h?BZGo`qVt*1w@9cQ?9liB;{i9EMuj+nWH zjUlJlwS{ekVLS5*HWG&Il~=Gl2toU=UEMX;2|T+9~TcO}#H zUKYfS@fB=6KJ*~Dv5$Kh#lfR;mF|jdnJ=oZ25YPly{=)IST)C8!xqv!vF93W8Ja76 zuVp{$7p-rp5-)FNZK-$4$sen&*06g|o$u7Kj;~jLd}-0NY{il}`g98mUCO<`J9a{r&2` z*`hsw4MyGMsf~*lS2sB8=E|)(>+Cw*pJ&q8h36si_2(h#&Hi{@74uYZJ-RsQ=OVEOt=dFxNByiYBwy;tiRb?s+c zd$K9J%2+*b?kcTSIIm*?W7<+Qx4+9l^B z+q6qNcCtHYp*VOGb9kQL$za7;;CXQumLUYBI`3vf#LYKCGFT+$+`)pyBex>P^#kgk1#O!oE}%J%6oJgUYa&w$MPR4R2_jbRR;7Ih3nOY!&>oPhul7 z;!i}<9vX)kHA;NtK)}xg(K{TMvGOtyN4<>pA_gDfMHo-u_Y1CeI$YiAVh3Qf&md&Ar_99ElIKR2!$X zPcNc#yF?OT!IH5{D4nC@R(3rtJJ~Mnu)FWN6QbGT+rau8#dWtq@>?qYz6~6qK}@}! zO{IFVS6=Ew_d8&1TjD{J!fn1zzBUyi2;PVl1MkA3vPQlZE1K_ui)OWaH(I=T7jj)C zGl&tXyCEX3l(|HSOLk-VS|LjjFFxCij#(~yZCA%b>;~4Vi3=ZQhs6Ac;hSle`0KRZ zOA2@dqzgR>kDzZ^tL`P%9Ktwm<=&f|N97G<0hxpUWAcW)H{U$Qf)Wcfei(&)w9vePM<=Rz66f?MA+P4)^5^PY6V+z{YBy947-ft;f#3#%;MnV;0a4k z;@C$Qw^&%7z*4$M65|j#lKccjIjeBu!Y%O&6`33H3%rOPKi`Y+_!=+5;;O~+Cy~QE zG3O~TZJXHnB#YwK$SQTuEs=A)h!N@ZB6{R(i9`wKQ;3&k5i`Y|K(HzteF|dikm*Vo zAZy3d>ZKWKJj{^M&;7)fmzlKc#!Dm;nv1&ES%nud*g`L2Ve7nz zm2LJSHg;pj8|*N`@Q%D9o3>Y1)4nE~wr5w%~#pl^RZ*d{X;_ zEQqhk)2^hsvOhnA$g}j5` z&7bDSAexL0lBPTvXEdeESyDD8zYG>eeTj-7+H^MshEsoahA$F~DVb7?<9PFPi7 zP^moeYphcqo?AY4T>wu$oziuj?kZ_cL!!~SWhq_9f@zob=23KlCaq~J#L;AKAH7-H z|GF|P8H)pX^%|9__Y;cZoSa)&FlJ>}rt-^3FOTij=k??1WG;Qc-n{m-r(LDctGj6B zswB#Ur_Ys!W4vBbQh`%7%g5?Y)sQ&rIJXkk?c#iC0o9|uBV?%%+RyWC1&b5=MsnNxvFy?i9^7gc0lB&LODy;W4uTTTt14D3YU*U(%|w@ zNV=ZsMKa*@QIt$LeSq|Hmi9I{d zviI4~2w8N%?_0>{@>TqDQMirG0E_W!mhEunY08=G%5#ZB*{vstaucLFwHkKp{^t@? zSmL?FR5totVj7!lFYo&NsZ7(^1?MKsVC&B%X0j{JB@Sgb3)+YUCsbbic?wGr$?|@z z_dbnH7gh4U&U>H1++vHo@9^FaMYA8;$n4EwC-W{S?y7GJOFfsE%Ep~bOk>JrARD&m z6I{@j!qtmRx{CKIAh4{mS1L!MwQbEy~)jct5M;TY*X2s#fng(aMan#yv|Lrr6q z=b@&v+Ow&__*@3N@N6=unQV(V*n|7iP3lZ+xDNuoND7PdBB^Yo7fEB~9q+I^;b6S$ z9rh&R43@o%V<7^>;Pq}ZDl!{53m~!zAR4A!ZICn~4~G3(i(dqgumm7+DZr2w07=p|nGAcEmLd(xsp=H` zG<8aEy2}PirmGv^P?uElvRqOl9p;k9YG%870}glf0nBmP0Y|v{!|E_oLCI9DcMflHc?C%Cc!3tc&YMXr&6#jeqSC9W}mrLGBplUyZ$6|OSC zO4nq-$*$>uQ(aELX)amA87^7HnXXz5-=F1@EjrsJE%|d?%K@ugvW|0I>j3Au0kj%7 z2VCfuJy7eGClX)ami1fYmi1fWmNlz$%d6VpT$J{27I3}02(Z}=qps$1PXlzjX9KplWf!%%s{z~HG6rL# zTlUgLZdrkg-7sBim$+p$E_E*hyv)4@@N&28rcEuf`CS?ql+vZ$RcvaRoF1<>wo)d4-N zaxC57>I?W_t8CwgTIHBI&??J&s8zP?W33Lr$6F%+pKOf;KX=0`S+iJiy=DWYK?b zD+K(bZ4%&LZIyt3x5Fuak0A;kJ zKWOMiS+lH-vS!&EtsNggy9*X8K44ElKNxY09Yn16@nbMaV&g>YN9+w16d5FcZ{thq zg~)|z*pqexJ&oOH-B>h);yH*_xCZ*iE9`qjDGbITtJMe++rjsXQTMP5F!INXbjbEn zJz%1DcWeUY>}lcZ&IdwIII0j>SexYo3;W3Xz{i0DwaV>9UsGh=n$hmX8$4_WaKC8MhFxie*(8ki07?O zVGg7SPuu6Rc?XK!U$7e}+*9@?+f5FPF8sR0aZNi8rFa(Pvi&%jEeQLk>k$faKQyP{ z?@_2(Kd^Y19_l5M2t8ii>wK*jF}TZ%SolUSV&#{45gRwf${$%Y%C_T2xG^pf2YzI+ z){X=tH>w*GLlzs+V&_lD6DOMC0;|R`1STV;NM6j5n+4MUkc;MA01yK{4!SL ze9f+gtNrz_*}L$v-}?>f93`fI3r|+0@c)i|)p3wngym=a#J&zKD{xHu9(8E6XN+2yU`}h{Nue;DPJhPS|8HT<6E(bi+9j zH^JZbp}~KpWY3!x=s(B-KDplfLY(8}?k(TS5O?}5ND z4_giP`6G`kF*ShihXc+Y$iMEe!Tey?z$Pw%Qg|49q|%{pZ>7iS7i}J5&c-OW)st{q zrSJt9D>C&iA}IQ11=UH}v2kth}tCWU~Bim`$Rz z7kEoD;;|)yftl2chhUf%bigdjLX-p?MYOP!Irew(LDOO~4a zh5dOZgVtY`pC^CkXPOgn#`w9PlCpB`QK_C+6qY+nN-GMAWDv{~GA^c~EH@8^0B?+_ zzE-KG$8_u*rdo4I|45h}e`w%=u}}K)0jx5wVk%NnwX`o(=8uI*B7bz{IA=;p z>6m8GnSQOr`_VQS_G%xY?+f72 zxf^jg{@|5$u+Hp;bCg48Ek~@%Uj7mK7@HXoBac8zo@`7+RKl(oc|44UhhOALh@8S*FfU@$BgD0bd6e(&NFxHi(5A-P`W2#T0^$faSwSjF#*0-G!F zOp2Clu2c+-1)D1oFUNw-6^ng?FpY}D)WKkLg&unxzmgEEdRsiEXSrCKfazH#ViPev zCwV?g#Juk)?Bc{zMPnMK=@gNjj%hmC^G~|`TBV4|49~%L zri%}AFkPp4-WxSkP=2m<_li6emr(*(KzcH>>J9v_Ac`5!gWN3&T7McRbW;g{KO zFv(@3>l?)IdsrQ$kAdPiew_*{W!SyAtQ8~W#U-5bvQae43%u6yVv0HUF*~O4s|t}* z_&zwRQn3)q2UvM#%lmXJgDPPL|H+GF@;@XJ;5aVl>X>Q8xpK?qi8)*$Pu|x*l=DZ- z3A5OT>5Xz|%b$k9QT(U<^o!mU#`EaJZyMl7s>)#C!+b2yD=R>BXIXiJ`1n2+VJua@ zBKCd+M%#hEa11V5uGj->`SVZ8lOW%hH{n4asBcUyb(WRDBscZMF97JDhz1WfP=2Ji z!trM;fpS^6%mdZ;U3m%iT{Sf01nYQDyz9Y15pOAWzEIp&i1D%jr^sQv%onl67%w%R z&x+-Ed4qXZ?!}_90^?b;S(&TZ^l!+U~owG1bmU<@5=AAUy563~n6Z#hUVHeycdX|2J?=wpYox9j8+NBUr zhVdof=W-#QC1x(euD@Hvi!v5tF8v`a``A#ppGNLuxtLD>tG(}luA*A^pIy%hp#>5` z2nh+KK@!pnO%jp-krqM?AR$0#LJ|msCWIi6a}Ys{W}_g@j-Uw2*ifw4P?};#K*d6} zT*WK$|LvKC65zi3-n#eQ_5RDOteJ1V*|X2=J-dG8_f>489qc5AhhXL9Lihk{s*fMN%g`S3F5ZQvRU&Z90i@+!rh2G;_g3 z*_QH$R8ScVu!^t>C#$V~F-xV6MZcJ-4va;=C{x=CQC&0C&~fM&(@pR3y8GUu9-V;C z0lcq?_#AUo#3X!<+2-*{%#EFmp{7m7cPLk#rrFiIsn5oV)*aLJiRYzyAU+7|Deq6>LMm7#};Vc#bLaNQP+5L2}F#FG8UxQI!rQX8s zp^H7$fm_(;ba6ekZJy4;1C|c#Il9=XyvxyjOBip_*p@t=C1F_A-b;>AiMcroD!#2M zFjKBk?XqMt%xJJCNpyUcEQaVBjr|nMi19zEc(id~Rnf)( zXqP~yK#gf}0+xEJc|BwkwBS25dy>sQb9Vq5k(I(v1wavMk$V6b-)ChLGQN5Z8gOIv z=mPczUED}btzb{n#SK-&Lbj7GZeSi?s8>ARYT6=vlBTNDVtkS&=J~}|&3c*PmAY>< zSDjtx8@{Tu8y~xwI_gH>@G(DLs{4k&xp0~OfGyPK+tD}t%>K*uFdw8+??5|g1p@-K zlR&j?B_0h>L+?a8X{o%c*qO{A7!*Raam@G|X#k;b2hz{DofJYswhZcxr^tSChBkx= z*^P7peAFKRi2ETp`S_tr4QIC)529PW$PS}pWvRpOa-oLY#hU zeWS=!z3|YBhKoRVWWQbsXckr&IRpB_Ke{i}9q9cl@8&+JV4Rv_#WUF^;_)Rk$1i~t zX{n*kCp{x0A7Eox`lM&VLg2#Pd@%METdTQ0gtHxNA^}M57AFx%?jQotQLO7^>b8j# zAh~OfPbz&l=p} zC9Gk@CS6C?>PXix)`i{r4ank;Y6XhL?U|j8QJj~nqG_xJc|?_zB1~c&`^YBZ*%vmE zz`n8w%xy)bSTZHCGxm*S_BWeIVSi`>ixk+El`_Bbd-Otia8?E;r2LHZ-Wjz{Z=_I5 zqcQ1OOULwFOQmD1)Qv#TgjYDRkrHnfO~CHkFB3*hHS^7Ut-=Cxa870oXHF2ypfzZ8 zSdD7HN7ZVyba>ipTjLjK$W-IevRUGKLh!-$GfR+WYlk zme*jk48uH;I9i62->Mg}so2g=TaS(!t~zZ%M-4O2Z_r&YRE6KqKDPYHTNscoO*a(A zwa?*I-Uf)!6QC}9oa}>dxv$Y*wHU>ss|#3w7BD#Jud071R4t?3Y=YClHX-OFn~-$A zO*rVCHsPcXshCb$rT_&itYY>RAO}icwg?!LykB5RPY&2O1pQ1Ct+5}}37rml$_CWf zI-0@lG*Imu&D!Acc$;9fyG?LtG;k{vQ?ZpoLZe|34q9yy9!|Q+%89DDSFqcmFKBj< zE|&(4tfd)!?;_3Vp=uZFgpGdZ2QZ#Rs?HB$P->@+K8W$Gt@-go_{Qma3GZ*DYt8=_ zV=NR>{_w#qAd6t+^fu&5jbWue2ouC=`XYAW>GTLD`3NYWO4wcO8TJ_-R{a^etCRk5 z@pql{?>5sxA)dfXs?&rEY@2IeQqu2Kea0;@4ab;?9BM>12^Ou9w-|+U75JLwbhw=+ zXdw|8wXF2J;GRxywdvDZ+@oxIg--LB&OaEK)Yi*U`i3T21C86d=JX?*5cG&mNcz26 z{~%JptL|GgqiB5!Mng%r2~G#ugrF1Empa8f``Q5&ij~w!AFN)6Z9t5<@Dbfe+pEow zVt$A=`)|_oL!wIEjQJr!9oUTdAzp3Uf=>~rhCYt@A=dPMf&o>cgPO3FttY7udprq< zw-i-x8+!p#lil0cqcE|Zx}B}4euj-w>@9YOI`a(U9$mac+iJiH*cChrdzazxiH55J z8;bSM>}T0t(#gE>Io6awxH9s2Y<7P?$nJ+oY3&DW1EFTxhxideD>^PtQ>$NOJ0Ts& zdx>38LqEcLgH?abssxI&xVu{QGFwElRKP22AIUUNzrsAJ`u#Ix#njr*krgx3zR+1Q zWR zUO~vSWxrZ z_59h>is1{t^mr)I4d8WUkgDEO{Z-TbY?wN{m-#mph92R2=3rt(AT*4UXl?WNBexgS zefyaoe-6ufwSGVI(d&KkydJ7ACLWMCU|?3Cd^qip7xnCs-K`JcTQCF<%SA)pGM#FhceQ^N7*Y|gvVD}NMW!IiW zyWnQpDcvqO+C^?nyEvrV#Tm2TZSBkERY-%uIf04w}PRL-3MNcf&QX)2a5x6(DR z-}?~(*m}eI>mhak)zx3^oB`|A`}KCGnc`&_^w()Rj;ytJK;z4>1A0I$D#J+EMLnWV zH>h{ZfSUD)`lF15hiO}wWY!PsP%=D5#OPhs%BeEK$q^|xN$(`Ket?zt z{L`c!h1g;hKy?6cv2!MA?&uCYZM{h-j+TG|oF6H=Xh?;pu|UKsDduU`j?n6-@o|`n z#tAdf_ZAl`vNJXzu|z_;DDp@3ZkI5YknG(PugG+U%KHtOPPa34BGXc} z>KrnirUHIPrc=$+zw1nA+nG9%=`1@_Co-LBXX-?zWi^>zU?Q*~ZEj$M90_NH2e4NC zp4DeDESJq-tJw1};nHzqwg-8CM6eF3rjIm$ zCfB=c+L~M+(W(}EJ*3JzqTf@sp(7SSjJ~T=wTAy6PC-o2FKj~6<2K=-_+XvzM2l+9 zhrqURDCcirDs3hBENr7!3BCwDFhKHsWR7`S@|y`=VwfYGd@CX4W`lbCELDF*@cY$< z2Cx-f!ql4$_$=&}%x(>NJkk!i4z+>KKT05Rd)bw8PEx8cMhnac3Io!Z^NApbLYu0a%CrQid27H5B2RkU} zEUk)_c(jF?7H>T|fZv9}K7{9yKyz3se-eJ@X8n%(!PfSJUGQMA{h$L62AOF$;K6#W zygNi{?%q*3$8CM@~S(O{ZQr()0c zGQdk4!?$D<(GenAi+0a%ZH*!O&u%b4y+cK2z%2I-H6nwC zJBp)30z^(#{f{-Rn*VtdYOGXGX5h=MQeQ5EeJW*ZY=R-ejK$&X0ZoKsaI~%^+pJ=5 z$MshG+R2_$3vNdaA71k9LpGmXcEzyEz3BIc5$@Z|t^_-E*_Fh$_fkp+``xPC5OY|X zuG}_e{cikcQXRq1lL)(lvr)m}b_F|8!C_|Fjk1zHvQ47CI*Ry`_Q03 z###01Kps-Qxe0G$8ShUi8CR;E0jRO1E{hqD*JW|ziMlLdY^}?Z#*=kf4rANptaAO6 zPGdU)qF9~|_FL%pd!Q*S%e7a*MHV$4yo$$+hpysru|WSt`0{S>+5i&v7rvfVQj3! zaT@oJ#J996%ldg;S9jG`X)T8uch_Yxqq;7O8>%i#7^|!n*v=f*TerZrX8pc=JgwK> zyRCMATI7|b${V2r{}IH!%$!1)iUChFfOA^eqn|J{s@n%pVzlmg7qj{hKW2=6~6iBWg zHFm?Sn2}&ayBP*S&t1TJcn@~lP8vefF?r4fhVRo*PM!u9T@o9^mcxknW7RW9grTdh zMl1*6kMVzvaSVt*d`=<%qAR|8}u!BDQx!_t)Sp4?=O5P!zRAJfW-v6*CrTS zYZIJpvy8B_yf4AAlJ&{9-Cn7KAYfdgC<(Sj?YRV*`qe$ zU|TH0!^xhs)niq+e-l8BJJs*GA_&?Z{{bS}vC$6tqWTRGZJfqJTi{;R15{^&Glg4)Hn$1CwRKVU{1ab0=nZ+ zFlNw6^iDXf9)(eCJR7FLzf|mW5`}^O7WL9{2(}?5J+T}TRqmnBk&N*MHo>`oMC`^~+)nDLbUcTs`)Gu8DAR%)aLAJGE6`pSG_h`=z=&F8^*{ zIyuq4+ikImv|P9W#pR8Kr9}fBt0^T@sz<;TDy^pE0wwQircKf9_y)TkF?s45&Zwzj zi4@&xYFJKOl3r88Gj$DjH-l#D8qQJ`b5O&X=BYWlhO_M&cA|!R*8GkGx%9AeR2Ry5 zJ7^;9j^xCRUS?W_et{e9pNVs7YdmlCBDNPUu0?QltxrG2PJA}z+UDdq*+CYQfuxP` zBNT%hj9ErMY%p4>!OM6AHd*C3aTZqLqn`8^p`3R=}JYRj{;?1CkJ?r8d;rY0-ijPod+>n&# z*tZLp;&wlE%Tm4p@{GXScnLJRD{kX66u$$TsbTgLhwi`=dG-^%SK^7GI>X!5nU&xV zvD1Vkv8HU=lEHSWLw6$8AUoCEDx`v&MHMeK`6}Lx%BSpj_Qm%?unxbcdpYoZX-7@8 z!CP3@oQ}2$LCb7H(xobJHBzj#uHiefO?y{+sI;N5LV(ZGk=4MarL?n6Fq&f%oQ~B* zAemLYhG#=IZ@v1VHF&8}_N!;#2RdKB_zWnNt=j`Wq)l1zlAG)V2iGFO2)kt2>rk@c zcB+%>xbKZ^NDKmd6F1gvJ#ZjLe7U@J99&dxL$%zC&v}qE#X=2Db$Nshn8nBzD?5C$nFya|-*r+PR1OmA~K* znP^{_Zsg=c%SvGD z>ar5q{WYv|J8xu`#2&7jESWu4mzBbvsLM)a+qL$j=EVkD?^Rug6VL9g!%1LkHK+Wt z#}e7bI*F3lLv=XGY*QUh3VXZ`CzWk$#DZ&IXmIxdhU>BvgL~_WySs*Cm0z>snT2Un z^E#T7!0xN_SR&g{hm*t}tiwrWkJjO&uq|~ssq9HDQPaN_gfFd~VvIYrK16eB7`FS2 zv9S6P-U7OH|3~;i=+@6X!k>fN@MDkiJrEaK&0Ic)hCRk^tJYMt2U$us4n;OS9!Py zO{qE(-02v)!HrmCx|%i ze4O7$%$PT^>%;4-b#L*5GM-kXE}5)0z07y0nC+Nk6W`&_s*~IKZuQh&Zps8!(QC<6 zHT7x!9)u%lJ8&vC8<~6uQLlf*PdgGAU0A$iy1DWVK85Jixl2mT_RmA32U%2~7kPwZ zYlsfvKvmcK5i$edXRBZ2VUEXaKo@n>24J{h`uO2R%v)PjvzM?QZ>&1M#3MX6g^FMs z^Cd~ey~zFHfpZ)9j?K0CnL57!_3=wQEWy+U=S?AIgzfEAoNj|@!%q-|bt4l=6-?K@ zrOlukFNEgfUHUtV#KgBl3mPfH=cT_S+dBk>bv3M4bkv*%4!R2YC$(~^wSe`paoW<0)Po{N&@XX)R%;>x8)(IjiOaEV zMP!m{NNBUFlE_BF0oEdIL)F&vJji|RM3UCHADKkGRc0k`EM5ZlL2Y&6FV2Ac!WQVQ zhe?B2gX;^H#0f5d=L0rqC_;5x|3y?BY$*TFt)0f zi{%aC95R@vj=WAXJhUzNvMkX*>mrDwQv+THSOJTuabm}3`~e~pIoirB-BzB5s1!}& z85Q^{HUo)=`CIDztNeZS?w9;6MNWK6afhYCCJQ#q9r!CwHlORS*r#;~Gf8O}jI16AD{|ONNtcOYU zo0eRyJ<9>m$6c^k{D^&z<}k!UYxWlP1OR@8hjnyXM~8Z5HR);N4!^27+=6W8uUqsR z)^WFWeA7Bwkj>nJY~~hZGq)g{xdqwGEy!kWK{j&>vYGF*p4x96Ey!km(4s%Ejvrdb zL!w;&@DJ9-3F~;$I$9Cs_-TtiV;#?0#~-cZPuB5g>-dXx{F`3uV@;DOX{2&^LqWDV3> zi~#_DI{OuG)?~IGs?!G!sL?!U@*`@)*BG}D{p@ROqvO@fI6=V=c{|uJ=!8eMzOm50 zPG&BfNP&x-P7#^P?$Yx?w|@Nw=4W=ZEGl`0*1KHJ$xqMC;Y)UWivf=&3AOG!40TBY z&3AsyQ1^}=>VD8e-8;OgHnURlDZYhPa_hcKmKD7!nVPzf@1d1crR~>eq8c6GzvP6$ zJl6Of&L{1G8ZjC+lGVny@MztQ=BN=Qe6d;S3aG*H@MygoSYEFpLf2W$0j(fz>;kd< za9AD8h9pY?-}q(rA^QO>@2)1gNV)xh|CZ6O@4#G`X--xfnn+*RV_>DLi3EyeuqF~I z*2qm@T}&I;jASSZtve~y%Oc8CX;W?UYUS5AYbe0va{CSJm(j0xkyiI;=e6|giw=YS zSMlO$%vHPunsF5`kq)_vmqc%FIYqm>>tGr(c)Lo1znY4B!1vSfOQuTKscz&1|7rXH~e=pL9p zg|Hkm@F2fKdu&Ck$3K9Cf2X1!@+i#u&wq%kA?lRAdRO@$;z?wW>VF6;g7X#v8#WBg zBA_!mxs^mhqT0y5A()R%Ncf-ttSyoRSHH&Jp_L7-_i>~+FcnocunU;t&;_h-t~`pV zsQO!MHk;HGHr0v3B3O(rBk0u1#`Y)xx>qIa&h$)o@(2C}?8e?b!ArHxS=uSAgqoU- zPICY>`>J+l`Ee|Gyng3R&Cnlt0)s7C-YJkt#OV>|__uHYLYnRja&z3y zBx=o{*!#9L_x#C+Q5a7|5P_&?rWX}R6I`1{idYh4?vVm%+NcN*q-kw>)f1;ln6B=| zMm4bWj6=j1!_gMLd^Zu%ieB98Ewc(Gj?^LpzCNsJK^j5{Zr-ox}kAMAeBO5xi=Rn%@iJ^tozz2y~Ry zYF7veb=(4EE1lw|?<1(8cKiW_5(%v>e?yc%#N5+Rq>w0I#OY>-*y8|e9RaJcM)X_g z2kr$_LvI>N{!aE{nJ@=oE<%iR#(OHZx#+D076^Uwsx7dHQu~{WaG1~R^Aq9R8Bx*B zrW_F!ZEZ?MR7BX6h^Pp+DIQS~rm1#nub+tEG`u22g|`rG@iqFl5Me5(g$Ut}kcwb^ z*@nxIiXfX3Ar-KQ(L5ef5ol3p#9sa)tPyQf(b6-RHuV4|m50BF+Sfuf$EyNLLd#a1 zVHGVj6`{5wF_&Q#&8-_yA^!$}3v>VxUT6kkrdJc)RNB^7RWnpogt?~~s>}XG_zcirB`|n>guX*hA>J5(ZV?;3*4lARx!zdn z00A~21E2MeobeNQ`+syhk;ng|+etk6>f7bo(<9fi21(`}ufBijb_&1YAKgyn-Sm

0lhF$@rY}1<9SpqxBRli2|TuzeHk~ACtib_#8a=qP3E1i!A;?5*Wjk| zOc=@o6&!vw`2(%^bo~cq=VI9gdzLZUY7lD#z(Azu4#>*yk(-{=b4*pSe-JEF+F0j! znqr+3XfNxWNb_-S4OOX5l}szGa|&H;om1%(%BxyiM$#agh^L8~2qHc0_M4z0qS4~w zO|SMC#%h8_PKM^2{7H6^g|Huz#+$}cSPBJ_FA=D3EDSrpH8vTOAxnA)CJ=vMMj6Hy zU=5{BAY#=6nGmEMP+zVV0a$D8Q=~hLSsms5_*c{2;(wqRY+rAd;bvp%T zui6~WUbZ=my<~G3+i7v2B2UZ0T9v{$YH1d4Nlf+fY7yx9G@`R(44YCgD<6{i7QCRu zcv21Tj!yWfD({Xp?;C1ecb??<+D@nL^CUsk*rv{diQzDz2R6S?sk|OQka|!p2KXo0 zt~U3;r1(&EtXK>ivL&%%0c^+|al#GHyOnXGlh&H-iHA-Cu6M^0MFp(G3X{ZA(!o5F zBswF+hKf!R2dX=ZBd`cVf_Z{fI4W<@iIzaX-=VULPME6gy#`ixHlw-H@T;S2D=#mnS~cUOG|3#lZ+``lP7_jB9dWs;xsm+G?Zv2=&n&ilYT=y#@r| z?&aMWhDZ+yAE=Y&tGy2iU$V%)PGL){AI9Y!s`z0jbmG`}n}}yqY$Ab`YNDk&`Y^Ok zNvzyvC$q&ikpd%R{iq|At-KgYQY*=l&}8COx;`bS0-P|M&Z!rcUgPT;qIB^m}T+i|1m+BHB zO}PwJp^g#J1Z^Rta+G;)3g$*w)&v)ek$85E_3TtUJ4OXe!?UB6XQ}w5zQ9yaq0*(VKwdeStN9LG_WBXKOK)TJC6Dvz_oK&f6XmVv4j#DaU z<5*OwJ<6w5>RK#yY3a^%7lcJ*hD+DMOqVYGY*$Mh=el(9ZgGX-IL}qC%QxQzc@8Oe z>GCabMd7&6rOS7#D;CE^E?vIGF6|$`#HCB=a;4(9)TPUMo2xU9%Urs|%Ux+Wu5jsc z-{I09Vx>!a$yd2_iSKr4FL~w4$8nWQ7w;a|ME$<2U6XNK;bpH@jtAwAy2!o6blzNxUs?N3kgQHt{pSd8__^TJ zRLj_{Glyxpz7{3+Sx&Xjj%n68&{^uwQ-GVTt9nZQ=z^l6!fE-_Cr&9Wo-y4xSUnd* z`Uf}yuSjns=86a)o9E3H{_q^J{?l8&&B5F*p5fU*BEu@ zVdR8?;e3po6HL!?(FjBIW<5k7^TLoT&@d*O=PGo=xLF0?Dh^jK(1Y?;aTw3K@ocdQ zSc+$hOwZf!EIj!xj1n*s)0#Qms-~IeZr2Y_RlzI7VQVh)BH0-0ATr&FKrTM;=er4Z zgbyOP)JZJHW9+C}wTks$)SGKb1_1BtuY=NVuj;%GAQbPbsq08f^mNm6oi6n3nnE87MU^>F>RINw4Z74bRq*|&vh@O@ zyRl+6xy4-Yh<+X>hnw*H9Oe0#_@!ooZ)HFgIS8A?RVrx6oF`Pl%>qJ8w#p{rVV7rd5@45S5s9$N1JN9IdDe9@Ohhaq1xA6I2uWp6 zX@T_M0a@^T8k#exw^dh}gRs3qr5XFI54U_OZQhdX*2Qc{ZpYjKznBQX89W9b=fA<- z{&p1@A`#!*yHW**%MkLs+7l`}!r#RihST>dBTRN{bM~6?vC6I;AB!5t)sir{K}}MR zhsoCPa@-dtL!p%XH4NS1X4O3$_jahFaM^+^Q|@rt(s5U$2u_EP=8F;<;v~DHMR-@O z7McNE81hc_WYGc!v^8VFC-zt{-#oWP_lkLD@Dt)D0(1s*!B(sdsf(z9ZQ=xV8K&oU zaU&QGHRLIA3w25L!Bb)(bqSUCv{*}B+&uTR2txv92Ah!GP*+2BdZ$=`y+MGhfy#eD ztl_N41=rCR#1u~Fx;$0MPBBN&3gW6~r=&=U2oyRco#Jw;s^`TNJIoYmiRBNxR9}Re zrzOHKcmZB>9^DAw&ffuTGYr5s);b$&$TRA>OcoLTLn{#uK#VB`MFryvrxX@V&o3E= zvAWiNk$;pZl60lyER)fczo35W&bm0driva~*O*?P#8Jak#XaC0a<6)#2hce_RiE|% zw8zJ4XEvZ#4ypcci=pHRwdrjU1C7`xZ;LE^gdjcdKZk&^IK8Mw>C-FKFJLk3qf508 zfHL@y4U3f`2+I7Dqv4Uifz6Ukr1gNJd zlvr!XWP~fN2k`Aj0M*)kWqLDp!!8lvO{oSY=Q>z?5Tp!2a2;`|;_KXzYCY}%O;erO z1v%V-UBX{q1iy?~@dlN?OSFJ>$W{5l_NI$wd1H6Dnq z066(8!oN8s7M%K}H}BWCyEC?;H5DxV=59=^sB-jSRPmZMp#9HEkA@%F5adbVHJp?{i+tvy^6t2 zgjE3f6(UBsNWF%+sHNQuL zVln*k*8&O6H~H|soQo0q&>z|kp_NBAf{cIolN{L7m{b824ZwG5n zIZ$VIK$Av!J)2;>p-ph!L=#E)4J(C&^|eJfc%V%IEk4hU7G`7Y9^@YiT#Y?fmcaW`hKK&4HF5Zq4zOaYVT4-D&RQ;E% zAy!W9kFd~s1!Kof)IL~o1Ri6}waU7QD498y@2!4UWJ9oOjV*AhaJ9DU z&53#owmX`$$Q5MQuw$;Pm7Nkk9j-t-r2{Dgtd#1)`$E)XprzzB%wao7Xhoze z%)3LhhVyS_bghB&_i#E(Cd|&iGMI_ldV+XYk#OT*p=wIQ8yz)H?W=z*H z8pr4BNQ6aYnU{4xY!@y?7l_x<1u_tdVp{QJ`_F`TSKCU}MjN=uw*Bv_V)h5X?NNst=zQ^3%@bD0fs4!hxwhziG7&9Sg^u*~w(+W#Qbm}y%uoTlyX;6WcI7&y(weC(V8ar`} z^|+O#ZV5qC3TEquFr&0^Y*f(1aq2=5X;B_EqSN4l$rHy0&D4Q+uiXxGu-$>VgR&5V zbwsCb`0d!B=%4{T`oPURE;hE0&5HvMSFzpF2V_ML4T`Z7*!L1}FR6!hC)egAf-|&x zc2Idt(9rZj+0k)9F)?_&hkZ9m-|emWi7`Wa1L`7b&^oScR5@|F3o!%Ronth?7w5WviyFHk%`+cg>~||a6~&}2@o<9HL);6%7sU{_t$azEE9$Bt zu5Qi$HN>IK|24$@HN;su)_BVm$b$|v5H)};raR0QXJ`i59^}o4(zcucJFV12ELm+` z!%F^%Xwd~$^1*{hIE6wIMxO0~;h=3j;pW=YCO92o6M~jlM3_W0gUg1~YmcTeSB$2I z?a{RTe||JgU>HrK|Gyqh6WGwO~XY{Iy_2OZYDqjCLQYSur+Gxb_&A zaK#vR%pT+7|MO#9BF7jP_y6@6m&mUk;}ZWGNaK^?7G8tV zzt4(4%_IlR--jZGIe4BX;>t&ai126+dWHD5?xvZ;z%{&X!0Nh*D3AIlQZXKTMXGW; z`gPsRI8VGH*|k#%p88LulDzZvQ)T7rl50>82T!|xvWuylJTn@>yX#b#6};Prhg~PG zx4(D0>)i2c#(4Yd-s3#}y7vT6zV1EAJ6`Wz0|&q1>RB=MuUYZ0S@Ew~@t>X*?NQg) zcnIc)M0uWoS=t%3_k@U$r$c!!t>t@O`l|(|gm397)#{`OktZ+R2rMa{Hr+Vk%VF<~ zflpgdO)MQ#Ix&CjgfS(?QI&p5wDQ#IKI5x!-VeF$yH5sF*n+%&68;n4wc$Nft5c#S zgO94}dP)S#qJk-fu#>=ZA@b{1Tx<3>EFgZ=_(<(TLiNNV=@7=3cmtJoTKMT}!JsZw z3r<4g-S4!hr&=wM4r&0gRj1#B3t@Z`%rmU?cK(M|m(%cA`8)=w5Oyv{p>#C9h~WLL z>n5c$Mi&)M&!19Idb9EArP6k_O7epbhd*#lX^Y2{j?FI~GkSE+e=Q^Gbj8}@2YYSN z@jt(|NS0Vzbojrpw)h`Q+>_Sskio0RiLvSqF+30lo7P1qq(%z58VVD&Ddh z0hWrF0zC4oDpoPLqDy_&-s(=9NTBs>B9Yd&i6q+4CX#7mn@FKeY$BCRs>UCR`fA3HFhE{Ek;?MR z4ehiEnU?-c96w{4Hgy}(31%gk|JH#s?;o4a{bf1#m*pH3u>Y4V=j@K@FyCD5%|2O~t5@Cbf2G0OwYq=nf871qOxKNS!#PnFO7Y^^|CSf0Wv-t8@)t*@Jyh8* zqAa9By1LhW@2f1dYb$)nf1|=}Rl_=jj3zn61*n1FXe^vD*3*yZ1q4A(XT`?fjCICa zFtFc)PhYAw925~0(xs_~L?l4LRNq4)*awnp(I>L51Rd|w#=Cn8?vN{$5lX*lGs?5C zdynzn*SXimhxfbAt=7#1&%N$F$p>Bco`Vm)-aQW|A6^r6_tTFEV)A9GO&`MHC{4Zo zA-scTsS_WHXfY;1WW=a5A42x_+3&=y@;f~()Z<;8iKtM9-3#raHEAM3^2SZGcS$fpJZg8Ctb z+IS%Cyhx9;Cgf9KnN2~M=J&UIc|S{Jun5pmSI-WUEht~5b{!IFs$Wmq)-ev>9Wr8d zK9ELAGN+Ab8>z~7%2sO5PPss}d{M^0)x$E|qcp`P80}>dew^mpE#o$WRnkAuGCUB8 zm>ajDW6lUJa}E2Km)tqim1lo4z)!e_{#!noqs%qrU;g5bnXbY1ivwZ9HR#{+;F%X=>D8qRRmDqk2g3^s%Qoen08j2URNWB5W(SHAfRm7auG z^mUC?k-v$3z~wmqo46mi9GJ3a>ZQi;fBN&?_}`fMYTl`Z!PdZ8tQo0qw5VOnR1~?! zDyNiZ$r$r@DJ9_xyNUphdT)ateT=@1U}viSCdB5#|u>d6NoGb;3ytNFr-u0nG)mlMfAJsXD^ zBMkg6gahPz#?J&Z4NL%v$YQugZb#I*BbcEZLYUPN04?L_Eieao1mUCJhJfn?aCd=@ zhfvcuvax`XUd6VtciA^8s)LLKTw)is{C>FE_SdI2h!I?96UlV8O{CD%HSAJG-<7knu4JUp^;a@d=~HTcC*WGf0guii;%O&M z_@UQY*NJqDO(fBoHjzwkvxyYC&LR*se!C_306a6xr5}@bF)h7_X6)gbZ2sC%dJrtM zZ&pj4a<<1L??|hi4p%Fk(pv?2$mNaov)m{$03lam{Am=SO^@Ui^<5>3`pV_NVOZ%a zi+M$yt4NKnFP|b)%$5!0A>yf@qvW8$W)l_nCG&%vbt~bw2D_%2A9~9NG&IB9X7bkR z<}%o0hWG3?x_<<#&zj4&7X$4!QgfTjp+JN_*j(NNh=(FSd7L3+)ZhU5K2}>{fpUw- zOz%AF(NMLZmGo2Z`rv>Vy%Q1fW>zcdiq+l7*T^;SKgZYz~1)W->grez@!VR764^nGp%djBg|93>-)Fb*AC`ZHzI{x z5h@}hJ=7>AT2VGmy;LnifD$oT6JdyZrLVDeTc8kVLjWkrx-Z!xn{cqD7J+ygcW9_% z4|R4u4^c0!=aI-{irTfFw?$ZvQk&pxwk9GGZP~gZ0hnYF4ge-ugp;kT4w5e;*wiaQ zaxah{s)FTuGRI78E#D>8QF0O@&xGvjxZlgl+8hK^Q9!&6a+I5Cd(*NohE@a(OLGPZl^h@GyDsv+hJCAk=Y=m zx&H=v7YI*tLYhniQP13zE>l5xm|u01Eo&a{DLYViLo>an?2KCt%<^oR1ERjU??!n5 zgqQhHZ|m0^o4fi*e{dR^pZAsfL3o=_=2*9yn(y?Nf#5VTf5?@$gYY%y3w zJnV*tvJOtSkUhc?l&;0D|d@H*NXSdBU*IOXr^i{|RfyJbB~ z$xrzk>WL%p*WZ2F4NJApU%8B<_4}0XQgKIFxOhE5_@X->Wr1q$QRW4$#O+7n?fjbU zS&Xbb>t9mr^Otr0&DE}Btf90#lK0#BYKG9D*#|EsXo~1(mlA862Yx`+e;AN#g(_#V zOcJ+*is(p?+)_mr0-QYj84`gW{2^z3qDD>nl(Y5rS33w^F(=yxh2=hiCj?oicqjWRik2n zY5cBkEXKWG)vd*{OPjyzQLF*&Y|zd$AF-M@U=?_TNr1KYXVckg_5wSMLA?c{yN{Nw zMW}_Ba^zLwUB5;n6&%d6fRXVIyy_2+mO`|%Q{dW})19=by=oyz>k!tTYMwC_%JR>TauUnJO<(cZ4}_nmoj)J4y{MlQXG1(tN*6CXtr)5%rkuW=mNg zVB)-jU>V-zWikTRkPjOD@%iFd|B6v6Xf56-5YcgTABjVxjw6d?A4KYiSu7`D0l8|i z9E%0yRuid;l=MM5^sj8PA$j^#jA0h~rT@aUhY2?Ma; zF`bvMdZHY8J*hq^$7k@aULZSBcY^A&Kvq(Byn17SbW?Yn>R%xjP*AYE3E*Hwx8>WpvGz(kkjp@NQcPhit{9p}wLGqVQs z+qGu+vIITy^>aXg&mG8@Tc}1QHvk=rSE~8P5xHT7y7xG5Ay(<9)P@uZQP{0&-*MhN zOI`I^0|w^sg;#M0X5{cY^&0Vt9|adBu2OwB%4X4bT=mc(lyK$M+}v#LRx3A3-xMnr zigK+kIyT&NDE_1U6=H}&R^c~0_SBE!B|JL&_rX1Wmy)WN< z5tLqE>af30+S`jb>Qj9epnbAT|GVT`g6-pTcgr_DGQ53<>ozv=VjHWcC$GlpkGo|P z^+C0q=F!dDH@j{UJrkPc3aex6SnpXS-@%Tx@E)|uo~qfs*kkojFWf8FVaGaRwcOJ5 zF~m1$iYUudXiLlwMWiXvMjJl^#HX9qU_KOJaI@aoJ7;ZTz| zW4Ifn9^WjN0r<1i7I{CU2Zy)FXAu_ap2y{VyuUXvOV+HC?KNCU1NGr5+0}gN3AuvG zp8~j!eM?44-)6=EfX`VLfTe|FW=t#0pHN&ny`L)ECZ{!jvl)y7wJBuT#A(w3+%Y}h zvKic6y&bE{foeTYln%1bY_N64I(h1L^aU~0zLaX6zH|)Jm(9ivZ^FZ^A1j+)s^RHw z&M(NliZyxwko>IQomo6t$5J$2uZ{F*F`yPSUemjjdL-Xqj{yLV0zNmJ20^{Co7_qA zF{Ne@faA7B+mP>{mWhaN+-e7=86f5Dz~nbo&Dw#XyF_i+fswXY{kcO9M`-(D zrW^#&J+y!veAvnQ!{$~$BWIC3bM`Z+TTCzs&&fA!fRFI!Wr1@@Q{Mq-(D`b^<1$Kr z8lm2N09K}-JugG5cgbYTWHGN`wYvTjEVW1N!m@XSW<;s{m$4ZduIayHI*WW&esF_c zE%=jO!1N^J$*p7^d7d01KhZ`I=l7zcfqJ)!?!bQME5w`fKseh@Y#`*7OAzzy8Mc>w zi()q*D&;*au~Sv?d(saAgWj6(hoHl{PNLIoBAL2uB89F|hmoRuYY@vK2os)_+ZVPm z899UUvjz;wM(nBlKIwhadt~M2wO}2tOn~s-gZ1bbJ4^>=xZ+uj#@2gCAWOfJor8?> z2Mo%|>7AXGJM{9W8d*PSg-0K5L7MIJAkC@qw2FOS`h*mC5aZ}j}8}~L2 z+dlx}`jW}^bpo4K{hE9X@}kYJ$tqN1+UwYI!O-?~8K!Q0L+;eem5X2Zi2+!Gm%Ji{ z>bqNR3(;S*A#H8Y)(8bS4jZ(`>BpERy@BvP6wxy7WzVzE@XY`~xBMP!$|A~YO*HTFT;++#HPx#sfy$8lLePF}k7qvUVu=G82i6_69vZ_48s z$G&}2uExN%=q>po#w?tI)O$ycsY=sWVy>b=g+ADE?&C=mUU0-K|*Sc?Lh zsyjZ02x9(6vdm-JRlIu2|6>TxrYhIRm^VuFDN40^Sr4_J$U^i(FxsfDpW-cBz9Iq3 zrnyBm+$o;G>1oD__aTus|BUG2e(wB5ogAU7qfS?z34{PJt+*-8K8;Mv1ObJWl;YA0cAb+8$n<$?@RZ~yNV8_vRqAP~| z>SMAE<-e#GPhq|Ms`~1bOmd8}W4SA@bHck`K?xrjC_;gwr>}jT{HB@+Q!C36f(N{jND0=)>AK?k>zwL0uG*) pF1pmI-ad=9`BH}(@FUjdOQo9n6ZW>BeUB!|f08%Tr9yL7{6A;DUK#)Z delta 45946 zcmaHU30PId`~P`o&bb!^7nFTRKu~s&#c)GF#SK*4O>n^_7eH}e@Ls^wa=pn|rfHd_ znH$+nOVdizGMC)4#ne*2?N-`q_4~{mBTN5(p8LG>&U@y}nKNhRop+mI{_>#t{|i_i zLi=`xe#L29ox8rB_j}$pUeoAlTQT5#TOnY%trK7uTRdQd%}3L;-)$UlS1G{yK>!t< z0lK6B1V#V^crbocv+z{H9WV0Fcxqh}muODC#qyV!XLF{#2KpRtJ2crBZ zp*)+3@+$HY!FAkfTtn&2;`k^_xHX;4M&>1Pqp8)qbvmDpmTKBygKLcM2llilk70cZ zx)k-y>s8bzt1!2ypf$_G9j$|T2iB{9&s@g|UoVUH9!L*~`BRLL!2T>!lb`J0e;{hw z7}4`X-M{f}pn38U>=15SCKAV3e41vk4UDbOEb6wmB6xQuzH7-sEHnaT8i|f;$Sbk6 z90W8%wy7XHuPCc9zh_={QP2FGTpGkaWcYoku~)PpSqD;GdG7dO=Tcyr!G4Bu~nG>u#=+9lpu^IMVS<;s`xr6^7{;`?j5XVVlG z&kt)>RfTrVkEb%RzAy8%(5oQ5Cp@x^=EiWKGsUGM7UDGkXpC$CzVY9GXjL;tEySlU z@Ze_2{9T3%jN=1p)QX?s8~zzWi-;WJ6t~1$IZMO!m7>(CNAC(9?@PNK6EYI$b;pw# zQO1r$qkEWReTI+Y(+n@`oAE|g6h`s32gqNfcc6w$d({!qCayt;K%-fb3mZPUOxRYj zX4Jz`+9rseb1Z2SOnV($+w7--jun~lobh2Q<$RP%b^ee_4PK^F3!kP^E1!cj(P|Ge z!Xq&ghR;C*GB46`$Nsjy)Y@^rZFB17_^oX?Wjlh~1ya5vvt24pb(FWupe~Lr?V_w_ zql~B&H1)tMER@kX$8YVT=)9wO`zZRr(XD+e>x^(CL|!lWz!J#xnU2TXM^lC4jrJ|6 z*ztAyc$)19=nzJe9ql?qSf{rzB2&?d%RR#!i#kkY+E2SW?(t;WFOF9WTe&TdG{RC{ z*odi962*#zzOs`?a9Oj+6bO zn0C|gYrj_3NB_QQp}gsPN4NgbZj0(4kR(<-Eg$fs3h*QZ94yW@XT zTe)qle|Eb0Y;tw9nHFu`aOXkC-;fV-b1a+|P0u)XPMbq*9lfWAVxV+D+MGJ6oX&Gq zYVfWqweapLwenuOX6P>Nx>l|6m9(3Jv}%XP{0eUK9^}}xWHm-zho!6PcH6o$mj)Q* z{@NshoxPP^p#YtJH<}ah%*7jE?$la|ney8gB`qbVmYUcSk;8k)srF zienkz!;bBMYaA!Ggi;g7jV)mm0T{wL%TTG#dZ^T3#VWP13YA*fLY2C(Cmk1G2%|T5 zEw|{#2O3@1L{fo1!x1{aAGf;?sk`~KJMl*w4X*ogl^1ghmpqD*54cxdlde`;QDAYa z3VzVDdy=1zS525BVPmM{z2$D=8wYP%_uQsI#O=95>%Lo`ON|tF({^d>TRNoea(Eou z$n8yv>uzjofY_GA6Ah~?c(yUQtEXsRX>6(X6-s`}t3pTA74KS)lBL7z=Dk=- zE1$Py%-6K}+6L`__JQ^j1yME?(;|9~-lZ>@jtSe24P;Z9V7u7|>^2YOIeaXCl<(kY zuwHc%Jq-$_7%|D9VCp88802G33o`t$0E^0Mi?@rO+rmf>L$3T5VLY}KUm6ri?L-p` z1yV~9XQAkj=pZ8!MaGUBS2S_*xJkn&mL%Uc?q%Os3*enugri;Ez0gI^M5t8o3AdELstHW3&8gZOwAwQ9nDQs0Lf zYb=`=#TK$9Y$b-plUUC;u@~4543NF- zb@moJ%8s+s7%ZQ#E9^S^ntjiHV!v|@z1M&@=APV-2lH?q&Et47Pv>oUme_Wi=G4u3 zd=Xg&>Rh8i4qDUPZG=QeN>Jj6U*kJ^szj$rFkOO~63midwght|n5&lHY6TZ7_=tj! zD!4?!r3x-naJhmj6kMsG!|}wL(f$g3R>4gQJ|}yaQgEd@_2ct*jq3Z7H&f`T6^ctyd_Dpm5i zf>#y%M!|0t{7%6e5>k+Y!3u^b7^+~Hg3T2SS1>}sNCjIc7^Psef-MznrC^NV7`g7_ zAtP00l!7G+j#hAtf@2jNr{F^hj#qGkf)f>-q+qFnWeS!nIN9;oQ^if>gwnNZ8qZ*p zX}xw0v*R4MrB84qzp{tMJHCG96g}kFzvqzaIM05WK0ZOVevb9?JRR%zZr=5pAJL>b z|9!)WCf3c_|2R>3o%eyKiOL*%4(_DVy76y7AgORX`qsBt2WB7ok|x)UKD?gXlQf>j z7SK8EvX%rk7s73EGaX4sw$lv9l_NK4I&e?N*GJdTG=;5wXAK0NHt)XYI!faM*(=P2 zgvX<-Z(ZmyM%)%Q*D>n7XK0Qp8+3dP1e(3apQ2fgAtzqY+i6-mJR*fZ+;LuA$CC%R zt9)T%Ei@)PI+B;O;{nTUED-LzYCvUO%MX8Jq}4@y@*OI!^SqP;?ov1Cavvh9+j?aU zkx|$6^C0f3dxp!U#FpjoIPN2!@V7Q~biAb3t+~FJ$Wqt;i@!Ko>-vAAb86ria$_aA z)_r?pF_DYo+Z(=hD}Go;SOvpwUclP<`_1R5k>iR)U#KwS2T;Kt`A73RxdsxcE!EF@5 z8M|pBoc(4Zn8PMwaEpmpxVuDJh{@Y1lDlwU(Re!*8gC>TN$ngxUy7wMV%2s^rP1PD zB;ubUUdV)A%q z)L%payGzKOAb?LMT1I|?F?yDK#q%=p5xqFQ9Nkpgr{Q;nI3>{#T1l_bXUvo3uyQcY z(-3JA_;BvvhaoGiaLoQCf)+W}{}M{A90z}ibAP<0k&xsK0nHFrGyYognG2}V*Isr61Q5v6A-z%lH%25!e8WkewDV-aXqZTAXfJ)N zZNYemWPMmA+bCKDQXJ%?A>xG~ignu+ZzTNP);|s!{_1&0#m+!Vpm)XPKvZ&C_y$p& z^+2!@Amxj1cQ7ADXGBR5g;{gLjf8Lzm%3P?Lp&uu2%-pjUHpNnX}@R{jAWk}5Del} zF(;Tpt!<)>$aLKB*Jeu?(~HEn!4L*s7EMB^6&(2v@w=zh)uc&{YtHze|n(HAPwzjnisP(LaLTphTx%Bzd?{iZdn-a-1XOVyvi$r{0w8JRDCC zkf;16GbmA`M7%{?>O@_sm(%4oWFahOx+hgDu3Mwv0tFuy6TGN|9v8>Fs7T~_Q*gRk z+UON^d5?m76;z8IsilqHQj|jq9#-&evBjH$(vPXkdkP*`@PvXV6+ETj`wFU6kkl$j zXT@=EvRATa1J=qzV*^zLRbnx`Wkst7N*8JI!QNKFodXS z>cQH2|rZK2r-iAQL!b&h@{ElWQdVqUDC=(!kl-+?~AZbYHj2~ zF>+M?9Ot4v5@p253(NP1(L~X45G7d`hZ|wg^&JPU1TxJgY6nqES}zU^qBxgYlXaAd z{C$?@G)=4-2)Q*%ypF`$BFu=AwuASQ$=^kLsg;o#iCk$rT+;SO8F6v0qP!DpPR&G< zY}SG^-P1(4?qwo6xT?Bj=spT*Y|(v{wm}bTY&SjZOnS|jP44zqwp7ogC@@)jKe0K9 z9`T$wd}ip_sgo;0%StAXE}cAa_@t2~A~_l3zO~qsO#3iu1H_6Hnrc0vv0-#j6Jb3p zZ@Akg*)lv+Wkt4r;$mxB%R`4|iiGyuODs>N)|4&|rP7m><{Xhm8_BXlW4~)F(8D$E z)uU|>c(svtE*Rw8kb!B$aOd|~VA|^*pdxoW+1hw^P&F3`*G$YVT;7>U{Tj8@p#BY_ z(=tV=Qh)p>6xYK8!0?G z&X@R5rK3t(d+6YuAeD?P8(lPV zc$xNYQyoL1o+9n1?pAYb8#pPnibyOF18)eWndqbqs(-Sp8h!{lwHQ!0weCXbtDnu~uFUAw^q+3oM% z8aJY7)JSzHPwejo9jmA4*`1;*AMw^>lzaM4zJ=`pVI?Nr0c#?Dkd^XkhzpzAj1+AO9G z=EZa^U2G`CWbe?EHc=OGttTC)&d%MvXf7E&Jd@h^iN?Jl+!PdG3GXi4deb@T=DgAy zBa`x+-}k{yR3KIt(g&0;%KJgF>?Ml&)9D61o29hz@e7)*bujDCA3!^6i%D;2XeAoE z$x@-A25Z8jEi2S*shHSrkDynmP|P1m^WANYZGAnn(&db|ijWa7X?GY(Q+TGWk7zTD z_ET@?FT==%YG;roVx*=m)AnoMU?uCWjf5WjJblU-Yr(p)Nl;Q>hQatx5r2ub5wFd_ zvf5D@Te;4+`kD-z=N~+*Ws^Chh;7Y3CN~+*Ws^Chh z;7Y3CN~+*Ws^Chh;7Y3CN~+*Ws^Chh;7Y3CN~+*5iQ+#f?ao&?qOlY7ClzT&gvU*N z4{v50DUQ#hT0X+Fr#Lx}!bH0_j95`JlzKMmX&dgDl^fs}WNWGQY$!aYL%(R4z@kLY zskFeY*ef&F&o9VMS{L(^Js!^@MBp^Kiiu`vkf-q!R!$4GJn+dj@^g=I9-gNG zMgKXl1C@vlbLk+B5;TvF-sh_}!dHFBD_b?eP0JU>b1*Va+@J>HQUdc9iCxG=oGYXZ zvHToa#qx)#On&`w&KdLN*B|SwvEl0{oAS|6O&f}-dI)?U0yHGzee^90g+5Tto@d8k zUX0+K_+-AC@8jpt;#T633Z4vMN1qOt-)OO68rJ*#={yK(+{EcTfkuk8(|ICI5XYzU zB$p3_4O=a(T=bGVxyl!1kx|0;SDpmbu-mUZ9Mbe8 znIwpnzw!j@q$ndqR<`IZODNOJ#FxMFAZw2VBS8{Z9I`~a=%tZHDwZ6v;|r`P^Eg&z z>MVx+#v}ame2oBHnL26IxT2CtV87B8DUF%w;>q85OOG7WsB!N&m?XzR08FRo)a8#* znZ*`hn`jOSKS`}}pYX5I@GwTh`PVHN4K)}I`@-sPqsey{7MnbYV65O<8^lNk7 z*3ULs#P5TW+Q~utb^8cgxmdS}e4Wb|Qcu`NQxB~8*3s~ zHb)^YE^K+S(WRxUpaCqFF)k7Zuq4#vVq! z57B0WK~B`GLTyu>#p`H2#(y(gh3K||Rx#TY=j9bJ>fIUoZ8i246>DwLP4T)t)HcJ} zZvz%fW}EJu`7}KY*6LxK=Ip)}f=lg2n#pXl1#b5dH_urDoG)&KlK#jCl2l)PiOEJbUCxl5ffh^N9_T!2+I!GY{~o}XLraC zqKWWbvaOZsVa`*#pcN~QT1l3F>2m`5+~*n4VIyFW_ob$ogBHpEbfseHO5M_x>ZL0+ zOjjzI{;n$Xrg-uX3L5jHVwg7-RJ@ogUd(@1lwTD5Rl(mB{9VD@3jU$sp9=mZp{^-N z3Ni&Dtb(qK&_8LA*!(9YRw{O_D@Ls=MyFmH(G1r~{|;*_9xSaRMQ%Mz$g zHWKKt*tgkeZ9UZ7h=h;}?M4q^JX6@V7}8bP-b6V33yPxioR^nV9)T})+YOrxcV6Bt zvrJ7(XD2766BaNznVli8 z#~2O&nbT(ufI#jd{0%(G?ariqgHkBgN1Lu`Z))GcRn>(af*!F8;`DDY5_Dpt*&}Qx zJJ0^$;o4elI?ofa2Ur)8{T4iC>0;Si@IYC4iWokDwd5A=Y9dzNSRyeNFVzhKex5+a zz80Z}AdfQkgNbnVi$t0;2*T=$!7=|(1TPtUNLAcK>;Pi%jxb`tc*_pM8O#IBr!pQQ zLJp%9;bvavQ6^&W7>Pt;(OhwuVi@~Q>_1H4*tcXF1O54T6M>=G?EEI8+fj5$W9Q|g zvhy36UEJwi=;h6vEsjZnwW%2T9$h96XZz!@YSo^h$H88oI73c1Z_mtZNISM>kajwL zilxux2UyrvpM^0JhKX}9t$I4&J4bzCn01DI0L2oLO7{!&v%8;XzPiyz%bzQK zFW^(ct{EX5AHsy@EAl=fXM~&rjbsqfYuYW0;<2zLT!y`J82ntPcvIe;Kg|5F1dbh&zsbNm0Gl2M$Qx%vghJV6Hd3X>*A zOQ2Ebe(s{3c7s=qg zJ$R(qki1;8C7J)BB=h$Fp``Gv|4>@uWLdi2Qa)kXGByL*YryyLyZ6rOz#v9h2w?|cunAeHCcOHAWE?j@%4{CkNRypP%R zTp4&*BwNWE|A&&y!a=FT+te3IVd?)V)S7kw4<(fq{fCmqru>JJ&K~{`C4;SL##`1u zt50E}Y*LeET!a@fk9HCFT!ef79$IVG;~rWnD;DKNtXbQNdoHE3h4;`h*pp3p6xz|J zs7GGs{Gz^jgLCOkaR3o=w72#b*gkW_lwV*~$`;@MLW5!Y?C~oC7qY~@Uon3>ioU-g z=%j-P`JJw2_`?p0Uj=N1uW6Uy9*G9aDMes|lRl!qSU5rx#$2oJ><2pN_aB=ccGU%wnb(FV=9goUYm3^d0ZXmg^&%=$DQm0u){)TLx zA;OkXh}lxVdYrR3g^LqQP-Rv<-C+Gp`i{?-LF4M_RyJ4RZm80Qt*C!S5M$5C3sM8y zsu0HE?)nQtUAI*=Yz^g!Fk(xotJp#8ChUICGPV;6>;TR>QLgg|&h`)tdW8nt0fU}l z!D7@?bhfbPsfYN^!WO|4IMd3OxZHrF8ex$)U;(x zn^~m|Yo-r-I74!5UpX+QX=~tSxk?S-QyrickPVjcOOR88SwA+NtwJEmr;q?+d4F!> zJNcOvS-zsZJBy@4W``K;ZHYwCNtMTP7=oPDg&|!KSa{F zRA}sL+HuFgXV0)d=nM^nAV5O}(r{;G5c4LtCiWp-Nl8*N$`tE^*^|!4LfB7a6run9 zL~#%c5l>BI&723rm<6$6=AB5Y2V8hp)B9G3I|6k2j`Ze8-6PkFgNPx$~_=)+82lC(Nx@W4*LmEW3;Ks@C@5&K|AUOQcuD+l!rj zTCiQz#G}g%nbp7=wl)#GX`EC#_Oxu!cM&TBft}y3NBr zPLw9H#}JXACoy|%6EfViZ5p^jXDZjWVZyA_Z5`}o;)OPlChVnR(gW-aO%mCeY@cqM zYM&?$v}U(D%TXVK;4u7-A-KYTHKGk9oXOxLn;;;6iWshD@CNmOhBhC87JJw^_6?+x z7Cf5|=F<>cu!FzNKSNVXMaW*m@J2*+r+$4Ciy)8`_Q}gG)P4!zZ7?v`lD9?sDUfGE zhkJ^AEZQxFAJ|AfO#4}MI7ME;+D%zj24$m)r1~m~vicVE)P4}lPLa2@Z$WNuj`qFG z1f*&|dh>+8Z%D4cfwa5o`G;)Q^QZU}w=(SynR*8g$jd40s{M6WJt_6|Xtzb;`!Wpo zH__vL3b1Iusx}uO{K8NB{jOVD*WUum+FBGfEascOiZ_LSOulvg9^6INyY5Q;=Pq3| zIE}lQD!FYZ`GgQj{7zr|Q?f|4m$)cCP2NFG?t0I(`r6ccLiyQ&BH{qFO9c4JOkhCc zyPlq2U!L4ijbpf9GmGqK#Ow_73vAw_) z^Ur2tLN*UTjQYZC9!;-^o!LAo;*CHf3{Jx-GpAIPOe~sQQ6XJuWg|zz%vnJ%wlY#B zo4jm?x1jZLy$Nj-FD_?+;C1gTXTgDk{EZN>%8HVaV__eiI`J+GX$zsRV6DON+pJ(M z=#(g4!Q#NDm##pN<^y7@%)KN&T*1=N5Ra80Mv4R^;W1%G2po?Ur4_>`6ipjF1yzoj zP&xvcvXSNvka?nPC2NTl^@)`T**_-jgBERx#-rI7x<;+FPqihOBr|!weVQ2CjukNb zRI#@mD`fTx(WE^je)|-0usu4|K3QaUkW;kKUM@~&ursweER)&ih;})MmbA|n%X1L+ zXrCqKY(la$d%Ycjl1xikzP8xNd3Yl^}|{gVCq< zV##o(jP1n=Vd&T=6Ygx9&zeYU#ERiC*taPF`*9OVQ(#RM1#B<$;1%VdkL}IcLs@*T zHzJE&oV9(}B#QNdFIua`Qu_leiiK2(W%ev0cw!I|YE$FtPadO{Bch?2?-YpzdY0H+ zphrM${4P#!X+4-^WXf3m8*^hsw|IR7Z4%oP^k}TiTTF!WZ6>1gT_$4imrcaN_nL^6 z@0Um`7=%7d&|8Sui44kRfgWw05No8!;D_E{Ax@#U-psln(TI^c^;e4!#7etGzutNj z6^psO^;qk}EsWG~7>O=7GC~-Ke-GEv7t1{vURrlRYRNx_sIZU^;qhS5C)ifDl#OCZ zT6eky^G^-JY%{5Wb_M)<9>fU*6P;?t}EtalW_y*QMN<8k%U+W6=2uo zd$>Uw1(B<923NAgjY+JdF$s6(i-Hg%ieu6^nj8s2(559B1+;Evu#8prs~yN*q$Xn9 zK=uVS7OMwgt~C-54`vgoq4U;Y<_3Q@gJfKcDe7%b%aO&HmR{oNVifh1Gk7R0L~8OH zBQSZJnx)Q-Kq(L5HIjX0)=+m6Pf11lBsE#+F*S0C&2(dhp#=B3J`^|n%+bNN+|2eW+UwTLj-kaKrXE0&+!v@ zRW%4PftD%+j-02P8&NG?9orWMA(ry^LTQt1i8LHrI%G~~y;W*3#K`FXc+(nlW_wE*Ly)-{9<3Sgc{*7;4!v%f5)Onrig%pTFFp+|zvqGzX}Xpqx$I_?G&8$JV_9c30f zI|Id9n8h~DM6pP5btXPZ#GT%og&M=1Nwcx2QjBxt9JsAu+*&@5t)-UE_)0c~cv7=2 z;?{iDLcB8{b1hN)IG+uG;k3JrJq3H&S2i{ama@@y2K%}54?89nBKg8=SYrm;SIWce z7OZ3~7qaz~=6q)%gKIU_d43T?gmY`>_lp_A3EPS>kFrXbyskgWu41ixZwcE1lh=%; z>>ZfAvX`-awX0b%6zt)v*==g?9QHWtP1Mf0;|bQEqT6fyUA~-`z`pOw-a&wWe-=hx z!v6Ibje^~p!6&d@E7jVIdW*+oQXpPmi)B1t{InJeelHQTj>SU79Jmf$*+V?F4xQXxTwI6stefz7 z3SE{b9(ani6w9AtQ(dvEg%86fNx84(6WtzO)yetECh2svcdg2DdOwYo6c&XM&#-k; z$LSTV9oF#sM7s(7M#|4!5xz7UkzCaa(6b3mEN6AXH|D+GnkOJs}^!sXV9!|dx@=C&b`D`Ht=3z8k=x0F`do#ti01R|1>ItJ?6uc>UYNGq$2CRlbGNA~i=`PT1ma4A8{ROrV)}mD}u(8D}`6(bxbaQ zSnsCsjr@IV*3I%AD9EPAa2LI?2n!STwM6Ku|`(7t5|N+TQL5kd~_`1 zKbuY9{C5-4`Clet=-fmsx>X^*R^3hZmQ_2U@oCJ-D!|Fs(jZMnt?tzq&a287v+7ul zzA3A!ml*Xt%K?Mi{5)F)2G?OT>i`BfJ(nPQ!1% zc2@fuI}iL}C+kYZ2(ny`*ti35VBWyqK0oaA$`;8lu`bxqlq_aq3q3@%eQGZ~ln2_) zyt$#huJYWX9gv7O9W?VU+8d%6CE$}y+|9f=(_S(W>|-+#U3=L?49#gG7VQ-iv1)rH z;xl${Grgs&j24|RVN_Ysq!BVaaki%p&)vUiY|ed%eC~aS`n>xP4UzRS^USem^Sw~F ziiiB?c~;GKAF7LH_eAXEzuEy=aEkaIH8BSEFH=6%O!a9p^%6G#m}Q1Zw9Ztiugk3Z zD9k%g9W`>q46RBOIhl85_1}@3e|Ler$hDgLk#%js{m6#)@cqaZ97S*^IQ8zjt=giy z$l?|>$MW3MpmDC*}tz6WtxG*}e9%M!$<*C1sK62)(`K=Jxp ztcmElk4>k6PTUbju&B#B9q#Qth4<_1%i7nNF7&t9IvP=b#{wEIHXMNfG~o~y^GxQr>|eRw8SO6pP=1NH|KiB34{~2TdL+-)BRboF_ie=kPlU z`BsAg2xf>&E15riEEC_%5p*@c z2#A6;V+vx3)ppZqKt~KmB=B&${QtZ*g1!{J957&9l1Ts`L0^c)4%kROk%_NBU`t+Zi7YhGR?5}`SGMp|-B*1z-!{{!BoXk+wLg<8QZ9iPIiV)j(t44-J(RQ>?^>z%1wZmIftDi4L^=sOKbKhb6yZz20{ z8V|%*o;wZhlQ@FjdV{{-DR)>p1vxdRJ|`sDX4Dj1mi_hA<=h_aD*<`#LzLJ&5K zK4>B-e58rA=HpBxm6w`G8s?)aoX%&PNCvlw4a2ePG>N|{5pOtYR6d2DPzc=2Pk{{G z^&|5_8oz8J>HNAvf;0Fx{yd%K4C<97&!Onwxu|E~yn#i9>O_v`#e*ZbpI?T0hwOsR zMFm-1a*O)*D=6rZm)l2gBbJTeAsCk1M<6tHOgPVDVskS%D!{^j9>K%tS>ZPl0j!&p zU2%V~)raYu#gdUcik^{4p!sl2xz;GA9~UK~un6eyiLXcFTj|Hd zs!^&V^nt&twzJ+vQ!j| zhUA|q=8tBfP(wD1hQp-0I5-+68vSh%I!304MfWlC@$ZVtG1!5u9~BqIut=+ZB+kf$ zNnnKsyo!84?J@QYtC}R{zQ+!V(eGjDnJDq|2>(^NC04r~oc41&-R$0!jacC?A;u_Y$LV@D|jm5sc+vaoZ|$sGH~9ICjTr*xT|bwtxJpje}XSJGRCwg9dgQQ5HV1iwPzsK<%#XHDIz>IzzBf>dUEN=lA@6nlP5r6_4(ME=)HP;jn=!M2GsR5QFuv{TLhXtLBN5pUV$1_s)m7CO^cSJ0Ie@{1CH6 z`|IqD+OZslrjOZCX@CBjore8cec!&{Visw4%6})zSBm!Eq5NuD{w7W+u!t9LvcoVk zSKPu@FI}|yiS2`t`F}q#U#dOHEUPTMlp3s>#@|K{woqZbdZ3M-!ElgvG z3V9q>vGbn%6IjJ|d*SwGVz4)t1~D%m{*_evy&Kbm8g>>vin;qGgx#)Kht{$EyBk@u zN!n6lp(czp5gjXuq8M076k@?jq7W-q5{0;6CF$A}OQDA-Z3>oNAeJ@d(bl1HMwYZj zCd@aWLcA%>!m%)g9yJk;RYp;Ce%3?`tTT#Y;g@TD`SY;GZT3Z1`H6Br{xYm_(f)it z`8copb3f`~fM<`St89)*NPYd5GifSEs6o6MgX)d0cbTA zAZ`LcJPey!0!*4(Vg*1FY|UCSwsC1G^8i{`0;Jjiv@~^gSGrBMIm2cFY-59wS9`!F z*Q-n$49!|Q8xF_P+S>v&ty1e~3q_`rEebH(76X`Liv!HHB>;A|B>{G|$-}?8+fo60 z*fIcn+8zMxW$Or-Z_5SjW9tgo*VY5D(1!2;t)HzQ-~gLE6llT$46w}Z16Xdy`)O0`p@38EEdi(5;{m7J(*bAL+XK!TYtKP4$KDNau00=c zp1luXrCqjtzFoH6ZXXO-WtShQ+AiNjsapGCEiA;gCq3VQ|{3dw*?}Z1%b;2prl|RUH5~RCNM;rb_nvvsJR~&sE_-H*IrOf50tOvehqC$-%U> zN_O&&D%r_9E30HL*Hy`;zEmas6falF{&iL}z*nl}nAuY;dvf-4pP1we0aT)w0#+s%5LsR}TaHpj!6wht;D2KdP2*@Nu<#gNxPj1wO5o!{k!6 ze1Xf=@&&HIPNHd_)yNn4yv7yqYK?q>|J5`F{Gvv_z?U`ta;|(;69o8mjeLV|YUI%W zt|k`nMvd(7?`ve+f2er?@W&e2)j!o_1O8kiyZV=!9)Q2q^ai|LBZtW!HL}rv*2qTx zRfEAzS`CH74eNo^o6hlPA{AU}d|)XX4$kOG~51aTBd!OGq? zj6Vx2`;{>M6NNZ0G=~^l8_V@XZ^E-v5%X1v_{$?u4w`~T4TW~K2^Q8*vGK=`r}4hL z3`)Ufewcp-dj}SzFLkcMqpWP6TIH}TuB=}c{nh%qQCi!yupW0|pNVe__`BVN&B}d5sD&GF7D!x*3Y?|X<2vh7j~i@AJ#Jy8 z^|+N))#H#zWYwl*uvwD*v8L}b5zby!NMGIDO&*~=1J9OrUAv8~CM~dsst=9D{+q|t zCgA_*S17s%{>mpI_E>~VQEp|s%ES1fI%*85PC5u6wL zBl9XvxX;DbEc-sxR5su~)HF8!KGbwpc^_&9!q85&mD(UPOe7hKu%e`}I1_2j5GO6m zq%t@%+CpO-XXeupXeTdtWUv(tc@XQ{CojK0R5Q2{i`yXxIElY)BFX$ci3H)m3V8t< zW=EMz6~mBVoL@DIrSq>8;-A64_r^9fGa9E}z3kPm=M)jsp8L0YMaFv;_UK!bUr?CW zQwCMOB;za#`($P3_W4^k%u)*EWnXzF#^BlrZlg%2Jwi^>2(dL1@=>_6cME=v;FZdV z=1(BP`*bwF2rt*JmYA|pVqh!&DjZy%G5l*xcnD~|{AswQHYY+hi4)~XkWFGmbTVX< z80Yn5j>BS-#pKpt2}vR|6)Yjq`A4dJT7okwU9yBU(KZ7tAyu?(gZf*GD{a6MQk)ka zkSw7!hjA!^&!sj_dyc#-Lu}1O8`GV=JIgk<7a3jA#&+U#SG2LM*p-JmGR44dXyXG; z&+hy&qE2FS540^yl=np2I*RCCXj=#8^k}ql`YlF_H@R5+PqO*UIzqgh&|))OSEpkE~v~eT#Z#6%-(XS=%Ac&-~YwKDl?U z$)U4dP9k}EK%b)gJ~_F4aF3n>eU}RGX<<#kC@AXNd9oZIcTw(`ASTHWToelKl+`Es z&Op#?O?V`MsAw_-cLFvjGS5y6daFCMzUrwe?pKeN;pVu#FuyRX2VOys6t};Gb?YUu{VUj& zlk{dLl8nP86eR_RODLo@4wq0!Dh`)WNSf{|5nl+&G9Q$o`>PJe1cVi)3&Ny&_si>( zn}aUEod3brzEgFn)7IW^at&9Ooas3K;E68UdnecGvTxeRi)*QA&F=mw&%Wf>WfY={CMy*Zk7w!Wy9U987l*mZHy zM-M~ud%wbiOrKy-EC-?cR2r0ujUh&5-hP;ae*E8#(LPA0>| z;)$@66^SR#8ttr!8Aca*vM9oYl9=|Q@Hl65pyi_XIU@$v$GPW>2zt9VnoIXh#!#@i z-s1F7u(<-U>p^r_z8E+RY_6B^ECMSo_?s2?7n?_c-SrdYC17`jB6>8~U0>(*(URT$ zkLfsQYNs@;e1)LsbVSuZg|lb=LJVL(m{T^vAaEOu?Lox<9YxpGh)d(J#b}~f9Ls~j zdr!o|?AsRSWbq8}+|)Q853}T`IP9K&CEmyl$E*D5W%U*hd09PN^iA>@T9X7rb1Q2D zrtcBA;&_Dhg};w_OtOZ!==)n5nex_y$=Kj`VjOd~ZjLds1On=i|ML_~q49o{b+llDsq2kI!49p?U3zOu)9PYH2 z$->2AYdHpHk+b(?UPsEFL!zI2Z8>$JtfKV9UW|5z_KQkIDHH zq=eE_M7q(i}gfOWOA*;ZOhk~J|oLpCrbM{(2uCqgG zP>vQEGcYJi#OWCrl%vG1ndq#MV&E(c$`MY_*>dfDNNk>i!8lHo&&6OIE28INFphCv zpT`#wtDYn#&&OAoC^BvM3KN`v*ks3!7g1GUtjoEc6N-3Mtjn(0ES-q`Uc({QK8`tm zgf3$zWHW@$|V{DT45nIHzuy^4kZiukFeCP)&_zV0keu00BVO%X*?BtDn%A}yz zFSm1^It#mhZl6y1eRK6v@nU=KGibLv4`BVW3kS-zp`TneRLPv&PW{ZYvpeJvp!2OemQmW}~*p~WjzAAg@ZI``E_O3%Q5s_v4Vqfd~M zxcL5gOEabq7i&9kU;h!3^q->AouHS96S$r|>ONKV?UkpGyU%_7dgbKl56MMXRoFEz z4?UpgilIBXKNgl@yKo9;5UM3W*6r7Day|3kzJIN*H`*RsK1nMASB2$${~&@!9aW1lgAN=z4CK z)fHmvBK{1kp5pAim|q29mdJRNKhCOWiqntsPgwN~v1^H}V!9Z(l<#HL(}d?TFxdHj zGuU}z^JDxltDY;$SMlAfdX9*$<@;FmZ0Ge_Def{cc{N5giOk0_sx{{ykE`caI-}M| z=3)_Tp9FI;MBBBPFS@w07R-e^FRYWy#nowFFXw=Z*t!AC#p>++v=nn2iHwbyY7NEd zjhJfgV%M{{)lCfCgsIj*cs|E(H20z2h%lu^5L{2dY3~8!USC8Rtiq`V=MfUtn|nC@ z6D=_$B9bkhkb;${lg6f+NIF|&A{lJ0_%z$VCufaJB$+jrNGJq#b)hxuW+JI?)bL9c`Qw<6=^DM{@)n5632+3;x!ptQSI!Na<`%+{b+3UcDk-4X_5oz50+v`j{u|9!+q`xZtN=09q)HT{Bu3 zox=>Dbn(|!3r>-&sXfVyq4f?w$sMjSo{=r(4l7q-JH^=n$}|V1zwGfXF(tGQKk*B77U%MBe>wiBx_qsq1-=nAULbbfb*dr_-q=6<4!2+K;wCtHBk z_d_`B)3Ar=Np=F=n~GDu*YJb6siABvvx@}>J;PUF|aTzUEH`(Dn# zS?e!e=Yd{_rPU!XTlO;~GV|Yq)QOAN5ma%g_GA8=$Ug(Wp)P)uGf;P~QZrB&0y9wj z^%Wl^27Uk$!l=E#9fpCK(pjwj1~VmB1bvH{lH>gDTg()v{xLj_U`*>iK`n-}<3-G4 z6n~&5@6M$AnOkGKA;w>ugMhoU*r^;(gAi7{ojyVUQ4&Ilmte{I0n%1a91rlk+Kj3v z89oC_1hEJYJTz=hXYOIJeeDdq_4P8f$9bSh2i=eL(r>-0E zR4Yy%*IOEnf8Etk+_+`YE&5~sp%yon)Rl^ww9^uRw0$0wJL!A)NpT>4lyEp_2p% zp%bbCLPGBlE=umrQxS~Zp$Eh+AVpcb6x$!A3GabE6cK$ksvR5uZ*~Jh!2I&tJ$v@t z+1=UM-I+7r`Hp&ir)(}BNEN}u9K)+SWq_zi7s18OcET>%fc#74?2@gCM<1aTS*=gF zkvg+W)=`(kbusHz-yJehY`A`wkz(?!624ZO$4brr&(}Hf)Y9oQ`5ND6cv(u{S==Xy z`;@O%|B3sQr$Yb2ed=pn`b)pj0*!$N`w%eF+2|PrgLvMe9uP=2C%=$`UH z5MD5rsd}eabC%#{>i9aIz~bE)(_dk&xGUaG9LbD#gQX8T05K334gn1y`wIH4T$NzO zSo}h*PCyr9;}v|j=BsJz;I%q?1z+-cjvVkksO4;xz&Os3tC8=}!o{d1V3me$WN#D0@Ji_t}H-2uENPAKZN?r>C#i_f!^7$y&AvkyV?Vs6^^pBxBwNO|s-$1p0N@fPsoi_Q z3YVo;?xT_DIixv)WJwN*kc3;vrWG<-14nSN#%kqcAe|8Eq<=#hB7C&K7y@(lp|Ci6 z+a*}M6JB<9A7E$~RKNXH6VU(Q2#j8J1WvDMAy(l8ftzA}wi-`EK9m422CEDE5&cLn zqt1q43^+8)uCg-Azb)>Yx)#nKQ&k-hrTA_HpDo1F&VmKll!O2Qr9~1q1KRS zUP9EnIlL>rG5(!(VSmQy!g7IaujN#}L~(eKx}i8VvlV}!ozT@Bjfgz(Nu2}AJBoB6 zWAP|$F+ec~H}x0fXH_)|Kvm;2<65cYT2dz=gV|vARX){CML1rIev@lss?jb_SJ{@ow$~b%85d_=q z2$ETjV6s;o!NuNGLwkwl!>Vc_?X`UAz9Pir234DB~3VA81|6R>2wh==yZ*zZ}jq&J-M z>(tiXBG!B+UZlgWGU9)M>OyZ(pR89wB?v;_xTig@BC2W#DzTwci7r%Ppp`w;uEb8L zL~~EJU5TSniNTit7=90}9TM201-Q8G56D$zQF!NmvzG=~1@m|UVH3)msuSb!@^4~g z-)$Gt9fi1j!}*Q|R{}Wv<`~3W4_r4cs{_M%blG$Dxs#@F%GA4&r*JfArnlBqF=Jaz z6*somR0-qxnks4RsHrlIoj0q>^dViwE>MHpl+w;w==j(z4S0+lRdGW_jmK}(G2@Bb zbliCIHk~k@x=kmIryDe{c@Wch<~Bo@@vQP6iI3~s>eG=tw`^Si2g?mA(@yQEt89G@ z4Kp^>&~Rg84UI6WYG|afsfNZhHrLR&jK@aeUfPv)J+q`ydA&-nYpC&PO%*d%)l_lA zS5qYnwPykkC-B@vOyrZ{xmi9DSsdW>*)oZj!^>k`oX-QmEwOZDd4!ccg^wmA+zOw^ zN5Glso5_y@Apq?NP;Z-RAgjxIb->qlvSkb6E35~~YMqTp}SHu%KV zFK=0W9F9_2I3*J9n~Z6(*429i_9R%@%k&wPjjv!gGjvv=FgMZipy624!Xhb%1IXfh);|L~PHnyn? zsO_Cw@u>`T%AhR55g3cnLNtI8_TdCeuN%FF!Oc0SuHz3dvkjMc#r7qc!jg4igvrn>Yf=IHa3|0)`RP_@>pfVUo~`mF*$ zxgY%E=xOy=t5)HiI6%F&3f-$hb#@i-;-xCUN86B9s<)3K_oH(AXe@s&RdiQpe4zhD zz%x)OJJo3zi5;4WLFFh6YLXQ7$7{ZWqG{rJ9f_ya!RjGJ1Mq6DQgpPMT7vUg=3CF_ z1L;xx3=*|`yq*Wa(S2n-e+({~m0S35b$J7C2$+Vwd;CW1?w}TKSC9eun!=S#&3vnej3QsA^@ghRsL!o$3?6= zNbPKnj|EqowSvXE18oJTG42NH&}!Zsp53Nvc>;H}b_Y0;+1g#tkz{LkT}KkF-F0k9 zH`BE|iL=&jf2~M@&%e)Fo(P{mhLLtLNWh^b6ytIv6a#2Dbm$h8tiw;Zs=`W_!5uyI zZ9*mWaBAe_Ce%oGr$+j0MvZjS750$2yczmj$0oWTIGv`KcXg~zJ_aigvuUdZTVMrX z`4&E-SCj#WTz=&(K9*{Iyh!>v;9L)~&F3*D# zAda;KmBvE00qJG88V?wg;1{fTnl%+0Z5Yk5Q=(C=;({!8@#f7;_VtZTQCyJ0K3AJ` z&qq2Poebu$j_U3D&UO}SRQXZU5V7BeKJ9EpgUiTh?GDrPO*)3R-@x2~xn!T7m$TF4 z!jm>25BxlNU6G1ll=j5+>7Vap(Cyhb7cQ(MGW-tOWHRCo+7vSKHmw@<4CBGYTCb0v z1E(8G1wJLGD{ue{o?%6BETsM_{z0BXHVZ3t{AL-_yJ&eDropJoz+QVxH4pdp-lX zuWqfg03We;5BMK#z)H(|I|e77g+VW;Irn@H&AF#zb>TT4oZiR)9{5o>d(V?b#stz8 z{8^iAh(v45HMgM;(kI}iJBQw82hK(@s+(xVti!_CdOC4zX&qu z<3Refs@$9tsC*0Oqu5*ntBV;iQyy3?qdfq zCAJN*oI0O`=|aLdaEEDpYqXdI5ttwVPfbA&VdIE~9fa0~qr{|3u>FzkM5(O-L-a5X zMl>5@q`$_z8}0}Zs%N%Fe9=T2%b-|b)90C-zJZM&)%MOTL1;wt1L~DWz)z#g-=E^Qya;Z4dY^x2*$^y+6@{k`3fkns%E=oyZ|B_-S1Z}lU(r) z#OGAi_oSU@1_LDNNI<0RGvJ)1#wWfVya~QgO?U7U_!wQ@!C%3r>A9W!kh;8{FIRFm zP-T@H_y{!@5+FAAH{!x>-oTk8dx`%aCNqz|#1Fv@w(({D1KePbyu#s18*Z)q51&G0 z3U&7{AEsKr%a3X~t9+<>_88xz65r%HB52w^{*t=zCi?!PY`sin?%w5yx7x=K18|bP zAFB~o-2)ti?qe0!7fsAwEiEk{Q(Zpn`o1YX3fu^ILP%4m)KqQx8CIuDf3R`?{1m z>ZA8DuzAvV6g|RwoC{6kxX`=x1-%L&h<%M=$MHao(--uf`tvwHf+3Wa%{0#3)5<40 zmzKu$rA^S6R!a7~hI*vwLRG!aPsntEA}3eZ-5E^qq`e8;(1kO&6F@H |T#WX9{^ zF=~Sc^cN5jzD`b(A8`4Bpd@Mwx|vak#Ve<40M&dQ{7h%TX(m`OYk~R2USOaqVN1XO z`Zz+x-UB@35(c6VsKjkN7|>JuwU)&$IYK7;#t|}r^U}L80r$ysED~^V+b|87u=ls| z#$~&j0?d||pNDyu+-|vrU3zF(f<{CF%20Y2B7ihN61d5NZe{wTb7M=>L$GBvRVl2Z zrYe;^R8y74R$frqEVii*ys6bERMc(2;+qVL`sjMQ?}nxf zXb`AUnCFJd(WJ5mYG~5f!!IWP$XCPLkR{q@ zTn&YFFtT&6+X1tp0kTHLp1l~&%M6L9f0~+hmLH7RSv;x7<0L+VF(X7$?%*VDgzhSmBz{y0$|9_1g(OcT%XT=nb) z{t7L}oQ8h?gyZJ8;}h0KE1wRHJF#;a=6$2_QhCwPFN#KOd8) zooz@N@2>lQH*1P>`WNs%l}8!}HSVS7G;i70wMUnN4BlIf{6I@Mgnf%u z&jOC{#>88H+Owc2gAcpyXn9==c;0Qsd0qP#@qX&kH?j!^aaaYZ@NXp#9iV5YZ#kB> zv}cofq00GIHW7X83GB^PGAM!%)OCJ~xsKSk(PkqZvxj96<1f(n>yB^AZ-(%;u^!Io)yqUTq1k?#UNmDt{X;}%wA4igU$<-x%OLAeYgi%!M4`b>A_e3!R*a8V0R0v{&-I8x z$ism8Dmjb@skvatkHkmth)RkUeK?PGC#aogM2sGM#yb)QpRLq0(eRqKRL7!4OZY9Y zYK|^MevD|zWt_XYt>7Zg9qa7k>Zsnu;@r{BF5283rT&T$EmU5th~} zVHJgO*FJ1<5$z6h6kOG94h4&Lhu8{EqufnZ8$CLPTSc#2YI}1L$IV!GBdv(toy%>6J{OiC{l@2ScHnp zg<-fA&<(f5*GDV^JgK~oSOR#G*;iB`(q&~|0gmKI>rkF(NKrHA3WOU|LF4<0f05?a z<$j_)A+ai9fH)qm=TQ7fHv{l~4|x}HX(NC+eVKlRNS(pJm%W9F$5^6#AtKwH+DQ!4 ze&jdX0Fe7F1 z8fcw$_(1#{pNFO(XPW`4iHQUUR@ibA&8{1^hh(f`&Mcf+Ah1n22B>fkS z--A3F+f}{SL_?OwKDUzhN`Mby-oUg=lsa=jhLcY!%NmFC(=n{C8vTaA^vOu#CycYP zEZ^C#dPCer&ZvLCfj7*jYV?}|QAJ>OwFLyIIYKI1?g(k@5iNkCz}e1VYaJmIOk(;s z(OK*<-G?X|0FpPb(G2XP({&Vg9oRpo5Q6b;DC+qDPlcAF4hoc?NBm^}bYS&Q!IRN|ABr|=5D=0lT9F%H3xE#l-+Cl~I~!?K}ioN_iwpOHw6i#TH?8Y7MM zb9(h3^|r#x{d3AB5h}LD>*a21WHSMa06TJ0$SL2U?01=+kuDn$mWvv3eNIpP1vV&d`RtB{GD0ndnkpQd*rp?s!yr8ilo4xa}tnz}ugKYF_I)Dw{saUS_ zPQh}mcOsUnz2mV|-qBe4ykMLltGpl=Adh+nVOi+~zXMt61@!<~;RWWKEcf=t@*yv# zr^tg|eE}8T&Y-U#UN3kHh{xLw%W`iPmiK$pu)NO;h6A$HtFOlGjl;6c8;#{+FBlQX zB5z|X7kC?CIo}(MFCGIj)yuFf^?>$*lz2eP zK+2|g^p#Ea=qtO|GYQLy9=IRL1kX4u$9eSiH7M6b2bSxDH7wWF7+kKav{88^mW|6} zuxwJUPqAsaKHZRVeIvrk^#wF5*B29B4o(abQ4XR85>=jqWlXuQiMXbV2amwAqetJ|P9Bg^tBH1 zbj5P8r#qHIJUy`->H#$c8ScS{5}Z38%o&l99$g2cJh~1>dxl{-)?+8#3N$_geFlQR zknV&m1)sr(2>Xh}v!>l5Z_@uE*eeZ_M@tdhaRQ#~9co*qnI5$yM1;cqaqqa2@iU#I zs*X5r^vu!5_E?bsrm(VwG6MeJ`3q$XI&ed@&>YXZz0Dc;?Xa!pEtIhs+H8Uhkl7r2 zFS>4v9DrEzVu{G6LbYNMtcL1UG&+)_Yym^gp!R*<43(vBhfhV%ZWt zX+1L#O4%^9Q==B`Zh-Q15#0^oTQkhmJ^*a}XHKUFRm5&_rlmg70NTj_?crcL72UH<=v^PBUo(Rt{G0Vh=&hzee21NL zPJCrSZFRXm@?~VPMXF#rI&#UVxT6isU{svFor;RHg)|11d~K1As)G;=T&umEiHcjI zw-=+oE1IB$fsT;EhB-ni8?A*9_@=c51}I1MR))HO6(EH39J4G|wr90{-7n(0fw0_z z>z<(eEcCeE6Vj6F(T`PNx3a$lldY?7>np$4ig;IyAlBkd;vRfM{!e63PpJw$D9%$) ziRJgc=tZb!mKyYdSV%oH)xSRwOQ~mu8gfW%q@L;4)k7F8Q_nOj;s^$6)U!}s`baFn z$Sc&dKoy@7>p3g&%vaY=i7A{e@XS+FKN9l=bra8A$CAQwj$=uucxJ20<6?^M6#9-# zE34r7z;CBw76w0D3|cM}e;@UfIltf~p2betY=LKyUADURUtzWcm$&0z7|vSKU%+gz z5_#)dkzaw{T2+J1JL|M)6-?G35-*8s5MOvfk0Id*T)lp-gq;6A{*ktkxIk`uhU& z^SZf`+-=mcPX*9mtJS4XL_+{i_2wOoWs*DdpZAI+cZR*U;hhe|)!|S7;T%|!8xg%Y zX!@OgNE6+uehJllfz4~7D>`{1NJXbkm{&X&uq&K)#2FC?9uC_zp5rW!Wq_eTD_~p zTgSN;bAk6R$I^tQzhh~_($BU;kcSYM{ak3Uhsi<>C7Me3{dK(!tSeW?&W9h7+H?>C+Fk`?Q8QG*eW-%BZJ<(~u^D-AH?qBU z9^7fFs;i7cl4YIfAx<^{;UK<7o4X(ijyF|@yU;{Nd59x09;$_866S0R-pmms4|fEU zM>v9uN2*iZ@EuB5*Sf)N3%FBvY;{yQ-DLu%J4?IERJ`JU?kXcFKdAn%t87L2k;<*j zB7pJuv#-pqjh+GKaL*g$yuSX=asBnYfmYP7H(h_}9gP~^Y$W8Jje>4Ay6Yc|f^Rlz z_zy;nZZ?XMrM_@^gj`Zb!)2Vj7{hzR^|9H{Y-$IG7#CEt2pKKU|E&+xfg;9t!5lu4 z>Ji(-8DnQmEFL#u>{R2d%88WC{6>!(H{Ceboadvkh^weF<12L}LdNm0qj-1KEK-K( zFcjlU+u9DKp~nC8Mzs8*8Q0_zn+w6RXCTf1wmN1;m=nhtXK)%SJ4!aTqiCq{ncf|Z zxKZ0m$IS@iqX^!`ws9`tQ`I3#Ch*gVfHT>@MAS@uVSEw?|Gd53=CJfLjgSAnz*zg_ zzir6DV_AKHrDJCx^mOc)G5L48$&GKW&;(gpPaAPPIyg^efO)eF^CzWjjyF{OHB`># zkU|`Z&h|F-b%6>krOC~Ow2`H)bRnkE++gL*A7GzGWFv}d4&|+X?mTa_@(z*5;K~^~ zRBl1QDULD+2Z?YFV$Sh~JCdB^ZRSW~jyKGfT5)}t`bLhyPO)8pGZY|%|9h|iYyyE} zTS~}5vXJBu(8C#^VI8FdiQR?j;1QX@I=Tm_K7}$H6C4i}%C7$X{DAh=bgLxUrSxE2 zeP0OAQh{nPP__leByXVX3wX);fieTg5){!?T^xw`=03{5NVbRXs%MdmgYRm35qfkz z)rKNGeLd7$TG?G)D3WQwRYeYxDR|rl4no9JS9Sj&83P#AvsgJ*PE3PdK@3Jrlh$=+8)>u5hO+_|l2qR+btg zCxQjO#M@GZ4VPC)3#;A;Daj*yIg;CX3^p25iuvHE070Oh9%Hk;$?EhZIS*l|Mfb{Q z{qbr{3`|JW`GGt6#>i+jZIqmWuH~1beFfH4oWMi7#s1rc0rrx9L)8 z@@={_ntPiroesH8mqBgrr2YkwHyt>Wx^FYgqN|)_A<3XZ)mcL7r_d(O6Z)aSmearJ z9784VrAzUF&EfY&c(bfi)8yj>vyO{q$osh4-1+uPMFjEdDZPkgHat&!?mCTY~F`y@l=HWHlQN_-e+iG

BRtpqw5{mS1#i_6Q%ECq zbRYWkAl};t*Vt(lw_kKd2>x^X(ML~G$M=g!w9=pVV}2eb}GdjLt&@9wh?(by#Niayr{qybz2V96PVN#_mZ z9q=k>dVvy*KKJ9}-WZ7!OIa1>5?Of#B1tcvy4FyH-h65clV-Y+lVZ8L0{JO>|rr*io*q23-=Q?EpX zfVaDqT_O8W>g{GNe?T^brnmLPgR&8XUe=orAwrXSds-)!%XrdOS4cRr-vL!TluSdo zRu$Pp4#BPUJLbaT;QT72li(Qhfxvw~GG2dyOrR35n>e7cLz3ig>hL%j#j@zb>g;%_ zdG!!{uZ0xAer+L@#ydh9&31%z3e>Q+$)JG2X(5v$lj?XGG-QSL_jN%ma#m7G0dP0q z_d@JW;2pFnH0}=CRNDRy+BBdP3+|Q;%f{VdX9k^n2W=*O@DAE6x=AAl^a<)fX?<=% zw<=O-%UczxwBrp$ANx0HwEqo_tw^VL->S%<^KVsT(&e`*vgl(f=^hE-gI?jyNn1EV zD(&D1X%wguy(^u9I9v-Eber&rdJC*)SII00`PLUc8B+bQBj61GKf$dzn)vX**Ty@4HYVd)Zs*y zOm=JDrZ6?Ej@eM~%^6~lItKP8wRa+|rB1J4f#d~kfB>bNcL~+Bj(MHd=|weSC2P;y z_7L-s2@=tL*WYM!02w|wTbCbPmi1q$v83xT@>$}I~ zLl8z-^B+eKf_jHrk3S(hLl|a#{iMBXv`TnhMya(=%U#qvO65Hx*HLe=`tBKdiF!v` zr=OM2!+gAYXe+3@z2o#cT0Oi?zC^uaRnP76bLt(Vi#QoupDcy5l{|sh+gJ211X&EX z>FN&9FEIj(0c5U}tzs`(;d}92Q0@0iKQ;G0QopwC^8d~T22Z<>G$7y&{iO?7K^rLG1e`K`3aWzh~NOjRMvu32Kz5VoKyHb6JJ=FMJ1)Rh~QmNXW z#5qY-d{V}m8?Tr3roQJc_54YcwMl(^QpQwX>m-#pB{QgZp6YN)dZ>4OlwQ>kgwA z)q0l zKa-{KA5J_g74?=W`ng<0y^EFmb9q1YE>h+>Sw+1I)zjzXC$-GL;C_u8H+BzFn=gY4 z0t^v;s;#bqeP750xD_3~lsf>zy7(oEhv!;oz7OU(MK5-yQT60;xkMPy; zS8&`qD(HI*Q|?l)eJ`s(?KAubxvjywV5@0}{>d~1HXR@nFy`8&>K$b{YQ&G|1)ng@ zc-+iM`eqjTPxKp9eS7+W>+&msM2y*~{e;@TM@{=l4k34|_kWTD;23ZAvn){i zf0nUIb7-hFKjU7E)psaHef=|>Fk@8EFLES49}Hqc&SH^AkJbXVjS5Zyo^ z{A@1dTebar@_d#5oea*LrLn;F&OSNlsDQYJ&(_HSZB+pRNccQGD6u#D=N9%KQrso4 zkk3>bzLQNOyWX%Y0+}tJegojBH!%Ur=QzE-WXc>N1wmVOKQNWHa)dP6$q~}&04>Cj zdwjpj75D(G{8i3Dx24uqIj>e=^^F&*-c{MkcDblmuA<%>s5-yN&FE6^_)S{10;AtH;M;m|wt*0kJracgdt#@wBs$~1FAfwYo)lRRzQnRmMI`)Ek zS#JfaAFlvt9;8}-PcqEVpwsSq)-y>`$HzXLK@f)!DxMIVSkgCsL6leF>I=~ z{~;g5cc|T;@NP6#Xa1BgV-U0EFS&sS2ZGyW{bku&)4JTH{&QJ&vR=3*AExsAP~Hwl ziI~HJgNzS>Q?PwGH&GSksoB(=-ss&RxOuc6YxczHGmG_fm+k#|$H&ZunBCfh6-6J~ zUSqn%Uh^VnjXsv%##1_tnL*SXqBn!a4Xw|c+eiC5HC4acRAc%B^}$Mr zJrvni=uqDSdX!p=ykG!eFbJ>BjW%vEgnUI_&>qIM1TO8FYK$;b09#%q%rs2&9290U zxJ&*JW-MT|QPPY99y+hE^jv(nQM=(LZr*|O=YD0qPprfD)!dWZ@ z2j4MJ%b=)8pTC&_FIi$8GwKHKDcs+6OraL}n=it1hF$Th_%8DZiO}-zBwV$sYyR68 zXg&uI($+w;5+0=NhUPgEqgS!2ZvtzmOW>6o-tkikxAtfTZ__nr{Fui4|PYDQ0cW+v;bRr51*n%K)LI&CI`SUk?cU4RH7mK;Y2> zNCkete#O-XuU9vadQ5`XZar|?huK%o)2Mm}m`$~(E5K|FvPg`KwUDMq#(D?F#dWWyOw=hB;%cftw|~f!PS` z!_$1>=1BxLp9(jD1Wr&%k>*Dv-l`pCVwNsdEr`bLNKtiTFe8zyR>qhQ!+#MGYi=Ql z*4we>dQz)RVDAX+p=qF2v@iqJ;y815t*qO0wbjA|7OYkzqa9?nFbm-L@wPBGV%8I@ zc-8DKjF7;fJ02$nMU?8)3O6gHj_I%IaK|I&#nv8Kfe{nR;A(3tb8r(s8fehYn8(?L zIrb*3174TQkn-_a_8)zdekLlkwV6QnIRl_WEBw?2JuVvIYzJ=+Mfat5YZH_9sthZ0 zTBJzC>p~5cv}qI4H&`^r*4ul^<}HU zN#+8$p-v>36>vk1Og0w*D|$NFEU(o*FvqSY$9# z;0S4xWxh|kTB3~!oOl;CudTTf2k~oXPJ@?fQ9JYhXhkopM|)fst>~%dbTGHmiXN(Y zM^n*??rLvG^J!YqO-<@#t`F+0D`y(5L@4?fsGck~2>#0Fbz1v*+E=-aIC* - + - + @@ -132,7 +132,6 @@ - @@ -143,7 +142,7 @@ - + @@ -278,22 +277,25 @@ + + + - + - - + + - + @@ -343,7 +345,7 @@ - + @@ -368,7 +370,21 @@ - + + + + + + + + + + + + + + + @@ -376,6 +392,22 @@ + + + + + + + + + + + + + + + + @@ -385,7 +417,7 @@ - + @@ -410,7 +442,7 @@ - + @@ -435,14 +467,14 @@ - + - + @@ -817,6 +849,20 @@ + + + + + + + + + + + + + + @@ -844,15 +890,15 @@ - + - - + + - + @@ -860,7 +906,7 @@ - + @@ -925,7 +971,7 @@ - + @@ -961,7 +1007,7 @@ - + @@ -969,8 +1015,8 @@ - - + + @@ -980,7 +1026,7 @@ - + @@ -992,7 +1038,7 @@ - + @@ -1018,7 +1064,7 @@ - + @@ -1027,7 +1073,7 @@ - + @@ -1063,9 +1109,11 @@ - + + + @@ -1094,6 +1142,7 @@ + @@ -1186,9 +1235,9 @@ - - - + + + @@ -1257,7 +1306,7 @@ - + @@ -1279,14 +1328,14 @@ - + - + @@ -1350,11 +1399,11 @@ - + - + @@ -1405,7 +1454,7 @@ - + @@ -1544,7 +1593,7 @@ - + @@ -1555,10 +1604,11 @@ - + + @@ -1742,8 +1792,8 @@ - - + + @@ -1754,7 +1804,7 @@ - + @@ -1851,7 +1901,7 @@ - + @@ -1967,67 +2017,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2051,7 +2040,7 @@ - + @@ -2089,15 +2078,15 @@ - + - - - - - + + + + + - + @@ -2153,7 +2142,7 @@ - + @@ -2205,15 +2194,15 @@ - - - - - - + + + + + + - + @@ -2333,42 +2322,40 @@ - + - - - + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + - - + + @@ -2471,8 +2458,6 @@ - - @@ -2567,14 +2552,7 @@ - - - - - - - - + @@ -2582,8 +2560,8 @@ - - + + @@ -2622,22 +2600,6 @@ - - - - - - - - - - - - - - - - @@ -2719,7 +2681,7 @@ - + @@ -2742,7 +2704,7 @@ - + @@ -2783,13 +2745,14 @@ + - + @@ -2869,7 +2832,7 @@ - + @@ -2900,7 +2863,7 @@ - + @@ -2919,8 +2882,8 @@ - - + + @@ -2965,13 +2928,13 @@ - + - + @@ -2979,8 +2942,8 @@ - - + + @@ -3040,7 +3003,7 @@ - + @@ -3062,7 +3025,7 @@ - + @@ -3189,7 +3152,7 @@ - + @@ -3211,8 +3174,8 @@ - - + + @@ -3223,7 +3186,7 @@ - + @@ -3238,7 +3201,7 @@ - + @@ -3246,12 +3209,12 @@ - + - + @@ -3337,7 +3300,7 @@ - + @@ -3398,7 +3361,7 @@ - + @@ -3450,7 +3413,7 @@ - + @@ -3480,7 +3443,7 @@ - + @@ -3523,15 +3486,6 @@ - - - - - - - - - @@ -3610,17 +3564,16 @@ - + - + - - - - - + + + + @@ -3687,11 +3640,11 @@ - - + + - - + + diff --git a/tools_layouts/adb/prm/switch/ext/register_access_table.adb b/tools_layouts/adb/prm/switch/ext/register_access_table.adb index ba3363d1..18f6a868 100644 --- a/tools_layouts/adb/prm/switch/ext/register_access_table.adb +++ b/tools_layouts/adb/prm/switch/ext/register_access_table.adb @@ -35,7 +35,110 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -93,6 +196,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -100,20 +238,39 @@ - + - + + + + + + + + + + + + + + + + + + + + - + - + @@ -126,16 +283,20 @@ - + + + + + @@ -150,7 +311,8 @@ - + + @@ -209,11 +371,17 @@ + + + + + + @@ -222,7 +390,7 @@ - + @@ -335,13 +503,16 @@ + + + - + @@ -355,10 +526,10 @@ - + - + @@ -387,6 +558,7 @@ + @@ -558,6 +730,14 @@ + + + + + + + + @@ -567,17 +747,18 @@ + - - + + - + @@ -649,7 +830,7 @@ - + @@ -753,7 +934,7 @@ - + @@ -779,7 +960,7 @@ - + @@ -787,19 +968,21 @@ - + + - + - + + @@ -821,7 +1004,7 @@ - + @@ -839,6 +1022,7 @@ + @@ -864,9 +1048,9 @@ - - - + + + @@ -1194,8 +1378,8 @@ - - + + @@ -1209,11 +1393,11 @@ - - - - - + + + + + @@ -1229,6 +1413,14 @@ + + + + + + + + @@ -1254,18 +1446,18 @@ - - - - + + + + - - + + - + @@ -1275,27 +1467,29 @@ + + - - - + + + - - + + - + @@ -1303,20 +1497,20 @@ - - - - - + + + + + - - + + - + @@ -1325,15 +1519,15 @@ - - - + + + - + @@ -1342,16 +1536,16 @@ - + - - - + + + @@ -1359,7 +1553,7 @@ - + @@ -1371,18 +1565,20 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + @@ -1401,8 +1597,8 @@ - - + + @@ -1461,12 +1657,16 @@ - + + + + + - + @@ -1476,7 +1676,7 @@ - + @@ -1496,18 +1696,19 @@ - + - + - + + - + @@ -1521,11 +1722,11 @@ - - + + - + @@ -1558,27 +1759,27 @@ - + - + - + - + - + @@ -1600,6 +1801,16 @@ + + + + + + + + + + @@ -1617,7 +1828,7 @@ - + @@ -1625,14 +1836,14 @@ - + - + @@ -1644,13 +1855,13 @@ - + - + - + @@ -1669,7 +1880,7 @@ - + @@ -1695,23 +1906,24 @@ - + - + + - + - + @@ -1757,7 +1969,7 @@ - + @@ -1767,7 +1979,7 @@ - + @@ -1785,13 +1997,13 @@ - + - + @@ -1807,7 +2019,7 @@ - + @@ -1817,11 +2029,11 @@ - + - + @@ -1834,12 +2046,12 @@ - + - + @@ -1847,7 +2059,7 @@ - + @@ -1948,7 +2160,7 @@ - + @@ -1956,8 +2168,8 @@ - - + + @@ -1979,7 +2191,7 @@ - + @@ -2005,7 +2217,7 @@ - + @@ -2014,7 +2226,7 @@ - + @@ -2023,25 +2235,6 @@ - - - - - - - - - - - - - - - - - - - @@ -2077,10 +2270,18 @@ - + + + + + + + + + @@ -2107,31 +2308,32 @@ + - - - - - - + + + + + + - + - + - + - - + + @@ -2225,9 +2427,9 @@ - - - + + + @@ -2256,9 +2458,9 @@ - + - + @@ -2296,8 +2498,8 @@ - - + + @@ -2307,7 +2509,7 @@ - + @@ -2316,7 +2518,7 @@ - + @@ -2349,7 +2551,7 @@ - + @@ -2408,18 +2610,25 @@ - + - + + + + + + + + - + @@ -2429,15 +2638,18 @@ + + + - + - + - + @@ -2454,7 +2666,7 @@ - + @@ -2472,6 +2684,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2499,15 +2736,16 @@ - + - - + + + @@ -2521,7 +2759,7 @@ - + @@ -2532,8 +2770,27 @@ + + + + + + + + + + + + + + + + + + + - + @@ -2542,7 +2799,7 @@ - + @@ -2590,7 +2847,7 @@ - + @@ -2609,7 +2866,7 @@ - + @@ -2622,7 +2879,7 @@ - + @@ -2637,20 +2894,22 @@ - + - + - + - - - - + + + + + + @@ -2691,7 +2950,7 @@ - + @@ -2734,11 +2993,11 @@ - + - + @@ -2747,7 +3006,7 @@ - + @@ -2763,7 +3022,7 @@ - + @@ -2801,8 +3060,8 @@ - - + + @@ -2830,16 +3089,16 @@ - + - + - - - + + + @@ -2854,8 +3113,8 @@ - - + + @@ -2867,8 +3126,8 @@ - - + + @@ -2883,8 +3142,8 @@ - - + + @@ -2898,19 +3157,19 @@ - + - - - + + + - + @@ -2937,7 +3196,7 @@ - + @@ -3017,7 +3276,7 @@ - + @@ -3028,7 +3287,22 @@ - + + + + + + + + + + + + + + + + @@ -3109,11 +3383,11 @@ - + - + @@ -3131,7 +3405,7 @@ - + @@ -3180,11 +3454,11 @@ - + - + @@ -3212,18 +3486,18 @@ - + - + - + @@ -3246,8 +3520,8 @@ - - + + @@ -3258,7 +3532,7 @@ - + @@ -3331,7 +3605,7 @@ - + @@ -3341,7 +3615,7 @@ - + @@ -3457,67 +3731,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3533,7 +3746,7 @@ - + @@ -3541,7 +3754,7 @@ - + @@ -3579,15 +3792,15 @@ - + - - - - - + + + + + - + @@ -3643,7 +3856,7 @@ - + @@ -3695,15 +3908,15 @@ - - - - - - + + + + + + - + @@ -3738,7 +3951,7 @@ - + @@ -3823,47 +4036,45 @@ - + - - - + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + - - + + - + @@ -3884,7 +4095,7 @@ - + @@ -3898,7 +4109,7 @@ - + @@ -3906,8 +4117,8 @@ - - + + @@ -3952,14 +4163,14 @@ - + - + @@ -3996,7 +4207,7 @@ - + @@ -4015,7 +4226,7 @@ - + @@ -4065,31 +4276,18 @@ - - - - - - - - - - + - - - - @@ -4111,7 +4309,7 @@ - + @@ -4153,7 +4351,7 @@ - + @@ -4212,8 +4410,6 @@ - - @@ -4349,20 +4545,30 @@ + + + + + + + + + - - - - - - - - + + + + + + + + + @@ -4370,8 +4576,8 @@ - - + + @@ -4383,6 +4589,25 @@ + + + + + + + + + + + + + + + + + + + @@ -4396,6 +4621,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4412,15 +4679,15 @@ - + - + - - + + @@ -4457,8 +4724,8 @@ - - + + @@ -4468,14 +4735,14 @@ - + - - + + @@ -4593,7 +4860,7 @@ - + @@ -4616,7 +4883,7 @@ - + @@ -4657,6 +4924,7 @@ + @@ -4665,7 +4933,7 @@ - + @@ -4677,10 +4945,11 @@ - + + - + @@ -4688,7 +4957,9 @@ - + + + @@ -4752,6 +5023,8 @@ + + @@ -4774,9 +5047,9 @@ - + - + @@ -4794,13 +5067,13 @@ - + - - - + + + @@ -4818,8 +5091,8 @@ - - + + @@ -4827,8 +5100,8 @@ - - + + @@ -4836,10 +5109,10 @@ - - + + - + @@ -4853,10 +5126,10 @@ - - + + - + @@ -4864,8 +5137,8 @@ - - + + @@ -4882,7 +5155,7 @@ - + @@ -4907,7 +5180,7 @@ - + @@ -4926,8 +5199,8 @@ - - + + @@ -4942,7 +5215,8 @@ - + + @@ -4994,7 +5268,7 @@ - + @@ -5007,13 +5281,13 @@ - + - + @@ -5028,13 +5302,13 @@ - + - - + + @@ -5043,7 +5317,7 @@ - + @@ -5067,21 +5341,21 @@ - + - - - - - + + + + + - - - + + + - - - + + + @@ -5096,66 +5370,66 @@ - + - + - + - + - + - + - + - + - - + + - - - + + + - + - + @@ -5193,10 +5467,10 @@ - - - - + + + + @@ -5212,7 +5486,7 @@ - + @@ -5230,7 +5504,7 @@ - + @@ -5279,7 +5553,7 @@ - + @@ -5295,7 +5569,7 @@ - + @@ -5303,11 +5577,11 @@ - + - - - + + + @@ -5351,6 +5625,7 @@ + @@ -5363,7 +5638,7 @@ - + @@ -5398,84 +5673,70 @@ + - + - + - + - - - + + + - + - - - - - - - - + + + - - - - - - - - - - - - - - - - + - - - - + + + + + + + - + - - + + + + - + - - + + @@ -5495,7 +5756,7 @@ - + @@ -5512,12 +5773,12 @@ - + - + @@ -5527,13 +5788,20 @@ - + - + + + + + + + + @@ -5576,16 +5844,15 @@ - - - + + - + - + @@ -5599,8 +5866,8 @@ - - + + @@ -5613,9 +5880,9 @@ - + - + @@ -5623,7 +5890,7 @@ - + @@ -5633,14 +5900,14 @@ - - + + - + - + @@ -5667,13 +5934,13 @@ - - + + - - - - + + + + @@ -5696,12 +5963,12 @@ - + - - - + + + @@ -5712,7 +5979,7 @@ - + @@ -5728,12 +5995,12 @@ - + - - - + + + @@ -5742,7 +6009,7 @@ - + @@ -5786,7 +6053,7 @@ - + @@ -5798,7 +6065,7 @@ - + @@ -5808,7 +6075,7 @@ - + @@ -5851,7 +6118,7 @@ - + @@ -5878,9 +6145,9 @@ - + - + @@ -5893,10 +6160,10 @@ - + - + @@ -5904,18 +6171,18 @@ - + - + - + - + @@ -5944,7 +6211,7 @@ - + @@ -5968,7 +6235,7 @@ - + @@ -6035,12 +6302,12 @@ - - - - + + + + - + @@ -6053,10 +6320,10 @@ - - - - + + + + @@ -6065,15 +6332,15 @@ - - + + - - - + + + - - + + @@ -6083,42 +6350,43 @@ - + - + - - + + - - + + + - - + + - - - - - + + + + + - + @@ -6133,21 +6401,21 @@ - + - - - - + + + + - + - + @@ -6177,12 +6445,12 @@ - + - - + + - + @@ -6193,9 +6461,9 @@ - + - + @@ -6207,8 +6475,8 @@ - - + + @@ -6220,34 +6488,34 @@ - + - + - - - + + + - - - + + + - - + + - - - - + + + + @@ -6256,16 +6524,16 @@ - + - + - + @@ -6276,9 +6544,9 @@ - + - + @@ -6289,12 +6557,12 @@ - + - - + + @@ -6303,19 +6571,19 @@ - + - + - + - + - + @@ -6328,9 +6596,9 @@ - - - + + + @@ -6343,16 +6611,16 @@ - + - - + + - + @@ -6362,7 +6630,7 @@ - + @@ -6371,7 +6639,7 @@ - + @@ -6381,13 +6649,13 @@ - + - + @@ -6468,7 +6736,7 @@ - + @@ -6520,7 +6788,7 @@ - + @@ -6550,7 +6818,7 @@ - + @@ -6593,15 +6861,6 @@ - - - - - - - - - @@ -6680,17 +6939,16 @@ - + - + - - - - - + + + + @@ -6699,22 +6957,22 @@ - + - + - + - + @@ -6733,7 +6991,7 @@ - + @@ -6742,11 +7000,11 @@ - + - + @@ -6761,7 +7019,7 @@ - + @@ -6773,7 +7031,7 @@ - + @@ -6794,7 +7052,7 @@ - + @@ -6811,9 +7069,9 @@ - + - + @@ -6823,14 +7081,14 @@ - + - + @@ -6839,7 +7097,7 @@ - + @@ -6858,13 +7116,11 @@ - + - - @@ -6874,7 +7130,7 @@ - + @@ -6895,15 +7151,15 @@ - + - + - - + + @@ -6930,13 +7186,13 @@ - + - - - + + + @@ -6967,7 +7223,7 @@ - + @@ -6975,7 +7231,7 @@ - + @@ -6988,19 +7244,19 @@ - + - + - - + + - + @@ -7038,7 +7294,7 @@ - + @@ -7047,23 +7303,24 @@ - + + - + - + - + - - + + @@ -7078,23 +7335,23 @@ - + - - - - + + + + - + @@ -7104,7 +7361,7 @@ - + @@ -7123,6 +7380,21 @@ + + + + + + + + + + + + + + + @@ -7133,12 +7405,12 @@ - - + + - + @@ -7151,11 +7423,11 @@ - + - + - + @@ -7170,12 +7442,12 @@ - + - + @@ -7218,11 +7490,11 @@ - + - + @@ -7244,9 +7516,8 @@ - - - + + @@ -7262,7 +7533,7 @@ - + @@ -7271,6 +7542,7 @@ + @@ -7301,13 +7573,14 @@ - - - - - - - + + + + + + + + @@ -7320,12 +7593,60 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + @@ -7372,6 +7693,14 @@ + + + + + + + + @@ -7380,16 +7709,42 @@ + + + + + - + - - + - - + + + - + + + + + + + + + + + + + + + + + + + + + + @@ -7400,7 +7755,7 @@ - + @@ -7411,15 +7766,14 @@ - + - + - - - + + @@ -7427,7 +7781,7 @@ - + @@ -7470,13 +7824,13 @@ - + - + @@ -7499,11 +7853,6 @@ - - - - - diff --git a/tools_layouts/reg_access_hca_layouts.c b/tools_layouts/reg_access_hca_layouts.c index 65478d2d..0b2703d6 100644 --- a/tools_layouts/reg_access_hca_layouts.c +++ b/tools_layouts/reg_access_hca_layouts.c @@ -2148,7 +2148,7 @@ void reg_access_hca_mcc_reg_print(const struct reg_access_hca_mcc_reg *ptr_struc adb2c_add_indentation(fd, indent_level); fprintf(fd, "component_size : " U32H_FMT "\n", ptr_struct->component_size); adb2c_add_indentation(fd, indent_level); - fprintf(fd, "device_type : " UH_FMT "\n", ptr_struct->device_type); + fprintf(fd, "device_type : %s (" UH_FMT ")\n", (ptr_struct->device_type == 0 ? ("Switch_or_NIC") : ((ptr_struct->device_type == 1 ? ("Gearbox") : ("unknown")))), ptr_struct->device_type); adb2c_add_indentation(fd, indent_level); fprintf(fd, "device_index : " UH_FMT "\n", ptr_struct->device_index); adb2c_add_indentation(fd, indent_level); diff --git a/tools_layouts/reg_access_hca_layouts.h b/tools_layouts/reg_access_hca_layouts.h index d2a9025e..c5ff8891 100644 --- a/tools_layouts/reg_access_hca_layouts.h +++ b/tools_layouts/reg_access_hca_layouts.h @@ -33,7 +33,7 @@ /*** - *** This file was generated at "2021-11-23 23:46:24" + *** This file was generated at "2022-01-26 16:01:32" *** by: *** > /mswg/release/tools/a-me/last_stable/adabe_plugins/adb2c/adb2pack.py --input adb/prm/hca/int/reg_access_hca.adb --file-prefix reg_access_hca --prefix reg_access_hca_ --no-adb-utils ***/ @@ -174,12 +174,12 @@ Other values are reserved */ u_int8_t category; /*---------------- DWORD[1] (Offset 0x4) ----------------*/ /* Description - LOCK_RESOURCE Modifier according to category field -For GENERAL_SEMAPHORE Table 1083, "GENERAL_SEMA -PHORE Category Layout," on page 1349 -For ICM_RESOURCE Table 1085, "ICM_RESOURCE Category -Layout," on page 1350 -For UAPP_RESOURCE Table 1087, "UAPP_RESOURCE Cate -gory Layout," on page 1350 */ +For GENERAL_SEMAPHORE Table 1091, "GENERAL_SEMA +PHORE Category Layout," on page 1358 +For ICM_RESOURCE Table 1093, "ICM_RESOURCE Category +Layout," on page 1359 +For UAPP_RESOURCE Table 1095, "UAPP_RESOURCE Cate +gory Layout," on page 1359 */ /* 0x4.0 - 0x1c.31 */ union reg_access_hca_lock_source_stop_toggle_modifier_category_modifier_auto category_modifier; }; @@ -281,7 +281,7 @@ ponent update. */ /* 0x10.30 - 0x10.30 */ u_int8_t signed_updates_only; /* Description - When set, this components may be read, see -Section 9.10.4, "Read Flow", on page 449. */ +Section 10.3.4, "Read Flow", on page 803. */ /* 0x10.31 - 0x10.31 */ u_int8_t rd_en; }; @@ -388,14 +388,14 @@ stamp in build_time */ u_int32_t version; /*---------------- DWORD[2] (Offset 0x8) ----------------*/ /* Description - Time of component creation. Valid only if build_ -time_valid is set. See Table 1833, "Date-Time Lay -out," on page 2066 */ +time_valid is set. See Table 1847, "Date-Time Lay +out," on page 2078 */ /* 0x8.0 - 0xc.31 */ u_int64_t build_time; /*---------------- DWORD[4] (Offset 0x10) ----------------*/ /* Description - User-defined time assigned to the component version. Valid only if user_defined_time_valid is set. See -Table 1833, "Date-Time Layout," on page 2066 */ +Table 1847, "Date-Time Layout," on page 2078 */ /* 0x10.0 - 0x14.31 */ u_int64_t user_defined_time; /*---------------- DWORD[6] (Offset 0x18) ----------------*/ @@ -979,15 +979,15 @@ handle the resource_dump_event */ /* 0x0.16 - 0x0.20 */ u_int8_t log_min_resource_dump_eq; /* Description - If set, Resource_dump register is supported. -See Table 1107, "RESOURCE_DUMP Register Layout," on -page 1360 */ +See Table 1115, "RESOURCE_DUMP Register Layout," on +page 1369 */ /* 0x0.22 - 0x0.22 */ u_int8_t resource_dump; /* Description - Log(base 2) of the size in granularity of 4KB to be allo cated by host in order to accommodate cr_dump. 0 means feature is not supported. -See Table 1105, "CORE_DUMP Register Layout," on -page 1358 */ +See Table 1113, "CORE_DUMP Register Layout," on +page 1367 */ /* 0x0.23 - 0x0.27 */ u_int8_t log_cr_dump_to_mem_size; /* Description - If set, Core dump of type of specific QP is supported. @@ -1070,7 +1070,7 @@ FPGA_CTRL are supported. */ /* 0x8.30 - 0x8.30 */ u_int8_t flash_gw_lock; /* Description - If set, SW is allowed to modify FPGA_CTRL register. See -Table 1065, "FPGA_CTRL Register Layout," on page 1337 */ +Table 1073, "FPGA_CTRL Register Layout," on page 1346 */ /* 0x8.31 - 0x8.31 */ u_int8_t fpga_ctrl_modify; /*---------------- DWORD[4] (Offset 0x10) ----------------*/ @@ -1118,8 +1118,8 @@ For Mellanox sandbox products u_int16_t sandbox_product_version; /*---------------- DWORD[30] (Offset 0x78) ----------------*/ /* Description - Sandbox basic capabilities per sandbox product ID. -For Mellanox sandbox products, see Table 957, "IPsec_Basic_Ca -pabilities Structure Layout," on page 1227. */ +For Mellanox sandbox products, see Table 965, "IPsec_Basic_Ca +pabilities Structure Layout," on page 1236. */ /* 0x78.0 - 0x78.31 */ u_int32_t sandbox_basic_caps; /*---------------- DWORD[31] (Offset 0x7c) ----------------*/ @@ -1129,8 +1129,8 @@ pabilities Structure Layout," on page 1227. */ u_int16_t sandbox_extended_caps_len; /*---------------- DWORD[32] (Offset 0x80) ----------------*/ /* Description - Extended capabilities address. -For Mellanox sandbox products, see Table 959, "IPsec_Extend -ed_Capabilities Structure Layout," on page 1227. */ +For Mellanox sandbox products, see Table 967, "IPsec_Extend +ed_Capabilities Structure Layout," on page 1236. */ /* 0x80.0 - 0x84.31 */ u_int64_t sandbox_extended_caps_addr; /*---------------- DWORD[34] (Offset 0x88) ----------------*/ @@ -1165,8 +1165,8 @@ Valid only for query operation. */ /* 0x0.0 - 0x0.7 */ u_int8_t status; /* Description - Indicates the control operation to be performed. Allowed -only when FPGA_CAP.fpga_ctrl_modify==1. Table 1061, -"FPGA_CAP Register Layout," on page 1332. +only when FPGA_CAP.fpga_ctrl_modify==1. Table 1069, +"FPGA_CAP Register Layout," on page 1341. 0x1: LOAD - when set, the FPGA will be forced to reload the image from flash according to image_select_admin value. 0x2: RESET - when set, the FPGA internal logic state @@ -1271,7 +1271,8 @@ NENT instructions. Otherwise, this field is reserved. */ /*---------------- DWORD[2] (Offset 0x8) ----------------*/ /* Description - Token representing the current flow executed by the FSM. -See Section 9.10.1, "Update Handle", on page 447. */ +See Section 10.2.1, "Component Update State", on +page 800. */ /* 0x8.0 - 0x8.23 */ u_int32_t update_handle; /* Description - Auto-update to all matching downstream devices is @@ -1279,8 +1280,8 @@ requested. */ /* 0x8.31 - 0x8.31 */ u_int8_t auto_update; /*---------------- DWORD[3] (Offset 0xc) ----------------*/ - /* Description - Current Update FSM state, See Section 9.10.8, "FSM -States", on page 450 + /* Description - Current Update FSM state, See Section 10.3.8, "FSM +States", on page 804 0x0: IDLE 0x1: LOCKED 0x2: INITIALIZE @@ -1295,8 +1296,8 @@ Other values are reserved */ /* 0xc.0 - 0xc.3 */ u_int8_t control_state; /* Description - Indicates the successful completion of the instruction, -or the reason it failed. See Section 9.10.7, "Error -Handling", on page 449 +or the reason it failed. See Section 10.3.7, "Error +Handling", on page 803 0x0: OK 0x1: ERROR 0x2: REJECTED_DIGEST_ERR @@ -1321,6 +1322,7 @@ Handling", on page 449 index in rejected_device_index) 0x15: REJECTED_LINKX_ACTIVATE (see module index in rejected_device_index) +0x16: REJECTED_TOKEN_ALREADY_APPLIED Other values should be treated as an unknown error. */ /* 0xc.8 - 0xc.15 */ u_int8_t error_code; @@ -1355,7 +1357,7 @@ Value 0x0 means that size is unspecified. */ u_int32_t component_size; /*---------------- DWORD[5] (Offset 0x14) ----------------*/ /* Description - Peripheral device type: -0: Switch / NIC +0: Switch_or_NIC 1: Gearbox */ /* 0x14.0 - 0x14.7 */ u_int8_t device_type; @@ -1386,8 +1388,8 @@ struct reg_access_hca_mcda_reg { /*---------------- DWORD[1] (Offset 0x4) ----------------*/ /* Description - Offset of accessed address relative to component start. Accesses must be in accordance to log_mcda_word_ -size in Table 1829, "MCQI CAPABILITIES Info Lay -out," on page 2063 */ +size in Table 1843, "MCQI CAPABILITIES Info Lay +out," on page 2075 */ /* 0x4.0 - 0x4.31 */ u_int32_t offset; /*---------------- DWORD[2] (Offset 0x8) ----------------*/ @@ -1451,14 +1453,14 @@ zero padded. */ u_int16_t data_size; /*---------------- DWORD[6] (Offset 0x18) ----------------*/ /* Description - Properties set structure according to info_type. -CAPABILITIES - See Table 1829, "MCQI CAPABILI -TIES Info Layout," on page 2063 -VERSION - See Table 1831, "MCQI VERSION Info -Layout," on page 2065 -ACTIVATION_METHOD - See Table 1835, "MCQI -ACTIVATION_METHOD Info Layout," on page 2067 -LINKX_PREPERTIES - See Table 1837, "MCQI -LINKX_PROPERTIES Info Layout," on page 2068 */ +CAPABILITIES - See Table 1843, "MCQI CAPABILI +TIES Info Layout," on page 2075 +VERSION - See Table 1845, "MCQI VERSION Info +Layout," on page 2077 +ACTIVATION_METHOD - See Table 1849, "MCQI +ACTIVATION_METHOD Info Layout," on page 2079 +LINKX_PREPERTIES - See Table 1851, "MCQI +LINKX_PROPERTIES Info Layout," on page 2080 */ /* 0x18.0 - 0x90.31 */ union reg_access_hca_mcqi_reg_data_auto data; }; @@ -1498,8 +1500,8 @@ Other values are reserved */ /* 0x4.0 - 0x4.15 */ u_int16_t identifier; /*---------------- DWORD[2] (Offset 0x8) ----------------*/ - /* Description - Component state in update flow, see Section 9.9.1, -"Component Update State", on page 446: + /* Description - Component state in update flow, see Section 10.2.1, +"Component Update State", on page 800: 0x0: IDLE 0x1: IN_PROGRESS 0x2: APPLIED @@ -1633,18 +1635,18 @@ FW_sec_ver_stat is 1, it will program the EFUSEs as needed. */ /* Size in bytes - 160 */ struct reg_access_hca_mgir { /*---------------- DWORD[0] (Offset 0x0) ----------------*/ - /* Description - Hardware Information, see Table 1718, "Hardware Info -Layout," on page 1982 */ + /* Description - Hardware Information, see Table 1732, "Hardware Info +Layout," on page 1994 */ /* 0x0.0 - 0x1c.31 */ struct reg_access_hca_mgir_hardware_info hw_info; /*---------------- DWORD[8] (Offset 0x20) ----------------*/ - /* Description - Firmware Information, see Table 1720, "Firmware Info -Layout," on page 1984 */ + /* Description - Firmware Information, see Table 1734, "Firmware Info +Layout," on page 1996 */ /* 0x20.0 - 0x5c.31 */ struct reg_access_hca_mgir_fw_info fw_info; /*---------------- DWORD[24] (Offset 0x60) ----------------*/ - /* Description - Software Information, see Table 1722, "Software Info Lay -out," on page 1986 + /* Description - Software Information, see Table 1736, "Software Info Lay +out," on page 1998 This field indicates the oldest software version compati ble with the current firmware */ /* 0x60.0 - 0x7c.31 */ @@ -2002,7 +2004,7 @@ formed. Used for debug. */ /* Size in bytes - 256 */ struct reg_access_hca_resource_dump { /*---------------- DWORD[0] (Offset 0x0) ----------------*/ - /* Description - See Section 24.8, "Resource Dump", on page 1290. */ + /* Description - See Section 24.8, "Resource Dump", on page 1299. */ /* 0x0.0 - 0x0.15 */ u_int16_t segment_type; /* Description - Sequence number. 0 on first call of dump and incre @@ -2154,8 +2156,8 @@ injected. */ u_int16_t num_repeat; /*---------------- DWORD[4] (Offset 0x10) ----------------*/ /* Description - stressor Modifier according to type field. -For SMBUS_FAILED,Table 1093, "SMBUS_FAILED Fault -Inject Modifier Layout," on page 1354 */ +For SMBUS_FAILED,Table 1101, "SMBUS_FAILED Fault +Inject Modifier Layout," on page 1363 */ /* 0x10.0 - 0x2c.31 */ struct reg_access_hca_smbus_failed_fault_inject_modifier per_type_modifier; }; @@ -2211,10 +2213,10 @@ Value 0x0 for freq indicates the Mini Flow will not be injected. */ u_int16_t num_repeat; /*---------------- DWORD[4] (Offset 0x10) ----------------*/ /* Description - stressor Modifier according to type field. -For IRISC_HANG Table 1097, "IRISC_HANG Mini-Flow Modi -fier Layout," on page 1355 -For PACKET_DROP Table 1099, "PACKET_DROP Mini-Flow -Modifier Layout," on page 1356 */ +For IRISC_HANG Table 1105, "IRISC_HANG Mini-Flow Modi +fier Layout," on page 1364 +For PACKET_DROP Table 1107, "PACKET_DROP Mini-Flow +Modifier Layout," on page 1365 */ /* 0x10.0 - 0x2c.31 */ union reg_access_hca_strs_mini_flow_reg_per_type_modifier_auto per_type_modifier; }; @@ -2323,16 +2325,16 @@ active. */ u_int8_t polarity; /*---------------- DWORD[4] (Offset 0x10) ----------------*/ /* Description - stressor Modifier according to type field. -For RXB_HANG Table 1075, "RXB_HANG Stop Toggle Modi -fier Layout," on page 1346 -For LOCK_RESOURCE Table 1081, "LOCK_RESOURCE Stop -Toggle Modifier Layout," on page 1348 -For SXP_HANG Table 1077, "SXP_HANG Stop Toggle Modi -fier Layout," on page 1347 -For RXB_HOST_HANG Table 1079, "RXB_HOST_HANG Stop -Toggle Modifier Layout," on page 1348 -For PAUSE_TX See Table Table 1089, "PAUSE_TX Stop Tog -gle Modifier Layout," on page 1351 */ +For RXB_HANG Table 1083, "RXB_HANG Stop Toggle Modi +fier Layout," on page 1355 +For LOCK_RESOURCE Table 1089, "LOCK_RESOURCE Stop +Toggle Modifier Layout," on page 1357 +For SXP_HANG Table 1085, "SXP_HANG Stop Toggle Modi +fier Layout," on page 1356 +For RXB_HOST_HANG Table 1087, "RXB_HOST_HANG Stop +Toggle Modifier Layout," on page 1357 +For PAUSE_TX See Table Table 1097, "PAUSE_TX Stop Tog +gle Modifier Layout," on page 1360 */ /* 0x10.0 - 0x2c.31 */ union reg_access_hca_strs_stop_toggle_reg_per_type_modifier_auto per_type_modifier; }; diff --git a/tools_layouts/reg_access_switch_layouts.c b/tools_layouts/reg_access_switch_layouts.c index ebb79b28..6d5eab37 100644 --- a/tools_layouts/reg_access_switch_layouts.c +++ b/tools_layouts/reg_access_switch_layouts.c @@ -889,8 +889,12 @@ void reg_access_switch_mdsr_reg_ext_pack(const struct reg_access_switch_mdsr_reg adb2c_push_bits_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->status); offset = 18; adb2c_push_bits_to_buff(ptr_buff, offset, 6, (u_int32_t)ptr_struct->additional_info); + offset = 0; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->type_of_token); offset = 32; adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->end); + offset = 64; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->time_left); } void reg_access_switch_mdsr_reg_ext_unpack(struct reg_access_switch_mdsr_reg_ext *ptr_struct, const u_int8_t *ptr_buff) @@ -901,8 +905,12 @@ void reg_access_switch_mdsr_reg_ext_unpack(struct reg_access_switch_mdsr_reg_ext ptr_struct->status = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 4); offset = 18; ptr_struct->additional_info = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 6); + offset = 0; + ptr_struct->type_of_token = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); offset = 32; ptr_struct->end = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); + offset = 64; + ptr_struct->time_left = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); } void reg_access_switch_mdsr_reg_ext_print(const struct reg_access_switch_mdsr_reg_ext *ptr_struct, FILE *fd, int indent_level) @@ -915,7 +923,11 @@ void reg_access_switch_mdsr_reg_ext_print(const struct reg_access_switch_mdsr_re adb2c_add_indentation(fd, indent_level); fprintf(fd, "additional_info : " UH_FMT "\n", ptr_struct->additional_info); adb2c_add_indentation(fd, indent_level); + fprintf(fd, "type_of_token : " UH_FMT "\n", ptr_struct->type_of_token); + adb2c_add_indentation(fd, indent_level); fprintf(fd, "end : " UH_FMT "\n", ptr_struct->end); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "time_left : " U32H_FMT "\n", ptr_struct->time_left); } unsigned int reg_access_switch_mdsr_reg_ext_size(void) @@ -986,6 +998,10 @@ void reg_access_switch_mtcq_reg_ext_pack(const struct reg_access_switch_mtcq_reg u_int32_t offset; int i; + offset = 20; + adb2c_push_bits_to_buff(ptr_buff, offset, 12, (u_int32_t)ptr_struct->device_index); + offset = 8; + adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->status); offset = 0; adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->token_opcode); for (i = 0; i < 4; ++i) { @@ -1021,6 +1037,10 @@ void reg_access_switch_mtcq_reg_ext_unpack(struct reg_access_switch_mtcq_reg_ext u_int32_t offset; int i; + offset = 20; + ptr_struct->device_index = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 12); + offset = 8; + ptr_struct->status = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); offset = 0; ptr_struct->token_opcode = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); for (i = 0; i < 4; ++i) { @@ -1058,6 +1078,10 @@ void reg_access_switch_mtcq_reg_ext_print(const struct reg_access_switch_mtcq_re adb2c_add_indentation(fd, indent_level); fprintf(fd, "======== reg_access_switch_mtcq_reg_ext ========\n"); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "device_index : " UH_FMT "\n", ptr_struct->device_index); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "status : " UH_FMT "\n", ptr_struct->status); adb2c_add_indentation(fd, indent_level); fprintf(fd, "token_opcode : " UH_FMT "\n", ptr_struct->token_opcode); for (i = 0; i < 4; ++i) { diff --git a/tools_layouts/reg_access_switch_layouts.h b/tools_layouts/reg_access_switch_layouts.h index e991e805..7aacb8b3 100644 --- a/tools_layouts/reg_access_switch_layouts.h +++ b/tools_layouts/reg_access_switch_layouts.h @@ -352,12 +352,12 @@ range index will lead to BAD_PARAM status of the register. */ u_int8_t data_valid; /*---------------- DWORD[4] (Offset 0x10) ----------------*/ /* Description - Properties of that field are based on query_type. -For slot information query_type data - see Table 609, -"slot_info Register Layout," on page 750 -For devices on slot query_type data - see Table 611, -"device_info Register Layout," on page 751 -For slot name query_type data - see Table 613, "slot_name -Register Layout," on page 752 */ +For slot information query_type data - see Table 539, +"slot_info Register Layout," on page 753 +For devices on slot query_type data - see Table 541, +"device_info Register Layout," on page 754 +For slot name query_type data - see Table 543, "slot_name +Register Layout," on page 755 */ /* 0x10.0 - 0x2c.31 */ union reg_access_switch_mddq_data_auto_ext data; }; @@ -389,12 +389,12 @@ struct reg_access_switch_mddt_reg_ext { u_int8_t read_size; /*---------------- DWORD[3] (Offset 0xc) ----------------*/ /* Description - Payload -For PRM Register type payload- See Table 601, "PRM -Register Payload Layout," on page 747 -For Command type payload - See Table 603, "Com -mand Payload Layout," on page 747 -For CrSpace type payload - See Table 605, "CrSpace -access Payload Layout," on page 748 */ +For PRM Register type payload- See Table 531, "PRM +Register Payload Layout," on page 750 +For Command type payload - See Table 533, "Com +mand Payload Layout," on page 750 +For CrSpace type payload - See Table 535, "CrSpace +access Payload Layout," on page 751 */ /* 0xc.0 - 0x10c.31 */ union reg_access_switch_mddt_reg_payload_auto_ext payload; }; @@ -406,8 +406,14 @@ struct reg_access_switch_mdsr_reg_ext { /* Description - 0: The debug session ended successfully 1: Failed to execute the operation. See additional_info for more details. -2: Debug session active -3-15: Reserved +2: Debug session active. See type_of_token for more details. +3: No token applied +4: Challenge provided, no token installed yet, see type_of_to +ken for details. +5: Timeout before token installed, see type_of_token for +details +6: Timeout of active token. +7-15: Reserved Note: Status might be '0' even when debug query is not allowed and additional_info field will expose the reason. */ @@ -422,11 +428,28 @@ allowed and additional_info field will expose the reason. */ 5: Debug session active */ /* 0x0.8 - 0x0.13 */ u_int8_t additional_info; + /* Description - 0: Debug FW token 1: CS token +2: FRC token +3: RMCS token +4: RMDS token +5: CRCS token +6: CRDT token */ + /* 0x0.24 - 0x0.31 */ + u_int8_t type_of_token; /*---------------- DWORD[1] (Offset 0x4) ----------------*/ /* Description - Set to '1' to end debug session. Setting to '0' will not trigger any operation. */ /* 0x4.31 - 0x4.31 */ u_int8_t end; +/*---------------- DWORD[2] (Offset 0x8) ----------------*/ + /* Description - Time left in seconds. +In case that status is 2 (debug session active) - time left for +token operation +In case that status is 4 (challenge provided, no token +installed yet) - time left for token installation +For any other status, field should be zero */ + /* 0x8.0 - 0x8.31 */ + u_int32_t time_left; }; /* Description - */ @@ -462,8 +485,27 @@ sequence number of each keep-alive session. */ /* Size in bytes - 112 */ struct reg_access_switch_mtcq_reg_ext { /*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - Device number. +For gearboxes, the index represents the gearbox die. +For cables, the index represents the module index +starting at index 1 while index 0 indicates the host +device. */ + /* 0x0.0 - 0x0.11 */ + u_int16_t device_index; + /* Description - Indicates the status of the desired token we are gener +ating the challenge for. +0x0 - OK +0x1 - TOKEN_ALREADY_APPLIED +0x2 - TOKEN_NOT_SUPPORTED +0x3 - NO_KEY_CONFIGURED (there is no public_key +that can be used for this token) +0x4 - INTERFACE_NOT_ALLOWED (asking for local +token from remote interface, or remote token from +local interface) */ + /* 0x0.16 - 0x0.23 */ + u_int8_t status; /* Description - The token which a challenge is generated for. -0: RMSC +0: RMCS 1: RMDT Other: Reserved */ From e0ce91b6e33e1730dfa58adefc4be7547e18d87f Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Mon, 17 Jan 2022 12:44:35 +0200 Subject: [PATCH 056/184] Fixing PMLP field access according to the PRM Description: PRM change the fields accessto array, so tool changed according that Tested OS: Linux64 Tested devices: SPC2, SPC3 Tested flows: mlxlink commands Known gaps (with RM ticket): NA Issue: 2917956 Issue: 2937749 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_amBER_collector.cpp | 4 ++-- mlxlink/modules/mlxlink_commander.cpp | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mlxlink/modules/mlxlink_amBER_collector.cpp b/mlxlink/modules/mlxlink_amBER_collector.cpp index d9475fa6..4d407e66 100644 --- a/mlxlink/modules/mlxlink_amBER_collector.cpp +++ b/mlxlink/modules/mlxlink_amBER_collector.cpp @@ -214,8 +214,8 @@ void MlxlinkAmBerCollector::init() updateField("local_port", _localPort); genBuffSendRegister(ACCESS_REG_PMLP, MACCESS_REG_METHOD_GET); - _moduleIndex = getFieldValue("lane0_module_mapping.module"); - _slotIndex = getFieldValue("lane0_module_mapping.slot_index"); + _moduleIndex = getFieldValue("module_0"); + _slotIndex = getFieldValue("slot_index_0"); } else { resetParser(ACCESS_REG_MPEIN); updateField("pcie_index", _pcieIndex); diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index 0284fc03..e047a814 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -383,7 +383,7 @@ void MlxlinkCommander::validatePortToLC() updateField("local_port", _localPort); genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); - u_int32_t slotIndex = getFieldValue("lane0_module_mapping.slot_index"); + u_int32_t slotIndex = getFieldValue("slot_index_0"); try { regName = "MDDQ"; @@ -641,7 +641,7 @@ void MlxlinkCommander::labelToSpectLocalPort() continue; } splitAdjustment = 0; - if ((getFieldValue("lane0_module_mapping.module") + 1) == _userInput._labelPort) { + if ((getFieldValue("module_0") + 1) == _userInput._labelPort) { checkWidthSplit(); if (_userInput._splitProvided) { if (_devID == DeviceSpectrum3 || _devID == DeviceSpectrum4 || @@ -665,7 +665,7 @@ void MlxlinkCommander::labelToSpectLocalPort() } updateField("local_port", _localPort); genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); - if ((getFieldValue("lane0_module_mapping.module") + 1) == _userInput._labelPort) { + if ((getFieldValue("module_0") + 1) == _userInput._labelPort) { return; } } @@ -888,7 +888,7 @@ void MlxlinkCommander::getCableParams() resetParser(regName); updateField("local_port", _localPort); genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); - _moduleNumber = getFieldValue("lane0_module_mapping.module"); + _moduleNumber = getFieldValue("module_0"); } catch (const std::exception &exc) { _allUnhandledErrors += string("Getting cable parameters via PDDR raised the following exception: ") + string(exc.what()) + string("\n"); } @@ -1023,7 +1023,7 @@ int MlxlinkCommander::handleEthLocalPort(u_int32_t labelPort, bool spect2WithGb) if (getFieldValue("width") == 0) { continue; } - if (getFieldValue("lane0_module_mapping.module") + 1 + if (getFieldValue("module_0") + 1 == labelPort) { targetLocalPort = localPort; fillEthPortGroupMap(localPort, labelPort, _userInput._setGroup, @@ -1147,7 +1147,7 @@ vector MlxlinkCommander::localToPortsPerGroup(vector localPor if (getFieldValue("width") == 0) { continue; } - labelPort = (getFieldValue("lane0_module_mapping.module")) + 1; + labelPort = (getFieldValue("module_0")) + 1; } else if (_devID == DeviceQuantum || _devID == DeviceQuantum2) { regName = "PLIB"; resetParser(regName); From 6543e9a5085203f8f870e3dd823c24c2f8f1e813 Mon Sep 17 00:00:00 2001 From: Guo-Fu Tseng Date: Wed, 12 Jan 2022 12:46:15 +0800 Subject: [PATCH 057/184] Fix compile error on Gentoo On Gentoo: #define LINUX_COMPILER "gcc (Gentoo 10.3.0-r2 p3) 10.3.0, GNU ld (Gentoo 2.37_p1 p0) 2.37" On Ubuntu: #define LINUX_COMPILER "gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04)" Error without patch: /bin/sh: -c: line 1: unexpected EOF while looking for matching `"' /bin/sh: -c: line 2: syntax error: unexpected end of file /bin/sh: line 1: [: -lt: unary operator expected make -C /lib/modules/5.10.61-gentoo/build M=/home/cooldavid/kernel CONFIG_CTF= CONFIG_CC_STACKPROTECTOR_STRONG= modules make[1]: Entering directory '/usr/src/linux-5.10.61-gentoo' /bin/sh: -c: line 1: unexpected EOF while looking for matching `"' /bin/sh: -c: line 2: syntax error: unexpected end of file /bin/sh: line 1: [: -lt: unary operator expected CC [M] /home/cooldavid/kernel/mst_vpd.o CC [M] /home/cooldavid/kernel/mst_main.o LD [M] /home/cooldavid/kernel/mstflint_access.o /bin/sh: -c: line 1: unexpected EOF while looking for matching `"' /bin/sh: -c: line 2: syntax error: unexpected end of file /bin/sh: line 1: [: -lt: unary operator expected MODPOST /home/cooldavid/kernel/Module.symvers CC [M] /home/cooldavid/kernel/mstflint_access.mod.o LD [M] /home/cooldavid/kernel/mstflint_access.ko make[1]: Leaving directory '/usr/src/linux-5.10.61-gentoo' --- kernel/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index c9416548..da21bdb2 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -52,9 +52,9 @@ CPP_PATCH := $(shell $(CPP) -dumpversion 2>&1 | cut -d'.' -f3) CPP_VERS := $(shell expr 0$(CPP_MAJOR) \* 1000000 + 0$(CPP_MINOR) \* 1000 + 0$(CPP_PATCH)) compile_h=$(shell /bin/ls -1 $(KSRC)/include/*/compile.h 2> /dev/null | head -1) ifneq ($(compile_h),) -KERNEL_GCC_MAJOR := $(shell grep LINUX_COMPILER $(compile_h) | sed -r -e 's/.*gcc version ([0-9\.\-]*) .*/\1/g' | cut -d'.' -f1) -KERNEL_GCC_MINOR := $(shell grep LINUX_COMPILER $(compile_h) | sed -r -e 's/.*gcc version ([0-9\.\-]*) .*/\1/g' | cut -d'.' -f2) -KERNEL_GCC_PATCH := $(shell grep LINUX_COMPILER $(compile_h) | sed -r -e 's/.*gcc version ([0-9\.\-]*) .*/\1/g' | cut -d'.' -f3) +KERNEL_GCC_MAJOR := $(shell grep LINUX_COMPILER $(compile_h) | grep -Eo ' [0-9]+\.[0-9]+\.[0-9]+[, $$]' | sed 's/[, ]//g' | cut -d'.' -f1) +KERNEL_GCC_MINOR := $(shell grep LINUX_COMPILER $(compile_h) | grep -Eo ' [0-9]+\.[0-9]+\.[0-9]+[, $$]' | sed 's/[, ]//g' | cut -d'.' -f2) +KERNEL_GCC_PATCH := $(shell grep LINUX_COMPILER $(compile_h) | grep -Eo ' [0-9]+\.[0-9]+\.[0-9]+[, $$]' | sed 's/[, ]//g' | cut -d'.' -f3) KERNEL_GCC_VER := $(shell expr 0$(KERNEL_GCC_MAJOR) \* 1000000 + 0$(KERNEL_GCC_MINOR) \* 1000 + 0$(KERNEL_GCC_PATCH)) ifneq ($(shell if [ $(CPP_VERS) -lt 4006000 ] && [ $(KERNEL_GCC_VER) -ge 4006000 ]; then \ echo "YES"; else echo ""; fi),) From c2693c8e5687a4de7a8c571e7814381323772feb Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Mon, 14 Feb 2022 17:03:05 +0200 Subject: [PATCH 058/184] update mstflint version to 4.19.0 --- configure.ac | 4 ++-- kernel/mstflint_kernel.spec | 2 +- mstflint.spec.in | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index e2515b44..849b1873 100644 --- a/configure.ac +++ b/configure.ac @@ -31,12 +31,12 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(mstflint, 4.18.0, eranj@mellanox.co.il) +AC_INIT(mstflint, 4.19.0, eranj@mellanox.co.il) AC_DEFINE_UNQUOTED([PROJECT], ["mstflint"], [Define the project name.]) AC_SUBST([PROJECT]) -AC_DEFINE_UNQUOTED([VERSION], ["4.18.0"], [Define the project version.]) +AC_DEFINE_UNQUOTED([VERSION], ["4.19.0"], [Define the project version.]) AC_SUBST([VERSION]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/kernel/mstflint_kernel.spec b/kernel/mstflint_kernel.spec index ece499a5..25690edf 100644 --- a/kernel/mstflint_kernel.spec +++ b/kernel/mstflint_kernel.spec @@ -22,7 +22,7 @@ %global _name kernel-mstflint %endif -%{!?version: %global version 4.18.0} +%{!?version: %global version 4.19.0} %{!?_release: %global _release 1} %global _kmp_rel %{_release}%{?_kmp_build_num}%{?_dist} diff --git a/mstflint.spec.in b/mstflint.spec.in index 8d09ad69..689e6bb9 100644 --- a/mstflint.spec.in +++ b/mstflint.spec.in @@ -1,6 +1,6 @@ %{!?ibmadlib: %define ibmadlib libibmad-devel} %{!?name: %define name mstflint} -%{!?version: %define version 4.18.0} +%{!?version: %define version 4.19.0} %{!?release: %define release 1} %{!?buildtype: %define buildtype "native"} %{!?noinband: %define noinband 0} From c8eb43f5d414e720ddb08efa143b85046d71f8a2 Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Mon, 21 Feb 2022 11:27:04 +0200 Subject: [PATCH 059/184] [mstfwtrace] livefish mode message Description: add check for FW info to prevent run and fail on livefish mode. match the output to internal mft tracer tool. Tested OS:Linux Tested devices: Nic in Livefish mode ( apps-01 -d 07:00.0) Tested flows: run "mstfwtrace -d 07:00.0 --tracer_mode MEM -m ICMD -l 1 -i all -s" from issue and expect output: "-E- Failed to get FW INFO: Unsupported icmd version, device maybe in livefish mode." Known gaps (with RM ticket): None Issue:2969662 --- tracers/fwtrace/mstfwtrace.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tracers/fwtrace/mstfwtrace.py b/tracers/fwtrace/mstfwtrace.py index bf732d7b..2647593c 100755 --- a/tracers/fwtrace/mstfwtrace.py +++ b/tracers/fwtrace/mstfwtrace.py @@ -349,10 +349,14 @@ def check_secure_fw_args(devInfo): def get_device_info(dev): + #check if livefish mode before continue to work with the device + CMDIFDEV.getFwInfo() + devIdChipRev = dev.read4(0xf0014) devId = devIdChipRev & 0xffff chipRev = (devIdChipRev >> 16) & 0xf + for devInfo in DEV_INFO_DB: if devId in devInfo["dev_id"] and \ (devInfo["chip_rev"] == -1 or devInfo["chip_rev"] == chipRev): @@ -436,8 +440,8 @@ def start_tracer(): global MST_DEVICE global CMDIFDEV MST_DEVICE = mtcr.MstDevice(DEV_NAME) - devInfo = get_device_info(MST_DEVICE) CMDIFDEV = cmdif.CmdIf(MST_DEVICE) + devInfo = get_device_info(MST_DEVICE) if FwTraceUtilities.is_driver_mem_mode_supported(): try: From 1b9433c921e44022f60f346e6e4e6f1d312bfe09 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Wed, 12 Jan 2022 14:48:40 +0200 Subject: [PATCH 060/184] new command for burning attestation certificate chain to its DTOC section Description: Burning/writing to device/image the given binary file to CERT_CHAIN_0 DTOC section Tested OS: Linux Tested devices: Carmel Tested flows: flint_oem -i carmel_cert_dtoc_2.bin set_attestation_cert_chain cert_chain_0.bin Known gaps (with RM ticket): N/A Issue: 2919326 Change-Id: If8209f22964a21504f59062d8fce3cdd98b58e32 Signed-off-by: ashargorodsk --- flint/cmd_line_parser.cpp | 1 + flint/err_msgs.h | 1 + flint/flint.cpp | 1 + flint/flint_params.h | 1 + flint/subcommands.cpp | 45 +++++++++++++++++++++++----- flint/subcommands.h | 12 ++++++-- mlxfwops/lib/fs3_ops.cpp | 38 ++++++++++------------- mlxfwops/lib/fs3_ops.h | 8 ++++- mlxfwops/lib/fs4_ops.cpp | 63 ++++++++++++++++++++++++++++++++++----- mlxfwops/lib/fs4_ops.h | 5 +++- mlxfwops/lib/fw_ops.cpp | 9 ++++-- mlxfwops/lib/fw_ops.h | 5 ++-- 12 files changed, 143 insertions(+), 46 deletions(-) diff --git a/flint/cmd_line_parser.cpp b/flint/cmd_line_parser.cpp index b176927c..39d74cf8 100644 --- a/flint/cmd_line_parser.cpp +++ b/flint/cmd_line_parser.cpp @@ -92,6 +92,7 @@ SubCmdMetaData::SubCmdMetaData() #ifndef EXTERNAL _sCmds.push_back(new SubCmd("", "smg", SC_Smg)); _sCmds.push_back(new SubCmd("", "set_vpd", SC_Set_Vpd)); + _sCmds.push_back(new SubCmd("", "set_attestation_cert_chain", SC_Set_Cert_Chain)); #endif _sCmds.push_back(new SubCmd("", "sv", SC_Sv)); _sCmds.push_back(new SubCmd("", "ri", SC_Ri)); diff --git a/flint/err_msgs.h b/flint/err_msgs.h index bc3545ce..f5e92e33 100644 --- a/flint/err_msgs.h +++ b/flint/err_msgs.h @@ -124,6 +124,7 @@ typedef enum { #define FLINT_MFG_ERROR "Failed to set manufacture guids: %s\n" #define FLINT_VSD_ERROR "Failed to set the VSD: %s\n" #define FLINT_VPD_ERROR "Failed to set VPD: %s\n" +#define FLINT_CERT_CHAIN_ERROR "Failed to set attestation certificate chain: %s\n" #define FLINT_SET_KEY_ERROR "Failed to set the HW access key: %s\n" #define FLINT_RESET_CFG_ERROR "Failed to reset Configuration: %s\n" #define FLINT_FIX_IMG_ERROR "Failed to fix device image: %s\n" diff --git a/flint/flint.cpp b/flint/flint.cpp index 1797ff46..a4bffbe5 100644 --- a/flint/flint.cpp +++ b/flint/flint.cpp @@ -153,6 +153,7 @@ map_sub_cmd_t_to_subcommand Flint::initSubcommandMap() #ifndef EXTERNAL cmdMap[SC_Smg] = new SmgSubCommand(); cmdMap[SC_Set_Vpd] = new SetVpdSubCommand(); + cmdMap[SC_Set_Cert_Chain] = new SetCertChainSubCommand(); cmdMap[SC_Fix_Img] = new FiSubCommand(); cmdMap[SC_Extract_4MB_Image] = new Extract4MBImageSubCommand(); #endif diff --git a/flint/flint_params.h b/flint/flint_params.h index c20a06f6..696e1925 100644 --- a/flint/flint_params.h +++ b/flint/flint_params.h @@ -61,6 +61,7 @@ typedef enum { SC_Sg, SC_Smg, SC_Set_Vpd, + SC_Set_Cert_Chain, SC_Sv, SC_Ri, SC_Dc, diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index 86a82b7a..2069e14f 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -1911,7 +1911,7 @@ FlintStatus SignRSASubCommand::executeCommand() //* Fill image_signature section with 0xff vector signature256Data(CX4FW_IMAGE_SIGNATURE_256_SIZE, 0xff); - _imgOps->Fs3UpdateSection(signature256Data.data(), FS3_IMAGE_SIGNATURE_256, true, CMD_SET_SIGNATURE, NULL); + _imgOps->UpdateSection(signature256Data.data(), FS3_IMAGE_SIGNATURE_256, true, CMD_SET_SIGNATURE, NULL); return FLINT_SUCCESS; #else reportErr(true, "Open SSL functionality is not supported.\n"); @@ -1953,7 +1953,7 @@ FlintStatus SignRSASubCommand::executeCommand() //* Fill image_signature section with 0xff vector signature256Data(CX4FW_IMAGE_SIGNATURE_256_SIZE, 0xff); - _imgOps->Fs3UpdateSection(signature256Data.data(), FS3_IMAGE_SIGNATURE_256, true, CMD_SET_SIGNATURE, NULL); + _imgOps->UpdateSection(signature256Data.data(), FS3_IMAGE_SIGNATURE_256, true, CMD_SET_SIGNATURE, NULL); return FLINT_SUCCESS; } } @@ -4757,6 +4757,42 @@ FlintStatus SmgSubCommand::executeCommand() return FLINT_SUCCESS; } +/*********************** + * Class: Set Attestation Cert Chain Subcommand + **********************/ +SetCertChainSubCommand::SetCertChainSubCommand() +{ + _name = "set attestation certificate chain"; + _desc = "Set read-only attestation certificate chain (For FS4 image only)."; + _extendedDesc = "Set Read-only attestation certificate chain, Set attestation certificate chain in the given FS4 image, intended for production use only."; + _flagLong = "set_attestation_cert_chain"; + _flagShort = ""; + _param = ""; + _paramExp = "Certificate chain file: bin file containing the certificate chain data"; + _example = FLINT_NAME " -i fw_image.bin set_attestation_cert_chain cert_chain.bin" +#ifndef __WIN__ + "\n" FLINT_NAME " -d " MST_DEV_EXAMPLE3 " -override_cache_replacement set_attestation_cert_chain cert_chain.bin (should be used when device is idle)" +#endif + ; + _v = Wtv_Dev_Or_Img; + _maxCmdParamNum = 1; + _minCmdParamNum = 1; + _cmdType = SC_Set_Cert_Chain; +} + +FlintStatus SetCertChainSubCommand::executeCommand() +{ + if (preFwOps() == FLINT_FAILED) { + return FLINT_FAILED; + } + FwOperations *ops = _flintParams.device_specified ? _fwOps : _imgOps; + if (!ops->FwSetCertChain((char*)_flintParams.cmd_params[0].c_str(), &verifyCbFunc)) { + reportErr(true, FLINT_CERT_CHAIN_ERROR, ops->err()); + return FLINT_FAILED; + } + return FLINT_SUCCESS; +} + /*********************** * Class: Set Vpd Subcommand **********************/ @@ -4780,11 +4816,6 @@ SetVpdSubCommand::SetVpdSubCommand() _cmdType = SC_Set_Vpd; } -SetVpdSubCommand:: ~SetVpdSubCommand() -{ - -} - FlintStatus SetVpdSubCommand::executeCommand() { if (preFwOps() == FLINT_FAILED) { diff --git a/flint/subcommands.h b/flint/subcommands.h index 379c7a89..a3629e44 100644 --- a/flint/subcommands.h +++ b/flint/subcommands.h @@ -445,13 +445,19 @@ class SmgSubCommand : public SubCommand inline bool verifyParams(); }; -class SetVpdSubCommand : public SubCommand +class SetCertChainSubCommand : public SubCommand { -private: +public: + SetCertChainSubCommand(); + ~SetCertChainSubCommand() {}; + FlintStatus executeCommand(); +}; +class SetVpdSubCommand : public SubCommand +{ public: SetVpdSubCommand(); - ~SetVpdSubCommand(); + ~SetVpdSubCommand() {}; FlintStatus executeCommand(); }; diff --git a/mlxfwops/lib/fs3_ops.cpp b/mlxfwops/lib/fs3_ops.cpp index 6347d2de..84853f13 100644 --- a/mlxfwops/lib/fs3_ops.cpp +++ b/mlxfwops/lib/fs3_ops.cpp @@ -268,12 +268,6 @@ bool Fs3Operations::GetMfgInfo(u_int8_t *buff) #define CHECK_IMAGE_INFO_VERSION(major) \ ((major) == 0) -#define FAIL_NO_OCR(str) do { \ - if (_ioAccess->is_flash() && _fwParams.ignoreCacheRep == 0) { \ - return errmsg(MLXFW_OCR_ERR, "-ocr flag must be specified for %s operation.", str); \ - } \ -} while (0) - #define RESIGN_MSG "-W- The image requires to be signed by a valid key, run sign command before applying.\n" #define INSERT_SHA_IF_NEEDS(callBackF) do { \ @@ -1457,7 +1451,7 @@ bool Fs3Operations::FwSetMFG(fs3_uid_t baseGuid, PrintCallBack callBackFunc) if (FwType() == FIT_FS3) { FAIL_NO_OCR("set manufacture GUIDs/MACs"); } - if (!Fs3UpdateSection(&baseGuid, FS3_MFG_INFO, false, CMD_SET_MFG_GUIDS, callBackFunc)) { + if (!UpdateSection(&baseGuid, FS3_MFG_INFO, false, CMD_SET_MFG_GUIDS, callBackFunc)) { return false; } // on image verify that image is OK after modification (we skip this on device for performance reasons) @@ -1527,7 +1521,7 @@ bool Fs3Operations::FwSetGuids(sg_params_t& sgParam, PrintCallBack callBackFunc, if (FwType() == FIT_FS3) { FAIL_NO_OCR("set GUIDs/MACs"); } - if (!Fs3UpdateSection(&usrGuid, FS3_DEV_INFO, false, CMD_SET_GUIDS, callBackFunc)) { + if (!UpdateSection(&usrGuid, FS3_DEV_INFO, false, CMD_SET_GUIDS, callBackFunc)) { return false; } // on image verify that image is OK after modification (we skip this on device for performance reasons) @@ -1607,7 +1601,7 @@ bool Fs3Operations::FwSetVPD(char *vpdFileStr, PrintCallBack callBackFunc) } FAIL_NO_OCR("set VPD"); - if (!Fs3UpdateSection(vpdFileStr, FS3_VPD_R0, false, CMD_BURN_VPD, callBackFunc)) { + if (!UpdateSection(vpdFileStr, FS3_VPD_R0, false, CMD_BURN_VPD, callBackFunc)) { return false; } // on image verify that image is OK after modification (we skip this on device for performance reasons) @@ -2071,7 +2065,7 @@ bool Fs3Operations::Fs3UpdateVpdSection(struct toc_info *curr_toc, char *vpd, int vpd_size = 0; u_int8_t *vpd_data = (u_int8_t *)NULL; - if (!ReadImageFile(vpd, vpd_data, vpd_size)) { + if (!ReadBinFile(vpd, vpd_data, vpd_size)) { return false; } if (vpd_size % 4) { @@ -2095,7 +2089,7 @@ bool Fs3Operations::Fs3UpdatePublicKeysSection(unsigned int currSectionSize, con int publicKeysSize = 0, publicKeysSizeInDW = 0; u_int8_t *publicKeysData = (u_int8_t *)NULL; - if (!ReadImageFile(publicKeys, publicKeysData, publicKeysSize)) { + if (!ReadBinFile(publicKeys, publicKeysData, publicKeysSize)) { return false; } @@ -2226,7 +2220,7 @@ bool Fs3Operations::Fs3UpdateForbiddenVersionsSection(unsigned int currSectionSi int size = 0, sizeInDW = 0; u_int8_t *data = (u_int8_t *)NULL; - if (!ReadImageFile(fileName, data, size)) { + if (!ReadBinFile(fileName, data, size)) { return false; } @@ -2243,7 +2237,7 @@ bool Fs3Operations::Fs3UpdateForbiddenVersionsSection(unsigned int currSectionSi } //add callback if we want info during section update -bool Fs3Operations::Fs3UpdateSection(void *new_info, fs3_section_t sect_type, bool is_sect_failsafe, CommandType cmd_type, PrintCallBack callBackFunc) +bool Fs3Operations::UpdateSection(void *new_info, fs3_section_t sect_type, bool is_sect_failsafe, CommandType cmd_type, PrintCallBack callBackFunc) { struct toc_info *curr_toc = (struct toc_info *)NULL; std::vector newSection; @@ -2355,7 +2349,7 @@ bool Fs3Operations::FwSetVSD(char *vsdStr, ProgressCallBack progressFunc, PrintC return errmsg("VSD string is too long(%d), max allowed length: %d", (int)strlen(vsdStr), (int)VSD_LEN); } FAIL_NO_OCR("set VSD"); - if (!Fs3UpdateSection(vsdStr, FS3_DEV_INFO, false, CMD_SET_VSD, printFunc)) { + if (!UpdateSection(vsdStr, FS3_DEV_INFO, false, CMD_SET_VSD, printFunc)) { return false; } // on image verify that image is OK after modification (we skip this on device for performance reasons) @@ -2609,7 +2603,7 @@ bool Fs3Operations::Fs3MemSetSignature(fs3_section_t sectType, u_int32_t size, P return true; } buff.resize(size, 0x0); - if (!Fs3UpdateSection(buff.data(), sectType, false, CMD_SET_SIGNATURE, printFunc)) { + if (!UpdateSection(buff.data(), sectType, false, CMD_SET_SIGNATURE, printFunc)) { return false; } return true; @@ -2701,7 +2695,7 @@ bool Fs3Operations::FwInsertEncSHA(MlxSign::SHAType shaType, const char *privPem sig.resize(CX4FW_IMAGE_SIGNATURE_256_SIZE, 0x0); cx4fw_image_signature_256_pack(&image_signature_256, sig.data()); - if (!Fs3UpdateSection(sig.data(), FS3_IMAGE_SIGNATURE_256, + if (!UpdateSection(sig.data(), FS3_IMAGE_SIGNATURE_256, false, CMD_SET_SIGNATURE, printFunc)) { return false; } @@ -2713,7 +2707,7 @@ bool Fs3Operations::FwInsertEncSHA(MlxSign::SHAType shaType, const char *privPem sig.resize(CX4FW_IMAGE_SIGNATURE_512_SIZE, 0x0); cx4fw_image_signature_512_pack(&image_signature_512, sig.data()); - if (!Fs3UpdateSection(sig.data(), FS3_IMAGE_SIGNATURE_512, + if (!UpdateSection(sig.data(), FS3_IMAGE_SIGNATURE_512, false, CMD_SET_SIGNATURE, printFunc)) { return false; } @@ -2754,7 +2748,7 @@ bool Fs3Operations::FwInsertSHA256(PrintCallBack printFunc) sig.resize(CX4FW_IMAGE_SIGNATURE_256_SIZE); cx4fw_image_signature_256_pack(&image_signature_256, sig.data()); - if (!Fs3UpdateSection(sig.data(), FS3_IMAGE_SIGNATURE_256, + if (!UpdateSection(sig.data(), FS3_IMAGE_SIGNATURE_256, false, CMD_SET_SIGNATURE, printFunc)) { return false; } @@ -2770,7 +2764,7 @@ bool Fs3Operations::CheckPublicKeysFile(const char *fname, fs3_section_t& sectio { int publicKeysSize = 0; u_int8_t *publicKeysData = (u_int8_t *)NULL; - if (!ReadImageFile(fname, publicKeysData, publicKeysSize)) { + if (!ReadBinFile(fname, publicKeysData, publicKeysSize)) { return false; } @@ -2822,7 +2816,7 @@ bool Fs3Operations::FwSetPublicKeys(char *fname, PrintCallBack callBackFunc) return false; } - if (!Fs3UpdateSection(fname, sectionType, false, CMD_SET_PUBLIC_KEYS, callBackFunc)) { + if (!UpdateSection(fname, sectionType, false, CMD_SET_PUBLIC_KEYS, callBackFunc)) { return false; } @@ -2845,7 +2839,7 @@ bool Fs3Operations::FwSetForbiddenVersions(char *fname, PrintCallBack callBackFu return errmsg("Setting Forbidden Versions is not applicable for devices."); } - if (!Fs3UpdateSection(fname, FS3_FORBIDDEN_VERSIONS, false, CMD_SET_FORBIDDEN_VERSIONS, callBackFunc)) { + if (!UpdateSection(fname, FS3_FORBIDDEN_VERSIONS, false, CMD_SET_FORBIDDEN_VERSIONS, callBackFunc)) { return false; } @@ -3716,7 +3710,7 @@ bool Fs3Operations::InsertSecureFWSignature(vector signature, const ch memcpy(image_signature_512.keypair_uuid, uuidData.data(), uuidData.size() << 2); signature.resize(CX4FW_IMAGE_SIGNATURE_512_SIZE, 0x0); cx4fw_image_signature_512_pack(&image_signature_512, signature.data()); - if (!Fs3UpdateSection(signature.data(), FS3_IMAGE_SIGNATURE_512, + if (!UpdateSection(signature.data(), FS3_IMAGE_SIGNATURE_512, false, CMD_SET_SIGNATURE, printFunc)) { return false; } diff --git a/mlxfwops/lib/fs3_ops.h b/mlxfwops/lib/fs3_ops.h index 103c2f6f..a3d4154b 100644 --- a/mlxfwops/lib/fs3_ops.h +++ b/mlxfwops/lib/fs3_ops.h @@ -72,6 +72,12 @@ chip_type == CT_CONNECTX7 || \ chip_type == CT_BLUEFIELD || chip_type == CT_BLUEFIELD2 || chip_type == CT_BLUEFIELD3) +#define FAIL_NO_OCR(str) do { \ + if (_ioAccess->is_flash() && _fwParams.ignoreCacheRep == 0) { \ + return errmsg(MLXFW_OCR_ERR, "-ocr flag must be specified for %s operation.", str); \ + } \ +} while (0) + class Fs3Operations : public FwOperations { public: @@ -138,7 +144,7 @@ class Fs3Operations : public FwOperations { bool CalcHMAC(const vector& key, vector& digest); virtual bool GetSectionSizeAndOffset(fs3_section_t sectType, u_int32_t& size, u_int32_t& offset); MlargeBuffer GetImageCache() { return _imageCache; } - virtual bool Fs3UpdateSection(void *new_info, fs3_section_t sect_type = FS3_DEV_INFO, bool is_sect_failsafe = true, CommandType cmd_type = CMD_UNKNOWN, PrintCallBack callBackFunc = (PrintCallBack)NULL); + virtual bool UpdateSection(void *new_info, fs3_section_t sect_type = FS3_DEV_INFO, bool is_sect_failsafe = true, CommandType cmd_type = CMD_UNKNOWN, PrintCallBack callBackFunc = (PrintCallBack)NULL); virtual bool PrepItocSectionsForCompare(vector& critical, vector& non_critical); virtual bool RestoreDevToc(vector& img, char* psid, dm_dev_id_t devid_t, const cx4fw_uid_entry& base_guid, const cx4fw_uid_entry& base_mac); bool IsCriticalSection(u_int8_t sect_type); diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 06136123..8ef2c7e6 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -2718,6 +2718,30 @@ bool Fs4Operations::Fs4UpdateVsdSection(std::vector section_data, cha return true; } +bool Fs4Operations::UpdateCertChainSection(struct fs4_toc_info *curr_toc, char *certChainFile, + std::vector &newSectionData) +{ + int cert_chain_buff_size = 0; + u_int8_t *cert_chain_buff = (u_int8_t *)NULL; + + if (!ReadBinFile(certChainFile, cert_chain_buff, cert_chain_buff_size)) { + return false; + } + if (cert_chain_buff_size % 4) { + return errmsg("Size of attestation certificate chain file: 0x%x is not 4-byte aligned!", cert_chain_buff_size); + } + + //* Assert given certificate chain doesn't exceed its allocated size + u_int32_t cert_chain_0_section_size = curr_toc->toc_entry.size << 2; + if ((u_int32_t)cert_chain_buff_size > cert_chain_0_section_size) { + return errmsg("Attestation certificate chain data exceeds its allocated size of 0x%xB", cert_chain_0_section_size); + } + + newSectionData.resize(cert_chain_0_section_size, 0); // Init section data with 0x0 + memcpy(newSectionData.data(), cert_chain_buff, cert_chain_buff_size); + + return true; +} bool Fs4Operations::Fs4UpdateVpdSection(struct fs4_toc_info *curr_toc, char *vpd, std::vector &newSectionData) @@ -2725,7 +2749,7 @@ bool Fs4Operations::Fs4UpdateVpdSection(struct fs4_toc_info *curr_toc, char *vpd int vpd_size = 0; u_int8_t *vpd_data = (u_int8_t *)NULL; - if (!ReadImageFile(vpd, vpd_data, vpd_size)) { + if (!ReadBinFile(vpd, vpd_data, vpd_size)) { return false; } if (vpd_size % 4) { @@ -2970,6 +2994,7 @@ bool Fs4Operations::isDTocSection(fs3_section_t sect_type, bool& isDtoc) case FS3_MFG_INFO: case FS3_DEV_INFO: case FS3_VPD_R0: + case FS4_CERT_CHAIN_0: isDtoc = true; break; @@ -3034,7 +3059,23 @@ bool Fs4Operations::VerifyImageAfterModifications() { return true; } -bool Fs4Operations::Fs3UpdateSection(void *new_info, fs3_section_t sect_type, bool is_sect_failsafe, CommandType cmd_type, PrintCallBack callBackFunc) +bool Fs4Operations::FwSetCertChain(char *certFileStr, PrintCallBack callBackFunc) { + if (!certFileStr) { + return errmsg("Please specify a valid certificate chain file."); + } + FAIL_NO_OCR("set attestation certificate chain"); + + if (!UpdateSection(certFileStr, FS4_CERT_CHAIN_0, false, CMD_UNKNOWN, callBackFunc)) { + return false; + } + // on image verify that image is OK after modification (we skip this on device for performance reasons) + if (!_ioAccess->is_flash() && !VerifyImageAfterModifications()) { + return false; + } + return true; +} + +bool Fs4Operations::UpdateSection(void *new_info, fs3_section_t sect_type, bool, CommandType cmd_type, PrintCallBack callBackFunc) { struct fs4_toc_info *curr_toc = (fs4_toc_info *)NULL; struct fs4_toc_info *old_toc = (fs4_toc_info *)NULL; @@ -3075,7 +3116,7 @@ bool Fs4Operations::Fs3UpdateSection(void *new_info, fs3_section_t sect_type, bo } - is_sect_failsafe = (sect_type == FS3_DEV_INFO); + bool is_sect_failsafe = (sect_type == FS3_DEV_INFO); if (isDtoc) { @@ -3157,6 +3198,12 @@ bool Fs4Operations::Fs3UpdateSection(void *new_info, fs3_section_t sect_type, bo if (!Fs4UpdateVpdSection(curr_toc, vpd_file, newSection)) { return false; } + } else if (sect_type == FS4_CERT_CHAIN_0) { + char *cert_chain_file = (char *)new_info; + type_msg = "CERT_CHAIN_0"; + if (!UpdateCertChainSection(curr_toc, cert_chain_file, newSection)) { + return false; + } } else if (sect_type == FS3_IMAGE_SIGNATURE_256 && cmd_type == CMD_SET_SIGNATURE) { vector sig((u_int8_t *)new_info, (u_int8_t *)new_info + CX4FW_IMAGE_SIGNATURE_256_SIZE); type_msg = "SIGNATURE"; @@ -3218,7 +3265,7 @@ bool Fs4Operations::Fs3UpdateSection(void *new_info, fs3_section_t sect_type, bo newSectionAddr = curr_toc->toc_entry.flash_addr << 2; - if (!_encrypted_image_io_access) { // In case of encrypted image we don't update ITOC since it's already encrypted + if (!_encrypted_image_io_access) { // In case of BB secure-boot sign flow we don't update ITOC since it's already encrypted if (!Fs4UpdateItocInfo(curr_toc, curr_toc->toc_entry.size, newSection)) { return false; } @@ -3228,7 +3275,7 @@ bool Fs4Operations::Fs3UpdateSection(void *new_info, fs3_section_t sect_type, bo return false; } - if (!_encrypted_image_io_access) { // In case of encrypted image we don't update ITOC since it's already encrypted + if (!_encrypted_image_io_access) { // In case of BB secure-boot sign flow we don't update ITOC since it's already encrypted if (sect_type != FS3_DEV_INFO) { if (!Fs4ReburnTocSection(isDtoc, callBackFunc)) { return false; @@ -3244,7 +3291,7 @@ bool Fs4Operations::Fs3UpdateSection(void *new_info, fs3_section_t sect_type, bo u_int32_t flash_addr = old_toc->toc_entry.flash_addr << 2; // If encrypted image was given we'll write to it if (_encrypted_image_io_access) { - DPRINTF(("Fs4Operations::Fs3UpdateSection updating encrypted image at addr 0x%x with 0x0\n", flash_addr)); + DPRINTF(("Fs4Operations::UpdateSection updating encrypted image at addr 0x%x with 0x0\n", flash_addr)); if (!_encrypted_image_io_access->write(flash_addr, (u_int8_t *)&zeroes, sizeof(zeroes))) { return errmsg("%s", _encrypted_image_io_access->err()); @@ -3738,7 +3785,7 @@ bool Fs4Operations::storePublicKeyInSection(const char *public_key_file, const c connectx4_public_keys_3_pack(&unpackedData, finishData.data()); //* Store public-key and uuid in section and update its matching ITOC entry (with updated section_crc and entry_crc) - if (!Fs3UpdateSection(finishData.data(), FS4_RSA_PUBLIC_KEY, true, CMD_BURN, NULL)) { + if (!UpdateSection(finishData.data(), FS4_RSA_PUBLIC_KEY, true, CMD_BURN, NULL)) { return errmsg("storePublicKeyInSection failed - Error: %s", err()); } @@ -3773,7 +3820,7 @@ bool Fs4Operations::storeSecureBootSignaturesInSection(vector boot_sig finishData.resize(connectx4_secure_boot_signatures_size()); connectx4_secure_boot_signatures_pack(&secure_boot_signatures, finishData.data()); - if (!Fs3UpdateSection(finishData.data(), FS4_RSA_4096_SIGNATURES, true, CMD_BURN, NULL)) { + if (!UpdateSection(finishData.data(), FS4_RSA_4096_SIGNATURES, true, CMD_BURN, NULL)) { return errmsg("storeSecureBootSignaturesInSection: store secure-boot signatures failed.\n"); } return true; diff --git a/mlxfwops/lib/fs4_ops.h b/mlxfwops/lib/fs4_ops.h index 3c0d3fa5..596a96be 100644 --- a/mlxfwops/lib/fs4_ops.h +++ b/mlxfwops/lib/fs4_ops.h @@ -182,7 +182,7 @@ class Fs4Operations : public Fs3Operations { int& toc_index); bool Fs4GetItocInfo(struct fs4_toc_info *tocArr, int num_of_itocs, fs3_section_t sect_type, vector& curr_toc); - bool Fs3UpdateSection(void *new_info, fs3_section_t sect_type = FS3_DEV_INFO, bool is_sect_failsafe = true, CommandType cmd_type = CMD_UNKNOWN, PrintCallBack callBackFunc = (PrintCallBack)NULL ); + bool UpdateSection(void *new_info, fs3_section_t sect_type = FS3_DEV_INFO, bool is_sect_failsafe = true, CommandType cmd_type = CMD_UNKNOWN, PrintCallBack callBackFunc = (PrintCallBack)NULL ); bool Fs4UpdateMfgUidsSection(struct fs4_toc_info *curr_toc, std::vector section_data, fs3_uid_t base_uid, std::vector &newSectionData); @@ -193,6 +193,9 @@ class Fs4Operations : public Fs3Operations { std::vector &newSectionData); bool Fs4UpdateVpdSection(struct fs4_toc_info *curr_toc, char *vpd, std::vector &newSectionData); + bool UpdateCertChainSection(struct fs4_toc_info *curr_toc, char *certChainFile, + std::vector &newSectionData); + bool FwSetCertChain(char *certFileStr, PrintCallBack callBackFunc); bool Fs4ReburnSection(u_int32_t newSectionAddr, u_int32_t newSectionSize, std::vector newSectionData, const char *msg, PrintCallBack callBackFunc); diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 82e585ff..8caf29f8 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -1802,7 +1802,7 @@ bool FwOperations::RomInfo::GetExpRomVerForOneRom(u_int32_t verOffset) return true; } -bool FwOperations::ReadImageFile(const char *fimage, u_int8_t*&file_data, int &file_size) +bool FwOperations::ReadBinFile(const char *fimage, u_int8_t*&file_data, int &file_size) { #ifndef UEFI_BUILD FILE *fh; @@ -2062,6 +2062,11 @@ const char* FwOperations::expRomType2Str(u_int16_t type) return (const char*)NULL; } +bool FwOperations::FwSetCertChain(char *, PrintCallBack) +{ + return errmsg("Operation not supported."); +} + bool FwOperations::FwSetTimeStamp(struct tools_open_ts_entry& timestamp, struct tools_open_fw_version& fwVer) { (void)timestamp; @@ -2109,7 +2114,7 @@ bool FwOperations::PrepItocSectionsForCompare(vector& critical, vector return errmsg("Operation not supported."); } -bool FwOperations::Fs3UpdateSection(void *new_info, fs3_section_t sect_type, bool is_sect_failsafe, +bool FwOperations::UpdateSection(void *new_info, fs3_section_t sect_type, bool is_sect_failsafe, CommandType cmd_type, PrintCallBack callBackFunc) { (void)new_info; diff --git a/mlxfwops/lib/fw_ops.h b/mlxfwops/lib/fw_ops.h index fc88b74e..36566706 100644 --- a/mlxfwops/lib/fw_ops.h +++ b/mlxfwops/lib/fw_ops.h @@ -192,6 +192,7 @@ class MLXFWOP_API FwOperations : public FlintErrMsg { // use progressFunc when dealing with FS2 image and printFunc when dealing with FS3 image. virtual bool FwSetVSD(char *vsdStr, ProgressCallBack progressFunc = (ProgressCallBack)NULL, PrintCallBack printFunc = (PrintCallBack)NULL) = 0; virtual bool FwSetVPD(char *vpdFileStr, PrintCallBack callBackFunc = (PrintCallBack)NULL) = 0; + virtual bool FwSetCertChain(char *certFileStr, PrintCallBack callBackFunc = (PrintCallBack)NULL); virtual bool FwSetAccessKey(hw_key_t userKey, ProgressCallBack progressFunc = (ProgressCallBack)NULL) = 0; virtual bool FwGetSection(u_int32_t sectType, std::vector& sectInfo, bool stripedImage = false) = 0; virtual bool FwResetNvData() = 0; @@ -220,7 +221,7 @@ class MLXFWOP_API FwOperations : public FlintErrMsg { virtual bool FsIntQuery() { return true; } bool FwSetPrint(PrintCallBack PrintFunc); - virtual bool Fs3UpdateSection(void *new_info, fs3_section_t sect_type = FS3_DEV_INFO, bool is_sect_failsafe = true, CommandType cmd_type = CMD_UNKNOWN, PrintCallBack callBackFunc = (PrintCallBack)NULL); + virtual bool UpdateSection(void *new_info, fs3_section_t sect_type = FS3_DEV_INFO, bool is_sect_failsafe = true, CommandType cmd_type = CMD_UNKNOWN, PrintCallBack callBackFunc = (PrintCallBack)NULL); //needed for flint low level operations bool FwSwReset(); virtual bool CheckCX4Device() {return true; /* deprecated always return true*/ } @@ -533,7 +534,7 @@ class MLXFWOP_API FwOperations : public FlintErrMsg { bool getInfoFromHwDevid(u_int32_t hwDevId, chip_type_t& chipT, const u_int32_t **swIds); HwDevData getInfoFromChipType(chip_type_t chipT) const; - bool ReadImageFile(const char *fimage, u_int8_t*&file_data, int &file_size); + bool ReadBinFile(const char *fimage, u_int8_t*&file_data, int &file_size); bool FwBurnData(u_int32_t *data, u_int32_t dataSize, ProgressCallBack progressFunc); bool FwBurnData(burnDataParamsT& burnDataParams); static bool FwAccessCreate(fw_ops_params_t& fwParams, FBase **ioAccessP); From 5fc0c248abfad89128c84ba14c257e280f250f7a Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Mon, 21 Feb 2022 12:50:23 +0200 Subject: [PATCH 061/184] [flint] Set image-iv in hw pointer as part of sign for secure-boot flow Description: As part of encryption flow we're setting the image-iv in hw pointer. Since in Carmel onwards we're signing before encrypting we need to make sure we're signing the hw pointer with the image-iv data. So in that case it's calculated as part of the sign for secure-boot flow In mlxfwencryption tool we're checking that if this hw pointer is already set with value(due to earlier sign), then verify it's the correct value of image-iv calculated in the mlxfwencryption tool and used for the encryption itself Tested OS: Linux Tested devices: Carmel Tested flows: flint_oem -i carmel_image_iv_test.bin --private_key /.autodirect/fwgwork/SMV/utils/dev_keys/private4k.pem --public_key /.autodirect/fwgwork/SMV/utils/dev_keys/public4k.pub --key_uuid 5dd6108a040811ec9f1a000000000000 rsa_sign Known gaps (with RM ticket): N/A Issue: 2896247 --- mlxfwops/lib/fs3_ops.cpp | 4 +++ mlxfwops/lib/fs4_ops.cpp | 64 +++++++++++++++++++++++++++++++++++++ mlxfwops/lib/fs4_ops.h | 3 ++ mlxfwops/lib/mlxfwops_com.h | 1 + 4 files changed, 72 insertions(+) diff --git a/mlxfwops/lib/fs3_ops.cpp b/mlxfwops/lib/fs3_ops.cpp index 84853f13..05227b18 100644 --- a/mlxfwops/lib/fs3_ops.cpp +++ b/mlxfwops/lib/fs3_ops.cpp @@ -315,6 +315,10 @@ bool Fs3Operations::GetImageInfo(u_int8_t *buff) _fwImgInfo.ext_info.fw_rel_date[1] = (u_int16_t)image_info.FW_VERSION.Month; _fwImgInfo.ext_info.fw_rel_date[2] = (u_int16_t)image_info.FW_VERSION.Year; + _fwImgInfo.ext_info.fw_rel_time[0] = (u_int16_t)image_info.FW_VERSION.Hour; + _fwImgInfo.ext_info.fw_rel_time[1] = (u_int16_t)image_info.FW_VERSION.Minutes; + _fwImgInfo.ext_info.fw_rel_time[2] = (u_int16_t)image_info.FW_VERSION.Seconds; + _fwImgInfo.ext_info.burn_image_size = image_info.burn_image_size; // assuming number of supported_hw_id < MAX_NUM_SUPP_HW_IDS diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 8ef2c7e6..fea79f61 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -3972,6 +3972,12 @@ bool Fs4Operations::signForSecureBoot(const char *private_key_file, const char * SecureBootSignVersion secure_boot_version = getSecureBootSignVersion(); + if (secure_boot_version == VERSION_2) { + if (!SetImageIVHwPointer()) { + return errmsg("signForSecureBoot failed - Error: %s\n", err()); + } + } + if (!storePublicKeyInSection(public_key_file, uuid)) { return errmsg("signForSecureBoot failed - Error: %s\n", err()); } @@ -4103,6 +4109,64 @@ bool Fs4Operations::FwSignWithHmac(const char *keyFile) #endif } +bool Fs4Operations::updateHwPointer(u_int32_t addr, u_int32_t val) { + struct image_layout_hw_pointer_entry hw_pointer; + hw_pointer.ptr = TOCPU1(val); + + //* Calculate CRC + vector hw_pointer_data(IMAGE_LAYOUT_HW_POINTER_ENTRY_SIZE, 0x0); + image_layout_hw_pointer_entry_pack(&hw_pointer, hw_pointer_data.data()); + hw_pointer.crc = calc_hw_crc(hw_pointer_data.data(), IMAGE_LAYOUT_HW_POINTER_ENTRY_SIZE - 2); + + //* Write HW pointer and its CRC to image + image_layout_hw_pointer_entry_pack(&hw_pointer, hw_pointer_data.data()); + if (!_ioAccess->write(addr, hw_pointer_data.data(), IMAGE_LAYOUT_HW_POINTER_ENTRY_SIZE)) { + return errmsg("updateHwPointer writing to hw pointer in addr 0x%08x failed\n", addr); + } + + return true; +} + +bool Fs4Operations::SetImageIVHwPointer() { + if (_ioAccess->is_flash()) { + return errmsg("SetImageIVHwPointer is not applicable for devices\n"); + } + fw_info_t fwInfo; + if (!FwQuery(&fwInfo, false, false, false, true)) { + return false; // implicit set to errmsg + } + //* Assuming query already done so image info section is parsed and following members initialized accordingly + struct image_layout_FW_VERSION fw_version; + fw_version.MAJOR = _fwImgInfo.ext_info.fw_ver[0]; + fw_version.MINOR = _fwImgInfo.ext_info.fw_ver[1]; + fw_version.SUBMINOR = _fwImgInfo.ext_info.fw_ver[2]; + fw_version.Hour = _fwImgInfo.ext_info.fw_rel_time[0]; + fw_version.Minutes = _fwImgInfo.ext_info.fw_rel_time[1]; + fw_version.Seconds = _fwImgInfo.ext_info.fw_rel_time[2]; + fw_version.Day = _fwImgInfo.ext_info.fw_rel_date[0]; + fw_version.Month = _fwImgInfo.ext_info.fw_rel_date[1]; + fw_version.Year = _fwImgInfo.ext_info.fw_rel_date[2]; + + vector fw_version_data(IMAGE_LAYOUT_FW_VERSION_SIZE, 0x0); + image_layout_FW_VERSION_pack(&fw_version, fw_version_data.data()); + DPRINTF(("Fs4Operations::SetImageIVHwPointer FW version and date for hash256:\n")); + for (u_int32_t i = 0; i < (u_int32_t)fw_version_data.size(); i += 4) { + DPRINTF(("Fs4Operations::SetImageIVHwPointer 0x%02x%02x%02x%02x\n", + fw_version_data[i], fw_version_data[i+1], fw_version_data[i+2], fw_version_data[i+3])); + } + + //* Calculate SHA256 on FW version and date + MlxSignSHA256 mlxSignSHA; + mlxSignSHA << fw_version_data; + vector sha; + mlxSignSHA.getDigest(sha); + + u_int32_t image_iv = ((u_int32_t*)sha.data())[0]; + DPRINTF(("Fs4Operations::SetImageIVHwPointer image_iv = 0x%08x", image_iv)); + + return updateHwPointer(DELTA_IV_HW_POINTER_ADDR, image_iv); +} + bool Fs4Operations::PrepItocSectionsForHmac(vector& critical, vector& non_critical) { if (!FsIntQueryAux(true, false)) { diff --git a/mlxfwops/lib/fs4_ops.h b/mlxfwops/lib/fs4_ops.h index 596a96be..c7626efd 100644 --- a/mlxfwops/lib/fs4_ops.h +++ b/mlxfwops/lib/fs4_ops.h @@ -49,6 +49,7 @@ #define HMAC_SIGNATURE_LENGTH 64 #define MAX_HTOC_ENTRIES_NUM 28 #define ENCRYPTED_IMAGE_LAST_ADDR_LOCATION_IN_BYTES 0x1000000 // 16MB +#define DELTA_IV_HW_POINTER_ADDR 0x88 enum SecureBootSignVersion {VERSION_1 = 1, VERSION_2}; class Fs4Operations : public Fs3Operations { @@ -266,6 +267,8 @@ class Fs4Operations : public Fs3Operations { bool QuerySecurityFeatures(); bool IsEncryptedDevice(bool& is_encrypted); bool IsEncryptedImage(bool& is_encrypted); + bool updateHwPointer(u_int32_t addr, u_int32_t val); + bool SetImageIVHwPointer(); void RemoveCRCsFromMainSection(vector& img); // Members diff --git a/mlxfwops/lib/mlxfwops_com.h b/mlxfwops/lib/mlxfwops_com.h index fd213685..a49f6f6e 100644 --- a/mlxfwops/lib/mlxfwops_com.h +++ b/mlxfwops/lib/mlxfwops_com.h @@ -454,6 +454,7 @@ typedef struct fw_info_com { char product_ver[PRODUCT_VER_LEN + 1]; u_int16_t fw_ver[3]; u_int16_t fw_rel_date[3]; + u_int8_t fw_rel_time[3]; u_int16_t min_fit_ver[4]; u_int16_t mic_ver[3]; u_int32_t image_size; From 48150ef73b1db3a9fd1215b77487db7f1057fb09 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Mon, 21 Feb 2022 12:53:12 +0200 Subject: [PATCH 062/184] [flint] rsa_sign using hsm was missing the image-iv set for Carmel onwards Description: setting image-iv was added to sign for secure-boot flow without HSM only, now adding it to HSM flow as well Tested OS: N/A Tested devices: N/A Tested flows: N/A Known gaps (with RM ticket): N/A Issue: 2896247 --- mlxfwops/lib/fs4_ops.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index fea79f61..52aab6fb 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -3907,6 +3907,12 @@ bool Fs4Operations::signForSecureBootUsingHSM(const char *public_key_file, const SecureBootSignVersion secure_boot_version = getSecureBootSignVersion(); + if (secure_boot_version == VERSION_2) { + if (!SetImageIVHwPointer()) { + return errmsg("signForSecureBoot failed - Error: %s\n", err()); + } + } + if (!storePublicKeyInSection(public_key_file, uuid)) { return errmsg("signForSecureBootUsingHSM failed - Error: storePublicKeyInSection failed"); } From 7a502e063ae6ac01cdc25a22ce4b9d59647c7e15 Mon Sep 17 00:00:00 2001 From: Roei Yitzhak Date: Sun, 16 Jan 2022 13:37:15 +0200 Subject: [PATCH 063/184] sign BF3 Description: Added boot_record_size for BF3 Tested OS:linux Tested devices: Tested flows:sign Known gaps (with RM ticket): Issue:2936683 Change-Id: I23088f9f0916392d74072e69ec2e5855ce88d3e5 Signed-off-by: ashargorodsk --- mlxfwops/lib/fs4_ops.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 52aab6fb..0cfcda79 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -3567,6 +3567,12 @@ bool Fs4Operations::getBootRecordSize(u_int32_t& boot_record_size) { case CT_CONNECTX7: boot_record_size = 0x3f4; return true; + + // For devices after Carmel we need to ignore the last 4B (CRC/auth-tag) + case CT_BLUEFIELD3: + boot_record_size = 0x4d0; // Actual size is 0x4d4 + return true; + default: return false; } @@ -3909,19 +3915,19 @@ bool Fs4Operations::signForSecureBootUsingHSM(const char *public_key_file, const if (secure_boot_version == VERSION_2) { if (!SetImageIVHwPointer()) { - return errmsg("signForSecureBoot failed - Error: %s\n", err()); + return errmsg("signForSecureBootUsingHSM failed - Error: %s\n", err()); } } if (!storePublicKeyInSection(public_key_file, uuid)) { - return errmsg("signForSecureBootUsingHSM failed - Error: storePublicKeyInSection failed"); + return errmsg("signForSecureBootUsingHSM failed - Error: storePublicKeyInSection failed (%s)\n", err()); } //* Get boot area signature vector boot_data; vector boot_signature; if (!getBootDataForSign(boot_data)) { - return errmsg("signForSecureBootUsingHSM failed - Error: getBootDataForSign failed"); + return errmsg("signForSecureBootUsingHSM failed - Error: getBootDataForSign failed (%s)\n", err()); } int rc = engineSigner.sign(boot_data, boot_signature); if (rc) { @@ -3994,7 +4000,7 @@ bool Fs4Operations::signForSecureBoot(const char *private_key_file, const char * vector boot_data; vector boot_signature; if (!getBootDataForSign(boot_data)) { - return errmsg("signForSecureBoot failed - Error: getBootDataForSign failed.\n"); + return errmsg("signForSecureBoot failed - Error: getBootDataForSign failed (%s)\n",err()); } if (!FwSignSection(boot_data, privPemFileStr, boot_signature)) { return false; From d96aacc2bb6c7f05fd03c8e2c04cd67952ed2ed5 Mon Sep 17 00:00:00 2001 From: Itay Avraham Date: Tue, 28 Dec 2021 23:26:05 +0200 Subject: [PATCH 064/184] Abir | Adding support for severl tools Description: Tested OS: l-pld23 Tested devices: /dev/mst/gbox/PTMX1_B10-mtusb-1_abir_gbox53XXX_ln0_0 Tested flows: Known gaps (with RM ticket): N/A Issue: 2907859 Change-Id: I0c0a753299e33d9651169907cdd6314e3f031f50 Signed-off-by: ashargorodsk --- dev_mgt/tools_dev_types.c | 9 +++++++++ dev_mgt/tools_dev_types.h | 4 +++- flint/subcommands.cpp | 1 + mflash/mflash.c | 2 ++ mflash/mflash_dev_capability.c | 3 +++ tools_res_mgmt/tools_res_mgmt.c | 5 +++++ 6 files changed, 23 insertions(+), 1 deletion(-) diff --git a/dev_mgt/tools_dev_types.c b/dev_mgt/tools_dev_types.c index f8fdee0d..3d8ac9f7 100644 --- a/dev_mgt/tools_dev_types.c +++ b/dev_mgt/tools_dev_types.c @@ -459,6 +459,15 @@ static struct device_info g_devs_info[] = { -1, //port_num NEED_CHECK DM_GEARBOX //dev_type }, + { + DeviceAbirGearBox, //dm_id + 0x256, //hw_dev_id + -1, //hw_rev_id + -1, //sw_dev_id + "Abir GearBox Managaer",//name + -1, //port_num NEED_CHECK + DM_GEARBOX //dev_type + }, { DeviceUnknown, //dm_id 0, //hw_dev_id diff --git a/dev_mgt/tools_dev_types.h b/dev_mgt/tools_dev_types.h index 0efb37ac..79ab714c 100644 --- a/dev_mgt/tools_dev_types.h +++ b/dev_mgt/tools_dev_types.h @@ -105,6 +105,7 @@ enum dm_dev_id DeviceQuantum2, // Blackbird DeviceGearBox, DeviceGearBoxManager, + DeviceAbirGearBox, DeviceCableCMIS, DeviceCableCMISPaging, DeviceEndMarker // Dummy Device - Marker for indicating end of devices when iterating @@ -148,7 +149,8 @@ enum hw_dev_id DeviceSpectrum3_HwId = 0x250, DeviceSpectrum4_HwId = 0x254, DeviceGearBox_HwId = 0x252, - DeviceGearBoxManager_HwId = 0x253 + DeviceGearBoxManager_HwId = 0x253, + DeviceAbirGearBox_HwId = 0x256 }; typedef enum dm_dev_id dm_dev_id_t; diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index 2069e14f..4853a130 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -4103,6 +4103,7 @@ bool SwResetSubCommand::IsDeviceSupported(dm_dev_id_t dev_id) case DeviceSecureHost: case DeviceGearBox: case DeviceGearBoxManager: + case DeviceAbirGearBox: reportErr(true, "The device type %d is not supported.\n", dev_id); return false; default: diff --git a/mflash/mflash.c b/mflash/mflash.c index 81868a92..1b71b141 100644 --- a/mflash/mflash.c +++ b/mflash/mflash.c @@ -2733,6 +2733,7 @@ int mf_set_reset_flash_on_warm_reboot(mflash *mfl) case DeviceSpectrum4: case DeviceGearBox: case DeviceGearBoxManager: + case DeviceAbirGearBox: set_reset_bit_dword_addr = 0xf0c28; set_reset_bit_offset = 2; break; @@ -2779,6 +2780,7 @@ int mf_update_boot_addr(mflash *mfl, u_int32_t boot_addr) case DeviceSpectrum3: case DeviceGearBox: case DeviceGearBoxManager: + case DeviceAbirGearBox: boot_cr_space_address = 0xf0080; offset_in_address = 0; break; diff --git a/mflash/mflash_dev_capability.c b/mflash/mflash_dev_capability.c index 3a090bfa..105de5fe 100644 --- a/mflash/mflash_dev_capability.c +++ b/mflash/mflash_dev_capability.c @@ -75,6 +75,7 @@ int is_four_byte_address_needed(mflash *mfl, MfError *status) case DeviceBlueField3: case DeviceGearBox: case DeviceGearBoxManager: + case DeviceAbirGearBox: return 1; default: *status = MFE_UNSUPPORTED_DEVICE; @@ -117,6 +118,7 @@ int is_flash_enable_needed(mflash *mfl, MfError *status) case DeviceSecureHost: case DeviceGearBox: case DeviceGearBoxManager: + case DeviceAbirGearBox: return 0; default: *status = MFE_UNSUPPORTED_DEVICE; @@ -155,6 +157,7 @@ int is_icmdif_supported(mflash *mfl, MfError *status, int *is7NmSuppported) case DeviceConnectX6LX: case DeviceGearBox: case DeviceGearBoxManager: + case DeviceAbirGearBox: *is7NmSuppported = 0; return 1; case DeviceQuantum2: diff --git a/tools_res_mgmt/tools_res_mgmt.c b/tools_res_mgmt/tools_res_mgmt.c index 208b5a1b..610eff96 100644 --- a/tools_res_mgmt/tools_res_mgmt.c +++ b/tools_res_mgmt/tools_res_mgmt.c @@ -206,6 +206,11 @@ static struct device_sem_info g_dev_sem_info_db[] = { {0xa68f8}, // hw_sem_addr 1, // vsec_sem_supported }, + { + DeviceAbirGearBox, // dev_id + {0xe74e0}, // hw_sem_addr + 1, // vsec_sem_supported + }, }; #define MAX_SEMAPHORE_ADDRES 8 From 00851f60aa703b4d4c2f0c031c3701a22272c10f Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Mon, 17 Jan 2022 21:03:42 +0200 Subject: [PATCH 065/184] Support Abir GB Description: Supporting Abir GB flash GW Tested OS: Linux/PLD Tested devices: Abir Tested flows: flint rb/clear_semaphore/verify (partially)/query Known gaps (with RM ticket): N/A Issue: 2938484 Change-Id: I36d00163e2680fdc87820d860d84a4d387c29a14 Signed-off-by: ashargorodsk --- mflash/mflash_dev_capability.c | 2 +- mlxfwops/lib/fw_ops.cpp | 4 ++- mlxfwops/lib/mlxfwops_com.h | 60 ++++++++++++++++++---------------- 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/mflash/mflash_dev_capability.c b/mflash/mflash_dev_capability.c index 105de5fe..f5ccc951 100644 --- a/mflash/mflash_dev_capability.c +++ b/mflash/mflash_dev_capability.c @@ -157,13 +157,13 @@ int is_icmdif_supported(mflash *mfl, MfError *status, int *is7NmSuppported) case DeviceConnectX6LX: case DeviceGearBox: case DeviceGearBoxManager: - case DeviceAbirGearBox: *is7NmSuppported = 0; return 1; case DeviceQuantum2: case DeviceSpectrum4: case DeviceConnectX7: case DeviceBlueField3: + case DeviceAbirGearBox: *is7NmSuppported = 1; return 1; default: diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 8caf29f8..9859c0be 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -1189,6 +1189,7 @@ const FwOperations::HwDevData FwOperations::hwDevData[] = { { "Spectrum4", SPECTRUM4_HW_ID, CT_SPECTRUM4, CFT_SWITCH, 0, {53120, 0}, {{UNKNOWN_BIN, {0}}}}, { "Gearbox", GEARBOX_HW_ID, CT_GEARBOX, CFT_GEARBOX, 0, {0, 0}, {{UNKNOWN_BIN, {0}}}}, { "GearboxManager", GB_MANAGER_HW_ID, CT_GEARBOX_MGR, CFT_GEARBOX, 0, {0, 0}, {{UNKNOWN_BIN, {0}}}}, + { "AbirGearbox", ABIR_GB_HW_ID, CT_ABIR_GEARBOX, CFT_GEARBOX, 0, {0, 0}, {{UNKNOWN_BIN, {0}}}}, { (char*)NULL, 0, CT_UNKNOWN, CFT_UNKNOWN, 0, {0}, {{UNKNOWN_BIN, {0}}}},// zero devid terminator }; @@ -2296,7 +2297,8 @@ u_int8_t FwOperations::GetFwFormatFromHwDevID(u_int32_t hwDevId) hwDevId == SPECTRUM2_HW_ID || hwDevId == SPECTRUM3_HW_ID || hwDevId == GEARBOX_HW_ID || - hwDevId == GB_MANAGER_HW_ID) { + hwDevId == GB_MANAGER_HW_ID || + hwDevId == ABIR_GB_HW_ID) { return FS_FS4_GEN; } return FS_UNKNOWN_IMG; diff --git a/mlxfwops/lib/mlxfwops_com.h b/mlxfwops/lib/mlxfwops_com.h index a49f6f6e..78b2e62f 100644 --- a/mlxfwops/lib/mlxfwops_com.h +++ b/mlxfwops/lib/mlxfwops_com.h @@ -59,35 +59,36 @@ #define EFIAPI #endif -#define CONNECTX_HW_ID 400 -#define SWITCHX_HW_ID 581 -#define SWITCH_IB_HW_ID 583 -#define SPECTRUM_HW_ID 585 -#define SWITCH_IB2_HW_ID 587 -#define QUANTUM_HW_ID 589 -#define SPECTRUM2_HW_ID 590 -#define SPECTRUM3_HW_ID 592 -#define QUANTUM2_HW_ID 599 -#define SPECTRUM4_HW_ID 596 -#define GEARBOX_HW_ID 594 -#define GB_MANAGER_HW_ID 595 -#define CX4_HW_ID 521 -#define CX4LX_HW_ID 523 -#define CX5_HW_ID 525 -#define CX6_HW_ID 527 -#define CX6DX_HW_ID 530 -#define CX6LX_HW_ID 534 -#define CX7_HW_ID 536 -#define BF_HW_ID 529 -#define BF2_HW_ID 532 -#define BF3_HW_ID 540 -#define CX2_HW_ID 400 -#define CX3_HW_ID 501 -#define CX3_PRO_HW_ID 503 -#define IS4_HW_ID 435 -#define CONNECT_IB_HW_ID 511 +#define CONNECTX_HW_ID 400 +#define SWITCHX_HW_ID 581 +#define SWITCH_IB_HW_ID 583 +#define SPECTRUM_HW_ID 585 +#define SWITCH_IB2_HW_ID 587 +#define QUANTUM_HW_ID 589 +#define SPECTRUM2_HW_ID 590 +#define SPECTRUM3_HW_ID 592 +#define QUANTUM2_HW_ID 599 +#define SPECTRUM4_HW_ID 596 +#define GEARBOX_HW_ID 594 +#define GB_MANAGER_HW_ID 595 +#define ABIR_GB_HW_ID 598 +#define CX4_HW_ID 521 +#define CX4LX_HW_ID 523 +#define CX5_HW_ID 525 +#define CX6_HW_ID 527 +#define CX6DX_HW_ID 530 +#define CX6LX_HW_ID 534 +#define CX7_HW_ID 536 +#define BF_HW_ID 529 +#define BF2_HW_ID 532 +#define BF3_HW_ID 540 +#define CX2_HW_ID 400 +#define CX3_HW_ID 501 +#define CX3_PRO_HW_ID 503 +#define IS4_HW_ID 435 +#define CONNECT_IB_HW_ID 511 #define INBAND_MAX_REG_SIZE 44 -#define MCDA_REG_HEADER 16 +#define MCDA_REG_HEADER 16 typedef enum { PROG_WITH_PRECENTAGE, @@ -297,7 +298,8 @@ typedef enum chip_type { CT_QUANTUM2, CT_SPECTRUM4, CT_GEARBOX, - CT_GEARBOX_MGR + CT_GEARBOX_MGR, + CT_ABIR_GEARBOX } chip_type_t; #define IS_HCA(chipType) \ From 79bf71c84ade73654efbf5f29a25cd716ccf5bd8 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Thu, 20 Jan 2022 21:39:50 +0200 Subject: [PATCH 066/184] In case of devices after Carmel we'll ignore boot-record CRC for fw-update signature Description: Same as secure-boot signature we need to ignore boot-record CRC since it'll be replaced by auth-tag once encrypted Tested OS: Linux Tested devices: BF3 Tested flows: flint rsa_sign Known gaps (with RM ticket): N/A Issue: 2942443 Change-Id: I2b8cb152ab6b5a90508fc63ab352bd780b45c762 Signed-off-by: ashargorodsk --- mlxfwops/lib/fs4_ops.cpp | 22 ++++++++++++++++++++++ mlxfwops/lib/fs4_ops.h | 1 + 2 files changed, 23 insertions(+) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 0cfcda79..ed3062c8 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -512,6 +512,20 @@ void Fs4Operations::RemoveCRCsFromMainSection(vector& img) { img = tmp_img; } +/* + This function responsible on removing boot-record last 4B of CRC +*/ +bool Fs4Operations::RemoveCRCFromBootRecord(vector& img) { + u_int32_t boot_record_size_without_crc = 0; + if (!getBootRecordSize(boot_record_size_without_crc)) { + return errmsg("Failed to get boot_record size\n"); + } + u_int32_t boot_record_crc_addr = _boot_record_ptr + boot_record_size_without_crc; + img.erase(img.begin() + boot_record_crc_addr, img.begin() + boot_record_crc_addr + 4); // Pop 4B of CRC + + return true; +} + bool Fs4Operations::GetImageDataForSign(MlxSign::SHAType shaType, vector& img) { if (!Fs3Operations::GetImageDataForSign(shaType, img)) { return false; @@ -519,7 +533,15 @@ bool Fs4Operations::GetImageDataForSign(MlxSign::SHAType shaType, vector& img); + bool RemoveCRCFromBootRecord(vector& img); // Members Fs4ImgInfo _fs4ImgInfo; From 0f0c0e4656cdd08a7f1099327a9cc7fedee65a7b Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Fri, 21 Jan 2022 14:35:52 +0200 Subject: [PATCH 067/184] Support BF3 global image status Description: N/A Tested OS: N/A Tested devices: N/A Tested flows: N/A Known gaps (with RM ticket): N/A Issue: None Change-Id: Ied955706babef12d70d328995f311416e930d59f Signed-off-by: ashargorodsk --- mlxfwops/lib/fw_ops.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 9859c0be..6114d09f 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -2597,6 +2597,7 @@ int CRSpaceRegisters::getGlobalImageStatus() case CT_CONNECTX6LX: case CT_CONNECTX7: case CT_BLUEFIELD2: + case CT_BLUEFIELD3: global_image_status_address = 0xE3044; break; case CT_QUANTUM2: From 80480d7445a10fc310096bc96df71f0b7d81c5cb Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Mon, 21 Feb 2022 14:35:07 +0200 Subject: [PATCH 068/184] [flint|mlxfwops] Update section hash in hashes_table implementation Description: Once a section gets updated we need to update its hash in hashes_table (if needed). This update must occur AFTER updating the section data and its matching ITOC entry in the file/flash, otherwise we'll fail on CRC error Tested OS: Linux Tested devices: Carmel Tested flows: flint_oem -i carmel_with_forbid_2.bin set_forbidden_versions forbidden.bin Known gaps (with RM ticket): N/A Issue: 2940476 2934898 --- mlxfwops/lib/fs4_ops.cpp | 70 ++++++++++++++++++++++++++++++++-------- mlxfwops/lib/fs4_ops.h | 12 ++++--- 2 files changed, 63 insertions(+), 19 deletions(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index ed3062c8..3f82d197 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -2756,7 +2756,7 @@ bool Fs4Operations::UpdateCertChainSection(struct fs4_toc_info *curr_toc, char * //* Assert given certificate chain doesn't exceed its allocated size u_int32_t cert_chain_0_section_size = curr_toc->toc_entry.size << 2; if ((u_int32_t)cert_chain_buff_size > cert_chain_0_section_size) { - return errmsg("Attestation certificate chain data exceeds its allocated size of 0x%xB", cert_chain_0_section_size); + return errmsg("Attestation certificate chain data exceeds its allocated size of 0x%x bytes", cert_chain_0_section_size); } newSectionData.resize(cert_chain_0_section_size, 0); // Init section data with 0x0 @@ -2793,8 +2793,9 @@ bool Fs4Operations::Fs4UpdateVpdSection(struct fs4_toc_info *curr_toc, char *vpd return true; } -bool Fs4Operations::Fs4ReburnSection(u_int32_t newSectionAddr, - u_int32_t newSectionSize, std::vector newSectionData, const char *msg, PrintCallBack callBackFunc) +bool Fs4Operations::Fs4ReburnSection(u_int32_t newSectionAddr, u_int32_t newSectionSize, + std::vector newSectionData, const char *msg, + PrintCallBack callBackFunc) { char message[127]; @@ -2822,17 +2823,15 @@ bool Fs4Operations::Fs4ReburnSection(u_int32_t newSectionAddr, return true; } -bool Fs4Operations::calcHashOnItoc(vector& hash, u_int32_t itoc_addr) { - //* Get ITOC data as vector of bytes +bool Fs4Operations::CalcHashOnSection(u_int32_t addr, u_int32_t size, vector& hash) { #if !defined(NO_OPEN_SSL) && !defined(NO_DYNAMIC_ENGINE) //mlxSignSHA is only available with OPEN_SSL - vector itoc_data; - u_int32_t itoc_size = _fs4ImgInfo.itocArr.numOfTocs * TOC_ENTRY_SIZE + TOC_HEADER_SIZE; - itoc_data.resize(itoc_size); - READBUF((*_ioAccess), itoc_addr, (u_int32_t*)&itoc_data[0], itoc_size, "Reading ITOC data"); + vector data; + data.resize(size); + READBUF((*_ioAccess), addr, (u_int32_t*)&data[0], size, "Reading section data for hash calculation"); //* Calculate SHA MlxSignSHA512 mlxSignSHA; - mlxSignSHA << itoc_data; + mlxSignSHA << data; mlxSignSHA.getDigest(hash); return true; #else @@ -2841,7 +2840,42 @@ bool Fs4Operations::calcHashOnItoc(vector& hash, u_int32_t itoc_addr) #endif } -bool Fs4Operations::updateHashInHashesTable(fs3_section_t section_type, vector hash) { +bool Fs4Operations::IsSectionShouldBeHashed(fs3_section_t section_type) { + bool res; + switch (section_type) { + case FS3_PUBLIC_KEYS_2048: + case FS3_PUBLIC_KEYS_4096: + case FS4_RSA_PUBLIC_KEY: + case FS3_IMAGE_SIGNATURE_256: + case FS3_IMAGE_SIGNATURE_512: + case FS4_RSA_4096_SIGNATURES: + res = false; + break; + default: + res = true; + } + + return res; +} + +bool Fs4Operations::UpdateSectionHashInHashesTable(u_int32_t addr, u_int32_t size, fs3_section_t type) { + if (getSecureBootSignVersion() == VERSION_2 && IsSectionShouldBeHashed(type)) { + DPRINTF(("Fs4Operations::UpdateSectionHashInHashesTable type=0x%x\n", type)); + + vector hash; + if (!CalcHashOnSection(addr, size, hash)) { + return errmsg("Failed to calculate section hash"); + } + + if (!UpdateHashInHashesTable(type, hash)) { + return false; + } + } + + return true; +} + +bool Fs4Operations::UpdateHashInHashesTable(fs3_section_t section_type, vector hash) { //* Init HTOC vector img; FwInit(); @@ -2969,12 +3003,14 @@ bool Fs4Operations::reburnITocSection(PrintCallBack callBackFunc, bool isFailSaf } if (getSecureBootSignVersion() == VERSION_2) { - //* Calculate SHA-512 on ITOC + vector hash; - if (!calcHashOnItoc(hash, newITocAddr)) { + u_int32_t itocSize = _fs4ImgInfo.itocArr.numOfTocs * TOC_ENTRY_SIZE + TOC_HEADER_SIZE; + if (!CalcHashOnSection(newITocAddr, itocSize, hash)) { return errmsg("Failed to calculate ITOC hash"); } - if (!updateHashInHashesTable(FS3_ITOC, hash)) { + + if (!UpdateHashInHashesTable(FS3_ITOC, hash)) { return false; } } @@ -3305,6 +3341,12 @@ bool Fs4Operations::UpdateSection(void *new_info, fs3_section_t sect_type, bool, } } + if (!UpdateSectionHashInHashesTable(newSectionAddr, curr_toc->toc_entry.size * 4, sect_type)) { + return false; + } + + + // TODO - in case hashes_table (HTOC) exists recalculate modified section SHA and store it in hashes_table. // TODO - Currently it's not implemented since there is no use-case where we need to update hashes_table, // TODO - so we prefer to ignore it for now instead of inserting a potential bug. diff --git a/mlxfwops/lib/fs4_ops.h b/mlxfwops/lib/fs4_ops.h index 2ec28383..8624b40e 100644 --- a/mlxfwops/lib/fs4_ops.h +++ b/mlxfwops/lib/fs4_ops.h @@ -197,9 +197,9 @@ class Fs4Operations : public Fs3Operations { bool UpdateCertChainSection(struct fs4_toc_info *curr_toc, char *certChainFile, std::vector &newSectionData); bool FwSetCertChain(char *certFileStr, PrintCallBack callBackFunc); - bool Fs4ReburnSection(u_int32_t newSectionAddr, - u_int32_t newSectionSize, std::vector newSectionData, - const char *msg, PrintCallBack callBackFunc); + bool Fs4ReburnSection(u_int32_t newSectionAddr, u_int32_t newSectionSize, + std::vector newSectionData, const char *msg, + PrintCallBack callBackFunc); bool Fs4ReburnTocSection(bool isDtoc, PrintCallBack callBackFunc); bool reburnDTocSection(PrintCallBack callBackFunc); bool reburnITocSection(PrintCallBack callBackFunc, bool isFailSafe); @@ -262,8 +262,10 @@ class Fs4Operations : public Fs3Operations { bool GetSectionSizeAndOffset(fs3_section_t sectType, u_int32_t& size, u_int32_t& offset); SecureBootSignVersion getSecureBootSignVersion(); - bool calcHashOnItoc(vector& hash, u_int32_t itoc_addr); - bool updateHashInHashesTable(fs3_section_t section_type, vector hash); + bool CalcHashOnSection(u_int32_t addr, u_int32_t size, vector& hash); + bool UpdateHashInHashesTable(fs3_section_t section_type, vector hash); + bool UpdateSectionHashInHashesTable(u_int32_t addr, u_int32_t size, fs3_section_t type); + bool IsSectionShouldBeHashed(fs3_section_t section_type); bool QuerySecurityFeatures(); bool IsEncryptedDevice(bool& is_encrypted); bool IsEncryptedImage(bool& is_encrypted); From 6d9b07217e5c9850d97d93bf8b065d29b83f3955 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Mon, 31 Jan 2022 17:47:26 +0200 Subject: [PATCH 069/184] cr0 interface fails Description: reg access fails due to timeout from icmd interface. icmd semaphore address for albatross updated to correct address. Tested OS: linux Tested devices: albatross protium model Tested flows: flint query Known gaps (with RM ticket): N/A Issue: 2953661 Change-Id: I05408f9bb2858d61dc5eba39896808655a7251d7 Signed-off-by: ashargorodsk --- dev_mgt/tools_dev_types.c | 2 +- fw_comps_mgr/fw_comps_mgr.cpp | 3 +++ mflash/mflash.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dev_mgt/tools_dev_types.c b/dev_mgt/tools_dev_types.c index 3d8ac9f7..44a22b0a 100644 --- a/dev_mgt/tools_dev_types.c +++ b/dev_mgt/tools_dev_types.c @@ -857,7 +857,7 @@ int dm_is_new_gen_switch(dm_dev_id_t type) int dm_dev_is_raven_family_switch(dm_dev_id_t type) { - return (dm_dev_is_switch(type) && (type == DeviceQuantum || type == DeviceQuantum2 || type == DeviceSpectrum2 || type == DeviceSpectrum3)); + return (dm_dev_is_switch(type) && (type == DeviceQuantum || type == DeviceQuantum2 || type == DeviceSpectrum2 || type == DeviceSpectrum3 || type == DeviceSpectrum4)); } int dm_dev_is_ib_switch(dm_dev_id_t type) diff --git a/fw_comps_mgr/fw_comps_mgr.cpp b/fw_comps_mgr/fw_comps_mgr.cpp index 23d6eccf..905b1cea 100644 --- a/fw_comps_mgr/fw_comps_mgr.cpp +++ b/fw_comps_mgr/fw_comps_mgr.cpp @@ -2228,6 +2228,9 @@ void FwCompsMgr::setLastRegisterAccessStatus(reg_access_status_t err) fw_comps_error_t FwCompsMgr::regErrTrans(reg_access_status_t err) { + if (err != ME_REG_ACCESS_OK) { + DPRINTF(("%s error - %d\n",__FUNCTION__, err)); + } switch (err) { case ME_REG_ACCESS_OK: return FWCOMPS_REG_ACCESS_OK; diff --git a/mflash/mflash.c b/mflash/mflash.c index 1b71b141..85b225e1 100644 --- a/mflash/mflash.c +++ b/mflash/mflash.c @@ -1497,7 +1497,7 @@ int check_cache_replacement_guard(mflash *mfl, u_int8_t *needs_cache_replacement cmd = EXTRACT(data, 16, 8); } else { // switches - if (devid_t == DeviceQuantum2) { + if (devid_t == DeviceQuantum2 || devid_t == DeviceSpectrum4) { MREAD4(CACHE_REP_OFF_BLACKBIRD, &data); off = data; MREAD4(CACHE_REP_CMD_BLACKBIRD, &data); From d3331ac112357eb15c7bf4e4d99629ab1df7bac1 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Tue, 1 Feb 2022 13:34:12 +0200 Subject: [PATCH 070/184] No support for LinkX Burning & Querying with Bagheera200 module Description: Added support for cable query and burn on Carmel Tested OS: Linux Tested devices: Cx7 Tested flows: Flint Query/Burn Known gaps (with RM ticket): N/A Issue: 2937866 Change-Id: Iee7eab255633ae26b3786a552c474898bdfa5fef Signed-off-by: ashargorodsk --- mlxfwops/lib/signature_manager.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mlxfwops/lib/signature_manager.h b/mlxfwops/lib/signature_manager.h index 80f89c6a..34555b15 100644 --- a/mlxfwops/lib/signature_manager.h +++ b/mlxfwops/lib/signature_manager.h @@ -116,7 +116,8 @@ class ConnectX6DXFwOperationsSignatureManager : public AbstractSignatureManager ConnectX6DXFwOperationsSignatureManager() : AbstractSignatureManager() {} virtual ~ConnectX6DXFwOperationsSignatureManager() {} virtual bool IsLifeCycleSupported() { return true; } - virtual bool IsSecureBootSupported() { return true; } + virtual bool IsSecureBootSupported() { return true; } + virtual bool IsCableQuerySupported() { return true; } }; class ConnectX6LXFwOperationsSignatureManager : public ConnectX6DXFwOperationsSignatureManager From 07604608f7bc9e387513bc8915d999f122b437a5 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Thu, 3 Feb 2022 09:18:46 +0200 Subject: [PATCH 071/184] Support signing Albatross and Abir Description: Albatross and Abir boot-record size added Tested OS: Linux Tested devices: Abir Tested flows: mlxburn -fw <> -c <> -wrimage Known gaps (with RM ticket): N/A Issue: 2959749 Change-Id: Ibd9ca58f7cc55e19b6bf6c6b9e2a2ba6c8bc1182 Signed-off-by: ashargorodsk --- mlxfwops/lib/fs4_ops.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 3f82d197..c4cd9eb6 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -3635,7 +3635,13 @@ bool Fs4Operations::getBootRecordSize(u_int32_t& boot_record_size) { // For devices after Carmel we need to ignore the last 4B (CRC/auth-tag) case CT_BLUEFIELD3: boot_record_size = 0x4d0; // Actual size is 0x4d4 - return true; + return true; + case CT_SPECTRUM4: + boot_record_size = 0x4f0; // Actual size is 0x4f4 + return true; + case CT_ABIR_GEARBOX: + boot_record_size = 0x3fc; // Actual size is 0x400 + return true; default: return false; From 2a6de99cb44bc04b37a8fbecf3c5e4eae1cc7888 Mon Sep 17 00:00:00 2001 From: Roei Yitzhak Date: Thu, 3 Feb 2022 13:57:44 +0200 Subject: [PATCH 072/184] new behaviour for level 4 (warm reboot) Description: 1. level 5 won't send MFRL (exit immediately) 2. level 4 will reboot the machine only after sync between the hosts 3. level 4 will set bits 3 and 6 for the MFRL.reset_trigger Tested OS: Tested devices: Tested flows: Known gaps (with RM ticket): End to end is not checked (FW doesn't support it yet) Issue: 2957718 Change-Id: I5bc5b7b02c5d6173d104bfc763dbc810263ab962 Signed-off-by: ashargorodsk --- small_utils/mlxfwresetlib/cmd_reg_mfrl.py | 2 +- small_utils/mstfwreset.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/small_utils/mlxfwresetlib/cmd_reg_mfrl.py b/small_utils/mlxfwresetlib/cmd_reg_mfrl.py index 1e8c84c5..1e0aa1cd 100755 --- a/small_utils/mlxfwresetlib/cmd_reg_mfrl.py +++ b/small_utils/mlxfwresetlib/cmd_reg_mfrl.py @@ -38,7 +38,7 @@ class CmdRegMfrl(): reset_levels_db = [ {'level': LIVE_PATCH, 'description': 'Driver, PCI link, network link will remain up ("live-Patch")', 'mask' : 0x1, 'support_reset_type': False}, {'level': PCI_RESET, 'description': 'Driver restart and PCI reset', 'mask' : 0x8, 'support_reset_type': True}, - {'level': WARM_REBOOT, 'description': 'Warm Reboot', 'mask' : 0x40, 'support_reset_type': True}, + {'level': WARM_REBOOT, 'description': 'Warm Reboot', 'mask' : 0x48, 'support_reset_type': True}, {'level': COLD_REBOOT, 'description': 'Cold Reboot', 'mask' : 0x80, 'support_reset_type': False} ] diff --git a/small_utils/mstfwreset.py b/small_utils/mstfwreset.py index 2803802f..3a818210 100644 --- a/small_utils/mstfwreset.py +++ b/small_utils/mstfwreset.py @@ -1374,6 +1374,12 @@ def resetFlow(device, devicesSD, reset_level, reset_type, cmdLineArgs, mfrl): if reset_level == CmdRegMfrl.PCI_RESET: # reset PCI resetPciAddr(device,devicesSD,driverObj, cmdLineArgs) + elif reset_level == CmdRegMfrl.WARM_REBOOT: + if SkipMultihostSync or not CmdifObj.isMultiHostSyncSupported(): + stopDriver(driverObj) + else: + stopDriverSync(driverObj) + rebootMachine() # Wait for FW to be ready to get ICMD try: @@ -1440,16 +1446,12 @@ def execResLvl(device, devicesSD, reset_level, reset_type, reset_sync, cmdLineAr if reset_level == mfrl.LIVE_PATCH: send_reset_cmd_to_fw(mfrl, reset_level, reset_type) - elif reset_level == mfrl.PCI_RESET: + elif reset_level in [mfrl.PCI_RESET, mfrl.WARM_REBOOT]: if reset_sync == SyncOwner.DRIVER: send_reset_cmd_to_fw(mfrl, reset_level, reset_type, reset_sync) else: resetFlow(device, devicesSD, reset_level, reset_type, cmdLineArgs, mfrl) - elif reset_level == mfrl.WARM_REBOOT: - send_reset_cmd_to_fw(mfrl, reset_level, reset_type) - rebootMachine() elif reset_level == mfrl.COLD_REBOOT: - send_reset_cmd_to_fw(mfrl, mfrl.WARM_REBOOT, reset_type) print("-I- Cold reboot required. please power cycle machine to load new FW.") else: raise RuntimeError("Unknown reset level") @@ -1762,12 +1764,10 @@ def check_positive_float(val): print("{0} reset level for device, {1}:\n".format(minimal_or_requested , device)) print("{0}: {1}".format(reset_level,mfrl.reset_level_description(reset_level))) - if (reset_level == 4): - print("\n-W- Note that reset in this level (4) is not supported on multi-host setups and Bluefield devices\n") AskUser("Continue with reset", yes) execResLvl(device, devicesSD, reset_level, reset_type, reset_sync, args, mfrl) - if reset_level != CmdRegMfrl.COLD_REBOOT and reset_level != CmdRegMfrl.WARM_REBOOT: + if reset_level != CmdRegMfrl.COLD_REBOOT: if FWResetStatusChecker.GetStatus() == FirmwareResetStatusChecker.FirmwareResetStatusFailed: reset_fsm_register() print("-E- Firmware reset failed, retry operation or reboot machine.") From 468826ff1c67718f8b07f1ecec389f4d248f5476 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Mon, 21 Feb 2022 15:06:57 +0200 Subject: [PATCH 073/184] [mlxfwreset] bug fix - multi-host sync optimization Description: In the current implementation the "sleep" in the mult-host synchronization code is 0.5 sec. It's too much when we want to sync a Windows host where the PCI link toggle sleep is only 100msec Tested OS:Windows Tested devices:BF2 Tested flows:reset Known gaps (with RM ticket): 2938334 Issue: --- small_utils/mstfwreset.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/small_utils/mstfwreset.py b/small_utils/mstfwreset.py index 3a818210..81fb2174 100644 --- a/small_utils/mstfwreset.py +++ b/small_utils/mstfwreset.py @@ -1261,7 +1261,7 @@ def reloadDriver(driverObj): if print_waiting_msg and diffTime > 2: print("Waiting for %s to run on all other hosts, press 'ctrl+c' to abort" % PROG) print_waiting_msg = False - time.sleep(0.5) + time.sleep(0.01) logger.debug('[Timing Test] MH SYNC state is GO') if status.fsm_state != SYNC_STATE_GO or status.fsm_sync_type != SYNC_TYPE_FW_RESET: @@ -1293,7 +1293,7 @@ def reloadDriver(driverObj): if print_waiting_msg and diffTime > 2: print("Synchronizing with other hosts...") print_waiting_msg = False - time.sleep(0.5) + time.sleep(0.01) logger.debug('[Timing Test] MH SYNC done') From 26667c87c56320050c1ccbc4eb87628a7bec3ea8 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Wed, 2 Feb 2022 20:28:17 +0200 Subject: [PATCH 074/184] Toggle GPIO feature Description: In case CX6/CX6DX/BF2/CX7 in livefish mode and direct-access flint will toggle GPIO in order to force flash out of HOLD state Tested OS: Linux Tested devices: Carmel (apps-113) with second source flash Tested flows: flint -ocr query/hw query Known gaps (with RM ticket): Can't determine livefish mode in case of MTUSB #2917335 Issue: 2917339 Change-Id: I400f83371509bbbbbee5c2f5d3fa7dae74970a64 Signed-off-by: ashargorodsk --- mflash/mflash.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++-- mflash/mflash.h | 18 +++++ 2 files changed, 214 insertions(+), 7 deletions(-) diff --git a/mflash/mflash.c b/mflash/mflash.c index 85b225e1..d78f3056 100644 --- a/mflash/mflash.c +++ b/mflash/mflash.c @@ -1558,7 +1558,7 @@ int release_semaphore(mflash *mfl, int ignore_writer_lock) return MFE_OK; } -int gen6_flash_init_com(mflash *mfl, flash_params_t *flash_params, u_int8_t init_cs_support) +int gen6_flash_init_com(mflash *mfl, flash_params_t *flash_params) { int rc = 0; FLASH_ACCESS_DPRINTF(("gen6_flash_init_com(): Flash init to use direct-access\n")); @@ -1584,11 +1584,6 @@ int gen6_flash_init_com(mflash *mfl, flash_params_t *flash_params, u_int8_t init mfl->f_sst_spi_block_write_ex = new_gw_sst_spi_block_write_ex; mfl->f_st_spi_block_read_ex = new_gw_st_spi_block_read_ex; mfl->f_spi_write_status_reg = new_gw_spi_write_status_reg; - if (init_cs_support) { - // Update the chip_select_support according to the banks number of cs. - rc = sx_init_cs_support(mfl); - CHECK_RC(rc); - } mfl->f_spi_status = cntx_st_spi_get_status;//need fix mfl->supp_sr_mod = 1; @@ -1706,7 +1701,7 @@ int sixth_gen_init_direct_access(mflash *mfl, flash_params_t *flash_params) mfl->gcm_en_addr = HCR_NEW_GW_GCM_EN_ADDR; mfl->f_lock = sixth_gen_flash_lock; - return gen6_flash_init_com(mfl, flash_params, 0); + return gen6_flash_init_com(mfl, flash_params); } int fifth_gen_init_direct_access(mflash *mfl, flash_params_t *flash_params) @@ -2241,6 +2236,195 @@ int get_dev_info(mflash *mfl) return MFE_OK; } + +void set_gpio_toggle_conf_cx6(gpio_toggle_conf_cx6* conf) { + conf->lock_addr = 0xf1004; + conf->functional_enable0_addr = 0xfc028; + conf->functional_enable1_addr = 0xfc024; + conf->mode1_set_addr = 0xfc04c; + conf->mode0_set_addr = 0xfc054; + conf->dataset_addr = 0xfc014; +} + +void set_gpio_toggle_conf_bf2(gpio_toggle_conf_cx6* conf) { + conf->lock_addr = 0xf1084; + conf->functional_enable0_addr = 0xfa028; + conf->functional_enable1_addr = 0xfa024; + conf->mode1_set_addr = 0xfa04c; + conf->mode0_set_addr = 0xfa054; + conf->dataset_addr = 0xfa014; +} + +void set_gpio_toggle_conf_cx7(gpio_toggle_conf_cx7* conf) { + conf->select_synced_data_out_addr = 0xf1078; + conf->fw_control_set_addr = 0xf1100; + conf->hw_data_in_addr = 0xf1078; + conf->fw_output_enable_set_addr = 0xf1104; + conf->fw_data_out_set_addr = 0xf1108; +} + +bool toggle_flash_io3_gpio_cx6(mfile* mf, gpio_toggle_conf_cx6 conf) { + FLASH_DPRINTF(("toggle_flash_io3_gpio_cx6\n")); + // Enable lock + if (mwrite4(mf, conf.lock_addr, 0xd42f) != 4) { + printf("-E- failed to enable GPIO lock\n"); + return MFE_CR_ERROR; + } + + //* Make sure GPIO 29 is controlled by FW (for our usage) instead of HW + // Enable functional_enable0 + u_int32_t functional_enable0 = 0; + if (mread4(mf, conf.functional_enable0_addr, &functional_enable0) != 4) { + printf("-E- failed to read functional_enable0\n"); + return MFE_CR_ERROR; + } + functional_enable0 = functional_enable0 & 0xdfffffff; + if (mwrite4(mf, conf.functional_enable0_addr, functional_enable0) != 4) { + printf("-E- failed to enable GPIO functional_enable0\n"); + return MFE_CR_ERROR; + } + // Enable functional_enable1 + u_int32_t functional_enable1 = 0; + if (mread4(mf, conf.functional_enable1_addr, &functional_enable1) != 4) { + printf("-E- failed to read functional_enable1\n"); + return MFE_CR_ERROR; + } + functional_enable1 = functional_enable1 & 0xdfffffff; + if (mwrite4(mf, conf.functional_enable1_addr, functional_enable1) != 4) { + printf("-E- failed to enable GPIO functional_enable1\n"); + return MFE_CR_ERROR; + } + + // Write to mode1_set + u_int32_t mode1_set = 0; + if (mread4(mf, conf.mode1_set_addr, &mode1_set) != 4) { + printf("-E- failed to read mode1_set\n"); + return MFE_CR_ERROR; + } + mode1_set = mode1_set | 0x20000000; + if (mwrite4(mf, conf.mode1_set_addr, mode1_set) != 4) { + printf("-E- failed to write to mode1_set\n"); + return MFE_CR_ERROR; + } + + //* Write to GPIO 29 + // Write to mode0_set + u_int32_t mode0_set = 0; + if (mread4(mf, conf.mode0_set_addr, &mode0_set) != 4) { + printf("-E- failed to read mode0_set\n"); + return MFE_CR_ERROR; + } + mode0_set = mode0_set | 0x20000000; + if (mwrite4(mf, conf.mode0_set_addr, mode0_set) != 4) { + printf("-E- failed to write to mode0_set\n"); + return MFE_CR_ERROR; + } + + // Write to dataset + if (mwrite4(mf, conf.dataset_addr, 0x20000000) != 4) { + printf("-E- failed to write to dataset\n"); + return MFE_CR_ERROR; + } + + return true; +} + +bool toggle_flash_io3_gpio_cx7(mfile* mf, gpio_toggle_conf_cx7 conf) { + FLASH_DPRINTF(("toggle_flash_io3_gpio_cx7\n")); + // write 0x0 to select_synced_data_out.16:1 + u_int32_t select_synced_data_out = 0; + if (mread4(mf, conf.select_synced_data_out_addr, &select_synced_data_out) != 4) { + printf("-E- failed to read select_synced_data_out\n"); + return MFE_CR_ERROR; + } + select_synced_data_out = select_synced_data_out & 0xfffeffff; + if (mwrite4(mf, conf.select_synced_data_out_addr, select_synced_data_out) != 4) { + printf("-E- failed to write 0x0 to select_synced_data_out.16:1\n"); + return MFE_CR_ERROR; + } + + // write 0x3 to fw_control_set.28:2 + u_int32_t fw_control_set = 0; + if (mread4(mf, conf.fw_control_set_addr, &fw_control_set) != 4) { + printf("-E- failed to read fw_control_set\n"); + return MFE_CR_ERROR; + } + fw_control_set = fw_control_set | 0x30000000; + if (mwrite4(mf, conf.fw_control_set_addr, fw_control_set) != 4) { + printf("-E- failed to write 0x3 to fw_control_set.28:2\n"); + return MFE_CR_ERROR; + } + + // write 0x3 to hw_data_in.4:2 + u_int32_t hw_data_in = 0; + if (mread4(mf, conf.hw_data_in_addr, &hw_data_in) != 4) { + printf("-E- failed to read hw_data_in\n"); + return MFE_CR_ERROR; + } + hw_data_in = hw_data_in | 0x00000030; + if (mwrite4(mf, conf.hw_data_in_addr, hw_data_in) != 4) { + printf("-E- failed to write 0x3 to hw_data_in.4:2\n"); + return MFE_CR_ERROR; + } + + // write 0x3 to fw_output_enable_set.28:2 + u_int32_t fw_output_enable_set = 0; + if (mread4(mf, conf.fw_output_enable_set_addr, &fw_output_enable_set) != 4) { + printf("-E- failed to read fw_output_enable_set\n"); + return MFE_CR_ERROR; + } + fw_output_enable_set = fw_output_enable_set | 0x30000000; + if (mwrite4(mf, conf.fw_output_enable_set_addr, fw_output_enable_set) != 4) { + printf("-E- failed to write 0x3 to fw_output_enable_set.28:2\n"); + return MFE_CR_ERROR; + } + + // write 0x3 to fw_data_out_set.28:2 + u_int32_t fw_data_out_set = 0; + if (mread4(mf, conf.fw_data_out_set_addr, &fw_data_out_set) != 4) { + printf("-E- failed to read fw_data_out_set\n"); + return MFE_CR_ERROR; + } + fw_data_out_set = fw_data_out_set | 0x30000000; + if (mwrite4(mf, conf.fw_data_out_set_addr, fw_data_out_set) != 4) { + printf("-E- failed to write 0x3 to fw_data_out_set.28:2\n"); + return MFE_CR_ERROR; + } + + return true; +} + +bool force_flash_out_of_hold_state(mflash *mfl) { + bool res = true; + if (dm_is_livefish_mode(mfl->mf)) { // TODO - consider moving this after checking if device type should support second source flash + switch (mfl->dm_dev_id) { + case DeviceConnectX6: + case DeviceConnectX6DX: { + gpio_toggle_conf_cx6 gpio_toggle_conf; + set_gpio_toggle_conf_cx6(&gpio_toggle_conf); + res = toggle_flash_io3_gpio_cx6(mfl->mf, gpio_toggle_conf); + break; + } + case DeviceBlueField2: { + gpio_toggle_conf_cx6 gpio_toggle_conf; + set_gpio_toggle_conf_bf2(&gpio_toggle_conf); + res = toggle_flash_io3_gpio_cx6(mfl->mf, gpio_toggle_conf); + break; + } + case DeviceConnectX7: { + gpio_toggle_conf_cx7 gpio_toggle_conf; + set_gpio_toggle_conf_cx7(&gpio_toggle_conf); + res = toggle_flash_io3_gpio_cx7(mfl->mf, gpio_toggle_conf); + break; + } + default: + break; + } + } + + return res; +} + //Caller must zero the mflash struct before calling this func. int mf_open_fw(mflash *mfl, flash_params_t *flash_params, int num_of_banks) { @@ -2272,6 +2456,11 @@ int mf_open_fw(mflash *mfl, flash_params_t *flash_params, int num_of_banks) mfl->opts[MFO_NUM_OF_BANKS] = spi_get_num_of_flashes(num_of_banks); rc = spi_update_num_of_banks(mfl, num_of_banks); CHECK_RC(rc); + + //* Before initializing flash methods (which including accessing the flash) + //* we need to toggle GPIO to get flash out of HOLD state (relevant to second source flash Winbond W25Q256JV) + rc = force_flash_out_of_hold_state(mfl); + int is7NmSuppported = 0; MfError status; int icmdif_supported = is_icmdif_supported(mfl, &status, &is7NmSuppported); diff --git a/mflash/mflash.h b/mflash/mflash.h index 227335de..387dbd63 100644 --- a/mflash/mflash.h +++ b/mflash/mflash.h @@ -108,6 +108,24 @@ EXTERN_C_START #define FLASH_ACCESS_DPRINTF(...) #endif +typedef struct gpio_toggle_conf_cx6 { + u_int32_t lock_addr; + u_int32_t lock_val; + u_int32_t functional_enable0_addr; + u_int32_t functional_enable1_addr; + u_int32_t mode1_set_addr; + u_int32_t mode0_set_addr; + u_int32_t dataset_addr; +} gpio_toggle_conf_cx6; + +typedef struct gpio_toggle_conf_cx7 { + u_int32_t select_synced_data_out_addr; + u_int32_t fw_control_set_addr; + u_int32_t hw_data_in_addr; + u_int32_t fw_output_enable_set_addr; + u_int32_t fw_data_out_set_addr; +} gpio_toggle_conf_cx7; + typedef enum MfCommandSet { CS_INTEL = 1, CS_AMD = 2, From 4df0e150685f1e4a90f1f32e67b8e44da1fefde9 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Sun, 6 Feb 2022 15:36:45 +0200 Subject: [PATCH 075/184] Fixing update section hash in hashes_table Description: Need to exclude DTOC sections Tested OS: Linux Tested devices: Carmel Tested flows: flint set_vpd command Known gaps (with RM ticket): N/A Issue: 2962602 Change-Id: I6e45bcff119085c97fa341065e142884fe65d921 Signed-off-by: ashargorodsk --- mlxfwops/lib/fs4_ops.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index c4cd9eb6..248550b9 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -3341,8 +3341,10 @@ bool Fs4Operations::UpdateSection(void *new_info, fs3_section_t sect_type, bool, } } - if (!UpdateSectionHashInHashesTable(newSectionAddr, curr_toc->toc_entry.size * 4, sect_type)) { - return false; + if (!isDtoc) { + if (!UpdateSectionHashInHashesTable(newSectionAddr, curr_toc->toc_entry.size * 4, sect_type)) { + return false; + } } From 7b23de0f94f94c4471dd57203bbb666e36ef0b79 Mon Sep 17 00:00:00 2001 From: Roei Yitzhak Date: Sun, 6 Feb 2022 16:47:18 +0200 Subject: [PATCH 076/184] Added image_size for query on image Description: Added new field to query on image. The new field indicates on the size of the burned image in bytes Tested OS: Linux Tested devices: Tested flows: Known gaps (with RM ticket): Issue:2962229 Change-Id: I6b589194073a9bbc2b86a76845727675ad78105b Signed-off-by: ashargorodsk --- mlxfwops/lib/fs4_ops.cpp | 21 +++++++++++++++++++++ mlxfwops/lib/fs4_ops.h | 1 + mlxfwops/lib/fw_ops.cpp | 4 ++++ mlxfwops/lib/fw_ops.h | 1 + 4 files changed, 27 insertions(+) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 248550b9..3d379212 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -3500,6 +3500,27 @@ u_int32_t Fs4Operations::getImageSize() return _fwImgInfo.lastImageAddr - _fwImgInfo.imgStart; } +bool Fs4Operations::getImageSize(u_int32_t* image_size){ + + bool is_encrypted; + if (!isEncrypted(is_encrypted)){ + return false; + } + + if (is_encrypted) { + + if (!getEncryptedImageSize(image_size)){ + return false; + } + } else { + *image_size = getImageSize(); + + } + + return true; +} + + void Fs4Operations::MaskItocSectionAndEntry(u_int32_t itocType, vector& img) { for (int i = 0; i < _fs4ImgInfo.itocArr.numOfTocs; i++) { diff --git a/mlxfwops/lib/fs4_ops.h b/mlxfwops/lib/fs4_ops.h index 8624b40e..895812b1 100644 --- a/mlxfwops/lib/fs4_ops.h +++ b/mlxfwops/lib/fs4_ops.h @@ -115,6 +115,7 @@ class Fs4Operations : public Fs3Operations { bool IsLifeCycleAccessible(chip_type_t chip_type); bool IsSecurityVersionViolated(u_int32_t image_security_version); bool GetImageInfo(u_int8_t *buff); + bool getImageSize(u_int32_t* image_size); protected: struct fs4_toc_info { diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 6114d09f..0c4b1598 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -2521,6 +2521,10 @@ bool FwOperations::IsSecurityVersionViolated(u_int32_t) return false; } +bool FwOperations::getImageSize(u_int32_t*){ + return errmsg("GetImageSize is not supported"); +} + #if !defined(UEFI_BUILD) && !defined(NO_OPEN_SSL) bool FwOperations::CheckPemKeySize(const string privPemFileStr, u_int32_t& keySize) { diff --git a/mlxfwops/lib/fw_ops.h b/mlxfwops/lib/fw_ops.h index 36566706..0ddf9d57 100644 --- a/mlxfwops/lib/fw_ops.h +++ b/mlxfwops/lib/fw_ops.h @@ -261,6 +261,7 @@ class MLXFWOP_API FwOperations : public FlintErrMsg { static int getFileSignature(const char *fname); virtual bool IsLifeCycleAccessible(chip_type_t chip_type); virtual bool IsSecurityVersionViolated(u_int32_t image_security_version); + virtual bool getImageSize(u_int32_t* image_size); #ifndef UEFI_BUILD static bool CheckPemKeySize(const string privPemFileStr, u_int32_t& keySize); From fa70af1e9aeb7a5f3a3d26dcc12aad5274e9e0a0 Mon Sep 17 00:00:00 2001 From: Roei Yitzhak Date: Mon, 7 Feb 2022 08:41:40 +0200 Subject: [PATCH 077/184] fix build issues on (freebsd and ARM) for commit 54bbe818 Description: Remove function overloading Tested OS: Tested devices: Tested flows: Known gaps (with RM ticket): Issue:2962229 Change-Id: Iaddec55037d097e3f6615823369b2f1b09e9c35a Signed-off-by: ashargorodsk --- mlxfwops/lib/fs4_ops.cpp | 2 +- mlxfwops/lib/fs4_ops.h | 2 +- mlxfwops/lib/fw_ops.cpp | 2 +- mlxfwops/lib/fw_ops.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 3d379212..349771cf 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -3500,7 +3500,7 @@ u_int32_t Fs4Operations::getImageSize() return _fwImgInfo.lastImageAddr - _fwImgInfo.imgStart; } -bool Fs4Operations::getImageSize(u_int32_t* image_size){ +bool Fs4Operations::GetImageSize(u_int32_t* image_size){ bool is_encrypted; if (!isEncrypted(is_encrypted)){ diff --git a/mlxfwops/lib/fs4_ops.h b/mlxfwops/lib/fs4_ops.h index 895812b1..da2debce 100644 --- a/mlxfwops/lib/fs4_ops.h +++ b/mlxfwops/lib/fs4_ops.h @@ -115,7 +115,7 @@ class Fs4Operations : public Fs3Operations { bool IsLifeCycleAccessible(chip_type_t chip_type); bool IsSecurityVersionViolated(u_int32_t image_security_version); bool GetImageInfo(u_int8_t *buff); - bool getImageSize(u_int32_t* image_size); + bool GetImageSize(u_int32_t* image_size); protected: struct fs4_toc_info { diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 0c4b1598..9066220f 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -2521,7 +2521,7 @@ bool FwOperations::IsSecurityVersionViolated(u_int32_t) return false; } -bool FwOperations::getImageSize(u_int32_t*){ +bool FwOperations::GetImageSize(u_int32_t*){ return errmsg("GetImageSize is not supported"); } diff --git a/mlxfwops/lib/fw_ops.h b/mlxfwops/lib/fw_ops.h index 0ddf9d57..45e65061 100644 --- a/mlxfwops/lib/fw_ops.h +++ b/mlxfwops/lib/fw_ops.h @@ -261,7 +261,7 @@ class MLXFWOP_API FwOperations : public FlintErrMsg { static int getFileSignature(const char *fname); virtual bool IsLifeCycleAccessible(chip_type_t chip_type); virtual bool IsSecurityVersionViolated(u_int32_t image_security_version); - virtual bool getImageSize(u_int32_t* image_size); + virtual bool GetImageSize(u_int32_t* image_size); #ifndef UEFI_BUILD static bool CheckPemKeySize(const string privPemFileStr, u_int32_t& keySize); From 3fca3998ca32ec0b286e639a2809566d7173d708 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Sun, 6 Feb 2022 20:15:12 +0200 Subject: [PATCH 078/184] Fixing Abir and Albatross crspace addresses Description: Wrong crspace addr in Abir caused the device to hang and not finish the burning Tested OS: Linux Tested devices: Abir Tested flows: burn ocr Known gaps (with RM ticket): N/A Issue: 2962488 Change-Id: I793fc1dfb5f50b6740816894a47129acfb58de15 Signed-off-by: ashargorodsk --- mflash/mflash.c | 11 ++++++++--- mflash/mflash_new_gw.c | 6 +++--- mlxfwops/lib/fs3_ops.cpp | 2 ++ mlxfwops/lib/fs3_ops.h | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/mflash/mflash.c b/mflash/mflash.c index d78f3056..1009a416 100644 --- a/mflash/mflash.c +++ b/mflash/mflash.c @@ -2904,6 +2904,8 @@ int mf_set_reset_flash_on_warm_reboot(mflash *mfl) case DeviceQuantum2: case DeviceConnectX7: case DeviceBlueField3: + case DeviceSpectrum4: + case DeviceAbirGearBox: return MFE_OK; case DeviceSpectrum: case DeviceConnectX4: @@ -2919,16 +2921,15 @@ int mf_set_reset_flash_on_warm_reboot(mflash *mfl) case DeviceBlueField2: case DeviceSpectrum2: case DeviceSpectrum3: - case DeviceSpectrum4: case DeviceGearBox: case DeviceGearBoxManager: - case DeviceAbirGearBox: set_reset_bit_dword_addr = 0xf0c28; set_reset_bit_offset = 2; break; default: return MFE_UNSUPPORTED_DEVICE; } + FLASH_DPRINTF(("mflash::mf_set_reset_flash_on_warm_reboot setting power_boot_partial_reset at addr 0x%x.%d\n", set_reset_bit_dword_addr, set_reset_bit_offset)); rc = mf_cr_read(mfl, set_reset_bit_dword_addr, &set_reset_bit_dword); CHECK_RC(rc); set_reset_bit_dword = MERGE(set_reset_bit_dword, 1, set_reset_bit_offset, 1); @@ -2969,10 +2970,13 @@ int mf_update_boot_addr(mflash *mfl, u_int32_t boot_addr) case DeviceSpectrum3: case DeviceGearBox: case DeviceGearBoxManager: - case DeviceAbirGearBox: boot_cr_space_address = 0xf0080; offset_in_address = 0; break; + case DeviceAbirGearBox: + boot_cr_space_address = 0xf1400; + offset_in_address = 0; + break; case DeviceSpectrum4: case DeviceQuantum2: boot_cr_space_address = 0xf1000; @@ -2989,6 +2993,7 @@ int mf_update_boot_addr(mflash *mfl, u_int32_t boot_addr) if (mfl->access_type != MFAT_UEFI && mfl->opts[MFO_FW_ACCESS_TYPE_BY_MFILE] != ATBM_MLNXOS_CMDIF) { // the boot addr will be updated directly via cr-space + FLASH_DPRINTF(("mflash::mf_update_boot_addr setting boot_start_address at addr 0x%x to 0x%x\n", boot_cr_space_address, boot_addr << offset_in_address)); rc = mf_cr_write(mfl, boot_cr_space_address, boot_addr << offset_in_address); CHECK_RC(rc); return mf_set_reset_flash_on_warm_reboot(mfl); diff --git a/mflash/mflash_new_gw.c b/mflash/mflash_new_gw.c index 7cec0916..1c6ab890 100644 --- a/mflash/mflash_new_gw.c +++ b/mflash/mflash_new_gw.c @@ -172,13 +172,13 @@ static int new_gw_exec_cmd_get(mflash *mfl, u_int32_t gw_cmd, u_int32_t *buff, i /* * Set input in: data0...data3 from the flash interface and execute a flash GW command * - * mfl - pointer to an initilized mflash obj + * mfl - pointer to an initialized mflash obj * gw_cmd - the flash gateway command to execute * buff - if != NULL pointer to a buffer to the input data for the flash GW. * buff_dword_sz - size for buff in dwords * addr - if != NULL *addr will be written to the addr bits of the flash GW. (for commands that write from flash) * msg - optional string that describes the action for debug purposes, not used ATM however its recommended to put usefull - * data for future dubugabillity. + * data for future debugability. * return : MFE_OK (0) upon success or a value != 0 upon error accroding to mlfash error code. */ static int new_gw_exec_cmd_set(mflash *mfl, u_int32_t gw_cmd, u_int32_t *buff, int buff_dword_sz, @@ -364,7 +364,7 @@ int new_gw_st_spi_block_write_ex(mflash *mfl, u_int32_t blk_addr, u_int32_t blk_ word = MERGE(word, data[offs + 3], 0, 8); //MWRITE4(HCR_FLASH_DATA + offs, word ); buff[offs / 4] = word; - DPRINTF(("-D- word = %#x, %d\n", word, HBS_CMD)); + DPRINTF(("-D- word = 0x%08x, %d\n", word, HBS_CMD)); } rc = new_gw_exec_cmd_set(mfl, gw_cmd, buff, (blk_size >> 2), &gw_addr, "PP command"); diff --git a/mlxfwops/lib/fs3_ops.cpp b/mlxfwops/lib/fs3_ops.cpp index 05227b18..85f3d5b5 100644 --- a/mlxfwops/lib/fs3_ops.cpp +++ b/mlxfwops/lib/fs3_ops.cpp @@ -3631,6 +3631,7 @@ bool Fs3Operations::invalidateOldFWImages(const u_int32_t magic_pattern[], Flash u_int32_t zeroes = 0; u_int32_t image_start_addrs[CNTX_START_POS_SIZE] = {0}; u_int32_t num_of_images_found; + DPRINTF(("Fs3Operations::invalidateOldFWImages new_image_start=0x%08x\n", new_image_start)); FindAllImageStart(flash_access, image_start_addrs, &num_of_images_found, magic_pattern); // Address convertor is disabled after FindAllImageStart() - use phys addresses @@ -3685,6 +3686,7 @@ bool Fs3Operations::DoAfterBurnJobs(const u_int32_t magic_pattern[], Fs3Operatio } else { flash_access->set_address_convertor(imageOps._fwImgInfo.cntxLog2ChunkSize, is_curr_image_in_odd_chunks); } + DPRINTF(("Fs3Operations::DoAfterBurnJobs - Invalidating old fw signature\n")); if (!flash_access->write(0, &zeroes, sizeof(zeroes), true)) { return errmsg(MLXFW_FLASH_WRITE_ERR, "Failed to invalidate old fw signature: %s", flash_access->err()); } diff --git a/mlxfwops/lib/fs3_ops.h b/mlxfwops/lib/fs3_ops.h index a3d4154b..5fb773f7 100644 --- a/mlxfwops/lib/fs3_ops.h +++ b/mlxfwops/lib/fs3_ops.h @@ -182,7 +182,7 @@ class Fs3Operations : public FwOperations { bool GetImgSigInfo512(u_int8_t *buff); bool invalidateOldFWImages(const u_int32_t magic_pattern[], Flash *f, u_int32_t new_image_start); bool bootAddrUpdate(Flash *flash_access, u_int32_t new_image_start, ExtBurnParams& burnParams); - bool DoAfterBurnJobs(const u_int32_t magic_patter[], Fs3Operations &imageOps, + virtual bool DoAfterBurnJobs(const u_int32_t magic_patter[], Fs3Operations &imageOps, ExtBurnParams& burnParams, Flash *flash_access, u_int32_t new_image_start, u_int8_t is_curr_image_in_odd_chunks); bool CreateDtoc(vector& img, u_int8_t* SectionData, u_int32_t section_size, u_int32_t flash_data_addr, From 88726e74802acf0f9bb98741d0fc7d98d8687c11 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Sun, 6 Feb 2022 20:21:17 +0200 Subject: [PATCH 079/184] New environment variable for toggling GPIO regardless of device's state Description: New "FORCE_GPIO_TOGGLE" env var to skip livefish mode check before toggling GPIO Tested OS: Linux Tested devices: Carmel Tested flows: flint hw query via mtusb Known gaps (with RM ticket): N/A Issue: 2962862 Change-Id: Id7769eea2675b2e7ba1c2c94a16e22de03716727 Signed-off-by: ashargorodsk --- mflash/mflash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mflash/mflash.c b/mflash/mflash.c index 1009a416..ebe8daf9 100644 --- a/mflash/mflash.c +++ b/mflash/mflash.c @@ -2396,7 +2396,7 @@ bool toggle_flash_io3_gpio_cx7(mfile* mf, gpio_toggle_conf_cx7 conf) { bool force_flash_out_of_hold_state(mflash *mfl) { bool res = true; - if (dm_is_livefish_mode(mfl->mf)) { // TODO - consider moving this after checking if device type should support second source flash + if (getenv("FORCE_GPIO_TOGGLE") != NULL || dm_is_livefish_mode(mfl->mf)) { switch (mfl->dm_dev_id) { case DeviceConnectX6: case DeviceConnectX6DX: { From 42f012871a2cc2ac204392c2a10f38ffca42ac4b Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Sun, 6 Feb 2022 15:31:47 +0200 Subject: [PATCH 080/184] a single interface for all signers in mlxsign_lib to support a more generic use of signers Description: Tested OS: Linux Tested devices: N/A Tested flows: N/A Known gaps (with RM ticket): N/A Issue: 2958466 Change-Id: Idd9356b2afe400737f01de2f18693ec8c719eaab Signed-off-by: ashargorodsk --- mlxsign_lib/Makefile.am | 3 +- mlxsign_lib/mlxsign_com_def.h | 1 + mlxsign_lib/mlxsign_lib.h | 4 ++ mlxsign_lib/mlxsign_signer_interface.cpp | 86 ++++++++++++++++++++++++ mlxsign_lib/mlxsign_signer_interface.h | 78 +++++++++++++++++++++ 5 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 mlxsign_lib/mlxsign_signer_interface.cpp create mode 100644 mlxsign_lib/mlxsign_signer_interface.h diff --git a/mlxsign_lib/Makefile.am b/mlxsign_lib/Makefile.am index aa88ea1c..9a2139c6 100644 --- a/mlxsign_lib/Makefile.am +++ b/mlxsign_lib/Makefile.am @@ -37,7 +37,8 @@ AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe $(COMPILER_FPIC) AM_CXXFLAGS += -DTOOLS_CRYPTO_KEY='$(TOOLS_CRYPTO_KEY)' -DTOOLS_CRYPTO_IV='$(TOOLS_CRYPTO_IV)' noinst_LIBRARIES = libmlxsign.a -libmlxsign_a_SOURCES = mlxsign_lib.cpp mlxsign_lib.h mlxsign_com_def.h mlxsign_openssl_engine.cpp mlxsign_openssl_engine.h +libmlxsign_a_SOURCES = mlxsign_lib.cpp mlxsign_lib.h mlxsign_com_def.h mlxsign_openssl_engine.cpp mlxsign_openssl_engine.h \ + mlxsign_signer_interface.h mlxsign_signer_interface.cpp if ENABLE_OPENSSL else diff --git a/mlxsign_lib/mlxsign_com_def.h b/mlxsign_lib/mlxsign_com_def.h index 1b47ce40..ea110e4f 100644 --- a/mlxsign_lib/mlxsign_com_def.h +++ b/mlxsign_lib/mlxsign_com_def.h @@ -48,6 +48,7 @@ enum ErrorCode MLX_SIGN_SUCCESS = 0, MLX_SIGN_SHA_INIT_ERROR, MLX_SIGN_SHA_CALCULATION_ERROR, + MLX_SIGN_ERROR, MLX_SIGN_RSA_PEM_FILE_ERROR = 0x100, MLX_SIGN_RSA_MESSAGE_TOO_LONG_ERROR, diff --git a/mlxsign_lib/mlxsign_lib.h b/mlxsign_lib/mlxsign_lib.h index cfdf6ef2..2682f3b2 100644 --- a/mlxsign_lib/mlxsign_lib.h +++ b/mlxsign_lib/mlxsign_lib.h @@ -39,6 +39,10 @@ #include #include #include "mlxsign_com_def.h" +#include "mlxsign_openssl_engine.h" + +using namespace std; + /* * Class MlxSignSHA: used for calculating SHA digest on a data buffer. diff --git a/mlxsign_lib/mlxsign_signer_interface.cpp b/mlxsign_lib/mlxsign_signer_interface.cpp new file mode 100644 index 00000000..d86323d0 --- /dev/null +++ b/mlxsign_lib/mlxsign_signer_interface.cpp @@ -0,0 +1,86 @@ +#ifndef NO_OPEN_SSL + +#include "mlxsign_signer_interface.h" + +using namespace MlxSign; + +MlxSignRSAViaOpenssl::MlxSignRSAViaOpenssl(string privPemFileStr): _privPemFileStr(privPemFileStr), _shaType(MlxSign::SHA512) +{} + +ErrorCode MlxSignRSAViaOpenssl::Init() +{ + int keyLength = 0; + int rc = _rsa.setPrivKeyFromFile(_privPemFileStr); + if (rc) { + printf("-E- Failed to set private key from file (rc = 0x%x)\n", rc); + return MLX_SIGN_ERROR; + } + + keyLength = _rsa.getPrivKeyLength(); + if (keyLength == 0x100) { + _shaType = MlxSign::SHA256; + } else if (keyLength == 0x200) { + _shaType = MlxSign::SHA512; + } else { + printf("Unexpected length of key(%d bytes)", keyLength); + return MLX_SIGN_ERROR; + } + + return MLX_SIGN_SUCCESS; +} + +ErrorCode MlxSignRSAViaOpenssl::Sign(const vector& data, vector& signature) +{ + vector sha; + int rc; + + if (_shaType == MlxSign::SHA256) { + MlxSignSHA256 mlxSignSHA; + mlxSignSHA << data; + mlxSignSHA.getDigest(sha); + } else { + MlxSignSHA512 mlxSignSHA; + mlxSignSHA << data; + mlxSignSHA.getDigest(sha); + } + + rc = _rsa.sign(_shaType, sha, signature); + if (rc) { + printf("-E- Failed to encrypt the SHA (rc = 0x%x)\n", rc); + return MLX_SIGN_ERROR; + } + + return MLX_SIGN_SUCCESS; +} + +MlxSignRSAViaHSM::MlxSignRSAViaHSM(string opensslEngine, string opensslKeyID): +_engineSigner(opensslEngine, opensslKeyID), +_opensslEngine(opensslEngine) +{} + +ErrorCode MlxSignRSAViaHSM::Init() +{ + int rc = _engineSigner.init(); + if (rc) { + printf("-E- Failed to initialize %s engine (rc = 0x%x)\n", _opensslEngine.c_str(), rc); + return MLX_SIGN_ERROR; + } + int keySize = _engineSigner.getPrivateKeySize(); + if( keySize != KEY_SIZE_512 ) { + printf("-E- The HSM key has to be 4096 bit!\n"); + return MLX_SIGN_ERROR; + } + return MLX_SIGN_SUCCESS; +} + +ErrorCode MlxSignRSAViaHSM::Sign(const vector& data, vector& signature) +{ + int rc = _engineSigner.sign(data, signature); + if (rc) { + printf("-E- Failed to create secured FW signature (rc = 0x%x)", rc); + return MLX_SIGN_ERROR; + } + return MLX_SIGN_SUCCESS; +} + +#endif //ENABLE_OPENSSL \ No newline at end of file diff --git a/mlxsign_lib/mlxsign_signer_interface.h b/mlxsign_lib/mlxsign_signer_interface.h new file mode 100644 index 00000000..98ba93fc --- /dev/null +++ b/mlxsign_lib/mlxsign_signer_interface.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) Jan 2013 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 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 AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef USER_MLXSIGN_LIB_MLXSIGN_SIGNER_INTERFACE_H_ +#define USER_MLXSIGN_LIB_MLXSIGN_SIGNER_INTERFACE_H_ + + +#include "mlxsign_lib.h" + +using namespace std; + +/* + * Class Signer: interface for various types of signers + */ + +class Signer { +public: + virtual ~Signer() {}; + virtual MlxSign::ErrorCode Init() = 0; + virtual MlxSign::ErrorCode Sign(const vector& msg, vector& signature) = 0; +}; + +class MlxSignRSAViaOpenssl : public Signer { +public: + MlxSignRSAViaOpenssl(string privPemFileStr); + + MlxSign::ErrorCode Init(); + MlxSign::ErrorCode Sign(const vector& msg, vector& signature); + +private: + string _privPemFileStr; + MlxSign::SHAType _shaType; + MlxSignRSA _rsa; +}; + +class MlxSignRSAViaHSM : public Signer { +public: + MlxSignRSAViaHSM(string opensslEngine, string opensslKeyID); + + MlxSign::ErrorCode Init(); + MlxSign::ErrorCode Sign(const vector& msg, vector& signature); + +private: + MlxSign::OpensslEngineSigner _engineSigner; + string _opensslEngine; +}; + +#endif /* USER_MLXSIGN_LIB_MLXSIGN_SIGNER_INTERFACE_H_ */ \ No newline at end of file From d651c9426383aacce8a94236145c024233ee7161 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Mon, 7 Feb 2022 16:45:26 +0200 Subject: [PATCH 081/184] Updating image_layout layouts to include new field 'secure_boot' in image_info struct Description: New 'secure_boot' field added to image_info for supporting 4k dev key secure-boot sign in mlxburn Tested OS: N/A Tested devices: N/A Tested flows: compilation Known gaps (with RM ticket): N/A Issue: 2962359 Change-Id: I9a81150d59495f49cb88648acb5aefdc2ec67c63 Signed-off-by: ashargorodsk --- mlxfwops/lib/fs4_ops.cpp | 4 +-- mlxfwops/lib/fs4_ops.h | 2 +- tools_layouts/image_layout_layouts.c | 40 ++++++++++++++++------------ tools_layouts/image_layout_layouts.h | 36 ++++++++++++++----------- 4 files changed, 46 insertions(+), 36 deletions(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 349771cf..3c85dc93 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -287,7 +287,7 @@ bool Fs4Operations::getExtendedHWAravaPtrs(VerifyCallBack verifyCallBackFunc, FB _security_version = hw_pointers.fw_security_version_pointer.ptr; _gcm_image_iv = hw_pointers.gcm_iv_delta_pointer.ptr; _hashes_table_ptr = hw_pointers.hashes_table_pointer.ptr; - _hmac_start_ptr = hw_pointers.hmac_start_pointer.ptr; // In case of encrypted device points to IMAGE_INFO section + _image_info_section_ptr = hw_pointers.image_info_section_pointer.ptr; _is_hw_ptrs_initialized = true; return true; @@ -982,7 +982,7 @@ bool Fs4Operations::GetImageInfo(u_int8_t *buff) bool Fs4Operations::encryptedFwReadImageInfoSection() { //* Read IMAGE_INFO section - u_int32_t image_info_section_addr = _hmac_start_ptr + _fwImgInfo.imgStart; + u_int32_t image_info_section_addr = _image_info_section_ptr + _fwImgInfo.imgStart; DPRINTF(("Fs4Operations::encryptedFwReadImageInfoSection image_info_section_addr = 0x%x\n", image_info_section_addr)); vector image_info_data; image_info_data.resize(IMAGE_LAYOUT_IMAGE_INFO_SIZE); diff --git a/mlxfwops/lib/fs4_ops.h b/mlxfwops/lib/fs4_ops.h index da2debce..4de948df 100644 --- a/mlxfwops/lib/fs4_ops.h +++ b/mlxfwops/lib/fs4_ops.h @@ -286,7 +286,7 @@ class Fs4Operations : public Fs3Operations { u_int32_t _authentication_end_ptr; u_int32_t _digest_mdk_ptr; u_int32_t _digest_recovery_key_ptr; - u_int32_t _hmac_start_ptr; + u_int32_t _image_info_section_ptr; u_int32_t _public_key_ptr; u_int32_t _security_version; u_int32_t _gcm_image_iv; diff --git a/tools_layouts/image_layout_layouts.c b/tools_layouts/image_layout_layouts.c index 3e4d6122..040f7957 100755 --- a/tools_layouts/image_layout_layouts.c +++ b/tools_layouts/image_layout_layouts.c @@ -32,7 +32,7 @@ /*** - *** This file was generated at "2021-11-08 14:11:31" + *** This file was generated at "2022-02-06 17:27:46" *** by: *** > /mswg/release/tools/a-me/last_stable/adabe_plugins/adb2c/adb2pack.py --input adb/image_layout/image_layout.adb --file-prefix image_layout --prefix image_layout_ --no-adb-utils ***/ @@ -1101,7 +1101,7 @@ void image_layout_hashes_table_pack(const struct image_layout_hashes_table *ptr_ offset = 96; image_layout_htoc_pack(&(ptr_struct->htoc), ptr_buff + offset / 8); for (i = 0; i < 28; ++i) { - offset = adb2c_calc_array_field_address(2016, 512, i, 16512, 1); + offset = adb2c_calc_array_field_address(2016, 512, i, 16416, 1); image_layout_htoc_hash_pack(&(ptr_struct->hash[i]), ptr_buff + offset / 8); } offset = 16400; @@ -1118,7 +1118,7 @@ void image_layout_hashes_table_unpack(struct image_layout_hashes_table *ptr_stru offset = 96; image_layout_htoc_unpack(&(ptr_struct->htoc), ptr_buff + offset / 8); for (i = 0; i < 28; ++i) { - offset = adb2c_calc_array_field_address(2016, 512, i, 16512, 1); + offset = adb2c_calc_array_field_address(2016, 512, i, 16416, 1); image_layout_htoc_hash_unpack(&(ptr_struct->hash[i]), ptr_buff + offset / 8); } offset = 16400; @@ -1182,7 +1182,7 @@ void image_layout_hw_pointers_carmel_pack(const struct image_layout_hw_pointers_ offset = 576; image_layout_hw_pointer_entry_pack(&(ptr_struct->fw_window_end_pointer), ptr_buff + offset / 8); offset = 640; - image_layout_hw_pointer_entry_pack(&(ptr_struct->hmac_start_pointer), ptr_buff + offset / 8); + image_layout_hw_pointer_entry_pack(&(ptr_struct->image_info_section_pointer), ptr_buff + offset / 8); offset = 704; image_layout_hw_pointer_entry_pack(&(ptr_struct->hmac_end_pointer), ptr_buff + offset / 8); offset = 768; @@ -1220,7 +1220,7 @@ void image_layout_hw_pointers_carmel_unpack(struct image_layout_hw_pointers_carm offset = 576; image_layout_hw_pointer_entry_unpack(&(ptr_struct->fw_window_end_pointer), ptr_buff + offset / 8); offset = 640; - image_layout_hw_pointer_entry_unpack(&(ptr_struct->hmac_start_pointer), ptr_buff + offset / 8); + image_layout_hw_pointer_entry_unpack(&(ptr_struct->image_info_section_pointer), ptr_buff + offset / 8); offset = 704; image_layout_hw_pointer_entry_unpack(&(ptr_struct->hmac_end_pointer), ptr_buff + offset / 8); offset = 768; @@ -1269,8 +1269,8 @@ void image_layout_hw_pointers_carmel_print(const struct image_layout_hw_pointers fprintf(fd, "fw_window_end_pointer:\n"); image_layout_hw_pointer_entry_print(&(ptr_struct->fw_window_end_pointer), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); - fprintf(fd, "hmac_start_pointer:\n"); - image_layout_hw_pointer_entry_print(&(ptr_struct->hmac_start_pointer), fd, indent_level + 1); + fprintf(fd, "image_info_section_pointer:\n"); + image_layout_hw_pointer_entry_print(&(ptr_struct->image_info_section_pointer), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); fprintf(fd, "hmac_end_pointer:\n"); image_layout_hw_pointer_entry_print(&(ptr_struct->hmac_end_pointer), fd, indent_level + 1); @@ -1303,6 +1303,8 @@ void image_layout_image_info_pack(const struct image_layout_image_info *ptr_stru u_int32_t offset; int i; + offset = 29; + adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->secure_boot); offset = 27; adb2c_push_bits_to_buff(ptr_buff, offset, 2, (u_int32_t)ptr_struct->encrypted_fw); offset = 26; @@ -1392,6 +1394,8 @@ void image_layout_image_info_unpack(struct image_layout_image_info *ptr_struct, u_int32_t offset; int i; + offset = 29; + ptr_struct->secure_boot = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); offset = 27; ptr_struct->encrypted_fw = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 2); offset = 26; @@ -1489,6 +1493,8 @@ void image_layout_image_info_print(const struct image_layout_image_info *ptr_str adb2c_add_indentation(fd, indent_level); fprintf(fd, "======== image_layout_image_info ========\n"); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "secure_boot : " UH_FMT "\n", ptr_struct->secure_boot); adb2c_add_indentation(fd, indent_level); fprintf(fd, "encrypted_fw : " UH_FMT "\n", ptr_struct->encrypted_fw); adb2c_add_indentation(fd, indent_level); @@ -1829,26 +1835,26 @@ void image_layout_image_layout_Nodes_print(const union image_layout_image_layout fprintf(fd, "======== image_layout_image_layout_Nodes ========\n"); adb2c_add_indentation(fd, indent_level); - fprintf(fd, "hashes_table:\n"); - image_layout_hashes_table_print(&(ptr_struct->hashes_table), fd, indent_level + 1); + fprintf(fd, "tools_area:\n"); + image_layout_tools_area_print(&(ptr_struct->tools_area), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); fprintf(fd, "itoc_entry:\n"); image_layout_itoc_entry_print(&(ptr_struct->itoc_entry), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); - fprintf(fd, "itoc_header:\n"); - image_layout_itoc_header_print(&(ptr_struct->itoc_header), fd, indent_level + 1); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "device_info:\n"); - image_layout_device_info_print(&(ptr_struct->device_info), fd, indent_level + 1); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "tools_area:\n"); - image_layout_tools_area_print(&(ptr_struct->tools_area), fd, indent_level + 1); + fprintf(fd, "hashes_table:\n"); + image_layout_hashes_table_print(&(ptr_struct->hashes_table), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); fprintf(fd, "image_info:\n"); image_layout_image_info_print(&(ptr_struct->image_info), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); fprintf(fd, "hw_pointers_carmel:\n"); image_layout_hw_pointers_carmel_print(&(ptr_struct->hw_pointers_carmel), fd, indent_level + 1); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "itoc_header:\n"); + image_layout_itoc_header_print(&(ptr_struct->itoc_header), fd, indent_level + 1); + adb2c_add_indentation(fd, indent_level); + fprintf(fd, "device_info:\n"); + image_layout_device_info_print(&(ptr_struct->device_info), fd, indent_level + 1); } unsigned int image_layout_image_layout_Nodes_size(void) diff --git a/tools_layouts/image_layout_layouts.h b/tools_layouts/image_layout_layouts.h index 343e007a..9b897ec6 100755 --- a/tools_layouts/image_layout_layouts.h +++ b/tools_layouts/image_layout_layouts.h @@ -32,7 +32,7 @@ /*** - *** This file was generated at "2021-11-08 14:11:31" + *** This file was generated at "2022-02-06 17:27:46" *** by: *** > /mswg/release/tools/a-me/last_stable/adabe_plugins/adb2c/adb2pack.py --input adb/image_layout/image_layout.adb --file-prefix image_layout --prefix image_layout_ --no-adb-utils ***/ @@ -439,7 +439,7 @@ struct image_layout_device_info { }; /* Description - */ -/* Size in bytes - 2064 */ +/* Size in bytes - 2052 */ struct image_layout_hashes_table { /*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - */ @@ -505,7 +505,7 @@ struct image_layout_hw_pointers_carmel { /*---------------- DWORD[20] (Offset 0x50) ----------------*/ /* Description - */ /* 0x50.0 - 0x54.31 */ - struct image_layout_hw_pointer_entry hmac_start_pointer; + struct image_layout_hw_pointer_entry image_info_section_pointer; /*---------------- DWORD[22] (Offset 0x58) ----------------*/ /* Description - */ /* 0x58.0 - 0x5c.31 */ @@ -531,6 +531,10 @@ struct image_layout_hw_pointers_carmel { /* Description - */ /* Size in bytes - 1024 */ struct image_layout_image_info { +/*---------------- DWORD[0] (Offset 0x0) ----------------*/ + /* Description - Indicate that this binary intended for secure boot enabled devices */ + /* 0x0.2 - 0x0.2 */ + u_int8_t secure_boot; /*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - 0x0 - not encrypted; 0x1 - encryption before signature; 0x2 - encryption after signature. */ /* 0x0.3 - 0x0.4 */ @@ -818,30 +822,30 @@ struct image_layout_tools_area { }; /* Description - */ -/* Size in bytes - 2064 */ +/* Size in bytes - 2052 */ union image_layout_image_layout_Nodes { /*---------------- DWORD[0] (Offset 0x0) ----------------*/ /* Description - */ - /* 0x0.0 - 0x80c.31 */ - struct image_layout_hashes_table hashes_table; + /* 0x0.0 - 0x3c.31 */ + struct image_layout_tools_area tools_area; /* Description - */ /* 0x0.0 - 0x1c.31 */ struct image_layout_itoc_entry itoc_entry; /* Description - */ - /* 0x0.0 - 0x1c.31 */ - struct image_layout_itoc_header itoc_header; - /* Description - */ - /* 0x0.0 - 0x1fc.31 */ - struct image_layout_device_info device_info; - /* Description - */ - /* 0x0.0 - 0x3c.31 */ - struct image_layout_tools_area tools_area; + /* 0x0.0 - 0x800.31 */ + struct image_layout_hashes_table hashes_table; /* Description - */ /* 0x0.0 - 0x3fc.31 */ struct image_layout_image_info image_info; /* Description - */ /* 0x0.0 - 0x7c.31 */ struct image_layout_hw_pointers_carmel hw_pointers_carmel; + /* Description - */ + /* 0x0.0 - 0x1c.31 */ + struct image_layout_itoc_header itoc_header; + /* Description - */ + /* 0x0.0 - 0x1fc.31 */ + struct image_layout_device_info device_info; }; @@ -984,7 +988,7 @@ void image_layout_hashes_table_pack(const struct image_layout_hashes_table *ptr_ void image_layout_hashes_table_unpack(struct image_layout_hashes_table *ptr_struct, const u_int8_t *ptr_buff); void image_layout_hashes_table_print(const struct image_layout_hashes_table *ptr_struct, FILE *fd, int indent_level); unsigned int image_layout_hashes_table_size(void); -#define IMAGE_LAYOUT_HASHES_TABLE_SIZE (0x810) +#define IMAGE_LAYOUT_HASHES_TABLE_SIZE (0x804) void image_layout_hashes_table_dump(const struct image_layout_hashes_table *ptr_struct, FILE *fd); /* hw_pointers_carmel */ void image_layout_hw_pointers_carmel_pack(const struct image_layout_hw_pointers_carmel *ptr_struct, u_int8_t *ptr_buff); @@ -1026,7 +1030,7 @@ void image_layout_image_layout_Nodes_pack(const union image_layout_image_layout_ void image_layout_image_layout_Nodes_unpack(union image_layout_image_layout_Nodes *ptr_struct, const u_int8_t *ptr_buff); void image_layout_image_layout_Nodes_print(const union image_layout_image_layout_Nodes *ptr_struct, FILE *fd, int indent_level); unsigned int image_layout_image_layout_Nodes_size(void); -#define IMAGE_LAYOUT_IMAGE_LAYOUT_NODES_SIZE (0x810) +#define IMAGE_LAYOUT_IMAGE_LAYOUT_NODES_SIZE (0x804) void image_layout_image_layout_Nodes_dump(const union image_layout_image_layout_Nodes *ptr_struct, FILE *fd); From 275204677b8819972dc96e5053e0a3ff28a317ce Mon Sep 17 00:00:00 2001 From: Roei Yitzhak Date: Tue, 8 Feb 2022 09:16:27 +0200 Subject: [PATCH 082/184] remove reset-level 5 (cold reboot) Description: According to the arch, reset-level 5 is deprecated Tested OS: Tested devices: Tested flows: Known gaps (with RM ticket): Issue:2957718 Change-Id: Iac18ddfb2c98be2c0de93c3bf881e40579b0e78a Signed-off-by: ashargorodsk --- small_utils/mlxfwresetlib/cmd_reg_mfrl.py | 3 +-- small_utils/mstfwreset.py | 15 ++++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/small_utils/mlxfwresetlib/cmd_reg_mfrl.py b/small_utils/mlxfwresetlib/cmd_reg_mfrl.py index 1e0aa1cd..70927335 100755 --- a/small_utils/mlxfwresetlib/cmd_reg_mfrl.py +++ b/small_utils/mlxfwresetlib/cmd_reg_mfrl.py @@ -34,12 +34,11 @@ class CmdNotSupported(Exception): class CmdRegMfrl(): - LIVE_PATCH, PCI_RESET, WARM_REBOOT, COLD_REBOOT= 0,3,4,5 + LIVE_PATCH, PCI_RESET, WARM_REBOOT = 0,3,4 reset_levels_db = [ {'level': LIVE_PATCH, 'description': 'Driver, PCI link, network link will remain up ("live-Patch")', 'mask' : 0x1, 'support_reset_type': False}, {'level': PCI_RESET, 'description': 'Driver restart and PCI reset', 'mask' : 0x8, 'support_reset_type': True}, {'level': WARM_REBOOT, 'description': 'Warm Reboot', 'mask' : 0x48, 'support_reset_type': True}, - {'level': COLD_REBOOT, 'description': 'Cold Reboot', 'mask' : 0x80, 'support_reset_type': False} ] FULL_CHIP, PHY_LESS, NIC_ONLY = 0,1,2 diff --git a/small_utils/mstfwreset.py b/small_utils/mstfwreset.py index 81fb2174..0333c769 100644 --- a/small_utils/mstfwreset.py +++ b/small_utils/mstfwreset.py @@ -1451,8 +1451,6 @@ def execResLvl(device, devicesSD, reset_level, reset_type, reset_sync, cmdLineAr send_reset_cmd_to_fw(mfrl, reset_level, reset_type, reset_sync) else: resetFlow(device, devicesSD, reset_level, reset_type, cmdLineArgs, mfrl) - elif reset_level == mfrl.COLD_REBOOT: - print("-I- Cold reboot required. please power cycle machine to load new FW.") else: raise RuntimeError("Unknown reset level") @@ -1767,13 +1765,12 @@ def check_positive_float(val): AskUser("Continue with reset", yes) execResLvl(device, devicesSD, reset_level, reset_type, reset_sync, args, mfrl) - if reset_level != CmdRegMfrl.COLD_REBOOT: - if FWResetStatusChecker.GetStatus() == FirmwareResetStatusChecker.FirmwareResetStatusFailed: - reset_fsm_register() - print("-E- Firmware reset failed, retry operation or reboot machine.") - return 1 - else: - print("-I- FW was loaded successfully.") + if FWResetStatusChecker.GetStatus() == FirmwareResetStatusChecker.FirmwareResetStatusFailed: + reset_fsm_register() + print("-E- Firmware reset failed, retry operation or reboot machine.") + return 1 + else: + print("-I- FW was loaded successfully.") elif command == "reset_fsm_register": reset_fsm_register() print("-I- FSM register was reset successfully.") From 4c0598e31ae85a8276f37b5d78af8b066aba6f52 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Wed, 9 Feb 2022 15:30:32 +0200 Subject: [PATCH 083/184] Fix for freeBSD build Description: Tested OS: freeBSD Tested devices: build machine Tested flows: build Known gaps (with RM ticket): N/A Issue: N/A Change-Id: Idf14f1cf8e595121910413e01332e19ee5c59319 Signed-off-by: ashargorodsk --- mlxfwops/lib/fs3_ops.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlxfwops/lib/fs3_ops.h b/mlxfwops/lib/fs3_ops.h index 5fb773f7..a3d4154b 100644 --- a/mlxfwops/lib/fs3_ops.h +++ b/mlxfwops/lib/fs3_ops.h @@ -182,7 +182,7 @@ class Fs3Operations : public FwOperations { bool GetImgSigInfo512(u_int8_t *buff); bool invalidateOldFWImages(const u_int32_t magic_pattern[], Flash *f, u_int32_t new_image_start); bool bootAddrUpdate(Flash *flash_access, u_int32_t new_image_start, ExtBurnParams& burnParams); - virtual bool DoAfterBurnJobs(const u_int32_t magic_patter[], Fs3Operations &imageOps, + bool DoAfterBurnJobs(const u_int32_t magic_patter[], Fs3Operations &imageOps, ExtBurnParams& burnParams, Flash *flash_access, u_int32_t new_image_start, u_int8_t is_curr_image_in_odd_chunks); bool CreateDtoc(vector& img, u_int8_t* SectionData, u_int32_t section_size, u_int32_t flash_data_addr, From 894c45983bd885e20ff910e2c0c433871e43187a Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Tue, 22 Feb 2022 11:40:33 +0200 Subject: [PATCH 084/184] port PRM changes based on Feb 2022 PRM releases Switch V1.55.063 - Feb 18 Adapters V0.57_DraftH Feb 20 Description: updated mlxconfig databases and relevant tool layouts. Issue:2980349 --- mlxconfig/mlxconfig_dbs/mlxconfig_host.db | Bin 477184 -> 488448 bytes .../adb/prm/hca/ext/register_access_table.adb | 384 +++--- .../prm/switch/ext/register_access_table.adb | 1038 +++++++++-------- tools_layouts/reg_access_hca_layouts.c | 6 + tools_layouts/reg_access_hca_layouts.h | 1 + 5 files changed, 741 insertions(+), 688 deletions(-) diff --git a/mlxconfig/mlxconfig_dbs/mlxconfig_host.db b/mlxconfig/mlxconfig_dbs/mlxconfig_host.db index 5bd02fc51e302856feafd9ce11e68c13c3c0f324..bee46d81d7adfb746afdb2af54513830b1dbdbb4 100644 GIT binary patch delta 42321 zcmbS!cX$=W_xGNe-Ft5co%H0UkWP9Josa|wBqV`^4mXt0d+*_@1W}}^fC4rId)N0fyNC#W|M@(+@5c+UW=$D)h zH#Svw@zU4blN5#axhnwgc9#LpcXtOYbSDC~bNeca@|T+f8q)wC84R$n2S8yOKu`og zU@Hb_<0XVQ-fnE_=*elNUgnu%8y}|*bTCnRNsH8Xduo1xt<`X1Q|G#7Oq=BzJ#Fe( zo3aV7mg{eO22fe!XP)5>Z4CdFe{ZDhw|O$7+wHSN!_;Al{LQ;%CS= zl>7)JPY|#DtJ1i_)cJU6RtV2wVs(G=7FR})=B0dOzN`$9C3pe)M|oa+b5ZrOr?UYl zze`-1sRcC8;BJvc5u;RG(Qzs*MA11EEvJe~125rCC z`YrQv%>X*bi^s8&UV~jZaLzWF`zC2CjpJ03;LpQn0uoU2NcYc(lKPf2A5*zcg? zcavN3NY=N!$W`3KRhH{2$>cjh4GQJCOdLI-`T4j?()g#G_vAel>kqF{7qO+4-QOdN z-3yvR-Nf|nnpclX&KJtxX~`EUK74`F&iYY0*pi2{yxi`CT)FxAvOaWzLWf%OXx6>B zxXe|UlUw4-E9kH81^q5ja#{_sXYn;C^PD($&=%1xf&VD0ijqxN9+If}?;AOc1A4gn z7U%UX$aUrS&FNm4uPl?(lJn_+beg}*@8#3~nOEh+C{ZM~V9|EYFQLeKu_uUB7B%wV~zuwDwN=L|@rHn10lEw%z({JxOm+X7H zJ?ljt`g3LNJnxUx!ZI9e)SOw#V(oGY&3B!@n3R3{x>AI!OZO~qqTe?l z#D4F!+H$s&(?KoJPWeq06)c3&cD?z)7;2?w4Q%K6==BOx%~mpMt}n;aNAx`dBSptI z)h7Dcfg!YG@1XaB?9W|m!qNR`La#Z^blV)K=hN3~$TXWkp?dE*F`my_4Z!DTiDie> z0DIuyZI~_F@TC6YoEUQIpUr9KXslKE^!9UO>`z?#xx)wXbHB{?)Yr}pp{Mjc za~D&IUOF!n6Q)1Xwlu)ZseG`RYJ8ZP+PKS1?R?bU`8J2Wo5I)8lZt3n$kM#3XAbg? z&hYj1uFmS5;~v^f{u9gQ*u3;3%hGMrXHJ_tVT|tK-pOJjggevjm6AAN>g>vyQ%6pA zjh;ToHD%hE%E_HOr^JRvMTN#hfQA3-@#vA$6U8^PZEf^FS9z$iT;r4OV%CH!+ZA>X zEmF3F_iomE)VEwsU)Te?6+cTCZ_OdKPqd4Jaw@SC)LO0mJ^!4H!Rd z)@;{=QLeeur_G$5?3y)axb5KY|6i)RR|kmSH#0|b zP3fbs)$|ihQ_d-U^c=tT+})-^pR!u#ZcmqDDno~LoK-nHboR7Ra7@YY@~Wo}^Nuw?GQ4xHd$c*m&G0k-uHGD8EqQ)& zVz$1t&Od4P_{z|NYhxXnTT&i6VOHpzS(Rf#N6rex4_$j1zjm#4@6?6pTW(9#uhd1f z{CC5yja=3LdF1}PAO1apa^nh8${{T%)08`u$CY=LA1Q#k&?u^>9rOl$&OBHwD_|46 z*zIgPJH)=?&3Q8K$7k~f{;!cGgfXtUl~cz| zn@Q{SJ&&}dQoY;uFf6t*Gv$1snW}sU(r_AX=4`yeOznKMnL7Ab{mAxU3fHe}51}l* z#f}i_qbC8n^kTqS`ZU1X^wofy^<99w^mlfIQiOhWM;K)ThH%ab%~WL-W~#B-W@=;0 z&D75BHd6=Nt$*}r7=0j0C$h+hnr7%4RS8x2MD{Lg59FqQcQzl>_{9cqrpCB^M(Yo) z+(@JJuB!x%)IV6I@7<{Jkl`vPL<|C9-zHQ@^; zd`UlXPm=u|6F;Iizt^|m6BGZ`gqKYCnF+r&;ddtd-h@Ax@JAE=X~MrGB*lc(IQ8B* zvb)Sog}!x5h1n*m+q*_p!Nkre>=D|eoBhj9Qb?eKi zVKS*UM!pJry0K+1JFP9TdDa9^@amI-WnUMjCp{3VzrDs&T-JH(#)lsoj5qVgH(uGA zPtE1{ab>TYh`YUFG0>D2raup3s@+I$?UJ4(w6LvF?o zgng+yK6d6BZf@{jm2~$T-sZ7OMnK^9=xc&qx6|-#= zP94QY8wCe;_Sc-(%FbRez4C@~CE}=!0x45mM%DHiXPM0v^g_xSdmjEPn}O|#Q{5-wMl$rr?6%p$&O;mmkL{@e2H%QnAe0(ZLHY4 z72Py#O5@VUrd{hxYN4=PT23t*TfIfZ=FQL#Ked3S>%EMpJ!?8lyEZ0+<(M?SxqBV0 zdqR%#lL~u?CM!>(=7+gEeYRfs+!MSyYgS{&C)yLuY@GAtKx%2NwTlYRW;1E4auJ1( zb9dH!J@x5lXrBJn(?@BpzVDe=Jmz?ncl7mjy36&gOTF~1&u-uQyg$*x#()<_5-n(4 zyl)fHl188X_Yp1DpEGdDH1 zf3qEfpf=|12Oxe)y7TbeWY?cPyp?SF(03k8l>D`g0%3W&B9wi~1!_uZG=yqs7oBB3 ztPfkx4sn&|@uhqhKaQ=gyEyPTMR3lWTZqcNEJWi07GmR}5{aTHEAQa(qQx#M(~c)= zDV_DAC*oqN7~wsAXT>hT|wlfe|^=jaqYLOiGuX7?@v;o{@eEtL*%{xhX=`DFZgj4`JsHE zs0-1;_0YdGJ@BVu^3^B(w5eSiWuSt;YULT_6KX;oX%cOuqpS_fWpmgA>?k@kgOBI; z@uTSDSpCY+?Wj%<_$8BG&`W=brBr>} zPsD3+e-qCoFh707Z=QPcui5mmKH=9KI;%hWYZ85`pZ+xk8cDO?66r&|({J%~T%Yh; z3Voz+20W#|{adPf1_PiU`OQbHc}Mjzt3I8mrDR?Ey_VllplI$S56|<7TGHP?_{RY) zKo+I<*ZrR6(bg*~N%pQwUwg<;#J^w*(AWH_>Fu|*5FbCQdgyojK7zvZFMeMQ5qjYt z?^B3g@~0H`PyV@rocE9UizxcZO3XvdpP59fDN-;-4^o79L?+>)FQ=zceH3WTqm{dq z*Og1ul2VmS8bFKa5qh6~Wr66`$!ryShJD6^c{%3pi;5y1by7TiEzSi|CY=+0PD-#J z3)TW9i~M>w^Yx+6VzgMOIsYLy(J)czq%eDVxRw--@~a$nC{3ru2`5F+yW$U7^HI?* z7|9VaFc`$;VsS7y@*HtbFqP0|@pUlR^g+=wgxb+tqGJdpYIkO6J(EP&5X_Lbe(-0| ze7A<6X`96dArwOs#nq{-o88?_8xFBWyx5+#XH?VR0Dp@Yw>xMa#R>ADxztX~_aH&B zqGc2Ml46YCn}A4ZVnrJa)vBg6f>Oohrc_HQG6@tbo6!VH7C$wk21*jEn$sQ7hyz;C zEJ`p|wV*jfSwd|^zfh*}XDd<(3zWBku$3-rT-d1IT|r`uH%+l`GWX59#0hVDroh~> z={b{hz=Q`)_>u`Q*P571x-!`GS!_zTw%7@N7=ns?jr+C?yI>ksP)spfR z%10~jrGs>lwLo`_W-FP&&T&sHopJmw{xas}Yw#cM)|lUQMJ^jB<=^DdbDk&3Go2dQ!uB((Ql7 zXdUIgzN@X>S3H}@J?VGx!g^{;XT;g{`1JEK2?Kli%tBQDwS{Q>dog_jO8jc&?W$rS z4%H^kY@j%5B33t0JA7Aj3*l;O3sJ$I@hBb!5VM3$4Ym-w+SWuo9BLHo3({tgRPPjH z1%Bppu|klOz7&rLOz+RcQ2`^}Zw={Kv3cTnI(<#K;*|`#o4OmLGAWZ$4`Wj{jboH= zfL+ED6^g`8n4W#a1D(jA-eOp1T1*AvWM`_QUc%Ldwo^~TqbpV&l^X535tv7bxF-jD zS+NM~PJ1Bj9P3WosK}U;OOJUpDQgqg9(-z^k|nm4Q5(^K(1x$qJdpM@RFKUhPhsD)4CR8Nw<^hK>UO#-yas0ZLuk-M$S7dWoN(QBg^gsfwAxFf)Z=&gD|$stGj{dYG_@2|Z2N z!h|hN*vf?7CiF3(uL%Q97-T}H3Byd-)`a0EG;NaH9%E)=MZaP zTBf&L+(E5QbyphaDj+1#7~wk#;>c+6+9-OOMu}ykX<1Wu3-?H`9Q2yE+b(;}TXY>p zGvg(vXszs0@OPG4QFri*2k3pqSt=XJ*02}Z*WAeq`F#Em{}7^9jVNQbL}*||;+a(lws_81riF0U+d@<}!a_7Q zQzD5}Z{_XmE(>w6$HnvWvCbBY&*oEt_DZJKKT>=(A3VBmck*G%JECX-7P8~1@z_FW zyeOSO%hYjg(sISw2bh=md;-m;vBrprl)*eFd1vLz&frR}XfY29^XbX-GEFp=Orcz& z3C4k`^c2xlWBzoxvraMUW>8n6$;K-)v6Da$>pYuYX*$CzCqK~N>5f&3nu%8P$WJs& zV$q^#4%K^3_wJbQ@9(T8rKj}+n-W=s2%1Zu(KMmW!%D6oRj7-p6w=y&#URfWU6;@S zY=N|t-hzC0cqujTSzblr$WjUuoeyg9qH-7&wv%J#CC$1IDJM+PXbNqiqx1vwhgv^_ zt;VQb;7xcqFB0)TLn|-wixh|F@f7<#DOy@bu)dsKwsuUtSJeE>lkE>)BW~MiYv)k6 zUCUKHCW~wpe!uV(dPwyCg@;pDF;ynr#JXR2l6^Sf9$#wp zoImtAs%g69Uqf{phU$YCZ5XOL4AtTrhN@yQ1sFfqp+e6^-nr)JdMd?2lEph$!Q#&* zF&~lKlN{oB8D)z#$H^|%+(ws(iF+R+KV!{uDkN4-axeqsZ#%^2`)rXSY6Z<_)ruV4 zYvf4TfG<{1HC4&6zD8Yh2Tgx!4HXb+qW4Tc>yWHI{2k(R5-VgA*fMrEguUbJ zGWXz7JeLpQbGgoU^Vj$%Smnb+$g`RcofeVLX(1k`q;I3|fTDbH^(6T=QO-p3((8F| z&jI;;^NRbq3i6cGV%2k+)8_-}VL|yGu9BSG{C=*Y;=Fvwdf+6#rMU}osq$8pv zr(an?PNAz`e*gS3*zA;pV%ZUFcz23>k5F*R)25>)x4@NCR$K&cg;~u+AD+ZYK{vYW^Wx)j({=o77w;KEVSE^2&Nq%Nwdm z`=^>_BKckD{+^=nT?*2gn9VJDkbM2A=?yQW|MP;sxCbw2zSc)RN4|;VBgfraS)yR* zPeJ}nf;w79yXiEuu@p9t)v?FfX=Mp-%G3Es5nrN~itQz81h$DjiRwstR_sbrW3amR zSqSF`Ekxz7T8PFES%{4vwh%jiS0e4`xHy%hMv3?-EKwXTQDf}$KP1uz9bYZX`(zT*4iwm{=C3^1V+&Gm8SLGaKf2G-&#D76+X zZ#x~(ntO+3_=^L($;$}dL4Bd)iYbqh-msr+!nPaSzO}W0-``C|(0oPsUM#+r=Fb>M z_hRv4&+PpqXkNy-C*^`{b8SHyw69^YZ2?UY3m4m>p>!jOgbiSUI3)8`R^G%_LD zwstf@lvLSbF_hCRg!4HTqVh!&i6gg_xAEI7#Lib*h=c15PtyXhMcJ*!+NUX%(7k4l zo_+>B>SNsVEUjVSQlOmxGc=i9$UfOu{>GFS(V<%KKRx{3e%ZrL5q=OI7Idu>4`Oaw ztSwCRegh9ejdO3vo(#FxlW#)Qk1(R%l2S~#81^=uqqatu!}Kb3k5D!$$}!~&k~Xz& z5a(vm8hQ*{_F4J^uI%<~2wTF0vXMQ-US}V(@8GR{jQhi|ou|CWhw~Y{TJ-)@?I+fM z#=N>rlTO?cI6^Hy?tmVU5_s(26nIFB`WFmR$KJ36GyYkE-lEAdEWtMB5`26Q`G!zy ziC<$X|CDrDOW#XW90TJCyMbe5Ua!sK7$IUeiirIONMjT%GeLo&H~f0m_44FIHTp>Z zHa3%E!It441cS;5e;@JUXAA~J@#<$RSZgbJw%9d^0&U90w!Ei_dy5bl|En(e!z?Bn z+kYTD$$j(tyNYs3N(%b+RGts!UH|>0U;edcl0QG!ibqokIQq4o>)&Ik52S+|DA#&! z;kC}}p3^V&Z!h!8mOPU1Vs{To>|Zb>e?H^_=9Rq8tmB5Ua1F>QEXZ4M!+_v5b3iKn zcn0Y+4tP~9x%RX_D$MC;R;P}UUUL*JD=x#X(!Yl~@>W-WiW+?@F;$Jbm6)a`-AYVX z(@bLIzv2fn)T~>JW~v<<-lI(vBkp>S49{qsFo3~JwDfoL{`2l*|cu3^uSR@<41k7Hoc^`foe+9er5V7T3D0<1_ z^tY64kI&RHa=~ZM9j7D)6HuS;@GL>xhQuD*Nz0MXTqg+{W?ZgTd@biEjaHHNcG+4- z$)iIKW639fL;(zj4rc<(MiU1lu=Z%;ngrGj8q`rq{8BVYWF6^8(Ib&{rXNIYBI`g` z8%{uxj5oqgzz_gaOP`bUQ`2@{#pYN0D#c4g&c~>I%1MY&_|XWVpMw4#YZRQ8oF+vq zJ_9{0S#X;*Cb4_eRV?@GX@{r9MuO@o+$q`4FqWeNWg4p%kN3_r*!K-Vo zDT9mB(?LhElYrhH06A*#LcDY;;yh`m5#VQpV?0diV~`0xS@ zKIx*z(W zg|d7$5lYPy>?HeBB%WnKqQ{*SY^xkS)yAsC^p|)Tw=>;B9PD94!0=#g#^|Z+8A%Ja zNt7MDj&t_rbzEidnYcJ|Cu#KIb-ImRypG%16%+SFJr4GBxE34hA<()24J}~)B5XB< z$i^_1a2@9?$Hc`uD^YLxb-KnTSoGbWFpZX6r`y?D6Zb?t4));n-*7T!$OmnqFYmVy z&fc&PmAz{r8apkK2>R5_ceJz1a$fk!Zk?%Y02ev06hfcLK&Rdgo6lLsu63$q4Q$Fg zaTmXXKgN%*&G8alnz9HqPOMo?)5X5G)plY`Qx?rMMXYSfGVE_bf`%7Ll;pwNL94~N zrYwYnKvYkreRP?`}LNm_m+o}TN9UFxkIYRZ%& zVtsSg7IKTxoWF75-B8Ci!(aWg6QJ_nBq`^BN&~*x;TVF0Q~x0Rz+m zJNpARl6ekxh(;ORJ=h?kk;djGtdiC}0Ew_Asvj#hv}BJ`rIFK$?Sx^)__{Tu3)x<8 z{J?l)h7Yq7jS~xe*|RjsNcUq7cp#0={_H%1?I1J=Y*M_|mPHsQ)zz{!lN+0@u zBAw7zyx)$Z^>gn-T4WuO#!<1EQ`u-U)z~~UwXr+&wa4RViD?(e~^h6u7A!*fCZ^Ms7z;Y3w26JF`;g zfzNhk<=8!1cERMZi344j8>)70S9YLxpwd^t-#molysCTygJm~#^Fmq+Yua(9VkVZb z+t`EbC3JO5h?WB&R^G`U;V<*^7@dFp6U%dX481J&C`nn8B*G%!zGdr_8-3POW8`^rmRF4#bfn zNhae&(K@WY6=M22EUqQuu5}o{r73WL;M&3Ev(;NMGyR#-WPC1DKDOoA0{&m`84wu$AFSd4~9A=)ooKwInv zniZo(Tj6z?V&qzK+9(Xa6)YpZ><(TDe6vU%$WrVMc0Ys5n{s_7K1=ed89Nhz<&u*}xVYk*2OB#;*&6jZ@1{|Rf(^4N5kaNdBT7!84NK34o;xY#$@ z=|q&40Hv~Ou`R60IJ`P7LF-}HC%qRc>%LR^6D9kI&{C0o zPizq^MZP;+6J`=D)D=8ow%b z%lwa4-p+qF5%{)Pyp|L0A=bFnD5ly4xzz-8Ad)!F)fN__s%DvR$YY&g!swjG`oWsCCXZc)&0=XjD}wdot$bFXdbWv-6VnP{ za_-gxGI$eXQ4dxo?G#6Pv0~Ug(3(oQQ}YzxoKSt@)di*$y3~Z#CfsboyG{6*37;_GQ^Mn<`lkJanK>y=pHwF{ zS4~fkYI=G!yC^!P251KYcosHLfAS7dzmlqcPTqi=zPb5%u9D(`(1&5aEQ9{sUwKVz zJ*E1zUL-ZqoU;Dcbl*Jn6EjAer|`)ZlFDaVNE)ASA?bXnM8c@n%4hNw4Q1Hco)gcP zu{0Rzu9mSS^s$&)&cZPuGysm2kWZM0un%BC@W*sBNnB-R5{VFNK4Et2nT;*Bp4r(N z6LC1$1F2e1Da8(C@eJc8`61+hI1Aydt3=Wuw3`n!HqJt9Y>|c7+3JQt>@k>V9v{R$ zr?z6_V2pB@xNQiV0-MecLzpKu%x4gyDlj=>tqC!@0uv%e+*g63(Q@t#gIZ}$8*LP( zO{7)o_$ZW$5Z+y;ZU%@D*m8S zh83RU7ivq?I?4crkMix1S(}I#z_;ly(Xx`kbIlZq#2`AtBB+d+2)6&Tl`NLqm})(+ zGtELA_=u)sv4Pc#c4M(E9ug&Eu?-c9Wn)<=w6JYsv1Q&S4vfWq#Kl)*S(?+)UMoTX z*MG-qB4*VIZWcNY<(cR+4!vv_RpU^zCLWZz5#r=HY~pIebT$%7xVgmUPe(5%T77kV zI{GR>_Ej0e8ZOQNONg^deK8ZI+8O9ksHhp&`g}HeGhN&_8^zMBVh_zhu~e%vbuKDP zv5LMw7e$i|uX(JHpwo_=kMZeX6?=a^inX_jJ+uJDvc-i37)3;7OAheGLe!XPq%4B4 z0?+&C#h6skk=HCmL~|!2v5L(ip4XK&%W(ezQaoQ4`39%XqNypyMP zqmAQ4-5!<&MdO7%Y&=zpsJ(0`Ec4ZS*-tduSlGx?H1XmKEX=^M1c?0;jKj|`L_tgy zt~Xhdc<6aHN4Q>NPVwT)tflDn0-FaNV?W9hO%g~$^`>3CgwKoYi-zYhxz(51y);); zyapv2Z`4CD-}X92W%4Uv^Rva4S1{Q>W4 z)kf*6C{HQh!{b(kqeCj|$`-O0*dIKS_fqb}!!aUgzveGi9?&A_1<~UrEt;MdK`&{s z5PW`y;mH0?Z*91=LzT{^T&8?0+)3!VFT{Z)%&;rs*>}`@`_~<`&a%kxDd2fW4roCT zBrhM(I?z`l=AhP{zLPI`i)9D3b_kbv^dNp?vN(27Yl~>09}jAg(A1{Bqy^9_ar;YJ zki8*J3zK%PkCw9t2fdM?MR!H++)5VJf!>z#gr721QC1_Y?=nn2eIQS4hpGD;Ov5Br z%*L}7Y!5pH$shtA@!85$zMdQKis$%cinUK5_HM5@_k@~=zCsd@VskA-<%=yugALkz zWaG;%#Lib)h=Z>ezdfn0)-Hu6FKE>XJGqdYywg&Nsvd}TeIbA+xyF~wwP~AIc*rUShW4v|$hj{Dq$ILg?7n%e9 zq$(TUoaU5@CDb!g&Hw^feh_oO)W%a%`HS@EgKfX z?$p}K+M$V=B^~(n$?^eQybB?JL&#eQV+?1W7NW9d7NW5h7Gh(qEX2;*m`I3&c?W7C zQ2%C58(rxdJ$vS4sr`)}X&&rTr;1&RD8fD?PD_(fYtVTyGZ!RlISG)lhZ*fKn>Lb7#Tbouc$S3$koZDc5n%@~`768{BY)y@T&L@+msA)wRyNi0*D_4T9Gt z*_{_;cV1$?dEwA_G3`HA{!q4)KV?Iho{SK-t%%@xkG^IOsJ@-p0O%Ym5PP|gonYU> zzZJ-n;5r`2Ct(BD`NN{`RW?#Yq}seN0p+Pc#Qr`mUP!e$u?$bA+5)xl(!U_~bR-1t zy&{s+Y`#$R9TM@!v)66gyzW1yz>CQ4u`OWUb6Ji?xxdcQ*5u{-A!vx%sZ#;=X15 ziVHC=yDz9dRnw)Pp-}KH|t%m;&C{roh*j0$$gqz!fk<$B+4U|N%Dwg zG7fesDe^dDDm>9jnj1h#cgtEc-11;*mRoYzZ1ZGKdv{ad9o#JdJGxr|c5=4{>6bk74E?Uo-o#=R7IlHO)iHqctK~;7s7_Jv`-`eOAhWnye$$fbUVuxhivgEa zkau6i_Jef3zt+p6U#Ew7#gczd<{fECs9c;_9}@-tRe&jnmny%=zH z4S=$y21>TFwnjF+p++`Z)S$UNl#Mk3$ZVHt+U9`I)yn>Tp;peB1GTcf2Ww@| zzEs;5@a5V_z*lSA0lrpMn~3D~+El${s&cD;xb`t!(s1wKD?CeW*@(Vt%lV9*fo&16?>*N=FRp$h}TqnQa>$)hwD|PY+%7Asgq6rwXQGVZ*|f{^G6**>6Jh0hG9aHQda@U z>M8+w9p(wCb!atdb!au&>oCR1QMU-tqaJTjlX^6on%1My)U4hC*t{N-n_ASP>D00w zO{Z4%UVyFZF}bNtJwAZE>oEl6Qy&WGTaU?2e)Un9&=gRQ?;vMA<~Rk{Cj*AmV>wf3 zJ-&v*>MT`QD!|pY%FEh%P;FtkMW?6x5+Q-bepXSzB2}K@%Z}~hvk}K zqfevmR7w>z4LavagxKzZaq=`YPYt%EBpBZYL&m6K8)2q6$UeXcI+X{(G*QUM@Wqhi z3O`lnTU!0N2RYiO73aBZrId04b-AYVngKi~eu*tU)Gug6RiCJvD zSJkzi`KM9Y>=7xs$nGjC=1nLjf6~+0up8(T|M`Io zHvNVN|Ijm8?SIm<*v9{)XS1ExzZDctF*Dl2OQ;_i&!99Xtq8QFk z$TGs_;O${a>gM2o!jjb0gFir_;!_Wf(|5+HCVU6ve50YZ0fy_$2XHOP&Y?7Kzlx=2?i!msp6#Yb?aZZ?_OTUu_`{zCrYA z&7;tsX{~t(A`(}(<}vn-30jV{&L%C>q8R_c^aLQ->O%|R{1XdN`R5j*@hcW$<3C75 zM(=y^PB?(l*^6(2T?~_RbmjXD>Ri%oVLHu=CZaO;o0T^xmaB{?4B#Gz{*o@=3n&_=8fC!;9z*+dN@-(&cb{65ooYI#R{DTc#NW7;k1?dW{X#ukAuGZC+E#a z;h@C6*@&qcN#9B&(EeMt)&~w-5ta#4@n5rf8~daj%_a31lk!yt3v^Hw>|ti1c5nnI zrok+^Xbx`!Ys2a}yaQCvLvwgMG}E8v@K9KJ{N^GVE85RR@54|rmj{t9mdr)iaTl>| zE>EQg#Cvmj65TIz-eT))?xgKPorl1n`z%uNJdhq1Q|6)6mWEK?5wRYfLit}%Bszuh z2cZm{592>lnsKr%e}t&LQ5_+BFI()4#4uzTrBVDM>{uc@hTjD<*0C7=5kfuo#^TkE zVo*E&9L!=~ar~;EpHcvq1;C@qVR&bJ;Kdq2)yjB1Xn6s5u&4CH%fpa9X?mC(c6MJ| zEjrdi-?iLHvF0Cu?1#oV=MI$w};a<{h{02(M$T#+tciC$7pe~ zFLyOzVT?vLCa&l}_V=M0#>o?-i2?fUcPti~A67?qu{{~{2SFw&m_OY_Oe*G2SL0Hu zoIgFp%yi73e9vBSZE;u87XU{5i|utDrH8@H)$C_0YFYm|CS+b`C)S?&}(+ zoo%q_-Jao^ZTofY)Ypu>cuqbGfx-1<3*qc-3sGT5z@so&vdt1U_L+s)**7KvSv-T4v!yghY1pa*sQP}_s(Xhp$Oau%eW>Gs^XCV&ukU9LlMW<{Ge}U-K z9%I-`oNtfe?`fRufM~XcbPlUn1Ybf$Ms=R-g+j42AM>D(QQAY!gMK2r7v@2!IMxgE zphWB~Kpn+mP;bnGzQU^yV$jiHi9R@NuNcaC2oJG{UYU&ZWlt#6aPZ|v7ND$SIq-2j z%FZL$x-*~0?-j{E^Ufl118g{J#q%4`_BA4BD(vq7v10Uk*qc`hw@fyOE%1ifr?=C( z!uc!K&a#Cwb(XlY9{%AKqUi?opAfIRKnkLJN!J4;Z~jZafIa$4)vS2=S93igihBwRQ>z-o$fdz$ya39Gwl}cjOzp1Ib?AD@beBiCbbZ$yz|9(A# z55Ki!Ca<`an8in%#4367(Dg=T^RZUj^Ksu%iAy$ZUZF)-E#fMve@RE3T3lh(h%}@nSNzuvPlsl%*EPt&c5YQ8Y{eomd+|}p=Gey zVg{<{wEUJwS?umxXxVJHypJg_x1X!9phvM8f{L3a_PekaUzK-fg}?%j#K}|n3=2tv z3}RB!`H}`dY(4|T_Che}axtR_Ou9_O^aYddZ(Qmtne-4bvjj|fu;^F{COydbqg1k| zfkt$Hjx!%4M5i(^wc(;uIT+F~alRZ(ZK!c_fMjYFTU^?ZJ@;eT7MNuc%^TtD! zkq1HcgDYKzy*>~}yb4$an}>pj5kGV{B8X0~AGsGAT*9X!u;qTfj~_7)giI9ob>d!C z8u`Jl)IX<3zIhtMRn`k9FnSdi=4pzYIDgB-mN=Qo>TV@wu}!xUv)NRX$2*95eQd3NKUs3v2!qX zLzhuHMDB)TMfNc4hLz&jFzkk7#NOeUe51vn5!ek!2`?9R!x9cz-jCl056t#4nA{V@ zj7m)I@gim{Cighw(pWjUr;3^5F}bIRjuSAsCmVlEkiRy`h@K=T_e{}gGA8#7(P;|m zpDxZ%!Q`H1oSZ5r_h(Ga3{om!^1&&mAE^x`Q<1V&si29t%WfC^!#^-T))CRtZgxL= zm3@w|fh67!=U?XNiL;}G+s*?ZmHjTU^0hbL-^R0YUKQkmWSXPZosGvTZ2xmPkL}f!PL}ODW(iW$!%@TIj zU?LEHc3iJ42wN|nIz{n8uF)$dF5Ao5VT(S^SJl9AWEn}<*jbCd`aC4H&#%+%>|61X zuNo%K*tw?|`ZRB2c@C0A>C@aPanACt<0>0uPJlT^^>jHTv&GICm;kek(wTf0HN@~N z$m-dMz<>kk*nCWa`C{(^4AML?Xdx!ST;a6{lVGQ+byjx3`iASC{)9x(5%JfHXfr(r zBg$_qP}#wPU2S^Zl$&G5&DN=~rb$*GP_F6P;?o5j4@M4wFq4=j*@` zxN)*xs&F1g^>SI*A$H!5xoS5`S4d{nTx8#gdD=`IyA$)Yso1*`uX>6>t1wTS2(Q&p z;knI@B4&O>>&>I*I2Ei zeDy#oZXtMQ0&8l&5U1tHH_rvz14M=S=Feh!B0lV*xGRyz(JwN@&|9=j;?2Yx6Ig5L zP`@SeOeo`j(>+8<684?5k{&Fs`r4aaYr=Qp-Xy5QXT;$oY!+7<)}z~6i|y+%9<87^ zU_4rim> ze-B2(*Eo5v91W*Yy;T+t5<9nHGy;v%`{Zb}71|U`>M?>toUyX zD*gN7=rg=6VhT}xsCfGCC$I)wjnLw-YwUiO2O}I`9DNqSZH%Q`2xq-4L}kMy5((yJ zmawr}3$e3}CW7mS(|v9fb2k2j~oLO8Jg8MQBYI zoC%%AmMdq7lrPyPh<&GVxv7(P!6|@cd>em`zsEmEa9x9l+QXas?v(OSd47)qS7C8a z*MR(f-HZF@tB;Cddw4+F4(U}jALiwEFYjp<$<4{_m9K7>hR2(p^vumu9}$mr;l5p8 zZ^{E%d2ZPt2tqXWKWgb-*r%XaeLx<9yQ!A$Me6;+*_8)r_nC2dN1wHMJJpB(qhyc% z>J}-nifD^MSj zx~5rSuYv-6kLng9_TnC$6r5Z)kyM;qH<2`c(L&PsR~C}NzqOD|{)iCr zhFTcH5=E!yv2GJYrx&pJ;>GzFux{gwll!Dx^}CAIx12Ac6r=iOxssB_&R4L2lZ?_= zvGsS7^D01b;cjD?yS~Sjg58vA%&_J3C^+UfaKUGpM=-a*BXWT|cpUGmxDX$|oP)qLm<2ugSk?Xk1PF}|~cK$kUV_#m!?d*He@*sDb@)oSt2M`9x zScZjgRv?kKP>#$88k=DuHdbdLcDBhv9PBY!PZ+%@TPN#y-9k7!Y9T5+Wg!~-#6oQB zD+{r+ALLo1wyw1ZeCwVRP6wXupD1z~>oZ_Ag7BAFw z9|{E570LSU0lKuVP@qoSKjiLE*GE?SjQHzgJ{aMngU_N;#N5eBRa9CkHl9PJCBk_g zl@=RU&U0^y_ks}>e@`iAVW>`r4RsB@1iM)*c)ri+i^X?+h9w>#BJRW z^sYiVlGhUBGM4Ww#0KTaq}ZVxnTSKx#GY>0@jS$?9Gur+V9_SR)m9dws@@i&ss0j4 zg@?i{VTZtMA`UfD^y&@{yjx7|&Le_u572yLah7BD$l3A|zgd-|=gh3cp@>&UEKd_D$C9#v*yS4OdFmiqKrtUe$1h|B4twvl~@(;{dB0Rdi#y)r~5;vFutm zeu-`zCI)|nZX9ZLqlRuAA~s$|Hx3rguhETzj4NMrPa9M%5fLP%F$qyAIl`D>HO@>zl)z0AC3kaI3qs( zln06Jqj`up+uZIUE;o~}eI)D`xHDpGFwdbLh53Wf)_(ovA?kj`Jqil{{>?G+bhua* zX7^$07Y!${nk&WN-!blEtZ}zt+((Oze_-543Fn^}_mRexKjoUlp?|q1Z5a3Q*0|d+ z?&GX+w_)7JUK@9=4u;-6SXFmG?>5(@9hFWN8#T2SwkoGhJxUXeD>fCCB0ODIYDc9r ztV->ubh=fk9hFWqD~+?uUBU9eLD7q&L6A3IqF-R>t%QO1C=|K~T!lE1*Yn3jXrb+4 z>*f|4_B!)Q7d!U4Er->3>~;5ks-;7MKX*Y(!#c(74ie!i?q86Is(M+7rs9SINwKN8 zRp5e_0a4P-J8-19=prIS?+_C&LjNlhD=s1cw7=MWQ46Ha;;oBXlvW+4`DTf~F4%%> z>Vag`j*-4^Tgn$=%Kk*4>{07bHv7G=%Lxd*&IDI%ec~9_7E;q zkUiu;55ajQS)l_xw7}{i2YP6}*+b-L@KXn{dPNNKQ(wiowGe-GK3o+W{ZZu-;S4~P zi;XJ*>SQQE#;_oD7a=UyXcnw~N9J9VUbx2-2WXemQxId#@J1ZuYze__DqGKW zA)IGRBm!HAeBjV{H|wg3a|amCrI08+$RbeOZXp~BiAhnhR)9o7GcfZutOOIW^GFMU zTp%tVWOBf9z$k&5G=!>uk*y(2eGSUp>tX5wQjP9y)iinC&D?PH6LJ_sBGf(dvYVz+ z>NmLe17){~EwMPT<0)U5gQ(h+`X)xVc4|5`@$hONhbzPoa3;FWReeOF)>ds9sI8S%n~K_68r?EwZ7u#+ZQ`#ibqLg=A=$FBHb&D9 zvNAubvd*Z?*Q!iIWj;o?F0wN3|6N&ER2EctGLvzQ*Nd5ONkS}<%;Q-ZY)IF9m2u$GC- z=sphC((O-o)cWJM^soL*XUe^zBn0u-OT_#TErm9U9U)kLOU028Ey=#AotBaU7iHoL z5%z`YTE2X#>Zb&UBBG^3lk_$F!k}As8%!zohHxzm&MJNX`5>mOY=}|+pkS+G^U<+R zt7C2G*dU`@581JS|GQ&*qGLmiA-!bBhTzDP9Hj`WvLaL#ZdGPSWo?aaePv}~|En@g zQaOR5j3H&Rwn(Gt01VT$W4Vn8Ji_p}5ifoe+%F8*z|LV?l;7DK>@rlbMy$DR(5-gj zvQl}6TG0Di3|$ua?`t9UQ|VfUj6yFtYfE72K6$3hIzWezg$p<2RQ}}+IgNjFL(ay3 zx*=!hfBcifp)ww;B}nhzbSG=e!1{OA;4avy;wT@WJttf1DgUd1 z96w57$}^(Xajh%eElQ7TaoEF`9LHqB-KM$nH1X935KBNO&EaWh_2^*qXsp$v4)kb@ z(QSzA(dhrxqsCuDRZ@G&i5>sH?-cY2i=ApvS>+I8Zsj zrXcESJ&uPx&rY$Qxets@{rGgg3O&0|gzmR35J`_g=3Dm&Z;iv5ra3Ab9H$%pe-N0M zkVtctLrjRGtg_6`M*L4Dk8Ik<#3Zc0K?`kgMAvHm9SEbXR}6Wk1XnwKiJiMunW>xK8-eSlac?si3hBs{KWOF27e6y$Xpol#*hlR zFyf4+qttP%NwQaLEbj2AZIv&o!oi6@-_KeZB@5I9;^XU+#Cw(MBuX^8jg?a*;eSt& zacUS2yNj?1*dSAlRTEU0pHhtbC#v=TudwR?ucGMMcj^WLgqjf2NeH1NAwBex0s#Uc zp(BJKRSCU=CQ-@Vpdt{xW1%W4UHU4&0)8qgND~n7!w(e|3n2LWDJaVS&Tf*Qk_YqT znR|Bj?Cj3$?37d9L*R3CWgf2w$ehPUlqOkS3V8t`iB{-bJ{)tYX9hn3;|}BwCzv8e zl%_goIGa$KqRSg^-I@)j4Y(-bijjH)Rx%GaX{QTqLjnGwd4zbZerczQ`*4)f(J2uQ zS`+d4bgMWcaHgx(Wubn8F3x?zh3?pO$YB>O=O2Qp-~sw8#_LR2%P(QOs2}--9JTpthV6-q?T)WQ2rMzRZ!VLNSJ{NYq8!4D#i(tY;H?nn zTufP#Lon7>6A>_H(f7f8-qo4U`)vWXIdj@7qoS=O>XKg3R&qjVT18tusoScD75cPp ztL~~~G1@BAy0TceRWGNlywFxXD_X=rDOpa5>Q*_B!unL4@WP2~tIKn`sd_uNv2H0o zpF<6rzn?#MjDdC zSRQMD_tPM``M2-nI&oH|xz zs?($fR8SNuXR=A_#r$g8NG5RCcEQpIdM5iC0jpfsRa=TvQ?t_#aSTx1_pnRTw(2Dg zpotg#&9jbYL9uARxYO(KN=7*^E^9sL0{z-%V#8~n&ijrwV3SMp9fp$|z%asjuUQ-M zUWYqemp5|1F2RJmu+JSqis0GuF8LZ=KLY47W2qa!Ac2Hqy1qbfAsj{+CYJ61MJ&Xm zT@L8eH`zgUj$MJEc)y-u{4imj-^hZER1Tq08npvImGAfG;>W5(jFd_2>g|Wg?6=zw zQ`pU_LyV)ToZ4k#*L>C?;@NpkgpzNa<3y|g^j)FTy5*R&}VYSJ?}9XT`G>cV{KAHFswv zvR5mzigZ-0oJLt$YtWFgI@FhoRcGdz0LO{xinuOLH_m+UZM| zcW}S@-ZaGpG3RhBLe|rxS~8_t?x$rs{@U|Ir2$I;i?$RSQ~?8adxsFLvnHCszD}bp zU@6$$A-q^Gwe$c0zL?&QMMFrX0T@t%k3(=Md+Z#+0z7Z>qi}6J_9mY6VYTut><%BY zmhIsy2$^Cn{frk98Ba@cODC(C5BV`ors_YO1a@`N{An#4L zow8$JHB?U?!VR`m-r$ffCq$h+ghl3Co@1EX=Q~wRno!R0~?@(J+R6o1RCjYaETq_}VS45Go#}PG95k z#=dybS1aWvosf;yIYJvyOd$^eKZ6`m>KC3wj;h1IV0OEu3MRsVoI*Kd6AY?$o8YXT zL%_7aAtVMv`;@`LHPK48XbPWCc;kNn@Kcux{eWPafhx=<7^|fT?V4yG3kK{n%^{)T zvk8b;)K+lFmX1bg$^jBgS*+(I{{-7F-3Ue^XC+fhA93DlBG+$qfqtu#iRT=Th1|jE zK}n({*G-&e1)b`4RrH|q=s`slJ?K1okaT)bvMlN47HaBO=sH|=`5He=`CQ=FJm2#V z(4Fm0lq_*Ow^zk2a7nJ)P%%I8PjmEpiExe54!18MPSFw9CBS$zCz-C<#0rbBle9N^$m;cVEYvI=$qHS zQcsefo7W>NTL^FFPcw6JAhdJAnj41DS?L%V5lJf^BbIA%2uma7y{87K9pAE{YX3J- z{W4YiJJ^L#wFXD^xz_UZ$iZqmtB;1Oh0dV;cPuz{uU1}Fn%fd zXY|$YsHNYr#!>tAGCr$YHgF&jmal(S<`A6ZKj?eu+_bJawnho6kMCFj_T87iV}AbU zwA>Pbz;dzf*M@@{8dtBxzg9sPar*mePbUJ$J{zaAey#R&GW(<2{1oo0Ha`{WqRkgs zV53j9X;c8CNX=MafJ$sv+>TZc&I9W~Jy8W#KFRGy)}`iTZ(9f_Yn7SCHd zL;`Q)5Q#j|A(D8iLnQMK4w1sU*hEn(PuKlLKc{VEm)$k57bZyFvYOm@xB=YDo516% z$xYDhkd+Ih6mV?4qAiH`-1D)!wUojs2iSY<_ z3-*lmC;tyj4?elcr)#T)E`MVXYGnD`;=r)P0_$=MjR0ArL@uO%20^&sd6%W?dl zhWWG~Os5|J?!fb8Hyp2jp>=5t&4svc9X*B-zcq%tBDP7JkLN+q+eS5CEb1wro}!jw zSt3+@&_je`6L~@n?FmWT4i(%Ja=y3Jmw;MQ=d(aFwHh?mCLid`0F0p@JA`D19l~IM z=+>tI5~&{RDZ|r6OHcaEfzw1Lr_7NyN4R;sKQ3?S=TX$#8l?q`)Nq=`ItMwqUi$M8mb8>K| zJDePxX%(CtoZYO}!!&1>!zsYo!{HR*>|Vhsz?o^a&expT4yOcXZ--NYvsVSD1ZPjx z`ayBBlkQsqdUQ;L|BnVtevCXz_F&;7fzXmm=g^h(eb|2d0=I-vnAP=RW8l5G40v{X zVFB_Z#>U^m^_Ia7IhzA{5Z|STdiyXpqkry@{Iov(`Bt^!CmGPRxQcTiFopRRz4W#@ z^`V~9cBmtxWjN*nKZl5iyMvvR0JtHWNThiVkwnL7q8XNW_K6hwj6V3NH$Lj0FXfV4q2=reTuDT2iOHj1Coh4rf3^AWfCT? z7gXOV5M8X$KLJ?cu5kzsU6Gw5*m{SMP|w*p2HWNkUTl{No5}+q$lo>H- zI|OHI9YU~mnh3Hl$EO|P9%bDq(c?&g3VU3fx1kbd5jZKkAQq3gN%pFPrUSwzE_rl^xd)~r2ERWNA){p zF-YGoYmKyMPgx86yj9i=X=itBq+Q*0k#=)ypY1faAJTNUKhg|$0Mbl1T+c~&cL>rR z?l7cT?r@|%-MWNc?&e6d-MY-a?p8>1+|fw;xd8}3a@}xDCwXq|(B0pyA80_48zLk! z(5x2}DGdpOcj?vY3zbnCVm z;~tB2ta}2|32sP}$U|=3iVwTB^ZG=$Zr4ffIY_6t=Odl!F4CUf(@fp?Gfa+jrdb2& zEK|3^Y*W{Mt{IGUo~i4%z>Grrh^g!MsM!)}k*S-p*wnQwF?GW}Zt6yU!qjzLXvQNg zH4~AVrmk_BsU6uDnW;#hG}{*8=P9!t(#0k^40*=XEwRMZZ*HmC1?e(Vw@SIG{oJ25 z(~&-B>K0O_e$&sJ+Ryz3Q@71a<^xDqm<32znz|)cn-H6kHRdFwub8?G)|%Se{Z(@| z($~!SuI?_f&eUzNzD&2l#xmUoo68KOTgos&kga99Pi!mG?Xjb*0n(jizDReK={~W$ zO!o$>EX=b&6p^u3@e}%U8KZ(q@wtpv-fr<0V#%lKo%K*29=CVBSVHXJ0hIMsB^!j^_vShTV*_lWyyN;B%Dq7Z z;ghyGBpcxn1}ks~FE(1$+X#*qRqRG6*09+aPn$!)ip_>5nBHt?g6qwOCIp?e`&m)M z$waI8d0in`KfH(vJ!E;mq`&{kmEV60eE$N~nPlBqp{rA9g{=}J;Gkd?uh!R1RY5P~ zx+#|TEBd;bm8}4gq;7>7){R&7Wz$vI>*4~hP19Uf&BjJ!ip5(vZz}xTRw9BLYD^QO z2iyR+G%;Et7T(z=#wxWZ!0=J2@6ft%z5Px7Pk<533V@6SB9vU$;GyBZSjC(4 z`N!WJ08Q=M&-oZ(9R(^ z>!gV!7>H@OPAobz9l~He9m0$CQSEy|C2ZLkp6XA%@_YvgM)LRU&M?2S`P!oS479^M z>&7lZanV-*jo!D)m=I9%yv+#C|C0&uvK^QB(hhKQ&d$j zn3CA*cQGZijd$gwus80?No6~}zEyD?);CiBxuflT5^<1#QI@@u3 z%8xc~Bwc5NSV!2O=a9zIb;dTNU6oB5QP)Yec#jAVKCgurI_gh;M)rW-jwz|Wiw?x# z`a&JuBbumbdte^0GLJ~=I)&F)1lx_`kMxUWD(E0yEVaB32>|NVP=h`ZkHEU;)FcCzJsGswB4#2o{jJ4)O!K>hp`3P&KnuTi+a=K{)Ztcos(63_P{ z3;RI(F=01kMmQIF;i7Qou3nSOrcUw3d^619gbkJ%>Tnw146!-GY`dyjG{Xh4*Gw$; zKA}G$YGW&Wzz+kdeIq+m^#M0ge|&~Pb(?B=8b90B(9jF7^!VMpV6H3<|rtLXbuU zW>mwr(KU1J!0IUjODR;%n!kS91XGr7xOfM%wLV-TGNvBcz3O?HYDxd@} z4s9ZXDQ~Gln_%|`PkD!6Jl-KVPu4^;fGXG=l6P_l1M(!D0|S=KXwfzr`cwT5^&6=N zA)3}(qPW%$!5~D_IX;{xR{w(A{PPQz^0pVu@PcFS|AGyP7cB8eRWF!T_k!cBa4xHT z!SQ#zU@v)}u3JyPV7vHx`)=YtSFO(NRpY2y!u_k}qpMb@qG}!Wy}9mOjfpp)!QpT@ zkj%9;sNYaQBN0$;2E?rIVTj_kL2zHhWiA2e;tqHZe+@Ch37E-aWC(sw))Fn6v26G_ z{Tt))pJx#Q0_e5<-jhv5WF+fL)uqn~a4lMv7y0{pXY|p!OV>|`UZe{4;ycNf!$hb%%$Fem$+zd*#bvZ{E%I@79VN*MuT_0VNxq|_)cwbf z!mIxVQvbQ5_}<=81UgE}{X2@E?kK*ue*>brsR(M49mFsjz<)ZFaIr{^*i@&#OUH-Xh zF}GLEK-D_mziP3%YB9H0&8V(wU9Ire)mN?C9aT&G$Ew-I-&?ixf38})+pFewt5C2$TrM*m>ZtRI`lUZwu*m|kezAnM=Q zG7KBc!`)>(8CSk3Bn;A~zp~{7SP_itgS-Xm#Xj=WfM)tu6cT;Rs{0@>P=Crde-WoE0oz2r>JW}Cg$-$UgrtcVS>mwlGbGJ85_ zL1lT;5R$NmnwKU^Jw4=8Ft4)NAz(K9+w5YNndh*J*=DYD7J_QCpM93kGIR9VIWVu% z7phymq-fayI5#v34uqw27hvxq$W^#k7DL=smp#B9cm2RtvQH2?WwPr92*0|jRq3(? zJa0cvm#v|{`z>8Ih3>dXcNqyM^3|C#1=cw^88Qj0j-jfJK89zEJ{G*c+Mj{re$MEag4)MJcdCv#({mk2;fyTV$$RnX(BsvR%8&Xvi!k zcb5rdrYA=}4O20@5xr)c!<>3U9%~M@>ut<3hd5`A+2&y9EJW?*Ae=43OV<}#xANp% z4iAjEgC&Amk5uLmc^pE-p+n^>Fg`+a%_GBgY3kN684S~s;0NS2GRCSqT-MN0gqn5@@zVBm#pMJWT=ZZL=oRGKWY(L}oiDm2Pw3dE;nPhlr=in$Y-LHg0bs z9pMm3becmX(^Ah!nO@`JhS9Nl+27eSN=B%uBjt2>-+wz&PJ~fSZh?FipTqS6xe_=J zY7{<>-Q(p^fIV2pCP?6^BjCwH=#vxGz=!3A3h_iA7o3br5Zvn`cI}DiL<`v#cDibJ z(_EeHf`}}V4|F2M8+?dOU{&})m}st%$_~e4Ggc=Ao6IR4NmIjhu(^oV>&|XKS8Cxb zYAF=9+UgDdBykSGp|G`c1aIq^D5t^#X4*u#7y=zqD5t@^Yeu2m2{}-UNpcG#GpsXH z_W1~=KzVuP^XUM^jzMPyPUw|xV(oA`gL5DGL zE*fE;ikv4m*O=RIh<#}@RXiV89hv4_IsxV?bLPvZ6kozFsW>=stIqJPQFWKX254;6 zVPGAjR)t6RH8p%G>%eFA5OWdl2R6%if3<93=61kczuo54WNfh4K z>ftBk6GwHm&;-DElmT@8TNpFi5kz;JY%V@b5PriH3JO*?w#jrX83Om<=Oe)0{$_TR{stxr&zb@haM& z%JURHJHvYQDFB2+V6^XPV2eXwbaJsQCZwh{V2O;=@DJ{#vZsy={OK|@Wu~rw2%wK# z7YT#Sb7$;UW&s9Z6FEq}B-dd{8w3v;4d-71FPa??t$YJbT0BoafU#p{@4j8NZA160J{b=Lv#zB4rIIG9xW19p z-qKpYtepJ5aGB2^IM`8xl2NuX%^kVg28m46=1JfNGcQtC>l=+BJI9YN92N>4B7seJ zh(tEmA(EKQ>Wg=~(8)<*u;vBU8)2WKUYO>l^KHrXK(*i20XlKGxzz~5=Ae_egNdKj=v~liM`~iO+#GpCF=kr-ACyvdKgk$e;_hEgy401 zEKGE_h@%uV*c%Sv#dhGHJc2x{8cye-#+Yc4qQ|tiDT$=6wd%p?FvEL7Eyg*x0KPFD z*7>igv(sTNSgMvn8EWi}7p*dI!LgnqN=%+K*7a@q{Ob|qx$@Q5fjH?|j>)Tm_1bdX z)9PFMSI9s_N3y%>Zn&Kf{OIAE*@{LrC_A~b*k_+?$8V;J6xDAZ*1?-gNU(6-=qS26$N%1kLE|qKdz5z~f2uuKNe21D za}DT~w^V!mb6w542KD9N>MeZ~rGC8zmz?G*<`*DHgnM?%@|w*W#;_Hv{8F~ro?cyw=c5VTCx*FdTP#_ z@)z9Y;kV?^xXZ9T@+34kZT?4|46Q?3x*&b(0K>mxx(3qy@0kzm6o$dsab=|vLsDNI zm3Uxg{=gjlA!?by0^6>7>f;do2E+AA{0kB@>PfP2O1M&2sJEV!es zqX*>}0lSu@V-jlaSZm~Qd665hI)=5Xc%zn*)K*hJ!`au>^3P;5Rrj>4rQYpF11VXn zenJkG-Stk(D0~F%PUC$;CVpB*8rv$1*r$tt%ll~*u|s`+8W;F_&d3fhmFaj!nj}#j zI3pKf^zL^S0`Pcs;w;`voVD(AtZ?G>2-}Eub!n$8jH7cA72+lAoZg{FV3lwKt`*U& zJ1b!G*>mtwc%S`;{aiKQ*qCc~nO>yQomyF;bG6+hlq|I6of+}8)14U!H22PoL^}4) zj3hem&WvQb7#ShA-6n;;d?!mP-L2Y;!sTA=v;?LrcXOW z3SDCp{Zr{KZA_TfPe+r;h9Q2Q77dXCZ5Nl8J0z!nUznZt&Pp57J7Zu*@BDajN0v2GYYTX6-MUAwEe*OIY{YwU^HCM49!FtA9wL5}E&AZ>o`Pe9R z{1#(VS9RrE6xT(K_)fwPRpnijn?0AX+~{rvT*A^G`>H*cg-xg`tfm?g z4&ndJ%d);Ybwy6Ak>1cR>uwgkT(XLO*25`qBd*Fr*td;r4ukaKI~R1}ElTsLGZdj+TV+>m+Lqt^LDt^q#9)<2|GBfEmF zh4W}wBi2)^{*(pnbjNK%9))fn;>+#iBXXYnPW@q4lTL>LqSXXq++KJV{uiTcYt{o@ zcs2uQ6oSots&bwu1@P2zBDu9nWgacyvn`y`yV9%(tr+^t6ZfHC5ERs4f&H1sLmZ|>mA%HbZZ-@7YwU@}+t+^tV~4qtQ+bD#9w zfgFfwKi~~6)<3=~^he2qp3#5QRN<@L|uPu!CWKvDkeJxzmL)cd)6s?t9bg)FFu^PcavZWCLJTxv|0- zFQ+lUTeizcIc4&+8T^zA*#X(bIMsWHOcIYaLu^g8X@?9`ukVmU)Za(2v25~=j4r=& z-B5krkrBq@%|tWpY#Z8)278fdF`}(rq{Ky1_@c+rdR}C<iVcy7u#ufYxMZ?!=8^x*&B5vYkbvD6x*w%mkBXP|2T7bFe?)cL=# zfatGY_*<^vc@6yrspVH?jGAx}!tc+n%Ffo#Tk?G`GR&ImWxNGsQ7fUQF@SgtY2cTK z&of`G`CGQu`we*DUzY*uoVPI)(u~+TMtBw47<8m{48(Y;(WQ}b0Y+2!iB#Fq*vq02UcTahx0>W@ya2&TrAKt!`lg}O;h768E@4LH>T*g%JU=eIFpo5GiX~2)zW6hGmt`rMH;UFa`J;nV>ziY zvth3=y{AXerWQs+^=OnatHz9b@@lFD(b(85i9=JQv@miY5inaADjAq;y>pn;w?XuSn$ za2sPjchINBc&F`wTo6(GXpf+_gl0rrWiDqcBF_ZFVPo9`xSTJtF zgJ?KSKUgq@kMyJ&!T1D1(s1D-)icd#jor}fG$RV8LaWn^=8$uJlxC!ajMlE2H7Jb0 zT(0c^)O{G1DDT3eHVT&73)y>>%br@s%?i|mZGR&iYZ?m>t8m3Kjk+Hwu7Uhmt(eW) zh;<-G+1M!Fg8c$*v5XV=oGVdEy!AI-N1VWk4fZJIJE@>>3_p$ILs23cL(QzQ`Lm{s zR>y~sK<^dEezUFU*cBaR$vF})2~5^pv(@ov+DNUR3P`@cW2scUgOP^Kb&n243^vzl zc1Pn4!d3H5#`Cb_*x$)m55dAioehsC9baKBwJ+T$hA_8F26{(Lbuhy)A$rTpG#0_W WV`_IJP@U_9FO+vj*D!R(GyexX%C~d? delta 41417 zcmaHT2YeL8`}aOGyLT57dO~{d5J+!?7D9jkApsH~ARJwK5_%7phK;(Cp-EFzlpgU! z1;K(91VNf00xF0i@Dsbh`<>l@3jSX{;hATiot>MV^32m_=3nujzr=q@Abqwo=zC6Y z*Se|Od9Qtraf(8(IEDb$I0^t~I64A$bF>1Cba*O?a@)ZHUo8fBu?S#hXMpaB0DfTr zzKt26h36CAI8f_m>%!@Ay}&izGOC5z&&C9evxe(CTs1GRCTb|LiPP+*#gpyBizkk< zC@b-5AN`Q45B09S;u>nxhVwu8Eobm+njdp^*r9$*Ir|s5qR?9vxlH+1@ln<`!OxWN zUzn4{l12H8K4zm>I&)heak268S)`@wMEc?4#Lwrq=-5w@Nr_ zQ~nT3epS8e#WVQ@*Ft%YzSGx3%A@BqP>sBQct;xXWs|$EG7xm}~Fb*`C`cr@x}J4;1wC1OKArPf-<*;Q>5A!CwP~eW&={D|K3wan)~3 zX75~kcF)X?J+jp=cnls=YuT{g`CaT?Gjr^{GYhiq`6+BZp4Bs7<$RWc&Qwvf*n_uZ z`I)^7ax#0^@eSDps7u+;XDW^F{Y+g-3q{F~%(G!UlRamvqaG2(Z*wp0Ib`>WA;Y+P zXfk^g^}grH<5~CY?0kDpM|+Q)p55(*`S$!IJ_7|G6+0)We!jgUruthZZfnUPo<+d7huNbN%Pnev_fS5+mh&nvtq}j*)7- z+(<3_F(b9|MM&eUPy1`3;WpBT&OvK3zND}8eQmrbOF!8rga+w$^=|E&TX%(Ofhe&& z-|ENIT76}^DB7mK-7cC|=|8knSe@t=H3#ae`{(K`RZ4uHh0~9zm8P14c*VEu6oC5f!1Ahzj*i{1?Z{M>g)P6e|kmVIc*O0 z)O$@2!o2B)G=vI_oXYzdsm2Ewsf7KDxR=xl4cd$Yf7X zkMiWUnf3L&`MKKUsU;=j^^Nnl)b4iVu?CtFr*O`^sI#(9iCdZ(z#XoG^sgUVNRQ}~ z9&<$u(STGL=E7k+U(hg;ctaiLcA<2Lq+csY)TP^35<$3rPY zCc$V^o{6YzxQS?Nx)>af5>J|WD_dtGHdZU1kLS(lfH)e@6RjUdX)Uli#r7sFn33Jt zDuK5q>#-m$v<2p|qm_?%Jdw|FrDqjBmK|qp=vim{4pk@aXf{-Dvup(o(LY}%$gWS& zb?#_7Snv6mzH5!D+L*Ffq07o*^lb$%FC1R`^2S2qPc;};8@j}UQTVQ>HI9BG;cpqK za)n0eVIs0`u|y|HFj;~r5=@n#%;00jex*1JyuyH$2COn*wE-6xaFGG=8{mG+_4Q)F zt`#E*b9l(gBJbA>>Kg_;V8DY0d|&@;Wo+4(27cavUm5U%0WTWx8v}l8z#9ghZylucc2D~dF#Tc-q0b3a`)_`#ajIW))swr6~8<{Eks?|dp)CVi($`1;= z$&!>G^x&>v^78CawQoG1jZtVlQa```O&U?VW`i5mxHF3_OksA)Rl=5LHsj?HV`@Lx z97Qy`_U20siB|+XTI;iEEhWf(%2%1K;BUFIQ#r2uMt;shGD)bJ1UU$`^9V zK)v0GhD+eCiwCq%SvekAt zwV$_>6WCK}r{Hg#@}%;La*FCv3Js(uXg6J8^&voyWJ}pz_8kx6?f76`$!qyZykz_n z$5OQzdO@_vV?pAT81@pK5%!iW%=J_&Ei2r{CXAVA7dM}0!7f8f=tOfZHQGfqY{kMD z3m0FuWGyINCedKLxhA5rp(diSsbWzplz80CTiG)P;$mYvQ?#5|u-ZQgDV8ZmMNTa9 zr$yq?SQbb%VnHkmr=enNENexT;%qDn6M1x}Bxx_{k? z$gQ^Mo8CmOwOhVjP1LZq>lJ_Q(!f1b&Phk6-uN?5v1*srMDOsmTD$uD*NGa{_PutO zQ{&pcH&ssV`oLSusA=twx1JzsqW^fyON1wD&GftjTJ4r!rV#n)!M~j*Z~f2TULY_1 z+21#jr=Ii2B7MLuKk-6OHB{YlZq`S&eB^+vSRQqflv zr%n*1Hu4ZR@>oN9R`2&$b8AJ4mYIrI#zx6*d_&*!S2V@xm;Q>Nc)i~3I6A3k+>WIa z`ncOM^qIcmb{d`2kKWFtFZHH(VqGuBYpHm9;YS-(qhw5soQXh zbW^^F(OMv96xx2y;w9P@kqc9f>qqaz(^;M0ji*z3^4$bF^E4&81i7ci%09R2OAdSK ze_nGDL;R_+Si(pX%iA+|ef}rv@+YyI2QI%#i}91Qh(0HOkM%|Z?w&i z()5wQxKiJ!Xu3!lW@1hfWxoP$#vInK%aAe#*8`O4nCx3-HbG*8J;APMKLU z@*kyo>PNTvQj&fRwHE93wkKi(XtzBca(K!1WIwx)=FtMbP&{=K-WfG!{7Czl5%vk= zC(fY7`ho3!B=j%02h-UaH}p<(@wgjJr)WX-X&Oa|8TCm(_G#3BzNZN1UkyN{c=3cM z`HDr2(8F=!S|h5YSef{Wg^g(pwGzKJrW$G~7B!(KDMt7-rODL7xu_{kB}x{m2mMY- z&O08Y5+w@mN!64fYn){%r2z^JsI{%gCo#mEG^&mk{c@njA?n$98RMQ6Qu%kH9hJK_>@m^b6LmiyM+EEIlPR^Ab=ut*l zPRha;P&d)46DCZKc&-yUsjGM-o90j#aXOo-sI#zlrp=V?bm@W*qC98wuF$Hfr+6lZ zDkxV3ccY!uLmcZy8>qW;YIoY|Qm=Q@7U|#_)0I@Q;Sp*o+85IEFt&VKNQWukxw|jT zC9SV}e7d)2SVZ0;zdyZBg~GLnPEdjKVi7eU>f^jQ058!1vEmU7eUT^~MAxXlun(qV z_4+kUO!xHmpRKev>(8^(&YBUVf=jPfluMX29ni)a+D|`%@D}rC9ocwR!}hbQ+#UPn zXugUc!n7GD*7{Q@_NBLFGDPI&sY%x5ky2+MeaYLwG+n%ur^eIM;%uH8YJDaaToxo4&OLW~-uYY>g9QF=ts+@y#en>4(a13|$98JmOGR!?ORSIKW zME(%W@w6nH5KFIC^YCIsvLXVq9IgIR9&Fq;^bKJKxbbYOY>_+Sk+o} z#Sn6i9Z93940|pZ1ZM_>gbmzkK$`(w3|QZQ4Gh@OfK3hPZa@zMdK=KkfW8I{G+>Yc zgAEvNzz72xh9qunVPs-N|3~RXi-G67T7m^kqeQP#ny-#*nwTZNdXBk^?@DP3jc^X0 zM9Iu`j7Ms=+#|V?B^s8&LiE}cdY48!=T61?qDP$vrqQcJ9a;K;MYjACl3y_2H#2^VvUvC;JGM$MRVNSrIC5V8pRh6O|A zu$c&F^-M%%ZW0Nt`G$pX3u|Ojt*nWO*wAN7@fcFWU0H%LtBG*tB9Sn02T!@i>YHQ> zYiJ@?*4RM6k(>Hzfk-A54c^)>i94%F<9LGmU)RA-!dB&i{HP6 zoI1T`J{8hb(RV(&YKmy@paWpaR8G)E#Nl$P;ic}m;z&8fkHrUBj7V+>(b4{{rREYP z)Xc!>%y7IBJlA=|}HvcF)5>CDIRCD1d@{LNpM zm#_d!>F|k+?Z1a|_TfELWuM(cHTK0l)WW{Lhg#XSd#H{5BJMC2sEtHzo?9@~BID6kjRCYun zVRYKeTi8Vtv9j+C1Uk;G5Y1m2K=)VriKkW8^VO#*hlq=A%dy!o=Y{1mOQO{Q@)R8f z?W;*6-TGIQmLUa*?cJ=N;`O!MmHrTW)3B7zh_BMH?R+H@X+Pq9h$9 zelzn{e#b;?sw&Q=W3Af6;?~q0`-+>1aJ7+%sH(d}VlWYn5*F3ZM67C%iP+RIk(B}A z>autugZ$|`@nQz#j&H@$3~JTqcR4-6v6mz)NwdWN&h)ww# zW6YDquuRsMjbroK3buoNz`kO?K{kux9e96U!XJZ#_8LFJuYlFq#Y>gko3@HK;2D94 z^o2~G5`W5MneeUVer0?H<45xY9eVo zTHGA3dV;qgku_LE@C4-D%zP3|W4&bF%gm?n0O64NFf*UVo4>k(x)Ev4?kmZiNOcZb zMeFI+=cs_l>MY!Z`AZh(Oo(z&@dcKMr?_>;;_KY{qLfu#%*AqcGx)O23HG)K766mh zX)7Jj+&qGly~TkYE~cwfz%1=&?2hEyu8COhuCDc ziXC8Actf7XNATtRW6Z!j(Po+2!e-+!p;|Po9woXO0DWqSu7V}-L=)jWRU%=Kw~YrH zZ*L+No@F9d-o-#rQTK4IMGF_b@#lf?TNED;M>Q6`dWC^tk5t_YfR^R}O)%2t9}&^QmjVL5ig`$uGQ=EJfL^ zoPv)x2%|BYp29|QoPNhflFi1!U_M64g3)Rp`+@uLu6!DQj(;X%4yvuVjpv9@531pm zEt61g;hEyii)t`qcf|RNa6+pxkvy`ViKx7hiDO zO2*?&g!5z*QF*$FXuPfPeP4~SK7zl@R2Rd{UT6w`w;yX;Jomm94!C3!TK2bZ-_JE6A0FjMjkmt7bwWt?l3rQ zr(k8ig1@!OUgb08JLu{m5Jmbz#aRq{_B(W*{(_1VhdDonRYN=8!%ncDcs(A$v-l7` z9irY2en=P&5x&^&+vI@xR%hQ>-uoB`R#JJeCFsiFEX%^5gr&B>!vi#$<_`hG{V*Xn4#lE;k zzM+UcNW9oT$|n3>wxPHt%hnez>)?rZ^WzyzEUqO_e`@fL7ZU$|!PRI};7ioZLM~?U zm&wyYHUrP!OrDbM>{v(5G*6>wz&=^j!z}uiEb4CHd3(vzo0|ROSCaq!m8RnA5%Sd< z8zr~xB+o!L3s(Frh- zQ0Ji<?vau{xVOgU>?8gz2gKIr`Nt%016`&r`{pD>5&EMNc?~UMv2RPE({a=e%Sa zv0~0wPz+m%j0^OkOH22ROsVl`V#7snf|iHD$>T24XsF=bGsV$z{C3bq$gOW&q**R4 z+}mdvnvLjno_w7BFVQC|1l#Z{uu`Oo30Gj(P7xnoAv-Kq(ceJ=O%hAKgN&Of&V2{7 zSAuABl}cd=+jbQefjDR3_fYSlA0Pf7c{{iNfH_5N%*;2}HBeqxl-Eh23|Qv&&@I*qR`_+W{JQh*d;xz48%&KQTkDk#X>Z|U)Q%~?iPc|P zTGMTDLMFe6#^)^^t$(%F+Ge51w&Rq@Fm#L0ThguJDO$25mK>s38wICpZ8MQu@)ad8 zbp8BO_{~=0%~O=7Hb+VE)+zAu`llhWhl-ffc-TUWMq-U@qh-o!?B^sK5qE#Wr{{{A zTj;+Y!uB(Cq3&Yv&)6xui4T5;@hC?O|AqR%o`uP0;IFi)<}YxTK4S7;Fw^uF zH~)g%*Gu%c4Sh0S?7dCPDNppdLm$Hg6nK}uu}z`^1)IGzC3YovARz~JH&o{y1~g25 z{8h2$cY4jHYLcc}#3O&u9&5Id=`8&Iq{qDn8<`;n9BRN(27FZP`;+_&i;YZ)0ZR=y z#eh={IL(054LHYu^9{JtfQCs^ec8Zw8SoVY?yj-1N|=_aY-}}5OTjK|5%m*0T-Yt@ zD>l_*J7JXS=gK<5D7DI!?I9X03hJ{R2<_1tunzQy=-hz4NCU<72JCSds%AE1w_!_~ z-iUofL!2EOv;G8^^XevSB-Q+7QIot(ht3G7=%u_ISDL1d z3}#+7TAreHNraw~zbp<7`buNL)#%5JWg+yauv?)n z&lFEuSuiaYTdgb#n$TB2aG0(5c@yFM8xv9a_a>t8n-YnpU*Vj6nnsA_?(Ah6?#%RH zTZo1^e{2SY0F^tv(S4(wr9R9`G*Zm;Wv|m1XObTjb(l%o`m>7+=8>QvmI3pKKpN^S z3q~jcY$Pi}*#DR|(Y+*v(7}t&fd-0HmZqZ z2~hPD@;_hJF(54`Rq*wh5;n#rxx|Y4p8#^pT>TJ%D*R_)zTa>p*4F09^U8-wi!aWIM#-p1Z#M?EqfcA@x*rQ7%MMx zX0?Zv2n>64ChG+w&+D125PN*1j+pMMIM9(fpyp;}u>(;}l+y~Nk4faFoQB)xefl5s zVOcOQEr(=x8Jb@@tnzF4VKBq3qGz=wj@#4$!clEWz}kZCG6Bp)nlQOVEfANhEy1); zxGbiV=mJYHQzOL^)e-^CwuOms6;isSs4Ap%iD)XMbctA0$mtTXs*uxF zOOz!mPRo>$U79qQb`kS6ODt;YW+Gh8H4t$-5TC0Surx>;Z3|d$s60yw;0t#Z^9orm zw!cpbS&r(`G`xiJcl33}k^Kc`&AHGckHFD*#L1 zD-(BT6FX}pCBvnqFa@O#!R+=E@v~tU5ks(Ye8tk4ppPEP+F|c~VJQ0%8)3~bHj#un znmK8YcylyMq}Rla(QGcA6BEb4@X<`rSi|tq+(bC$mqAfkZ;6D##%bg&Y?g^w*&+k6 z+1SPetqas88V7A3(>QJ%i-!p%+C(^OE0IJDtnol&BTdA@W}1kVEvy;OwnD7kHlBS) zL1M)Ov^h{Ln8+qT4*q!}bETRoOzj_|JgeYuFM@>5D{u=@6R3|#luiAxWzD9Av<}XO zcVL~mN_Uw%i)QUuABK-aAjbw)3%Afo_8t2Zp4ecX3@hg#UdpTZO1@PDU9og2^XADc zt9Ma;L7qK7uSZT+QIG7t**)wDbWFxm8p?fEwlq5Mp8qB!@LvBWB=UlP6Owqpe-o1V zfPWKGc-f$TQ&Rbme-qO9aA|)q8j_Q3wj}ofN&?S+fRf1jJU~g}eIKAC^P|a%< z@JAjfl*;W7P}2A?sU8>&>X*|4c9|}+ck&)4Ch*=56BBviKZ#}L`$@e2KdB}$nGbxJ zn8F7?OiblNA0|S>H=CYqFUZQb%T}`B2Pg?;EcpRaBFlMzlEel*KuKn$4^Y5!AE2bN zl@CzT*w&^z8a-z=sCPkuJs%ORA>u%9-n4DXL(dXfw})s+Z16+0WHw1O?!%k5seb5D zDqHmsEsbq!!Xwd)-Uy=YoM-QoGa#Ej7eo5M;`Xi#O6Ku=Oic;v0k^ZkQ-+s-r$mU2 zC0L)~lKnh_UC!V<+9YtEP_xvDNhlQ}JSMa2X`V`of+(xK%D0H$ZjBhLMQ}P?WNr{! z@?jI)02|B?2vX_J%lIZGg`ZYNw$d`Bqx8#CYb4WbVq{l{Ay$#sjYVmu(`@Gy7Q*Ou z%~S^AgYFn9r@Kg_Ns&41On0UrK*hqC@zBb+OkHhE_18S$gBvkg(5Du6rdEm@QxSRc zfoL|3#ag=sX)UBFw)j`_W{`Ftord6)DzRW1YmOap*EH}jiwK&IoFckUM@|!E)A2eN zn`G`0ae6w7$YL_w*h30)3a#g7`A!%)2SQ}CB9v?ko6d5Tb`Z?YLY{sUsz#u4Tlo-P z$PyI4_ivRr+K9K*#-M`3;^Q7HLK_KmoM=DT8fmq#$53vRIMSWPYVQK=D7JNH{@Pv? zd0(8Z)q*33(a*?y;;VThjB(VY;r5XejZlMvz)F=#^CE#8{2?PfQ&lDtHV($QMAj!I0gcJRWt@l+r-yhk+_IGUD2=W#PY5z zthMYxcR6tsT83m0MB?4bW!RqwAVA?2I>nl>wh$>6vTc|=@i1Zteh7sX=s@Q_W+B=F zpl!vHi)xE{kswbpt$8=1RDTP{K?r51Vdt}2xjYmwUhjUQjmspw;?@#T0{Yfj(ONEY z9wL6I3dwGP*1&30W$nQtc$n%TAYnFjrHLR+3)CWmNgTbZdBG2fGXfBC&%drE;%j># z(?@Jc)goME;CV`OEjnF%g=i;nB#~R|Nhj>{ep+xSjEs}CW)?0`-d~J;-{PmeiD&Kg z(Rb6e)4;lld9KvKwG7X@HrL{%>$%l|Fil3f8v;|DRaJW;vs8*L@fuMLDsip(-cVt@=4w z&k17V92AQ;i#J~%|0S?u%qD2AA3DVsd+ zK(Q3@jRSlnx$cL{QDc%bzJkTen1$h$kR_yv6&5RmG_+d4CKK=2w2S!pF%}^{dJJj#Cr`{QgK6!PyMXS1lC81)3JLGZ)vCt&8KPR`JUP@bU5CoX0`Ly?VM!q!t4 z=SNEzympFq!w{>Ka9kN*f>B623rjRUVWwRt&BDQBkAGst>WV4om7tN@oDPyJ;j~`>7 zJ`}6@AMr*xBBV2GN$-jL&MbvK6bm{t|3JIH<{xciQ;Mey9dDmD3dKuC*-M6xF@2#U z#XFs$(>*4>?F^1NTQuqdHut57>jGAGUX*rWUVJFD5FkGEt9YslX2MT0@oqni{(_!} zgAP+B+Yu!=b&8C9nug4r#K&bA{brUH4c}(XY;^PQ zoJZy``a>#Vo=R&4ew&r#iOiln7OGfjPo8dFhbSH_ zS+Nr|4e@8mp&~O6M(Kr>%vGZ|6E#@k^0=3r(6B_lE!yVcr311YekF5()L&m0Yx8)L zb$^VOSx0mi*YbE1ocWoP$Ku7UI`_QdOCNkVvkzDg}gSv z^3dDaY$J3L>g62vEaYhzG$uX=m7t$E_Z+MoeZ{a%ND9T}O;{!c&U4R0FGdu`h!BF?LMzTP4soLwn*nRwL3ZtL_X3uqLmXPFHV^^PuuIu^H_<2>PJzxcL6`#XXd)VK zXCjOzml{YpKjbl4$p+fvq=Pg zqUad-7F7`9le9CG{t z=#7)ax&vUqrQ)vx==c)R|7{qZip5TuOceFrff7GKzPi5V6L7^j^3DEW2zV( z%qCIr8GBodI?6m)MVXj;6#j>bc``j9njK@!Xs)y6F*c1vpA#rH@^etQ`Lyi`>=n-) z0oCIqusKKB+spEn@ta>@&C<+n;Ak5GE{( z9TROYu^pn%MO1P0EPGkFU&321@~wl7ypvcHF zSYEjQ1D<04EUrR5M+Gu!|7{cD>|+yA*>Q;kLuEHgSlG8FVrAD21e*A7rl?cep8GSz zx-4zaLr_zUiE!4zK*XIfh^i6oxgP>*MoUr{249vH6UN?qVq?$Me8oP6bMeR(b_{k3 zqm%nwMJImxmF&dtq2NDz0Udkod*<0QTzOhiHY*2}Z^#1IL6-6~4MPajlTgWb(0g=} zend2YFLuW)*hj{&c}&MT-^)H@mk~VTja{-kys&e54Z@B-;1{qkJBk%Y;4z*c4_!91 zntl@>;qw^yEZ!U?spOH7Xra;lMJ&k!Jc}L~RMm(JE(WGuPO{$h4$djBXXy{AI z5~~v_3||jNem-Nvi-}FUTvvp~^m;RlCuuu0{6DLYOXkW=r)}4S$%JphiDTOjKK% zMDhMHYETsaaEW9!`C(#;n*J~`Rc-q)F-^@h++uH~!q=wk69;aq=pHrFL=s@ZGbo9$ z-~sW1%xUD4VZSqw6xi4b7U1>5K`*6_|Ht%6#DqHq2F^xSh57)|1%FXF%@06Wo z@0^(>EhYi~MK8-wUAAU~0H{!e-m8}Og>WH#|X=_#!IKk2Eg2K43+w=|8tbpNyP z1?CCmcxYY+U=$pi`0%qt*5zSh5;IIr_xi!CC7BgJTr!1KJWNbwLNp%A-OFBh0;S~yfL5gdvC{zJq&^#uBY8@K zv^OLgcN8Q!tiY2UHo#Pe3t*Z~o=Ww1lqb%r>m0uFV^Zye^B z130`KKp9!i0Y{h1z8h06zjbW6{JwGJ^7|%~%P*T)-W0I7ycu9gxi?^GxgX%<@<6~T z9#u)6$Fzy;;<3mz+%gZX$l>>SDy*#S zr4m5dU8w>(E9E?Ttt?v#JpAuPQmo?^F%OWFn;svz(|3bA(tGT1~tPttPb!)0?!a znSj20Zeu#!@D~YJ3d^RAV?Ou(~y1P&Fnzg;aL{ z46VkOQCM|n!0_rEz=&#mA4OGT4pDS9zKmK_WAanWYWYdA)nftUs-|xS5*-rWS^xE5F6{lA|MM7fpcmVy!yv+%D6sn&bvSgcHoASH~2Zoz&k|Z zHcJ@2B^qzHgy6j82PUGjqb8!UGbUnTmrTUUevn8Q{Vev*;GRafw7ecK$wY zVOQ?sR(A6~ZexE4$1Lt|G|^9Np9%4bvA7x=Zx0V(2OGZw4`6#2{v6H>e(l14CV%Id zdi*7#P-m5!?BEcwtv-L2f}On^@Li-fR_-dIUL*cKq_Q}1w-IjzO&3WF!UCt7h{|W1 zh{hczV&Mx+#L5?%h>h!_YZI7rf<$o>xIvx}i<|H$OHE5HGu%bY@5Uk-|J<;KLqGq* zL^!`-A}YUZA{xJDA{PFWL|W1BHSW9(4)H-kUI}l?Nq2q@j+EUV_`Yy4pc#Li!kiwS z94_D(vDpjLsf8%@=C8s!8|B0IQMB{2564;6I5EkOe*kN1hCe?5L+fpSL|4GV8yUz? z*Z4tcwS+;RND^(r_+5z7ZNm8`SZ*(d^Is_5c{+l>NH|kh9wlE&5nH11>&ebu&H1-7 zMk+0auY$$(SPcIX(NViv;?;D~zZHK27F_pOe#6UM0RwmfTHdFK;Y_9xFvGnISHp1O zw}yAI+&f%ZWDT^bzXixENtpO?p~aJ_lSKI%-rG7YO)HWntOJWI5u$;xxH5IRXz&br z=e%h943DG#iHS1zm3T(xeiDbD;bGQqqO}a;tpNy-k9&r@SueHFGNqs9LT9Uw7}8sw zx%)+wti?xtEmp1NEnu~TD+3DQI$mEie+H(qbK=jnJVo4CVQD6*E+T&&jBw#A?`3af zS#hw$sOhFyyAJldGve?%D2mr=ywGPI#O5Rn31YsIF(mCoR0@Wqt@Cn<9Fk6AQW}ON zOJt;DNIE)ir_0{W6p5kA(YrbY`*AQi+ zq8wGOU>a{!Uc(8UFr2m+0(P+mr{7M|FYsr#KoClQgwj98w!)YF8GIj{`}5Yk5C-N- z{tSPWe`*BM_Z6=V;qY$V6^Dm#bpIVwic4X$CDIJ>J5s!BoW`E54>LiZ-Z^=F<+VJE zMgDN^3xCRK6G`CbO(YS4J;tLX1ojw6G6H)HB!&Mf5r4$6$^76n6}H%TG9yCo-9IEX z@3}ramG$X|sKu;KvY=IVOyEXW}|UdIl3$&jZ}E{XsYG%L=m!`lCFJke>X)?9MsRUOE<< z7cX_}(LEdS9QHOaDe+HZTgQII`>hZ zkt)gquXf4mq(1KjDO%h-ZfVNY)xr&z8F{Udqz8)TXLiXJHxF=+p80usJ=C@TQCpv$ zIqI|6MBy029<%^)?Uyh~a&QuJJN&60IKnj%HkEBKhI4SzK5#nj)a$QTLzx(lrb@RW39gQjOf{kMOojD z*K#C-Sl1T({gWJWV{kxjmM)QfHBsDwv!dmli98-8iw0Q)pb)aZ72=xyT7YAXr7CBE3maDZtSA`nI z=aSu7K0>}VSZo=IHV$(38YSB}LZsmYDa_r+Mx%|x#I7-@W2opq7Hu3N+{dAfL%7<; z5AGxUT_t(ww;PScLHG^ujeknt;v}>b%4xQpc-B*)mVu#sh8R7?0mzT1!uo-q9L ziF~S&Ch^%un#>(Y18KqX4S)-m9{|*sUr?LT=Ya08vwdNtiTr|*Ch^Ngn#`{mX$t?z zNK^UmG7U-NcjdzERMaz5hJV-DrR)X9eP9>mIuk>L^rYjs9O2x@WbrNGCrgBdA?m&q zIwF!`qJ*i<#3vmkr#>$;!HvF>Q#`wWzP)!IjA8w=#XhF`h&Pz(s$DXc`rT|RSl8FW z4VRGBa1~)!I6@-=0kkg-o8QrP)~2F6p3oVCNsktr$78r36{Qm}+@nO)L=5*x=jDlV zxW|i0B^d5;BBK<;J=S@=d!Vys33ere>Eb$DsU> z&U|e&H(kp$3MDX{$Vg>Y@iI!HJ#Pi`)-+B05zJ#?nvV?OLDW@rmB|P(CIpLeidYhY zMY&XL4S~a|jch;yZ4^gB(GKrWtl&>Rk`&Kq>lYAbF1-oRdHIAMa>#AU6 zeWMZq)vIe_cq)D=Z9eAtba8Ax=J_mvEZ)}41g*V{vE8vD27@3YE%b@6 z`isET7GM3XXXI@;O+-JL@n7pI>aVsm5sPKcyhx{scwc62Z1#tfYsqR$D!gPy6^C%o zPVS~A^k~g`e0w9Yc|AI{p(x#ePHiBfHlkDOJ1=jPo$4+oJ%<_JRAg+zjBnz+y-D^` zV`t0n-|fgo}$fW^h+~waWlHq!+H88*`>bD@-4EkkJz#mUFz-ZwM}+ukVxBs zE)5jNcA!fG#IBuq)nD}Ag)a3I?zQ}fj&dyo$z#R`l}pMmxVHiqW>B88kVYar?>V%0T@Ute8$S;~m62D?1$^1tXN#VB)#G1L zJU@9a<7?sPOnjN<%lIW@_`}5JS1|mcqI5TgKSV^mis27-UVasaC~My2YLYiaDAb)I za84l^ChiqDlyHXrgn7Fy8_desN*vvNpM8n5KpM^h{Ya+%zoa=O4&i>ortqe><2kW4`Cnb)Z&_AgVIoF|<^Aok7gR7aU5He9uM+swzx z&tlM3O9;;4g6Oa2cUFFtSdjKhIM2oHF;7C(zdnpKi}Gg#&oc-f;)gYu?Z1nL-&-Q- zx0RrU7R*fC zJcRB=i)`$#`#)`Ce;RaAJR9Z^DEMfe7;*^s|L&KuuItU3GVd>4#2Otm@$-j)e`?^ei7Go~(ueE={ep=v zZU_9TDE$;a;*Hbv@@|HfM#@>Hk*ciFNHsRbNG)tG(okAzYd&-40PcQMbK&9 zA5zQA)BFf!IJ=#J&;tv_;4k=1sNMNz`SbAG|9X~hpiJk=bEqE*`|2;@oMMrYh2I#!1ZUS}U zCPPQ-svKGE9&z_FFG4hX(G^sRpc`4Kic0guitkWqPvL(RmF7CHUxjm}TPT*fa-OU> z+0hC5{8Vz_-VM18ey8kb^_9n!4ayWmr)01JYzmIQzJyz7jv_`y!>Ui_xqKv?;>-C~ z{t^EYqGN;@c1v}SQ>F0SHLnlu6*hUIy?39kIk_5mZ~K4KO(j|k{8{xD1B$I~Oe1-% zZ=`nCA9gl<-bQb2L;%ku-M-XE8zv7DibXlrW-00w$v8XbcgZxp%DuCDJNb&t&jgtlJdHs53_tq4-b9BweHk{K_ z-UUp1Ws}9gD&~!FDCiU7)1Ot`komg!(57OI$qz3XP-Pnd-RMA0qG z!Xk4PYM6!n#fqOX3;PNGUoZ>%IijY>6CI>@Y4L#2K+Lxf5XK9fJsk6~K&k}86S2&@8seb&?y z@~faHtTXXNr!BrrT`M#3^qe?ah5fFr_*o|Hgm*O#h`%Uuswt9Q5~bBRay3vamc-5C zt!k{ALh(&Cg$4EZ(tKg`n>umCn14q=cCNd2sd$40cPY&ixeIXh#VK*rUB%TG5I_us zLjW-l6#|HXXb?bv#LzEh-pc=~`3h`ixF}N9m!Pv6>)L`I9V%96Y9&;6e~Wq)O8<3> z3TE-B*`pTp=qR&CE$GpaW{+CXqa*5i)Kx8lKw9L6O2?U%T2bj(v7$aI9V7f3pwiLK z>kVY3C1#~oR9b9SYDJ|J%}TAPbb?VSS&gPn6-8dCb&6T54Yf`dE4)$bB;oIaT1%bR zePpdO&01}!b%t514Yf`;Yqg=)X-2K#HYvV0U|tHi(O^VYJ_qseDtF_tyf>f9SMWCw z8TzHXJo^?&A*7y2pAChn$6i=j_soRdPi6g0JHE!o8;B^r|IEssHlNwpi_-2NEKcu* z7-Q7%hb(1a{`>A>9qwTWQTkHE&c^n2Stda?E4y)DSn)Ev2R=1HYF}10PxKE`58_~3 zV6Zv^8s~~&bj57pAA+u!<-8uEj)$u0d?ZZW4);}=vwnn%e zlbEw(D>V^&h?o|uULuQgK%BZ$USQ#tpx(q`ag^O4)+Hl~&qcm~1E%Hi)i!5`6g7$J zS>4lH$eXQP6w$sMCXbl+Vbs_jtM+QiWZyOcv&Y{h%<)0E%kKla&b$%BS^<0RDVXhA z@gmr9xAQYtQd2FNT44qh$h@~Qa7*b&C(>z(uAXdfotmz7mzT_JnU|=~JsFS7Ahw^3 zz&+e2PDWcli`O#bvm0|;!0fegJw%)-i8QBA%)FH! zF%cU-F5)*L$|epo*v&a0P4Uv_(HOH2XnCKQwT5Xeaxj{{Phv;%<9& z0JPBo9b{#Voo*dvWzEdWvQe3bS(%2)+?^dd%gUPm-<5SiWnRt!U1epSPPcCAEviXU zZy=8^o|96FbP+@>`K!L2#-|5y@wl2i1tO%6_o0VBnS&*~C z09je!|5aH_iyU$fxJz(c?NgD@TJ%ET`H8oRNB9DR{n=Ei^7}(9+6!e>U0}?Z>*xs?j4El zjWoO0hVG4Ub{HkQH~jzVUgzCMRjgb&H=8>Ll*n46ooeW0>&wkV6m zD*P)-ZS2giLI5ovUENX~pQ?_d7-xrRvi=tTcm31VV0po2@Juj{IOn37D(oh)&Sz(- z)kI0oAFI{IxSOGTaCM@y!(4SJQGzq5N*zS`#!?SZ5HOObOn_lPS!kd2uhrvq`?u)SD6UsYbD|bOQ7*U(u7dqwawX54t-$Y>*A;X8w%x?z8G_ z6+4)Hk7^hHudpkR%c@xa@60(f!y+n*A|R`>38E}7kSi$U3L+x7B_iSqxZ^Hh#{0gu zsG0BB)!f?5rCiFBZCX~EyJl&rH?8iin_7Br_t$Op_nmXl6#W=~%z5TH&pFJ@JLjC4 zXZb##Z-R~wKogtvjo5T8e?=c5ue}8AUY>QjY%@*|kn=a|8?f~X*`iM&IdbV1{W8|Z zrtq1q5FTm?_umHLA?jX_%WK=fFS2CX4%M1#)9MN>sWUG_YOp0W?-fWD7`W4Gl)oCm zqM;?3yb~(GDEY)rUG1hjDWVPjw^`TeXp3O9$|5*jB13jTVy#(+llD#(p5rN(cZ6{k z-t}g314_GCghul$LZ@RC5kh9WU)TFUuV}XV%wzHdCA(^2AmXaV*`#|d!Yd* zRomQvlcv4gfRnE6Y@&tVY*68YgQ{)L+e8ZctC3sTfRm(|vCH+nP%_EdGYw=?v<(e7 zcJ28FoK)?l2Anjl^R@=8bZv*)!K;5(?;me_Qt5SXV_2T_wngrJdLZ^-LHqR6u=QQr zr@w({qb=|1M`3L-=Q!VwxnF8M2eTDD+IkMI?$`YRg}NNRb%;prj@|7uW zgZgnYQJy%6UQLi|Kf-=xyz%5A{TV_kjphH;D+o`bwfS`wGU1GVLec4U<#O`{eYfmz zTvy>IQ%~xz%d5w+yP0P4d9qg9uWqX1AH!xd;}i~)jV2%Kz@MEdar|B+Yjn}%x*7HN zhkSnBbOZMf(O@RZ`CN|?+i#}kF;r?EU%C2oJ<59vaO$iCKXzHNQk`fnFMqDL^WGMD zGxHAuJA_;_&Hr#%-6&Xoc218(={0aF2Uydp@Sq^H+n&$pmKZ4!0s)`g{tDRam&zd4u@b|dY9F!q4-7(<6e5e@NqKiRG$Ty{Km!0X`zdC=50 zBxrev<$Ma>OlP(4@Cz21pi#_=0UC;#5YNnnduBpTE~AIVWpzToA~VO*iH(?vAjPFO|&x{RhAwDGT}42Im%J=MU27sFzP>!JvAh zP?mm4{(T$`g*|JcMI>ocEFxK}vWOIIzD3xzMT!VVSgmTra49t}o-c)~)9{mDl!j zXmaXRJkV5Te2)W>O@7d?*GIj4iyV1~rb-~a$!NF?xq$(_9pF6Ypn=d3c^XH%11V)3 z!m?HZqhLR9ps(Wv7YdC;SE%`h!!$St4nQw#!z*qDfkXw)sm!)zu zeH*N(!XlC>BHO=*pTgwtp*6BoAB&wzn^;5|^)-p=blO~bjF~sf%^m_EjQjxw19}eV zU#YaEDsbXfmbpY4bQdp)cDRd|OnctNOQA(~@$7U`^Xi8GB$Za*C74E6+{H_$FREFj z8rWkfa^P9n?GW10>R#+58h47f5>33lnoP5AucpwUw^!}7!mM_!zgH@)z5R3=U3q&ooxXH4F6Pfn zfr+%W+yVclxQ=(9OQuQjuT(1Rhm#$={%OJN&v!7H@E`q@ z`+sTutOt7xg6A-C}ZRyx5k+1}LA?%3qNY<-DibNEOLnE<%5NL`GlI?c}I@=n}Ry zzsrl4^jNHxHH*;TYzj^sv}EQ9rnRsLt_4|y(88Z$N8r9;zERTz-lz^AtCwj)^|Fz% zoU*k5JF4$(x(9j-3|IBd2c7O{TK{ekj45Xj^P4Z&-{H@3#Dh&&t{@p+>=*(PSI>44&|5v;sSgFR;VNLvY<@*)a?mJo8#b%e{cUz(>3IHN87|SU%8S?+fh! z4heE|H$;Z|AZ^)%NdMAX_9?H>Efm}^;q3_u( zQ*-ssVoiM#hj#CWLqq(xTs@Jv<&j)HQq1qbI>VV~#Y4ZuP@CM{iWRBEH1)l2hn}@H zj<#dNICNDpiRf9B;hTh>S%R@Q1v^17#yHwZ4MCiY=?cMihHp1DOzm&V^ngsfakPh$ z=^$gWA(LSEKB#08Z_4zAOh@BrUzSWdsj+K~FlE~nAa1vV=jV9hATJ9fsDr&=<`Ql&iAQuHK?uq7fv#Kb1_}Is2?-XRt`%G`Gf2ui(nh(wu81MumXpWi-1rc z1K*u*kq)sO+wd1)aQh8;8HQ;!0DV*jw~n%DDinVo%k^*K;2|5MCVxy}VR%1Yvx7bj z8u$etDLIvk?tm!?;scALYy0KJH(4k$A(|4JwpZ>`^|!4$)!tNBgyQk(Zij}@khO2J z5WwU6+tHgHG9eW?5?=~sk?`TID4AW1Tvf$WCQqB8phhOoDw|eZS~A7*}4c=mW2izKhg_%s%WK*S-y%OSgDwMtO-f;*2r0#|{$JXQl& z0Wpxd5Uj9#AOi?wig7d_8cjqid{w||;R{eUm@Od>7}o}~E&$Fn+841`3C#aEyMSr6 z!qH7h)InqTfTOFDN{9Baw!qQFh#$^gBk&?HC3Q&luq1UzX4XsUkjyaRiOj`fn_#8KseVD77)&< z7ZwoiFXJcI3lFk{Js_NK341_zV7;&hg!7E}S*#r)g|cWi`w4E%1Lm;vgcQj5dF-?a zR@;=O+hEVl!{S>Z^IQ7oMp`V=IFw?Vtv3LP=S7$2d5u!$?YmO#+O>uE;REp1+!+DMQt6UjGtZVxh|IBkFqb^P6kKU#cU24 zW7I5D*O$uRCvp8~>Aiye*Nl#>4`@6k!~O?M%R`T`5Io3r)#Sty6-;*Ar9$kEx)5AR z4!hJ|^^mIqQTB4QLD|O;t3V@@UmtaL zLHU?d_4o;A2Fj&Q)$e6a^+POos*uAKPSxX;P8D(}oy90uIaT+bc1}?3UF|GKxyGq_ z_KZ_S9h;xU9NarvW>jvf<}WFF4fD|U3QdvT;>PLi$>cJ z@74<&LkE2eJ|8hiCHa(gNVx!bQ)#3yUwPp>*2sfvhyFxD^AOsxKWo@Vo|147@tO9q`}^uZV|fH#UhxNp$I!ds!R!?^~Qq*HDCS12LzYqI-b3;#?LF&vsWg= zCHui#v9(xst32?=7XDv2bbaEa^vUc)y0#H@E6%g`2HI; zo78oaW$DLAh#W6t@U$I%*gGBnV*0X|Mbm@UihHx;}y#SLdki#XAKF}&%$0He_ula^*&j) z&*d*`NOb6DDp5ghVNP~&cFy4bmcMUdc5W72g(38b%y@?QjX$AW%OC_Jff-5mCjdh} z+`q~3P%ZP`r;GCY6l9ZQURa|wrBUiLITEhw+vq1y3S);26G(|R7ikl=Y9G)j?Mv0| zKS)cZ5-A$cAO7jROiyF|A?CG z1e(A-S!D+3pE(phYqoFX{y;buUy-#z$fA&_t+I$DSouv(vbNqLQefvdId<6jO(GR` zeh{sow^sGG>DsHxBdu@{fISd@Gr0dC!Ir(nu!2|UyxCX+WxJOtvj*r zda#_H^4$-i?tJuN5=)^l1(J0O`E`}5d?SDVkVZq*9eDu2bmL|315kgDlaIYmW4$Lu zvmjuaSCyAQ(e9(N(C?O&2LMg?m~{nZ9T|=_AFWiG;r<)ozN7Up;R_xrL&Q|ah6r+ zbeZQRCf=w8nRj{EfUrvPo-TUHSsKYysT} zuh3r*AU+J?;p-J%@sD!XC_M%+;pa!`q40P6Z4|b*Z^@5F>s>|nbk+;Xc$pbS06A{R zj8eTj`J1dM#a{WG+*+!uG*%}|^#nYh>vL%=w>G^ik?#V|Bu%`qPJhK>xqV5Dhi!Wl zvqwTx-feoAJp3IC<-7lU!Fy2cja#(@>z&3KAg9N%yVuOKH1SebSFp2117NO~lEkf6uSpSYo_hZlTH z-JTU;;S0`0F4?N$X_G68$CQnpIj*?8tg5VBcZIT8D3oxrc=Y7SGm58`&6qZ)UQVT( z&5vYurEn_#orF*rz9;(YLE`Bs=C3CEhAljl>NRqkKYUd7%H#feM|LQY`4=gZfS=sk zN_fkFNun`1DR(^2BYDY~G1K(J^2T%UvN$f=KhG1$3HR5m5A-wU#DwplGr}5D4-9Fz z^_zH9I>W5N7xSEK*+lqY=4#}9o3@lrC+{1H+hI{^QXA)t@_V4Y zN(2&W>+U1h{m5F%uu0rgE)~3~Tz!>I^+`NAb={pYe$nmy{evGZv$gjz@UK#| zHfF1A_;7tilW}PHx45Y@&banFYf78c#yi{H*3^}2d4rZtX_Z751vq2xZmSF{#gLm# zz48nD(i=|QSVGy}0=@`l)XpY#8P53In)cdSo`N6?^{9K&0vpiK9zhJ$H<*T5+H}~| zPpZ#JYYO#OhTb&}s4u4FeEBIek)wG}U%tqC}V(3y|rc&?1CB z)FeDS^bsoUu&2!6JcQ~ovV`+Cc$vj3A`&Zdv##ryH|hk_(=CGQT`WRCtENujPFcuR zg*#mz%l*yAm+Da#%rMp4S%d~vB7lbzRP>L+A7)S_ngoX;Q4u~u?{@cSr{6K!@fdC6 zMhDLH(EAT}XXDxf^~2riFNQmnW4Ir<|8S>bD)74-*X54Jbx~8nl)8W0x*ONB>)Y1t zFWQzS(6+AkZ(9%kWt>n`!I!qRA*^^9Tn5(wJnG+urUkap}kW(qWx37 zKzy00J_+tP?4;ks<=*x~nkprP8JrJB>Co36W0y%mDHArPQwxIdb>l zX52Bjz184aACmjN19}?Q2G$R5kG~k)bPo(}=KTjZmw(yFL$!_CVCa9#w!$~>0d1x; zTLuo{RgE*8S$8yY2pTDG4Cerec2DAUx>n`vC!3b?nYuR1*;oECjaOlnC!BrEv$V?D z+d2!Xm%EtH0rJP(VqO<-J=p7jYJ~K`PH2GthXifoVFf>n47`C_rZ(C3f51Hc2_~M$)|PQQp6xysq3QkQwK7Bw53uS? z&zCi-KG>=YeTX8`;1V`s9FJ<9705!d+)z4PgjdY0xNRkpA^$aoM2&O*`Z9AKW+ ztDL#&>}+`LsSD+eQqDqr$T=HO5CRaXIu7_qDsxOTat_Am3Sc80SIdh%Lh5IxTjO=a0iR(EQCjW;usi4T9p;ImB#` zsB#urXT>aMp>-BIT<2h%bwPuwE;MdT;&XI_g3Ou1k&Jw#bWY_bp)wpcjX#TzF8VQ- z3|DuPH>UFtcqE0);MYm1(R3#FRC$jAt9VQ36lLNpUIAymb+dShdp^(doZ#2KgIX_U*^CCseGcu#bKs&_1%4U?~W_j&B9#U@a=(Hnt$@*1Zd{F zszVzsg$}d`J1w(_R655Z(&*zBkxn;YamW1d!cc1`5J|M1MI_U17Lh{p710tMF(p!w zOvWVA=o1!^PB+R-E}G*mQ5KN|4@;AiOmi(F1wNK0$4;v(A{9QCCMS)qRYZ&GoywP^ zXKr3`)*xj3fLT7~PDT>#awj91=H1Cip=0i3*y-#$8L9NKI~i$oeLcgg{{N=aS7nJ1 z>Ma^=5lOVOMI_S!7Lh_rEy7M`DIx%BZS$Hmy3Qif>8{;1{J6>yexjBGynB*7zX&gr ziL&rvzS-^MQ(^m@=HyR6i$z>~8Wi9&T>Moizham0mo+4~I{P?(PARVzEalI6&h(qp zMoqJDd43s>y@hSiM9y2rhd^m`dKrHj3b4xM{2L8^L4_;vuV>3BH{a$t%WtT8X{4-? zKtwq91PZ_+On`sTY{?&!`s-vS$CkZ45@nv~kHliy)LWG>V9?CEt;Vzkx7E1z@NG4r zxo)d@Xh=ALJgPGB4FcEbv2xiSggTU~LtE$(r&)xq&9(@pEwl&@C}&efXiF@@1NMdu zZ@_$t@U1tAveQ>sga&Ja$@Kv%Zn z8NQy(HB#1cJEhKQIcYuro;nxG;T!l@WP#CrBZS?Xcpx+kL7RA6Xc&x)mv{~(Hu=OB zKFz%yzYQ~<-_DVWKsWa8;C@Q6aC#@NA;iNN{3=gWFc*&3cwdz(_tb7IvD~k6Xf592 zB?!nF{}#_A#LL+HHh%yqbB(Xx;Ul1tFf#Y?t^{}x)$j6w0K_m(zQ;S%UwDwOBfiE9 z2i1RUYV7-nw?-x^9B-q5L4xFKr}-+tM&y3N*TC`Y@+bTnJPOW#%C{4E3p{?7UqFC34sGSq z&-flV_VxK3Bh*^m;0&S;b8NP)@C!g5HQ?ke2CmT=>Wv7ADYgZ+94vSaV6(2G4i{;g zw2zl(2I(D`KfrxrMTET8ku!PXMXs|m3Cw@sEvBIQr{)e=UJDjF)sLx)igd!EmAu$O zc*zr?f_Y3BqkkC3{QFtk=bL=wi#c$c8=&a5Ffwi-B(fl@A zC~|YE84)dKf6f055BN#{;6DJ-VE8}zX(*{Xe#1{kG$DZiX@r~EbmSd9NUj4Cr9XUX zSJTsobIOIv@ICC;e?;=!G_<*D#kH$`a#S#B=CPq2>wtKssuj;1i=ehzcbte6Qxez% zs%HTCZ7JjI)YpT|tdEOYe=ve9l+|$}4sP{Z;zR=6A3w)6SOJWfBx1;Fx#K)fC;ye- zo##j=b3;a5;9aQg4>{%n?*wEAoNXarauNKmpXAvKyleQc>SO9dyVz(KKrd9AnTamJ zgdV32)MjX_wYQA0_xTMZO>7kmO!ZzXb_BKX&dM(A10T3PSr~+UmwBst011rY+RIp* zv{TGbtVS-XL&S=ggW8ffl&$2EH3V^)(XwLzkJMx9ZzuPCN<1kBa!vr2TQPEd02b{3 zlJ5q<<=}f&3y{ADa6vA+ukac0Cz*MLa|AuTIR7dRF~)-L`B@Ec2!;Q~Vk*u!{%>B! z;89}#A0|A!PDcIAztP3BmYc4ud4+^i_(@Iu181L?YyRMoD~1jBf}6s=5`|*3QCH*k*~^79+G!0##1g(R=+Dx4%~<%ePk z;->}@=!`nbkBK;q@TpBy3?Xi$s*&77jD|sff`|A`8T7|`iBA*?VV6eYE!g#cZX_nd zu0O#?tb)fVZ7dd&bXnV2D31WqM68ELz@{eRf@h|m|GObBsIhh)!=&o+WP_CV3Bz1 zi~ugg3Se&?MD)Xt2!d^c%!LEAaZvobfaA0WDD|H!)wfRM7m>oBJz~ajSD)gohv{zR zpK^zTXI6fpzC`)9-NEgXr$41U_8Kq?Q}va1-61zCPj||xQKF^(s4|tj8zq{1^vuc9 zAG=v&n2m_-cqd8($&ENG7w+bQ>kc!hf5TzklIlyPZ?p(xt1Q+o-ZDskSVh?1(SSh( znFWIf=~9+Nix&Qi?rI4#sOeA2$D@UR^@_V%U+`c-p1$m^YX+nB%kSpq_t9NyX=MI? z00ICIaB!XpYM`6p6ehoaCKhnOIncK&=R%W}2f!VDSMxmhZkqM{>;fPP_RKBNUshc+ zd4qGa`Tz{y3N0zh>{FmGymftH|IA!{>n+DzRaNi-JFJClB5mRJ6M;Zy4Du83yUUVq zv=9e9d;0kgS2JzGt(oQ}hbBXh`CALoOn%Z*O!MsF=ijHHi27<6)&5x30n6^`R^l+C zqsjs>DSOM7f#P{Ml)M!v)*+H=M36{fh-z9MCT3yR<{2*Lc;?pM5UDo9MV$E&lW&BJ zLD(!cju0DwSg}1q7@qy=#bT|dJ<&!?bH|HBkHY5W!%?EH4w34+qP~^$VB%5K+9U{nAPf=?0ocQgvIsi`9Gc>!Ql~|v z(KRLkmBscjEt{;UcC?ml_V8p`wTBP#2TCizCi03EaAk4f5Nozz-*#~i_xG8oFfniv z=kx`#_6^fMS7s4O+9Zoe)}~rSiZ;t4?3yXuiac!9(=?Y!^h?*4-qTYiQ5$rI}JFYknpQJws3CtD{jhp|W%!P4<<=z>O* zALX07Sct6J1s8#jcClvU|5R$aHi$LI65qgZ|8167jeYUrZ1E1%2RMYuW5ci-1HLP4 zW!;1>=Rb&d{b+;sQlEwK#@XHio|xlg$G+k-GS=|wC#Jx-FX#0~-^yi^9DHLY$>lj> zDK;T?!pzxCm^F)>Bw7Ym-GH9SEmmlQc9Fm)euubHN zfuc~38DyOZlgoypah3UK&1C5uDB8&GgV65Q-2|+C`JxP4FOz$G6;R_$*{y@bkk*Z8 zuniNq8d*p`g=1z2RhUkbk$ZHHc0uXueg_;tp=eKjl^qI2G8rvP)nSX2g(4zggg*;_ zZf0!7lsl0xddO3Sq5#=|ql>UKoFB{5)GsjLJFIG;tXohdfB-3tYd%h?`EuqAmGI7OUDyxu6*5-jUmi zg+1hr)+`v!oHVAgOlg{+XR^pKB{NEFue(QyH0r8GQd@C|x)vI&M8JW0ft)j1EXRh+ zyHrfYhHF8oc-UPodSSQJyBupjqRCkm0v#}oFLba6VXs&92_Uo$Y}Qz%wjLOcZ#TiZZ2agM%67unfUx}G=sEP*4km(|yFvVT^|I76~R{#J2 diff --git a/tools_layouts/adb/prm/hca/ext/register_access_table.adb b/tools_layouts/adb/prm/hca/ext/register_access_table.adb index b8e6371e..de5f4683 100644 --- a/tools_layouts/adb/prm/hca/ext/register_access_table.adb +++ b/tools_layouts/adb/prm/hca/ext/register_access_table.adb @@ -35,7 +35,7 @@ - + @@ -94,24 +94,17 @@ - + - + - - - - - - - @@ -132,10 +125,13 @@ + + + @@ -226,6 +222,7 @@ + @@ -233,11 +230,13 @@ + + @@ -287,15 +286,15 @@ - - + + - + @@ -340,12 +339,12 @@ - - - - - - + + + + + + @@ -370,7 +369,7 @@ - + @@ -417,7 +416,7 @@ - + @@ -442,7 +441,7 @@ - + @@ -467,14 +466,14 @@ - + - + @@ -835,7 +834,9 @@ + + @@ -860,7 +861,7 @@ - + @@ -885,15 +886,34 @@ + + + + + + + + + + + + + + + + + + + - + - - + + @@ -906,7 +926,7 @@ - + @@ -971,7 +991,7 @@ - + @@ -1007,7 +1027,7 @@ - + @@ -1015,8 +1035,8 @@ - - + + @@ -1026,7 +1046,7 @@ - + @@ -1038,7 +1058,7 @@ - + @@ -1050,6 +1070,14 @@ + + + + + + + + @@ -1058,13 +1086,13 @@ - - + + - + @@ -1073,7 +1101,7 @@ - + @@ -1202,7 +1230,7 @@ - + @@ -1235,9 +1263,9 @@ - - - + + + @@ -1247,8 +1275,9 @@ - + + @@ -1306,7 +1335,7 @@ - + @@ -1316,7 +1345,7 @@ - + @@ -1324,18 +1353,18 @@ - + - + - + @@ -1377,8 +1406,8 @@ - - + + @@ -1399,11 +1428,11 @@ - + - + @@ -1454,7 +1483,7 @@ - + @@ -1593,7 +1622,7 @@ - + @@ -1602,9 +1631,9 @@ - + - + @@ -1637,7 +1666,7 @@ - + @@ -1725,7 +1754,7 @@ - + @@ -1792,8 +1821,8 @@ - - + + @@ -1804,14 +1833,14 @@ - + - + @@ -1901,7 +1930,7 @@ - + @@ -2196,10 +2225,10 @@ - - - - + + + + @@ -2262,6 +2291,10 @@ + + + + @@ -2325,10 +2358,10 @@ - + - + @@ -2349,7 +2382,7 @@ - + @@ -2521,11 +2554,12 @@ - + + @@ -2543,7 +2577,6 @@ - @@ -2552,16 +2585,17 @@ - + + - - + + @@ -2569,6 +2603,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2600,6 +2674,22 @@ + + + + + + + + + + + + + + + + @@ -2668,7 +2758,7 @@ - + @@ -2681,7 +2771,7 @@ - + @@ -2704,7 +2794,7 @@ - + @@ -2748,15 +2838,15 @@ - - + + - + @@ -2801,7 +2891,7 @@ - + @@ -2832,7 +2922,7 @@ - + @@ -2863,7 +2953,7 @@ - + @@ -2915,39 +3005,19 @@ - + - - - - - - - - - - - - - - - - - - - - - - - + + + @@ -2958,41 +3028,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3000,12 +3035,6 @@ - - - - - - @@ -3025,7 +3054,7 @@ - + @@ -3152,7 +3181,7 @@ - + @@ -3174,8 +3203,8 @@ - - + + @@ -3186,7 +3215,7 @@ - + @@ -3201,7 +3230,7 @@ - + @@ -3209,12 +3238,12 @@ - + - + @@ -3300,7 +3329,7 @@ - + @@ -3345,7 +3374,7 @@ - + @@ -3361,7 +3390,7 @@ - + @@ -3413,7 +3442,7 @@ - + @@ -3437,13 +3466,13 @@ - + - + @@ -3478,12 +3507,12 @@ - - + + - - - + + + @@ -3560,13 +3589,14 @@ - + - + - - + + + @@ -3640,11 +3670,11 @@ - - + + - - + + diff --git a/tools_layouts/adb/prm/switch/ext/register_access_table.adb b/tools_layouts/adb/prm/switch/ext/register_access_table.adb index 18f6a868..861a8ed8 100644 --- a/tools_layouts/adb/prm/switch/ext/register_access_table.adb +++ b/tools_layouts/adb/prm/switch/ext/register_access_table.adb @@ -35,19 +35,20 @@ - + - - - - + + + - - - - + + + + + + - + @@ -59,7 +60,7 @@ - + @@ -70,23 +71,22 @@ - + - - - + + + - - + @@ -98,45 +98,45 @@ - - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - + - + - + - + @@ -196,39 +196,23 @@ - - - - - - - - - - - - - - - - - - + - + + - - + + @@ -238,35 +222,35 @@ - + - + - - - - - - - + + + + + + + - - - + + + - + @@ -283,15 +267,12 @@ - + - - - @@ -338,7 +319,7 @@ - + @@ -471,6 +452,7 @@ + @@ -480,6 +462,7 @@ + @@ -487,11 +470,13 @@ + + @@ -507,8 +492,6 @@ - - @@ -830,7 +813,7 @@ - + @@ -929,12 +912,12 @@ - - - - - - + + + + + + @@ -960,7 +943,7 @@ - + @@ -977,9 +960,9 @@ - + - + @@ -1004,7 +987,7 @@ - + @@ -1048,9 +1031,9 @@ - - - + + + @@ -1414,11 +1397,7 @@ - - - - - + @@ -1448,14 +1427,14 @@ - + - + @@ -1475,21 +1454,21 @@ - - - + + + - + - + @@ -1497,11 +1476,11 @@ - - - - - + + + + + @@ -1553,7 +1532,7 @@ - + @@ -1597,8 +1576,8 @@ - - + + @@ -1666,7 +1645,7 @@ - + @@ -1676,7 +1655,7 @@ - + @@ -1696,19 +1675,19 @@ - + - + - + - + @@ -1722,11 +1701,11 @@ - - + + - + @@ -1759,27 +1738,27 @@ - + - + - + - + - + @@ -1804,7 +1783,7 @@ - + @@ -1828,22 +1807,32 @@ - + + + + + + + + + + + - + - + @@ -1855,13 +1844,13 @@ - + - + - + @@ -1880,7 +1869,7 @@ - + @@ -1906,7 +1895,7 @@ - + @@ -1919,11 +1908,11 @@ - + - + @@ -1969,7 +1958,7 @@ - + @@ -1979,7 +1968,7 @@ - + @@ -1997,13 +1986,13 @@ - + - + @@ -2019,7 +2008,7 @@ - + @@ -2029,15 +2018,34 @@ - + - + + + + + + + + + + + + + + + + + + + + @@ -2059,7 +2067,7 @@ - + @@ -2160,7 +2168,7 @@ - + @@ -2168,8 +2176,8 @@ - - + + @@ -2191,7 +2199,7 @@ - + @@ -2203,6 +2211,14 @@ + + + + + + + + @@ -2211,13 +2227,13 @@ - - + + - + @@ -2226,7 +2242,7 @@ - + @@ -2328,7 +2344,7 @@ - + @@ -2427,9 +2443,9 @@ - - - + + + @@ -2439,8 +2455,9 @@ - + + @@ -2458,7 +2475,7 @@ - + @@ -2498,8 +2515,8 @@ - - + + @@ -2509,7 +2526,7 @@ - + @@ -2518,7 +2535,7 @@ - + @@ -2528,7 +2545,7 @@ - + @@ -2536,7 +2553,7 @@ - + @@ -2551,7 +2568,7 @@ - + @@ -2588,8 +2605,8 @@ - - + + @@ -2610,11 +2627,11 @@ - + - + @@ -2628,7 +2645,7 @@ - + @@ -2638,18 +2655,19 @@ + - + - + - + @@ -2665,8 +2683,14 @@ + + + + + + - + @@ -2681,7 +2705,7 @@ - + @@ -2736,16 +2760,15 @@ - + - - + + - @@ -2759,7 +2782,7 @@ - + @@ -2770,27 +2793,8 @@ - - - - - - - - - - - - - - - - - - - - + @@ -2799,7 +2803,7 @@ - + @@ -2847,7 +2851,7 @@ - + @@ -2866,7 +2870,7 @@ - + @@ -2879,7 +2883,7 @@ - + @@ -2894,10 +2898,10 @@ - + - + @@ -2905,11 +2909,9 @@ - - - - - + + + @@ -2950,7 +2952,7 @@ - + @@ -2993,11 +2995,11 @@ - + - + @@ -3006,7 +3008,7 @@ - + @@ -3022,7 +3024,7 @@ - + @@ -3060,8 +3062,8 @@ - - + + @@ -3089,16 +3091,16 @@ - + - + - - - + + + @@ -3113,8 +3115,8 @@ - - + + @@ -3126,8 +3128,8 @@ - - + + @@ -3142,8 +3144,8 @@ - - + + @@ -3157,19 +3159,19 @@ - + - - - + + + - + @@ -3196,7 +3198,7 @@ - + @@ -3276,7 +3278,7 @@ - + @@ -3285,9 +3287,9 @@ - + - + @@ -3322,7 +3324,7 @@ - + @@ -3375,6 +3377,12 @@ + + + + + + @@ -3383,11 +3391,11 @@ - + - + @@ -3405,7 +3413,7 @@ - + @@ -3442,7 +3450,7 @@ - + @@ -3454,7 +3462,7 @@ - + @@ -3486,18 +3494,18 @@ - + - + - + @@ -3520,8 +3528,8 @@ - - + + @@ -3532,7 +3540,7 @@ - + @@ -3615,7 +3623,7 @@ - + @@ -3910,10 +3918,10 @@ - - - - + + + + @@ -3976,6 +3984,10 @@ + + + + @@ -4039,10 +4051,10 @@ - + - + @@ -4063,7 +4075,7 @@ - + @@ -4074,7 +4086,7 @@ - + @@ -4095,7 +4107,7 @@ - + @@ -4109,7 +4121,7 @@ - + @@ -4117,8 +4129,8 @@ - - + + @@ -4163,14 +4175,14 @@ - + - + @@ -4207,7 +4219,7 @@ - + @@ -4226,7 +4238,7 @@ - + @@ -4351,7 +4363,7 @@ - + @@ -4520,11 +4532,12 @@ - + + @@ -4542,7 +4555,6 @@ - @@ -4560,7 +4572,7 @@ - + @@ -4568,16 +4580,17 @@ - + + - - + + @@ -4626,7 +4639,7 @@ - + @@ -4724,8 +4737,8 @@ - - + + @@ -4735,14 +4748,14 @@ - + - - + + @@ -4847,7 +4860,7 @@ - + @@ -4860,7 +4873,7 @@ - + @@ -4883,7 +4896,7 @@ - + @@ -4927,8 +4940,8 @@ - - + + @@ -4946,14 +4959,14 @@ - + - + @@ -5019,7 +5032,7 @@ - + @@ -5047,9 +5060,9 @@ - + - + @@ -5067,13 +5080,13 @@ - + - - - + + + @@ -5091,8 +5104,8 @@ - - + + @@ -5100,8 +5113,8 @@ - - + + @@ -5109,10 +5122,10 @@ - - + + - + @@ -5126,10 +5139,10 @@ - - + + - + @@ -5137,8 +5150,8 @@ - - + + @@ -5155,7 +5168,7 @@ - + @@ -5180,7 +5193,7 @@ - + @@ -5268,7 +5281,7 @@ - + @@ -5302,13 +5315,13 @@ - + - - + + @@ -5376,25 +5389,25 @@ - + - + - + - + @@ -5424,7 +5437,7 @@ - + @@ -5486,7 +5499,7 @@ - + @@ -5504,7 +5517,7 @@ - + @@ -5553,7 +5566,7 @@ - + @@ -5569,7 +5582,7 @@ - + @@ -5577,11 +5590,11 @@ - + - - - + + + @@ -5638,7 +5651,7 @@ - + @@ -5672,41 +5685,42 @@ + - + - + - + - - - + + + - + - + - + @@ -5714,6 +5728,7 @@ + @@ -5721,22 +5736,22 @@ - - - - + + + + - + - - + + @@ -5756,7 +5771,7 @@ - + @@ -5773,12 +5788,12 @@ - + - + @@ -5788,7 +5803,7 @@ - + @@ -5844,15 +5859,15 @@ - + - + - + @@ -5866,8 +5881,8 @@ - - + + @@ -5880,9 +5895,9 @@ - + - + @@ -5890,7 +5905,7 @@ - + @@ -5900,14 +5915,14 @@ - - + + - + - + @@ -5934,13 +5949,13 @@ - + - - - - + + + + @@ -5966,9 +5981,9 @@ - - - + + + @@ -5998,9 +6013,9 @@ - - - + + + @@ -6009,7 +6024,7 @@ - + @@ -6053,7 +6068,7 @@ - + @@ -6065,7 +6080,7 @@ - + @@ -6075,7 +6090,7 @@ - + @@ -6118,7 +6133,7 @@ - + @@ -6145,9 +6160,9 @@ - + - + @@ -6163,7 +6178,7 @@ - + @@ -6171,18 +6186,18 @@ - + - + - + @@ -6211,7 +6226,7 @@ - + @@ -6235,7 +6250,7 @@ - + @@ -6304,7 +6319,7 @@ - + @@ -6350,17 +6365,17 @@ - + - + - - + + @@ -6373,8 +6388,8 @@ - - + + @@ -6383,10 +6398,10 @@ - + - + @@ -6401,21 +6416,21 @@ - + - + - + - + @@ -6475,8 +6490,8 @@ - - + + @@ -6488,7 +6503,7 @@ - + @@ -6503,7 +6518,7 @@ - + @@ -6515,7 +6530,7 @@ - + @@ -6524,7 +6539,7 @@ - + @@ -6533,7 +6548,7 @@ - + @@ -6544,9 +6559,9 @@ - + - + @@ -6557,12 +6572,12 @@ - + - - + + @@ -6571,19 +6586,19 @@ - + - + - + - + - + @@ -6596,9 +6611,9 @@ - - - + + + @@ -6611,14 +6626,14 @@ - + - - + + @@ -6630,7 +6645,7 @@ - + @@ -6639,7 +6654,7 @@ - + @@ -6649,13 +6664,13 @@ - + - + @@ -6671,7 +6686,7 @@ - + @@ -6720,7 +6735,7 @@ - + @@ -6736,7 +6751,7 @@ - + @@ -6788,7 +6803,7 @@ - + @@ -6812,13 +6827,13 @@ - + - + @@ -6853,12 +6868,12 @@ - - + + - - - + + + @@ -6935,13 +6950,14 @@ - + - + - - + + + @@ -6957,22 +6973,22 @@ - + - + - + - + @@ -6991,7 +7007,7 @@ - + @@ -7000,7 +7016,7 @@ - + @@ -7019,7 +7035,7 @@ - + @@ -7031,7 +7047,7 @@ - + @@ -7052,7 +7068,7 @@ - + @@ -7071,7 +7087,7 @@ - + @@ -7081,14 +7097,14 @@ - + - + @@ -7097,7 +7113,7 @@ - + @@ -7130,7 +7146,7 @@ - + @@ -7158,8 +7174,8 @@ - - + + @@ -7186,13 +7202,13 @@ - + - - - + + + @@ -7231,7 +7247,7 @@ - + @@ -7244,19 +7260,19 @@ - + - + - - + + - + @@ -7294,7 +7310,7 @@ - + @@ -7303,7 +7319,7 @@ - + @@ -7311,16 +7327,16 @@ - + - + - + - - + + @@ -7335,17 +7351,17 @@ - + - - - - + + + + @@ -7361,7 +7377,7 @@ - + @@ -7383,11 +7399,11 @@ - + - + @@ -7405,12 +7421,12 @@ - - + + - + @@ -7423,11 +7439,11 @@ - + - + - + @@ -7442,12 +7458,12 @@ - + - - + + @@ -7490,11 +7506,11 @@ - + - + @@ -7502,7 +7518,7 @@ - + @@ -7513,15 +7529,15 @@ - + - + - + @@ -7533,11 +7549,11 @@ - + - + @@ -7555,7 +7571,7 @@ - + @@ -7567,7 +7583,7 @@ - + @@ -7646,7 +7662,7 @@ - + @@ -7702,7 +7718,7 @@ - + @@ -7721,9 +7737,9 @@ - + - + @@ -7748,18 +7764,18 @@ - + - + - + @@ -7767,7 +7783,7 @@ - + @@ -7824,13 +7840,13 @@ - + - + diff --git a/tools_layouts/reg_access_hca_layouts.c b/tools_layouts/reg_access_hca_layouts.c index 0b2703d6..5e8a5f6e 100644 --- a/tools_layouts/reg_access_hca_layouts.c +++ b/tools_layouts/reg_access_hca_layouts.c @@ -1205,6 +1205,8 @@ void reg_access_hca_mgir_fw_info_pack(const struct reg_access_hca_mgir_fw_info * adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->dev); offset = 3; adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->string_tlv); + offset = 1; + adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->dev_sc); offset = 32; adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->build_id); offset = 80; @@ -1260,6 +1262,8 @@ void reg_access_hca_mgir_fw_info_unpack(struct reg_access_hca_mgir_fw_info *ptr_ ptr_struct->dev = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); offset = 3; ptr_struct->string_tlv = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); + offset = 1; + ptr_struct->dev_sc = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); offset = 32; ptr_struct->build_id = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); offset = 80; @@ -1318,6 +1322,8 @@ void reg_access_hca_mgir_fw_info_print(const struct reg_access_hca_mgir_fw_info adb2c_add_indentation(fd, indent_level); fprintf(fd, "string_tlv : " UH_FMT "\n", ptr_struct->string_tlv); adb2c_add_indentation(fd, indent_level); + fprintf(fd, "dev_sc : " UH_FMT "\n", ptr_struct->dev_sc); + adb2c_add_indentation(fd, indent_level); fprintf(fd, "build_id : " U32H_FMT "\n", ptr_struct->build_id); adb2c_add_indentation(fd, indent_level); fprintf(fd, "year : " UH_FMT "\n", ptr_struct->year); diff --git a/tools_layouts/reg_access_hca_layouts.h b/tools_layouts/reg_access_hca_layouts.h index c5ff8891..df9a00f4 100644 --- a/tools_layouts/reg_access_hca_layouts.h +++ b/tools_layouts/reg_access_hca_layouts.h @@ -661,6 +661,7 @@ ware version. */ /* Description - When set, string-TLV is supported. */ /* 0x0.28 - 0x0.28 */ u_int8_t string_tlv; + u_int8_t dev_sc; /*---------------- DWORD[1] (Offset 0x4) ----------------*/ /* Description - Firmware Build ID. Optional. . */ /* 0x4.0 - 0x4.31 */ From d3e945013b06fd6950bd7e0e47a2f663b4f49bca Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Tue, 22 Feb 2022 13:09:56 +0200 Subject: [PATCH 085/184] fix mstflint version to 4.18.1 --- configure.ac | 4 ++-- kernel/mstflint_kernel.spec | 2 +- mstflint.spec.in | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 849b1873..be29c891 100644 --- a/configure.ac +++ b/configure.ac @@ -31,12 +31,12 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(mstflint, 4.19.0, eranj@mellanox.co.il) +AC_INIT(mstflint, 4.18.1, eranj@mellanox.co.il) AC_DEFINE_UNQUOTED([PROJECT], ["mstflint"], [Define the project name.]) AC_SUBST([PROJECT]) -AC_DEFINE_UNQUOTED([VERSION], ["4.19.0"], [Define the project version.]) +AC_DEFINE_UNQUOTED([VERSION], ["4.18.1"], [Define the project version.]) AC_SUBST([VERSION]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/kernel/mstflint_kernel.spec b/kernel/mstflint_kernel.spec index 25690edf..7db0b5bb 100644 --- a/kernel/mstflint_kernel.spec +++ b/kernel/mstflint_kernel.spec @@ -22,7 +22,7 @@ %global _name kernel-mstflint %endif -%{!?version: %global version 4.19.0} +%{!?version: %global version 4.18.1} %{!?_release: %global _release 1} %global _kmp_rel %{_release}%{?_kmp_build_num}%{?_dist} diff --git a/mstflint.spec.in b/mstflint.spec.in index 689e6bb9..8de018cf 100644 --- a/mstflint.spec.in +++ b/mstflint.spec.in @@ -1,6 +1,6 @@ %{!?ibmadlib: %define ibmadlib libibmad-devel} %{!?name: %define name mstflint} -%{!?version: %define version 4.19.0} +%{!?version: %define version 4.18.1} %{!?release: %define release 1} %{!?buildtype: %define buildtype "native"} %{!?noinband: %define noinband 0} From 66ce977036615190bcee4f29c134061c2097df92 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Thu, 24 Feb 2022 14:15:37 +0200 Subject: [PATCH 086/184] [mstlink] Fixing amber collect fixes Description: -> Fixing amber for PCIe links -> Supporting PRBS info collection Issue: 2944358 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_amBER_collector.cpp | 108 ++++++++++++++++++-- mlxlink/modules/mlxlink_amBER_collector.h | 5 + mlxlink/modules/mlxlink_enums.h | 62 ++++++++++- mlxlink/modules/mlxlink_maps.cpp | 83 +++++++++++++++ mlxlink/modules/mlxlink_maps.h | 6 +- 5 files changed, 253 insertions(+), 11 deletions(-) diff --git a/mlxlink/modules/mlxlink_amBER_collector.cpp b/mlxlink/modules/mlxlink_amBER_collector.cpp index 4d407e66..617809dd 100644 --- a/mlxlink/modules/mlxlink_amBER_collector.cpp +++ b/mlxlink/modules/mlxlink_amBER_collector.cpp @@ -41,6 +41,7 @@ MlxlinkAmBerCollector::MlxlinkAmBerCollector(Json::Value &jsonRoot): _jsonRoot(j _splitPort = 0; _secondSplit = 0; _numOfLanes = 0; + _maxLanes = MAX_NETWORK_LANES; _csvFileName = ""; _mstDevName = ""; _iteration = 0; @@ -154,6 +155,8 @@ void MlxlinkAmBerCollector::startCollector() void MlxlinkAmBerCollector::init() { try { + _isPortPCIE = (_pnat == PNAT_PCIE); + if (!_isPortPCIE) { resetLocalParser(ACCESS_REG_PDDR); updateField("local_port", _localPort); @@ -166,7 +169,7 @@ void MlxlinkAmBerCollector::init() _isPortIB = (_protoActive == IB) && (_pnat != PNAT_PCIE); _isPortETH = (_protoActive == ETH) && (_pnat != PNAT_PCIE); - _isPortPCIE = (_pnat == PNAT_PCIE); + _maxLanes = MAX_NETWORK_LANES; if (_protoActive == IB) { _activeSpeed = getFieldValue("link_speed_active"); @@ -216,6 +219,26 @@ void MlxlinkAmBerCollector::init() _moduleIndex = getFieldValue("module_0"); _slotIndex = getFieldValue("slot_index_0"); + + resetLocalParser(ACCESS_REG_PMPT); + updateField("module", _moduleIndex); + updateField("slot_index", _slotIndex); + updateField("host_media", 1); + updateField("lane_mask", 0x1); + sendRegister(ACCESS_REG_PMPT, MACCESS_REG_METHOD_GET); + + _moduleHostSt = getFieldValue("status"); + + resetLocalParser(ACCESS_REG_PMPT); + updateField("module", _moduleIndex); + updateField("slot_index", _slotIndex); + updateField("host_media", 0); + updateField("lane_mask", 0x1); + sendRegister(ACCESS_REG_PMPT, MACCESS_REG_METHOD_GET); + + _moduleMediaSt = getFieldValue("status"); + + _inPRBSMode |= (_moduleHostSt >= PMPT_STATUS_GEN_ONLY || _moduleMediaSt >= PMPT_STATUS_GEN_ONLY); } else { resetParser(ACCESS_REG_MPEIN); updateField("pcie_index", _pcieIndex); @@ -224,6 +247,7 @@ void MlxlinkAmBerCollector::init() genBuffSendRegister(ACCESS_REG_MPEIN, MACCESS_REG_METHOD_GET); _numOfLanes = getFieldValue("link_width_active"); + _maxLanes = MAX_PCIE_LANES; } _sheetsList[AMBER_SHEET_GENERAL] = FIELDS_COUNT{4, 4, 4}; @@ -686,7 +710,7 @@ vector MlxlinkAmBerCollector::getLinkStatus() updateField("grp", PPCNT_STATISTICAL_GROUP); sendRegister(ACCESS_REG_PPCNT, MACCESS_REG_METHOD_GET); u_int64_t rawError = 0; - for (u_int32_t lane = 0; lane < LANES_NUM; lane++) { + for (u_int32_t lane = 0; lane < _maxLanes; lane++) { val = "N/A"; if (lane < _numOfLanes) { rawError = add32BitTo64( @@ -733,7 +757,7 @@ void MlxlinkAmBerCollector::fillParamsToFields(const string &title, const vector &values, vector &fields, bool laneLimit) { - u_int32_t limit = laneLimit ? LANES_NUM : values.size(); + u_int32_t limit = laneLimit ? _maxLanes : values.size(); string val = ""; string fieldName = ""; for (u_int32_t idx = 0; idx < limit; idx++) { @@ -991,7 +1015,7 @@ string MlxlinkAmBerCollector::getCableBreakoutStr(u_int32_t cableBreakout, u_int void MlxlinkAmBerCollector::calcRxTxPowerLane(vector &fields, string str) { - for (u_int32_t lane = 0; lane < LANES_NUM; lane++) { + for (u_int32_t lane = 0; lane < _maxLanes; lane++) { string laneStr = to_string(lane); fields.push_back(AmberField(str + laneStr, to_string(getPower(getFieldValue(str + laneStr))))); } @@ -999,7 +1023,7 @@ void MlxlinkAmBerCollector::calcRxTxPowerLane(vector &fields, string void MlxlinkAmBerCollector::getTxBiasLane(vector &fields) { - for (u_int32_t lane = 0; lane < LANES_NUM; lane++) { + for (u_int32_t lane = 0; lane < _maxLanes; lane++) { string laneStr = to_string(lane); fields.push_back(AmberField("tx_bias_lane" + laneStr, to_string(getFieldValue("tx_bias_lane" + laneStr) / 500.0))); } @@ -1012,7 +1036,7 @@ void MlxlinkAmBerCollector::loopAllLanesStr(vector &fields, const st fieldName = toLowerCase(fieldName); - for (u_int32_t lane = 0; lane < LANES_NUM; lane++) { + for (u_int32_t lane = 0; lane < _maxLanes; lane++) { string laneStr = to_string(lane); dpStateStr = getStrByMask(getFieldValue(fieldName + laneStr),_mlxlinkMaps->_dataPathSt); fields.push_back(AmberField(str + laneStr, dpStateStr)); @@ -1140,8 +1164,8 @@ void MlxlinkAmBerCollector::getModuleInfoPage(vector &fields) _mlxlinkMaps->_txInputFreq))); fields.push_back(AmberField("rx_cdr_cap", _mlxlinkMaps->_rxTxCdrCap[getFieldValue("rx_cdr_cap")])); fields.push_back(AmberField("tx_cdr_cap", _mlxlinkMaps->_rxTxCdrCap[getFieldValue("tx_cdr_cap")])); - fields.push_back(AmberField("rx_cdr_state", getRxTxCDRState(getFieldValue("rx_cdr_state"),LANES_NUM))); - fields.push_back(AmberField("tx_cdr_state", getRxTxCDRState(getFieldValue("tx_cdr_state"),LANES_NUM))); + fields.push_back(AmberField("rx_cdr_state", getRxTxCDRState(getFieldValue("rx_cdr_state"),_maxLanes))); + fields.push_back(AmberField("tx_cdr_state", getRxTxCDRState(getFieldValue("tx_cdr_state"),_maxLanes))); fields.push_back(AmberField("vendor_name", getAscii("vendor_name", 16))); fields.push_back(AmberField("vendor_rev", getVendorRev(getFieldValue("vendor_rev")))); fields.push_back(AmberField("module_fw_version", getFwVersion(passive,getFieldValue("fw_version")))); @@ -1210,7 +1234,7 @@ void MlxlinkAmBerCollector::getModuleInfoPage(vector &fields) string MlxlinkAmBerCollector::getBitmaskPerLaneStr(u_int32_t bitmask) { string bitMaskStr = ""; - for (u_int32_t lane = 0 ; lane < LANES_NUM; lane++){ + for (u_int32_t lane = 0 ; lane < _maxLanes; lane++){ bitMaskStr += getBitvalue(bitmask, lane + 1) ? "1" : "0"; if (lane != 7 ) { bitMaskStr += ","; @@ -1643,11 +1667,77 @@ vector MlxlinkAmBerCollector::getTestModeInfo() return fields; } + +void MlxlinkAmBerCollector::getTestModeModulePMPT(vector &fields, string moduleSide, + ModuleAccess_t mode) +{ + resetLocalParser(ACCESS_REG_PMPT); + updateField("module", _moduleIndex); + updateField("slot_index", _slotIndex); + updateField("host_media", moduleSide == "host"); + updateField("ch_ge", (u_int32_t)mode); + sendRegister(ACCESS_REG_PMPT, MACCESS_REG_METHOD_GET); + + string modeStr = mode == MODULE_PRBS_ACCESS_GEN? "generator" : "checker"; + + fields.push_back(AmberField("prbs_" + modeStr + "_pattern_cap_" + moduleSide, + getPrbsModeCap(PRBS_RX, getFieldValue("prbs_modes_cap")))); + fields.push_back(AmberField("prbs_" + modeStr + "_pattern_admin_" + moduleSide, + getStrByValue(getFieldValue("prbs_mode_admin"), _mlxlinkMaps->_prbsModesList))); + fields.push_back(AmberField("prbs_" + modeStr + "_msb_lsb_swap_" + moduleSide, + getStrByValue(getFieldValue("swap_admin"), _mlxlinkMaps->_modulePrbsSwapAdmin))); + fields.push_back(AmberField("prbs_" + modeStr + "_polarity_" + moduleSide, + getStrByValue(getFieldValue("invt_admin"), _mlxlinkMaps->_modulePrbsInvAdmin))); + fields.push_back(AmberField("prbs_" + modeStr + "_modulation_" + moduleSide, + getStrByValue(getFieldValue("modulation"), _mlxlinkMaps->_modulePrbsModulation))); + fields.push_back(AmberField("prbs_" + modeStr + "_lane_rate_cap_" + moduleSide, + getStrByMask(getFieldValue("lane_rate_cap"), _mlxlinkMaps->_modulePrbsRateCapToStr))); + fields.push_back(AmberField("prbs_" + modeStr + "_lane_rate_admin_" + moduleSide, + getStrByValue(getFieldValue("lane_rate_admin"), _mlxlinkMaps->_modulePrbsRateCapToStr))); +} + +void MlxlinkAmBerCollector::getTestModeModulePMPD(vector &fields, string moduleSide) +{ + vector> pmpdParams(PMPD_PARAM_LAST, vector(_numOfLanes, "")); + + for (u_int32_t lane = 0; lane < _numOfLanes; lane++) { + resetLocalParser(ACCESS_REG_PMPD); + updateField("module", _moduleIndex); + updateField("slot_index", _slotIndex); + updateField("host_media", moduleSide == "host"); + updateField("lane", lane); + sendRegister(ACCESS_REG_PMPD, MACCESS_REG_METHOD_GET);; + + pmpdParams[PMPD_PARAM_STATUS][lane] = getStrByValue(getFieldValue("status"), _mlxlinkMaps->_modulePMPDStatus); + pmpdParams[PMPD_PARAM_PRBS_BITS][lane] = to_string(add32BitTo64(getFieldValue("prbs_bits_high"), + getFieldValue("prbs_bits_low"))); + pmpdParams[PMPD_PARAM_PRBS_ERRORS][lane] = to_string(add32BitTo64(getFieldValue("prbs_errors_high"), + getFieldValue("prbs_errors_low"))); + pmpdParams[PMPD_PARAM_SNR][lane] = getFieldStr("measured_snr") + "dB"; + pmpdParams[PMPD_PARAM_BER][lane] = getFieldStr("ber_coef") + "E-" + getFieldStr("ber_magnitude"); + } + + fillParamsToFields("prbs_checker_status_" + moduleSide, pmpdParams[PMPD_PARAM_STATUS], fields); + fillParamsToFields("prbs_checker_bit_" + moduleSide, pmpdParams[PMPD_PARAM_PRBS_BITS], fields); + fillParamsToFields("prbs_checker_error_" + moduleSide, pmpdParams[PMPD_PARAM_PRBS_ERRORS], fields); + fillParamsToFields("prbs_checker_snr_" + moduleSide, pmpdParams[PMPD_PARAM_SNR], fields); + fillParamsToFields("prbs_checker_ber_" + moduleSide, pmpdParams[PMPD_PARAM_BER], fields); +} + vector MlxlinkAmBerCollector::getTestModeModuleInfo() { vector fields; try { + fields.push_back(AmberField("prbs_status_host", getStrByValue(_moduleHostSt, _mlxlinkMaps->_modulePrbsSt))); + getTestModeModulePMPT(fields, "host", MODULE_PRBS_ACCESS_CH); + getTestModeModulePMPT(fields, "host", MODULE_PRBS_ACCESS_GEN); + getTestModeModulePMPD(fields, "host"); + + fields.push_back(AmberField("prbs_status_media", getStrByValue(_moduleMediaSt, _mlxlinkMaps->_modulePrbsSt))); + getTestModeModulePMPT(fields, "media", MODULE_PRBS_ACCESS_CH); + getTestModeModulePMPT(fields, "media", MODULE_PRBS_ACCESS_GEN); + getTestModeModulePMPD(fields, "media"); } catch (const std::exception &exc) { throw MlxRegException( "Failed to get Test Mode Module information: %s", exc.what()); diff --git a/mlxlink/modules/mlxlink_amBER_collector.h b/mlxlink/modules/mlxlink_amBER_collector.h index c04444d1..7583b755 100644 --- a/mlxlink/modules/mlxlink_amBER_collector.h +++ b/mlxlink/modules/mlxlink_amBER_collector.h @@ -110,6 +110,8 @@ class MlxlinkAmBerCollector :public MlxlinkRegParser { void initCableIdentifier(u_int32_t cableIdentifier); void getModuleLatchedFlagInfoPage(vector &fields); void groupValidIf(bool condition); + void getTestModeModulePMPT(vector &fields, string moduleSide, ModuleAccess_t mode); + void getTestModeModulePMPD(vector &fields, string moduleSide); bool _isQsfpCable; bool _isSfpCable; @@ -154,6 +156,8 @@ class MlxlinkAmBerCollector :public MlxlinkRegParser { bool _isValidSensorMvcap; bool _isValidSensorMtcap; bool _inPRBSMode; + u_int32_t _moduleHostSt; + u_int32_t _moduleMediaSt; Json::Value &_jsonRoot; vector _amBerCollectorOutput; @@ -164,6 +168,7 @@ class MlxlinkAmBerCollector :public MlxlinkRegParser { u_int32_t _numOfLanes; u_int32_t _moduleIndex; u_int32_t _slotIndex; + u_int32_t _maxLanes; }; #endif /* MLXLINK_AMBER_COLLECTOR_H */ diff --git a/mlxlink/modules/mlxlink_enums.h b/mlxlink/modules/mlxlink_enums.h index e60e0868..24988f57 100644 --- a/mlxlink/modules/mlxlink_enums.h +++ b/mlxlink/modules/mlxlink_enums.h @@ -80,7 +80,8 @@ #define LANES_NUM 8 #define NUM_OF_BINS 16 #define MTMP_GEARBOX_SENSOR_OFFSET 256 -#define LANES_NUM 8 +#define MAX_NETWORK_LANES 8 +#define MAX_PCIE_LANES 16 // cables parse definition @@ -1359,4 +1360,63 @@ enum AMBER_SHEET { AMBER_SHEET_TEST_MODE_MODULE_INFO = 14 }; +typedef enum MODULE_PRBS { + MODULE_PRBS_SELECT, + MODULE_PRBS_MODE, + MODULE_PRBS_GEN_RATE, + MODULE_PRBS_GEN_PAT, + MODULE_PRBS_GEN_SWAP, + MODULE_PRBS_GEN_INV, + MODULE_PRBS_GEN_LANES, + MODULE_PRBS_CH_RATE, + MODULE_PRBS_CH_PAT, + MODULE_PRBS_CH_SWAP, + MODULE_PRBS_CH_INV, + MODULE_PRBS_CH_LANES, + MODULE_PRBS_SHOW_DIAG, + MODULE_PRBS_CLEAR_DIAG +} ModulePrbs_t; + +typedef enum MODULE_PRBS_ACCESS { + MODULE_PRBS_ACCESS_BOTH, + MODULE_PRBS_ACCESS_GEN, + MODULE_PRBS_ACCESS_CH, + MODULE_PRBS_ACCESS_CH_GEN +} ModuleAccess_t; + +enum MODULE_PRBS_LANE_RATE { + MODULE_PRBS_LANE_RATE_1G = 0x1, + MODULE_PRBS_LANE_RATE_SDR = 0x2, + MODULE_PRBS_LANE_RATE_40G_40G = 0x8, + MODULE_PRBS_LANE_RATE_FDR = 0x10, + MODULE_PRBS_LANE_RATE_EDR = 0x20, + MODULE_PRBS_LANE_RATE_HDR = 0x80, + MODULE_PRBS_LANE_RATE_NDR = 0x100 +}; + +enum PMPT_STATUS { + PMPT_STATUS_NORMAL_MODE = 0, + PMPT_STATUS_NOT_SUPPORTED = 1, + PMPT_STATUS_CONFIG_ERROR = 2, + PMPT_STATUS_GEN_ONLY = 3, + PMPT_STATUS_CH_ONLY = 4, + PMPT_STATUS_BOTH = 5 +}; + +enum PMPD_STATUS { + PMPD_STATUS_NOT_SUPPORTED = 0, + PMPD_STATUS_NORMAL_MODE = 1, + PMPD_STATUS_NOT_LOCKED = 2, + PMPD_STATUS_LOCKED = 3 +}; + +enum PMPD_PARAM { + PMPD_PARAM_STATUS, + PMPD_PARAM_PRBS_BITS, + PMPD_PARAM_PRBS_ERRORS, + PMPD_PARAM_SNR, + PMPD_PARAM_BER, + PMPD_PARAM_LAST +}; + #endif /* MLXLINK_ENUMS_H */ diff --git a/mlxlink/modules/mlxlink_maps.cpp b/mlxlink/modules/mlxlink_maps.cpp index d635448b..16511491 100644 --- a/mlxlink/modules/mlxlink_maps.cpp +++ b/mlxlink/modules/mlxlink_maps.cpp @@ -865,6 +865,88 @@ void MlxlinkMaps::qsfpFarEndCableBreakoutMapping() "2 far-ends with 1 channel implemented in each (i.e. 2x1 break out)"; } +void MlxlinkMaps::modulePrbsMapping() +{ + _modulePrbsSt[PMPT_STATUS_NORMAL_MODE] = "Normal mission mode"; + _modulePrbsSt[PMPT_STATUS_NOT_SUPPORTED] = "Module is disabled/not connected"; + _modulePrbsSt[PMPT_STATUS_CONFIG_ERROR] = "unsupported configuration setting"; + _modulePrbsSt[PMPT_STATUS_GEN_ONLY] = "PRBS Generator only"; + _modulePrbsSt[PMPT_STATUS_CH_ONLY] = "PRBS Checker only"; + _modulePrbsSt[PMPT_STATUS_BOTH] = "PRBS traffic both Checker and Generator"; + + _modulePrbsSwapAdmin[0] = "NO MSB <-> LSB swapping"; + _modulePrbsSwapAdmin[1] = "MSB <-> LSB swapping"; + + _modulePrbsInvAdmin[0] = "NO PRBS inversion"; + _modulePrbsInvAdmin[1] = "PRBS inversion"; + + _modulePrbsModulation[0] = "NRZ test pattern"; + _modulePrbsModulation[1] = "PAM4 encoding"; + + _modulePrbsRateCapToStr[0] = "Non Selected"; + _modulePrbsRateCapToStr[MODULE_PRBS_LANE_RATE_1G] = "1.25 Gb/s"; + _modulePrbsRateCapToStr[MODULE_PRBS_LANE_RATE_SDR] = "2.5 Gb/s"; + _modulePrbsRateCapToStr[MODULE_PRBS_LANE_RATE_40G_40G] = "10.3125 Gb/s"; + _modulePrbsRateCapToStr[MODULE_PRBS_LANE_RATE_FDR] = "14.0625 Gb/s"; + _modulePrbsRateCapToStr[MODULE_PRBS_LANE_RATE_EDR] = "25.78125 Gb/s"; + _modulePrbsRateCapToStr[MODULE_PRBS_LANE_RATE_HDR] = "53.125 Gb/s"; + _modulePrbsRateCapToStr[MODULE_PRBS_LANE_RATE_NDR] = "106.25 Gb/s"; + + _modulePrbsRateStrToCap["1G"] = MODULE_PRBS_LANE_RATE_1G; + _modulePrbsRateStrToCap["1.25G"] = MODULE_PRBS_LANE_RATE_1G; + + _modulePrbsRateStrToCap["IB-SDR"] = MODULE_PRBS_LANE_RATE_SDR; + _modulePrbsRateStrToCap["SDR"] = MODULE_PRBS_LANE_RATE_SDR; + _modulePrbsRateStrToCap["2.5G"] = MODULE_PRBS_LANE_RATE_SDR; + + _modulePrbsRateStrToCap["10G"] = MODULE_PRBS_LANE_RATE_40G_40G; + _modulePrbsRateStrToCap["40G"] = MODULE_PRBS_LANE_RATE_40G_40G; + _modulePrbsRateStrToCap["10.3125G"] = MODULE_PRBS_LANE_RATE_40G_40G; + + _modulePrbsRateStrToCap["IB-FDR"] = MODULE_PRBS_LANE_RATE_FDR; + _modulePrbsRateStrToCap["FDR"] = MODULE_PRBS_LANE_RATE_FDR; + _modulePrbsRateStrToCap["14G"] = MODULE_PRBS_LANE_RATE_FDR; + _modulePrbsRateStrToCap["14.0625G"] = MODULE_PRBS_LANE_RATE_FDR; + + _modulePrbsRateStrToCap["IB-EDR"] = MODULE_PRBS_LANE_RATE_EDR; + _modulePrbsRateStrToCap["EDR"] = MODULE_PRBS_LANE_RATE_EDR; + _modulePrbsRateStrToCap["25G"] = MODULE_PRBS_LANE_RATE_EDR; + _modulePrbsRateStrToCap["25.78125G"] = MODULE_PRBS_LANE_RATE_EDR; + + _modulePrbsRateStrToCap["IB-HDR"] = MODULE_PRBS_LANE_RATE_HDR; + _modulePrbsRateStrToCap["HDR"] = MODULE_PRBS_LANE_RATE_HDR; + _modulePrbsRateStrToCap["50G"] = MODULE_PRBS_LANE_RATE_HDR; + _modulePrbsRateStrToCap["53.125G"] = MODULE_PRBS_LANE_RATE_HDR; + + _modulePrbsRateStrToCap["IB-NDR"] = MODULE_PRBS_LANE_RATE_NDR; + _modulePrbsRateStrToCap["NDR"] = MODULE_PRBS_LANE_RATE_NDR; + _modulePrbsRateStrToCap["100G"] = MODULE_PRBS_LANE_RATE_NDR; + _modulePrbsRateStrToCap["106.25G"] = MODULE_PRBS_LANE_RATE_NDR; + + _modulePrbsModeCapToStr[PRBS31_CAP] = "PRBS31"; + _modulePrbsModeCapToStr[PRBS23A_CAP] = "PRBS23"; + _modulePrbsModeCapToStr[PRBS7_CAP] = "PRBS7"; + _modulePrbsModeCapToStr[PRBS11_CAP] = "PRBS11"; + _modulePrbsModeCapToStr[PRBS9_CAP] = "PRBS9"; + _modulePrbsModeCapToStr[PRBS13A_CAP] = "PRBS13"; + _modulePrbsModeCapToStr[SSPR_CAP] = "SSPR"; + _modulePrbsModeCapToStr[SSPRQ_CAP] = "SSPRQ"; + + _modulePrbsModeStrToCap["PRBS31"] = PRBS31_CAP; + _modulePrbsModeStrToCap["PRBS23"] = PRBS23A_CAP; + _modulePrbsModeStrToCap["PRBS7"] = PRBS7_CAP; + _modulePrbsModeStrToCap["PRBS11"] = PRBS11_CAP; + _modulePrbsModeStrToCap["PRBS9"] = PRBS9_CAP; + _modulePrbsModeStrToCap["PRBS13"] = PRBS13A_CAP; + _modulePrbsModeStrToCap["SSPR"] = SSPR_CAP; + _modulePrbsModeStrToCap["SSPRQ"] = SSPRQ_CAP; + + _modulePMPDStatus[PMPD_STATUS_NOT_SUPPORTED] = "Not Supported"; + _modulePMPDStatus[PMPD_STATUS_NORMAL_MODE] = "Normal Mode"; + _modulePMPDStatus[PMPD_STATUS_NOT_LOCKED] = "Not Locked"; + _modulePMPDStatus[PMPD_STATUS_LOCKED] = "Locked"; +} + void MlxlinkMaps::qsfpComlianceMapping() { _cableComplianceQsfp[QSFP_ETHERNET_COMPLIANCE_CODE_Unspecified] = @@ -1162,6 +1244,7 @@ void MlxlinkMaps::initCableComplianceMapping() dataPathStateMapping(); errorCodeResMapping(); techMapping(); + modulePrbsMapping(); } void MlxlinkMaps::initCableTechnologyMapping() diff --git a/mlxlink/modules/mlxlink_maps.h b/mlxlink/modules/mlxlink_maps.h index b5d0d294..6e20bb1f 100644 --- a/mlxlink/modules/mlxlink_maps.h +++ b/mlxlink/modules/mlxlink_maps.h @@ -133,6 +133,7 @@ class MlxlinkMaps{ void vccFlagsMapping(); void dataPathStateMapping(); void errorCodeResMapping(); + void modulePrbsMapping(); void rxPowerTypeMapping(); void phyHstFsmHdrStateMapping(); void maxReadReqSizeMapping(); @@ -170,8 +171,11 @@ class MlxlinkMaps{ std::map _modulePrbsSwapAdmin; std::map _modulePrbsInvAdmin; std::map _modulePrbsModulation; - std::map _modulePrbsRateCap; + std::map _modulePrbsRateCapToStr; + std::map _modulePrbsRateStrToCap; std::map _modulePMPDStatus; + std::map _modulePrbsModeCapToStr; + std::map _modulePrbsModeStrToCap; std::map _pepcStatus; std::map _IBSpeed2Str; std::map _EthExtSpeed2Str; From 01252fa30fcb85d6e8c27ea6c5a822a025e19381 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Thu, 24 Feb 2022 15:54:05 +0200 Subject: [PATCH 087/184] [mstlink] Fixing warning message while configuring RM loopback Description: Fixing warning message while configuring RM loopback Issue: None Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_commander.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index e047a814..dd851092 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -4234,7 +4234,7 @@ void MlxlinkCommander::checkPplrCap() supportedLoopbacks.c_str()); } } - if (loopBackVal == PHY_REMOTE_LOOPBACK) { + if (loopBackVal == PHY_REMOTE_LOOPBACK && _productTechnology < PRODUCT_7NM) { string warMsg = "Remote loopback mode pre-request (all should be satisfied):\n"; warMsg += "1. Remote loopback is supported only in force mode.\n"; warMsg += " please use the --link_mode_force flag if force mode not configured\n"; From 3d54fa152d1c0a34746e9e2d707ed3b11f4faaf1 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Thu, 24 Feb 2022 16:38:05 +0200 Subject: [PATCH 088/184] [mstlink][PMPT/PMPD] Supporting module PRBS test mode Description: Adding a new flags to enable the module PRBS test mode: --prbs_select : Module PRBS test mode side selector [MEDIA, HOST] --prbs_mode : Perform PRBS test mode on the Module [EN(Enable),DS(Disable)] --generator_rate : Set PRBS generator lane rate [HDR(50G)(default), 1.25G, SDR(2.5G), 10.3125G, FDR(14G), EDR(25G), NDR(100G)] --generator_pattern : Set PRBS generator pattern [PRBS31 (default), PRBS23, PRBS7, PRBS11, PRBS9, PRBS13, SSPR, SSPRQ] --swap_generator : Enable PAM4 MSB <-> LSB generator swapping (Optional) --invert_generator : Enable PRBS generator inversion (Optional) --generator_lanes : PRBS generator lanes to set (one or more lane separated by comma)[0,1,2,3,4,5,6,7] (Optional - Default all lanes) --checker_rate : Set PRBS Checker Lane rate [HDR(50G)(default), 1.25G, SDR(2.5G), 10.3125G, FDR(14G), EDR(25G), NDR(100G)] --checker_pattern : Set PRBS Checker pattern [PRBS31 (default), PRBS23, PRBS7, PRBS11, PRBS9, PRBS13, SSPR, SSPRQ] --swap_checker : Enable PAM4 MSB <-> LSB checker swapping (Optional) --invert_checker : Enable PRBS generator inversion (Optional) --checker_lanes : PRBS checker lanes to set (one or more lane separated by comma)[0,1,2,3,4,5,6,7] (Optional - Default all lanes) --show_diagnostic_info : Show PRBS diagnostic counters information --clear_diagnostic_info : Clear PRBS diagnostic counters Issue: 2946700 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_cables_commander.cpp | 403 +++++++++++++++++++ mlxlink/modules/mlxlink_cables_commander.h | 79 ++-- mlxlink/modules/mlxlink_commander.cpp | 74 +++- mlxlink/modules/mlxlink_commander.h | 32 +- mlxlink/modules/mlxlink_enums.h | 5 +- mlxlink/modules/mlxlink_maps.cpp | 4 + mlxlink/modules/mlxlink_ui.cpp | 177 +++++++- mlxlink/modules/mlxlink_ui.h | 1 + mlxlink/modules/mlxlink_user_input.cpp | 8 + mlxlink/modules/mlxlink_user_input.h | 10 + mlxlink/modules/mlxlink_utils.cpp | 14 +- mlxlink/modules/printutil/mlxlink_record.cpp | 10 +- mlxlink/modules/printutil/mlxlink_record.h | 5 +- 13 files changed, 773 insertions(+), 49 deletions(-) diff --git a/mlxlink/modules/mlxlink_cables_commander.cpp b/mlxlink/modules/mlxlink_cables_commander.cpp index d4c5c5c8..1815ac50 100644 --- a/mlxlink/modules/mlxlink_cables_commander.cpp +++ b/mlxlink/modules/mlxlink_cables_commander.cpp @@ -1028,3 +1028,406 @@ MlxlinkCmdPrint MlxlinkCablesCommander::readFromEEPRM(u_int16_t page , u_int16_t free(pageH); return bytesOutput; } + +u_int32_t MlxlinkCablesCommander::getModeAdminFromStr(u_int32_t cap, const string &rateStr) +{ + int modeAdmin = _prbsMode; + if (!rateStr.empty()) { + modeAdmin = _mlxlinkMaps->_modulePrbsModeStrToCap[rateStr]; + if (!modeAdmin) { + string validRates = "["; + for (auto it = _mlxlinkMaps->_modulePrbsModeCapToStr.begin(); + it != _mlxlinkMaps->_modulePrbsModeCapToStr.end(); it++) { + if (it->first & cap) { + validRates += it->second + ","; + } + } + validRates = deleteLastChar(validRates); + validRates = "]"; + throw MlxRegException("Invalid PRBS pattern value [%s] \nValid values are: %s\n", + rateStr.c_str(), validRates.c_str()); + } + modeAdmin = (int)log2((float) modeAdmin); + } + return modeAdmin; +} + +u_int32_t MlxlinkCablesCommander::getRateAdminFromStr(u_int32_t cap, const string &rateStr) +{ + int rateAdmin = _prbsRate; + if (!rateStr.empty()) { + rateAdmin = _mlxlinkMaps->_modulePrbsRateStrToCap[rateStr]; + if (!rateAdmin) { + if (!_modulePrbsParams[MODULE_PRBS_CH_RATE].empty() && + !_modulePrbsParams[MODULE_PRBS_GEN_RATE].empty()) { + if (_modulePrbsParams[MODULE_PRBS_CH_RATE] != _modulePrbsParams[MODULE_PRBS_GEN_RATE]) { + throw MlxRegException("Checker and Generator must be running in the same lane rate\n"); + } + } + string validRates = "["; + for (auto it = _mlxlinkMaps->_modulePrbsRateStrToCap.begin(); + it != _mlxlinkMaps->_modulePrbsRateStrToCap.end(); it++) { + if (it->second & cap) { + validRates += it->first + ","; + } + } + validRates = deleteLastChar(validRates); + validRates += "]"; + throw MlxRegException("Invalid PRBS lane rate configuration [%s] \nValid configurations are: %s\n", + rateStr.c_str(), validRates.c_str()); + } + } + return rateAdmin; +} + +bool MlxlinkCablesCommander::getInvAdminFromStr(u_int32_t cap, const string &invStr) +{ + bool invAdmin = false; + if (!invStr.empty()) { + invAdmin = true; + if (!cap) { + throw MlxRegException("PRBS inversion is not supported by the module\n"); + } + } + return invAdmin; +} + +bool MlxlinkCablesCommander::getSwapAdminFromStr(u_int32_t cap, const string &swapStr) +{ + bool swapAdmin = false; + if (!swapStr.empty()) { + swapAdmin = true; + if (!cap) { + throw MlxRegException("PAM4 MSB <-> LSB swapping is not supported by the module"); + } + } + return swapAdmin; +} + +u_int32_t MlxlinkCablesCommander::getLanesFromStr(u_int32_t cap, const string &lanesStr) +{ + u_int32_t laneMask = 0; + string temp = lanesStr; + if (!lanesStr.empty()) { + if (!cap) { + throw MlxRegException("No support of per lane configuration by the module"); + } + auto lanesVec = MlxlinkRecord::split(temp, ","); + u_int32_t val = 0; + for (auto it = lanesVec.begin(); it != lanesVec.end(); it++) { + strToUint32((char*)(*it).c_str(), val); + if (val > (_numOfLanes - 1)) { + throw MlxRegException("Invalid lane index [%d], valid lanes range is [0 to %d]", val, (_numOfLanes - 1)); + } + laneMask |= (u_int32_t)pow(2.0, (double) val); + } + } + return laneMask; +} + +void MlxlinkCablesCommander::getNumOfModuleLanes() +{ + try { + // As a WA, use module_width for MEDIA and HOST lanes + // TODO: use module_media_width once it be supported + //if (_modulePrbsParams[MODULE_PRBS_SELECT] == "HOST") { + resetParser(ACCESS_REG_PMTM); + updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); + genBuffSendRegister(ACCESS_REG_PMTM, MACCESS_REG_METHOD_GET); + + _numOfLanes = getFieldValue("module_width"); + //} else { + //_numOfLanes = getFieldValue("module_media_width"); + //} + } catch (MlxRegException &exc) { + } +} + +void MlxlinkCablesCommander::checkAndParsePMPTCap(ModuleAccess_t moduleAccess) +{ + bool regFaild = false; + try { + resetParser(ACCESS_REG_PMPT); + updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); + updateField("host_media", _modulePrbsParams[MODULE_PRBS_SELECT] == "HOST"); + updateField("ch_ge", (u_int32_t)moduleAccess); + updateField("lane_mask", 0x1); + genBuffSendRegister(ACCESS_REG_PMPT, MACCESS_REG_METHOD_GET); + } catch (MlxRegException &exc) { + regFaild = true; + } + + if (regFaild || getFieldValue("status") == PMPT_STATUS_NOT_SUPPORTED) { + throw MlxRegException("Module doesn't support PRBS and diagnostics data"); + } + + u_int32_t chAccessShift = moduleAccess == MODULE_PRBS_ACCESS_CH? MODULE_PRBS_GEN_INV : 0; + + _prbsRate = getRateAdminFromStr(getFieldValue("lane_rate_cap"), + _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_RATE + chAccessShift)]); + _prbsMode = getModeAdminFromStr(getFieldValue("prbs_modes_cap"), + _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_PAT + chAccessShift)]); + _prbsInv = getInvAdminFromStr(getFieldValue("invt_cap"), + _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_INV + chAccessShift)]); + _prbsSwap = getSwapAdminFromStr(getFieldValue("swap_cap"), + _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_SWAP + chAccessShift)]); + _prbsLanes = getLanesFromStr(getFieldValue("ls"), + _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_LANES + chAccessShift)]); +} + +void MlxlinkCablesCommander::preparePrbsParam(ModuleAccess_t moduleAccess) +{ + if (moduleAccess != MODULE_PRBS_ACCESS_BOTH && + (_modulePrbsParams[MODULE_PRBS_GEN_RATE] != _modulePrbsParams[MODULE_PRBS_CH_RATE])) { + throw MlxRegException("PRBS Checker and Generator lane rate must be provided with the same rate"); + } + + switch (moduleAccess) { + case MODULE_PRBS_ACCESS_CH: + case MODULE_PRBS_ACCESS_GEN: + checkAndParsePMPTCap(moduleAccess); + break; + case MODULE_PRBS_ACCESS_CH_GEN: + checkAndParsePMPTCap(MODULE_PRBS_ACCESS_CH); + checkAndParsePMPTCap(MODULE_PRBS_ACCESS_GEN); + break; + default: + checkAndParsePMPTCap(MODULE_PRBS_ACCESS_BOTH); + } +} + +u_int32_t MlxlinkCablesCommander::getPMPTStatus(ModuleAccess_t moduleAccess) +{ + resetParser(ACCESS_REG_PMPT); + updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); + updateField("host_media", _modulePrbsParams[MODULE_PRBS_SELECT] == "HOST"); + updateField("ch_ge", (u_int32_t)moduleAccess); + updateField("lane_mask", 0x1); + genBuffSendRegister(ACCESS_REG_PMPT, MACCESS_REG_METHOD_GET); + + return getFieldValue("status"); +} + +void MlxlinkCablesCommander::sendPMPT(ModuleAccess_t moduleAccess) +{ + resetParser(ACCESS_REG_PMPT); + updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); + updateField("host_media", _modulePrbsParams[MODULE_PRBS_SELECT] == "HOST"); + updateField("ch_ge", (u_int32_t)moduleAccess); + updateField("e", 1); + updateField("prbs_mode_admin", _prbsMode); + updateField("lane_rate_admin", _prbsRate); + updateField("invt_admin", _prbsInv); + updateField("swap_admin", _prbsSwap); + updateField("lane_mask", _prbsLanes? _prbsLanes : 0xff); + updateField("le", _prbsLanes != 0); + updateField("modulation", _prbsRate >= MODULE_PRBS_LANE_RATE_HDR); + genBuffSendRegister(ACCESS_REG_PMPT, MACCESS_REG_METHOD_SET); + + if (getPMPTStatus(moduleAccess) == PMPT_STATUS_CONFIG_ERROR) { + throw MlxRegException("Unsupported configuration setting"); + } +} + +void MlxlinkCablesCommander::enablePMPT(ModuleAccess_t moduleAccess) +{ + try { + switch (moduleAccess) { + case MODULE_PRBS_ACCESS_CH: + case MODULE_PRBS_ACCESS_GEN: + sendPMPT(moduleAccess); + break; + case MODULE_PRBS_ACCESS_CH_GEN: + sendPMPT(MODULE_PRBS_ACCESS_CH); + sendPMPT(MODULE_PRBS_ACCESS_GEN); + break; + default: + sendPMPT(MODULE_PRBS_ACCESS_BOTH); + } + } catch (MlxRegException &exc) { + throw MlxRegException("Module doesn't support PRBS and diagnostics data"); + } +} + +void MlxlinkCablesCommander::disablePMPT() +{ + resetParser(ACCESS_REG_PMPT); + updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); + updateField("host_media", _modulePrbsParams[MODULE_PRBS_SELECT] == "HOST"); + updateField("ch_ge", 0); + updateField("e", 0); + updateField("prbs_mode_admin", _prbsMode); + updateField("lane_rate_admin", _prbsRate); + updateField("modulation", 1); + updateField("lane_mask", 0xff); + genBuffSendRegister(ACCESS_REG_PMPT, MACCESS_REG_METHOD_SET); +} + +void MlxlinkCablesCommander::handlePrbsTestMode(const string &ctrl, ModuleAccess_t moduleAccess) +{ + if (ctrl == "EN") { + MlxlinkRecord::printCmdLine("Enabling Module PRBS Test Mode", _jsonRoot); + getNumOfModuleLanes(); + preparePrbsParam(moduleAccess); + enablePMPT(moduleAccess); + } else if (ctrl == "DS") { + MlxlinkRecord::printCmdLine("Disabling Module PRBS Test Mode", _jsonRoot); + disablePMPT(); + } else { + throw MlxRegException("Invalid PRBS Module mode, please check the help menu"); + } +} + +void MlxlinkCablesCommander::getPMPTConfiguration(ModuleAccess_t moduleAccess, vector &prbsPattern, + vector &prbsRate, vector &prbsInv, + vector &prbsSwap) +{ + resetParser(ACCESS_REG_PMPT); + updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); + updateField("host_media", _modulePrbsParams[MODULE_PRBS_SELECT] == "HOST"); + updateField("ch_ge", (u_int32_t)moduleAccess); + updateField("lane_mask", 0x1); + genBuffSendRegister(ACCESS_REG_PMPT, MACCESS_REG_METHOD_GET); + + u_int32_t index = (u_int32_t)pow(2.0, (double)getFieldValue("prbs_mode_admin")); + prbsPattern.push_back(MlxlinkRecord::addSpaceForModulePrbs(_mlxlinkMaps->_modulePrbsModeCapToStr[index])); + + index = getFieldValue("lane_rate_admin"); + prbsRate.push_back(MlxlinkRecord::addSpaceForModulePrbs(_mlxlinkMaps->_modulePrbsRateCapToStr[index])); + + string capStr = getFieldValue("invt_cap")? "" : "Not Supported"; + string adminStr = getFieldValue("invt_admin")? "Yes" : "No"; + prbsInv.push_back(MlxlinkRecord::addSpaceForModulePrbs(!capStr.empty()?capStr:adminStr)); + + capStr = getFieldValue("swap_cap")? "" : "Not Supported"; + adminStr = getFieldValue("swap_admin")? "Yes" : "No"; + prbsSwap.push_back(MlxlinkRecord::addSpaceForModulePrbs(!capStr.empty()?capStr:adminStr)); +} + +string MlxlinkCablesCommander::getPMPDLockStatus() +{ + string lockStatusStr = ""; + + for (u_int32_t lane = 0; lane < _numOfLanes; lane++) { + resetParser(ACCESS_REG_PMPD); + updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); + updateField("host_media", _modulePrbsParams[MODULE_PRBS_SELECT] == "HOST"); + updateField("lane", lane); + genBuffSendRegister(ACCESS_REG_PMPD, MACCESS_REG_METHOD_GET); + + lockStatusStr += MlxlinkRecord::addSpaceForModulePrbs(_mlxlinkMaps->_modulePMPDStatus[getFieldValue("status")]); + lockStatusStr += ","; + } + + if (!lockStatusStr.empty()) { + lockStatusStr = deleteLastChar(lockStatusStr); + } + + return lockStatusStr; +} + +void MlxlinkCablesCommander::showPrbsTestMode() +{ + MlxlinkCmdPrint prbsOutput = MlxlinkCmdPrint(); + setPrintTitle(prbsOutput, "Module PRBS Test Mode", MODULE_PMPT_INFO_LAST); + + getNumOfModuleLanes(); + + try { + resetParser(ACCESS_REG_PMPT); + updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); + updateField("host_media", _modulePrbsParams[MODULE_PRBS_SELECT] == "HOST"); + updateField("ch_ge", 0); + updateField("lane_mask", 0x1); + genBuffSendRegister(ACCESS_REG_PMPT, MACCESS_REG_METHOD_GET); + } catch (MlxRegException &exc) { + throw MlxRegException("Device doesn't support Module PRBS and diagnostics data"); + } + + setPrintVal(prbsOutput, "Status", _mlxlinkMaps->_modulePrbsSt[getFieldValue("status")]); + setPrintVal(prbsOutput, "Lock Status [per lane]", getPMPDLockStatus(), ANSI_COLOR_RESET, true, true, true); + + vector prbsAcces, prbsPattern, prbsRate, prbsInv, prbsSwap; + prbsAcces.push_back(MlxlinkRecord::addSpaceForModulePrbs("Checker")); + prbsAcces.push_back(MlxlinkRecord::addSpaceForModulePrbs("Generator")); + + getPMPTConfiguration(MODULE_PRBS_ACCESS_GEN, prbsPattern, prbsRate, prbsInv, prbsSwap); + getPMPTConfiguration(MODULE_PRBS_ACCESS_CH, prbsPattern, prbsRate, prbsInv, prbsSwap); + + setPrintVal(prbsOutput, "PRBS Access", getStringFromVector(prbsAcces), ANSI_COLOR_RESET, true, true, true); + setPrintVal(prbsOutput, "PRBS Pattern", getStringFromVector(prbsPattern), ANSI_COLOR_RESET, true, true, true); + setPrintVal(prbsOutput, "PRBS Lane Rate ", getStringFromVector(prbsRate), ANSI_COLOR_RESET, true, true, true); + setPrintVal(prbsOutput, "PRBS Inversion", getStringFromVector(prbsInv), ANSI_COLOR_RESET, true, true, true); + setPrintVal(prbsOutput, "PRBS MSB<->LSB Swap", getStringFromVector(prbsSwap), ANSI_COLOR_RESET, true, true, true); + + prbsOutput.toJsonFormat(_jsonRoot); + + cout << prbsOutput; + +} + +void MlxlinkCablesCommander::getPMPDInfo(vector &traffic, vector &errors, vector &ber, + vector &snr) +{ + string traficStr, errorsStr, berStr, snrStr; + for (u_int32_t lane = 0; lane < _numOfLanes; lane++) { + resetParser(ACCESS_REG_PMPD); + updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); + updateField("host_media", _modulePrbsParams[MODULE_PRBS_SELECT] == "HOST"); + updateField("lane", lane); + genBuffSendRegister(ACCESS_REG_PMPD, MACCESS_REG_METHOD_GET); + + traficStr = to_string(add32BitTo64(getFieldValue("prbs_bits_high"), + getFieldValue("prbs_bits_low"))); + errorsStr = to_string(add32BitTo64(getFieldValue("prbs_errors_high"), getFieldValue("prbs_errors_low"))); + berStr = to_string(getFieldValue("ber_coef")) + "E-" + to_string(getFieldValue("ber_magnitude")); + snrStr = to_string(getFieldValue("measured_snr")) +" dB"; + + traffic.push_back(MlxlinkRecord::addSpaceForModulePrbs(traficStr)); + errors.push_back(MlxlinkRecord::addSpaceForModulePrbs(getFieldValue("errors_cap")? errorsStr : "Not Supported")); + ber.push_back(MlxlinkRecord::addSpaceForModulePrbs(getFieldValue("ber_cap")? berStr : "Not Supported")); + snr.push_back(MlxlinkRecord::addSpaceForModulePrbs(getFieldValue("snr_cap")? snrStr : "Not Supported")); + } +} + +void MlxlinkCablesCommander::showPrpsDiagInfo() +{ + vector traffic, errors, ber, snr; + MlxlinkCmdPrint diagOutput = MlxlinkCmdPrint(); + + getNumOfModuleLanes(); + + setPrintTitle(diagOutput, "Module PRBS Diagnostic Counters", MODULE_PMPD_INFO_LAST); + + getPMPDInfo(traffic, errors, ber, snr); + + setPrintVal(diagOutput, "PRBS Traffic (bits) [per lane]", getStringFromVector(traffic), ANSI_COLOR_RESET, true, true, true); + setPrintVal(diagOutput, "PRBS Errors [per lane]", getStringFromVector(errors), ANSI_COLOR_RESET, true, true, true); + setPrintVal(diagOutput, "PRBS BER [per lane]", getStringFromVector(ber), ANSI_COLOR_RESET, true, true, true); + setPrintVal(diagOutput, "Measured SNR [per lane]", getStringFromVector(snr), ANSI_COLOR_RESET, true, true, true); + + diagOutput.toJsonFormat(_jsonRoot); + + cout << diagOutput; +} + +void MlxlinkCablesCommander::clearPrbsDiagInfo() +{ + MlxlinkRecord::printCmdLine("Clearing PRBS Diagnostic Counters", _jsonRoot); + + resetParser(ACCESS_REG_PMPD); + updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); + updateField("host_media", _modulePrbsParams[MODULE_PRBS_SELECT] == "HOST"); + updateField("cl", 1); + genBuffSendRegister(ACCESS_REG_PMPD, MACCESS_REG_METHOD_GET); +} diff --git a/mlxlink/modules/mlxlink_cables_commander.h b/mlxlink/modules/mlxlink_cables_commander.h index 91caa195..47de9795 100644 --- a/mlxlink/modules/mlxlink_cables_commander.h +++ b/mlxlink/modules/mlxlink_cables_commander.h @@ -111,18 +111,36 @@ class MlxlinkCablesCommander :public MlxlinkRegParser{ MlxlinkCablesCommander(Json::Value &jsonRoot); virtual ~MlxlinkCablesCommander(); - void readMCIA(u_int32_t page, u_int32_t size, u_int32_t offset, - u_int8_t * data, u_int32_t i2cAddress); - void writeMCIA(u_int32_t page, u_int32_t size, u_int32_t numberOfZeroBytes, - u_int32_t offset, u_int8_t * data, u_int32_t i2cAddress); + vector getPagesToDump(); + vector getCableDDM(); + void writeToEEPROM(u_int16_t page , u_int16_t offset, vector &bytesToWrite); + MlxlinkCmdPrint readFromEEPRM(u_int16_t page , u_int16_t offset, u_int16_t length); + void handlePrbsTestMode(const string &ctrl, ModuleAccess_t moduleAccess); + void showPrbsTestMode(); + void showPrpsDiagInfo(); + void clearPrbsDiagInfo(); + + u_int32_t _moduleNumber; + u_int32_t _slotIndex; + u_int32_t _cableIdentifier; + bool _sfp51Paging; + bool _passiveQsfp; + u_int32_t _localPort; + u_int32_t _numOfLanes; + MlxlinkMaps *_mlxlinkMaps; + map _modulePrbsParams; + +private: + /**** MCIA helper funcitons ****/ + void readMCIA(u_int32_t page, u_int32_t size, u_int32_t offset, u_int8_t * data, u_int32_t i2cAddress); + void writeMCIA(u_int32_t page, u_int32_t size, u_int32_t numberOfZeroBytes, u_int32_t offset, u_int8_t * data, + u_int32_t i2cAddress); void initValidPages(); - void loadEEPRMPage(u_int32_t pageNum, u_int32_t offset, u_int8_t* data, - u_int32_t i2cAddress = I2C_ADDR_LOW); + void loadEEPRMPage(u_int32_t pageNum, u_int32_t offset, u_int8_t* data, u_int32_t i2cAddress = I2C_ADDR_LOW); void bytesToInt16(u_int16_t *bytes); void convertThreshold(ddm_threshold_t &field); void fixThresholdBytes(); - vector getCableDDM(); void prepareDDMOutput(); /**** CMIS helper functions *******/ void getCmisModuleFlags(u_int32_t moduleOffset, u_int8_t *page0L); @@ -138,34 +156,43 @@ class MlxlinkCablesCommander :public MlxlinkRegParser{ void prepareSFPDdmInfo(); void prepareThresholdInfo(u_int8_t *page); void readCableDDMInfo(); - void setPrintDDMFlagsSection(MlxlinkCmdPrint &cmdPrint, - const ddm_threshold_t &flags, const string &flagGroup); - string getDDMThresholdRow(u_int16_t temp, u_int16_t volt, u_int16_t rxPower, - u_int16_t txPower, u_int16_t txBias); - vector getPagesToDump(); - bool readFromPage(u_int8_t *pageBuffer, u_int32_t fieldOffset, void *data, - u_int32_t size = 1); - void addPageToOutputVector(u_int8_t *pageBuffer, u_int32_t page, u_int32_t offset, - u_int32_t length); + void setPrintDDMFlagsSection(MlxlinkCmdPrint &cmdPrint, const ddm_threshold_t &flags, const string &flagGroup); + string getDDMThresholdRow(u_int16_t temp, u_int16_t volt, u_int16_t rxPower, u_int16_t txPower, u_int16_t txBias); + bool readFromPage(u_int8_t *pageBuffer, u_int32_t fieldOffset, void *data, u_int32_t size = 1); + void addPageToOutputVector(u_int8_t *pageBuffer, u_int32_t page, u_int32_t offset, u_int32_t length); void checkParams(u_int16_t page , u_int16_t offset, u_int16_t length); - void writeToEEPROM(u_int16_t page , u_int16_t offset, vector &bytesToWrite); - MlxlinkCmdPrint readFromEEPRM(u_int16_t page , u_int16_t offset, u_int16_t length); u_int16_t getStatusBit(u_int32_t channel, u_int16_t val, u_int32_t statusMask); - u_int32_t _moduleNumber; - u_int32_t _slotIndex; - u_int32_t _cableIdentifier; - bool _sfp51Paging; - bool _passiveQsfp; - u_int32_t _localPort; - u_int32_t _numOfLanes; + void getNumOfModuleLanes(); + u_int32_t getRateAdminFromStr(u_int32_t cap, const string &rateStr); + u_int32_t getModeAdminFromStr(u_int32_t cap, const string &adminStr); + bool getInvAdminFromStr(u_int32_t cap, const string &invStr); + bool getSwapAdminFromStr(u_int32_t cap, const string &swapStr); + u_int32_t getLanesFromStr(u_int32_t cap, const string &lanesStr); + + void getPMPTConfiguration(ModuleAccess_t moduleAccess, vector &prbsPattern, vector &prbsRate, + vector &prbsInv, vector &prbsSwap); + void getPMPDInfo(vector &traffic, vector &errors, vector &ber, vector &snr); + string getPMPDLockStatus(); + + void checkAndParsePMPTCap(ModuleAccess_t moduleAccess); + void preparePrbsParam(ModuleAccess_t moduleAccess); + u_int32_t getPMPTStatus(ModuleAccess_t moduleAccess); + void sendPMPT(ModuleAccess_t moduleAccess); + void enablePMPT(ModuleAccess_t moduleAccess); + void disablePMPT(); -private: Json::Value &_jsonRoot; vector _validPages; vector _pagesToDump; vector _cableDDMOutput; cable_ddm_q_t _cableDdm; + + u_int32_t _prbsRate; + u_int32_t _prbsMode; + bool _prbsInv; + bool _prbsSwap; + u_int32_t _prbsLanes; }; #endif /* MLXLINK_CABLES_COMMANDER_H */ diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index dd851092..8c7d4257 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -253,7 +253,7 @@ void MlxlinkCommander::checkValidFW() void MlxlinkCommander::getProductTechnology() { try { - if (_devID == DeviceConnectX7) { //TODO: remove after supporting SLRG for Carmel + if (_devID == DeviceConnectX7 || _devID == DeviceQuantum2) { resetParser(ACCESS_REG_MGIR); genBuffSendRegister(ACCESS_REG_MGIR, MACCESS_REG_METHOD_GET); @@ -1615,7 +1615,7 @@ void MlxlinkCommander::operatingInfoPage() _fecActive = getFieldValue("fec_mode_active"); u_int32_t phyMngrFsmState = getFieldValue("phy_mngr_fsm_state"); int loopbackMode = (phyMngrFsmState != PHY_MNGR_DISABLED) ? getFieldValue("loopback_mode") : -1; - _linkUP = (phyMngrFsmState == PHY_MNGR_ACTIVE_LINKUP || phyMngrFsmState == PHY_MNGR_PHYSICAL_LINKUP); + _linkUP = (phyMngrFsmState == PHY_MNGR_ACTIVE_LINKUP); _portPolling = phyMngrFsmState == PHY_MNGR_POLLING; _protoCapability = getFieldValue("cable_ext_eth_proto_cap"); if(_protoActive == IB) { @@ -4427,10 +4427,11 @@ void MlxlinkCommander::initCablesCommander() _cablesCommander->_localPort = _localPort; _cablesCommander->_numOfLanes = _numOfLanes; _cablesCommander->_cableIdentifier = _cableIdentifier; + _cablesCommander->_mlxlinkMaps = _mlxlinkMaps; _cablesCommander->_sfp51Paging = isSFP51Paging(); _cablesCommander->_passiveQsfp = isPassiveQSFP(); } else { - throw MlxRegException(string("No plugged cable detected")); + throw MlxRegException("No plugged cable detected"); } } @@ -4461,8 +4462,9 @@ void MlxlinkCommander::showCableDDM() } } } catch(MlxRegException &exc) { - _allUnhandledErrors += string( "Showing DDM info raised the following"\ - " exception: ") + string(exc.what()) + string("\n"); + _allUnhandledErrors += "Showing DDM info raised the following exception: "; + _allUnhandledErrors += exc.what_s(); + _allUnhandledErrors += "\n"; } } @@ -4490,8 +4492,9 @@ void MlxlinkCommander::writeCableEEPROM() _cablesCommander->writeToEEPROM(_userInput._page , _userInput._offset, bytesToWrite); } } catch(MlxRegException &exc) { - _allUnhandledErrors += string("Writing cable EEPROM raised the "\ - "following exception: ") + string(exc.what()) + string("\n"); + _allUnhandledErrors += "Writing cable EEPROM raised the following exception: "; + _allUnhandledErrors += exc.what_s(); + _allUnhandledErrors += "\n"; } } @@ -4505,8 +4508,61 @@ void MlxlinkCommander::readCableEEPROM() cout << bytesOutput; } } catch(MlxRegException &exc) { - _allUnhandledErrors += string("Reading cable EEPROM raised the following"\ - " exception: ") + string(exc.what()) + string("\n"); + _allUnhandledErrors += "Reading cable EEPROM raised the following exception: "; + _allUnhandledErrors += exc.what_s(); + _allUnhandledErrors += "\n"; + } +} + +void MlxlinkCommander::performModulePrbsCommands() +{ + try { + initCablesCommander(); + if (_cmisCable) { + if (_cableMediaType == ACTIVE || _cableMediaType == OPTICAL_MODULE) { + if (_userInput.modulePrbsParams[MODULE_PRBS_SELECT] != "HOST" && + _userInput.modulePrbsParams[MODULE_PRBS_SELECT] != "MEDIA") { + throw MlxRegException("Invalid module side PRBS select, please check the help menu"); + } + _cablesCommander->_modulePrbsParams = _userInput.modulePrbsParams; + if (_userInput.isPrbsModeProvided) { + ModuleAccess_t prbsModuleAccess = MODULE_PRBS_ACCESS_BOTH; + if (_userInput.isPrbsChProvided && !_userInput.isPrbsGenProvided) { + prbsModuleAccess = MODULE_PRBS_ACCESS_CH; + } else if (!_userInput.isPrbsChProvided && _userInput.isPrbsGenProvided) { + prbsModuleAccess = MODULE_PRBS_ACCESS_GEN; + } else if (_userInput.isPrbsChProvided && _userInput.isPrbsGenProvided) { + prbsModuleAccess = MODULE_PRBS_ACCESS_CH_GEN; + } + if (_userInput.modulePrbsParams[MODULE_PRBS_GEN_RATE] == _userInput.modulePrbsParams[MODULE_PRBS_CH_RATE] && + _userInput.modulePrbsParams[MODULE_PRBS_GEN_PAT] == _userInput.modulePrbsParams[MODULE_PRBS_CH_PAT] && + _userInput.modulePrbsParams[MODULE_PRBS_GEN_SWAP] == _userInput.modulePrbsParams[MODULE_PRBS_CH_SWAP] && + _userInput.modulePrbsParams[MODULE_PRBS_GEN_INV] == _userInput.modulePrbsParams[MODULE_PRBS_CH_INV] && + _userInput.modulePrbsParams[MODULE_PRBS_GEN_LANES] == _userInput.modulePrbsParams[MODULE_PRBS_GEN_LANES]) { + prbsModuleAccess = MODULE_PRBS_ACCESS_BOTH; + } + _cablesCommander->handlePrbsTestMode(_userInput.modulePrbsParams[MODULE_PRBS_MODE], prbsModuleAccess); + } else { + _cablesCommander->showPrbsTestMode(); + } + + if (_userInput.isPrbsShowDiagProvided) { + _cablesCommander->showPrpsDiagInfo(); + } + + if (_userInput.isPrbsClearDiagProvided) { + _cablesCommander->clearPrbsDiagInfo(); + } + } else { + throw MlxRegException("The PRBS test mode supported over Active/Optical modules only"); + } + } else { + throw MlxRegException("The PRBS test mode supported for CMIS modules only"); + } + } catch(MlxRegException &exc) { + _allUnhandledErrors += "Module PRBS test mode raised the following exception: "; + _allUnhandledErrors += exc.what_s(); + _allUnhandledErrors += "\n"; } } diff --git a/mlxlink/modules/mlxlink_commander.h b/mlxlink/modules/mlxlink_commander.h index dd750b22..8d4273ce 100644 --- a/mlxlink/modules/mlxlink_commander.h +++ b/mlxlink/modules/mlxlink_commander.h @@ -179,6 +179,34 @@ #define WRITE_OFFSET_FLAG_SHORT ' ' #define READ_LEN_FLAG "length" #define READ_LEN_FLAG_SHORT ' ' +#define CABLE_PRBS_SELECT "prbs_select" +#define CABLE_PRBS_SELECT_SHORT ' ' +#define CABLE_PRBS_MODE "prbs_mode" +#define CABLE_PRBS_MODE_SHORT ' ' +#define CABLE_PRBS_GEN_RATE "generator_rate" +#define CABLE_PRBS_GEN_RATE_SHORT ' ' +#define CABLE_PRBS_GEN_PAT "generator_pattern" +#define CABLE_PRBS_GEN_PAT_SHORT ' ' +#define CABLE_PRBS_GEN_SWAP "swap_generator" +#define CABLE_PRBS_GEN_SWAP_SHORT ' ' +#define CABLE_PRBS_GEN_INV "invert_generator" +#define CABLE_PRBS_GEN_INV_SHORT ' ' +#define CABLE_PRBS_GEN_LANES "generator_lanes" +#define CABLE_PRBS_GEN_LANES_SHORT ' ' +#define CABLE_PRBS_CH_RATE "checker_rate" +#define CABLE_PRBS_CH_RATE_SHORT ' ' +#define CABLE_PRBS_CH_PAT "checker_pattern" +#define CABLE_PRBS_CH_PAT_SHORT ' ' +#define CABLE_PRBS_CH_SWAP "swap_checker" +#define CABLE_PRBS_CH_SWAP_SHORT ' ' +#define CABLE_PRBS_CH_INV "invert_checker" +#define CABLE_PRBS_CH_INV_SHORT ' ' +#define CABLE_PRBS_CH_LANES "checker_lanes" +#define CABLE_PRBS_CH_LANES_SHORT ' ' +#define CABLE_PRBS_SHOW_DIAG "show_diagnostic_info" +#define CABLE_PRBS_SHOW_DIAG_SHORT ' ' +#define CABLE_PRBS_CLEAR_DIAG "clear_diagnostic_info" +#define CABLE_PRBS_CLEAR_DIAG_SHORT ' ' #define SHOW_TX_GROUP_MAP_FLAG "show_tx_group_map" #define SHOW_TX_GROUP_MAP_FLAG_SHORT ' ' #define SET_TX_GROUP_MAP_FLAG "tx_group_map" @@ -252,6 +280,7 @@ enum OPTION_TYPE { CABLE_SHOW_DDM, CABLE_EEPROM_WRITE, CABLE_EEPROM_READ, + CABLE_PRBS_CMDS, SEND_BER_COLLECT, SEND_AMBER_COLLECT, SEND_PAOS, @@ -266,7 +295,7 @@ enum OPTION_TYPE { SET_TX_GROUP_MAP, GRADE_SCAN_ENABLE, ERR_INJ_ENABLE, - RS_FEC_HISTOGRAM = 33, + RS_FEC_HISTOGRAM, SLRG_TEST, // Any new function's index should be added before FUNCTION_LAST in this enum FUNCTION_LAST @@ -460,6 +489,7 @@ class MlxlinkCommander: public MlxlinkRegParser { vector validateBytes(const vector &strBytes); void writeCableEEPROM(); void readCableEEPROM(); + void performModulePrbsCommands();; MlxlinkCmdPrint _toolInfoCmd; MlxlinkCmdPrint _operatingInfoCmd; diff --git a/mlxlink/modules/mlxlink_enums.h b/mlxlink/modules/mlxlink_enums.h index 24988f57..183bc125 100644 --- a/mlxlink/modules/mlxlink_enums.h +++ b/mlxlink/modules/mlxlink_enums.h @@ -74,6 +74,7 @@ #define ACCESS_REG_PPRT "PPRT" #define ACCESS_REG_PMPT "PMPT" #define ACCESS_REG_PMPD "PMPD" +#define ACCESS_REG_PMTM "PMTM" //define all used regs above this line #define QSFP_CHANNELS 4 @@ -1234,6 +1235,7 @@ enum ETH_LINK_SPEED { ETH_LINK_SPEED_40G_KR4 = 0x80, ETH_LINK_SPEED_56G_KR4 = 0x100, ETH_LINK_SPEED_56G_R4 = 0x100, + ETH_LINK_SPEED_10M = 0x400, ETH_LINK_SPEED_10G_CR = 0x1000, ETH_LINK_SPEED_10G_SR = 0x2000, ETH_LINK_SPEED_10G_LR = 0x4000, @@ -1275,7 +1277,8 @@ enum ETH_LINK_SPEED_EXT { ETH_LINK_SPEED_EXT_Reserved_14 = 0x4000, ETH_LINK_SPEED_EXT_400GAUI_8 = 0x8000, ETH_LINK_SPEED_EXT_400GAUI_4 = 0x10000, - ETH_LINK_SPEED_EXT_800GAUI_8 = 0x80000 + ETH_LINK_SPEED_EXT_800GAUI_8 = 0x80000, + ETH_LINK_SPEED_EXT_SGMII_10M = 0x8000000 }; enum IB_LINK_SPEED { diff --git a/mlxlink/modules/mlxlink_maps.cpp b/mlxlink/modules/mlxlink_maps.cpp index 16511491..9fa963bd 100644 --- a/mlxlink/modules/mlxlink_maps.cpp +++ b/mlxlink/modules/mlxlink_maps.cpp @@ -212,6 +212,7 @@ void MlxlinkMaps::ethSpeedMapping() _ETHSpeed2Str[ETH_LINK_SPEED_100_BaseTx] = "BaseTx100M"; _ETHSpeed2Str[ETH_LINK_SPEED_1000_BaseT] = "BaseT1000M"; + _ETHSpeed2Str[ETH_LINK_SPEED_10M] = "BaseT10M"; _ETHSpeed2Str[ETH_LINK_SPEED_1000_SGMII] = "CX"; _ETHSpeed2Str[ETH_LINK_SPEED_1000_KX] = "KX"; _ETHSpeed2Str[ETH_LINK_SPEED_10G_CX4] = "CX4"; @@ -275,6 +276,7 @@ void MlxlinkMaps::extEthSpeedMapping() _EthExtSpeed2Str[ETH_LINK_SPEED_EXT_400GAUI_8] = "400G"; _EthExtSpeed2Str[ETH_LINK_SPEED_EXT_400GAUI_4] = "400G"; _EthExtSpeed2Str[ETH_LINK_SPEED_EXT_800GAUI_8] = "800G"; + _EthExtSpeed2Str[ETH_LINK_SPEED_EXT_SGMII_10M] = "10M"; } void MlxlinkMaps::ibSpeedMapping() @@ -304,6 +306,7 @@ void MlxlinkMaps::speedToLanesMapping() _ETHSpeed2Lanes[ETH_LINK_SPEED_1000_BaseT] = 1; _ETHSpeed2Lanes[ETH_LINK_SPEED_1000_SGMII] = 1; _ETHSpeed2Lanes[ETH_LINK_SPEED_1000_KX] = 1; + _ETHSpeed2Lanes[ETH_LINK_SPEED_10M] = 1; _ETHSpeed2Lanes[ETH_LINK_SPEED_10G_CX4] = 4; _ETHSpeed2Lanes[ETH_LINK_SPEED_10G_KX4] = 4; _ETHSpeed2Lanes[ETH_LINK_SPEED_10G_BaseT] = 1; @@ -329,6 +332,7 @@ void MlxlinkMaps::speedToLanesMapping() _ETHSpeed2Lanes[ETH_LINK_SPEED_100G_LR4] = 4; _ETHSpeed2Lanes[ETH_LINK_SPEED_100G_SR4] = 4; + _ExtETHSpeed2Lanes[ETH_LINK_SPEED_EXT_SGMII_10M] = 1; _ExtETHSpeed2Lanes[ETH_LINK_SPEED_EXT_SGMII_100M] = 1; _ExtETHSpeed2Lanes[ETH_LINK_SPEED_EXT_1000BASE_X] = 1; _ExtETHSpeed2Lanes[ETH_LINK_SPEED_EXT_2_5GBASE_X] = 1; diff --git a/mlxlink/modules/mlxlink_ui.cpp b/mlxlink/modules/mlxlink_ui.cpp index 6332f07a..711ad9bb 100644 --- a/mlxlink/modules/mlxlink_ui.cpp +++ b/mlxlink/modules/mlxlink_ui.cpp @@ -198,6 +198,51 @@ void MlxlinkUi::printSynopsisCommands() printf(IDENT2); MlxlinkRecord::printFlagLine(WRITE_OFFSET_FLAG_SHORT, WRITE_OFFSET_FLAG, "offset", "Specific page offset to read/write"); + + printf(IDENT); + MlxlinkRecord::printFlagLine(CABLE_PRBS_SELECT_SHORT, CABLE_PRBS_SELECT, "side", + "Module PRBS test mode side selector [MEDIA, HOST]"); + printf(IDENT2); + MlxlinkRecord::printFlagLine(CABLE_PRBS_MODE_SHORT, CABLE_PRBS_MODE, "cmd", + "Perform PRBS test mode on the Module [EN(Enable),DS(Disable)]"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_RATE_SHORT, CABLE_PRBS_GEN_RATE, "rate", + "Set PRBS generator lane rate [HDR(50G)(default),1.25G,SDR(2.5G),10.3125G,FDR(14G),EDR(25G),NDR(100G)]"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_PAT_SHORT, CABLE_PRBS_GEN_PAT, "pattern", + "Set PRBS generator pattern [PRBS31(default),PRBS23,PRBS7,PRBS11,PRBS9,PRBS13,SSPR,SSPRQ]"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_SWAP_SHORT, CABLE_PRBS_GEN_SWAP, "", + "Enable PAM4 MSB <-> LSB generator swapping (Optional)"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_INV_SHORT, CABLE_PRBS_GEN_INV, "rate", + "Enable PRBS generator inversion (Optional)"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_LANES_SHORT, CABLE_PRBS_GEN_LANES, "lanes", + "PRBS generator lanes to set (one or more lane separated by comma)[0,1,2,3,4,5,6,7] (Optional - Default all lanes)"); + + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_CH_RATE_SHORT, CABLE_PRBS_CH_RATE, "rate", + "Set PRBS checker lane rate [HDR(50G)(default),1.25G,SDR(2.5G),10.3125G,FDR(14G),EDR(25G),NDR(100G)]"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_CH_PAT_SHORT, CABLE_PRBS_CH_PAT, "pattern", + "Set PRBS checker pattern [PRBS31(default),PRBS23,PRBS7,PRBS11,PRBS9,PRBS13,SSPR,SSPRQ]"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_CH_SWAP_SHORT, CABLE_PRBS_CH_SWAP, "", + "Enable PAM4 MSB <-> LSB checker swapping (Optional)"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_CH_INV_SHORT, CABLE_PRBS_CH_INV, "", + "Enable PRBS checker inversion (Optional)"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_CH_LANES_SHORT, CABLE_PRBS_CH_LANES, "lanes", + "PRBS checker lanes to set (one or more lane separated by comma)[0,1,2,3,4,5,6,7] (Optional - Default all lanes)"); + printf(IDENT2); + MlxlinkRecord::printFlagLine(CABLE_PRBS_SHOW_DIAG_SHORT, CABLE_PRBS_SHOW_DIAG, "", + "Show PRBS diagnostic counters information"); + printf(IDENT2); + MlxlinkRecord::printFlagLine(CABLE_PRBS_CLEAR_DIAG_SHORT, CABLE_PRBS_CLEAR_DIAG, "", + "Clear PRBS diagnostic counters"); + MlxlinkRecord::printFlagLine(MARGIN_SCAN_FLAG_SHORT, MARGIN_SCAN_FLAG, "", "Read the SerDes eye margins per lane"); printf(IDENT); @@ -210,7 +255,6 @@ void MlxlinkUi::printSynopsisCommands() MlxlinkRecord::printFlagLine(LANE_INDEX_FLAG_SHORT, LANE_INDEX_FLAG, "lane_index", "Run eye for specific lane index (Optional - Default all lanes)"); - MlxlinkRecord::printFlagLine(PREI_RX_ERR_INJ_FLAG_SHORT, PREI_RX_ERR_INJ_FLAG, "", "Enable the RX link deterioration"); printf(IDENT); @@ -393,8 +437,32 @@ void MlxlinkUi::validatePRBSParams() } } } else if (prbsFlags) { // add check for lanes flag to work with PRBS and eye scan only - throw MlxRegException( - "PRBS parameters flags valid only with PRBS Enable flag (--test_mode EN)"); + throw MlxRegException("PRBS parameters flags valid only with PRBS Enable flag (--test_mode EN)"); + } +} + +void MlxlinkUi::validateModulePRBSParams() +{ + if (!_mlxlinkCommander->_userInput.isPrbsSelProvided && (_mlxlinkCommander->_userInput.isPrbsModeProvided || + _mlxlinkCommander->_userInput.isPrbsChProvided || + _mlxlinkCommander->_userInput.isPrbsGenProvided || + _mlxlinkCommander->_userInput.isPrbsShowDiagProvided || + _mlxlinkCommander->_userInput.isPrbsClearDiagProvided)) { + throw MlxRegException("Please select PRBS module side using --" CABLE_PRBS_SELECT " [MEDIA|HOST] flag!"); + } + + if (!_mlxlinkCommander->_userInput.isPrbsModeProvided && (_mlxlinkCommander->_userInput.isPrbsChProvided || + _mlxlinkCommander->_userInput.isPrbsGenProvided)) { + throw MlxRegException("--" CABLE_PRBS_MODE " flag should be provided!"); + } + + if (_mlxlinkCommander->_userInput.isPrbsModeProvided && (_mlxlinkCommander->_userInput.isPrbsShowDiagProvided || + _mlxlinkCommander->_userInput.isPrbsClearDiagProvided)) { + throw MlxRegException("PRBS Module Diagnostic info flags are not working while configuring the PRBS test mode!"); + } + + if (_mlxlinkCommander->_userInput.isPrbsShowDiagProvided && _mlxlinkCommander->_userInput.isPrbsClearDiagProvided) { + throw MlxRegException("are mutually exclusive, please select one command only"); } } @@ -445,10 +513,14 @@ void MlxlinkUi::validateCableParams() bool readWriteFlags = _mlxlinkCommander->_userInput._page >= 0 || _mlxlinkCommander->_userInput._offset >= 0 || _mlxlinkCommander->_userInput._len >= 0 ; - bool cableCommandProvided = (_mlxlinkCommander->_userInput._dump || + bool prbsParamProvided = _mlxlinkCommander->_userInput.modulePrbsParams.size(); + bool cablePrbsParamProvided = _mlxlinkCommander->_userInput.isPrbsSelProvided || prbsParamProvided; + bool cableCommandProvided = _mlxlinkCommander->_userInput._dump || _mlxlinkCommander->_userInput._write || _mlxlinkCommander->_userInput._read || - _mlxlinkCommander->_userInput._ddm); + _mlxlinkCommander->_userInput._ddm || + cablePrbsParamProvided; + if(!_mlxlinkCommander->_userInput._cable && (cableCommandProvided || readWriteFlags)){ throw MlxRegException("\"--" CABLE_FLAG "\" flag should be specified!"); } else if (_mlxlinkCommander->_userInput._cable) { @@ -570,6 +642,7 @@ void MlxlinkUi::paramValidate() validatePRBSParams(); validateSpeedAndCSVBerParams(); validateCableParams(); + validateModulePRBSParams(); validateTxGroupParams(); validateGradeScanParams(); validateErrInjParams(); @@ -639,6 +712,21 @@ void MlxlinkUi::initCmdParser() AddOptions(WRITE_OFFSET_FLAG, WRITE_OFFSET_FLAG_SHORT, "offset", "Specify page offset"); AddOptions(READ_LEN_FLAG, READ_LEN_FLAG_SHORT, "length", "Length of data to read in bytes"); + AddOptions(CABLE_PRBS_SELECT, CABLE_PRBS_SELECT_SHORT, "side", ""); + AddOptions(CABLE_PRBS_MODE, CABLE_PRBS_MODE_SHORT, "cmd", ""); + AddOptions(CABLE_PRBS_GEN_RATE, CABLE_PRBS_GEN_RATE_SHORT, "rate", ""); + AddOptions(CABLE_PRBS_GEN_PAT, CABLE_PRBS_GEN_PAT_SHORT,"pattern", ""); + AddOptions(CABLE_PRBS_GEN_SWAP, CABLE_PRBS_GEN_SWAP_SHORT, "", ""); + AddOptions(CABLE_PRBS_GEN_INV, CABLE_PRBS_GEN_INV_SHORT, "rate", ""); + AddOptions(CABLE_PRBS_GEN_LANES, CABLE_PRBS_GEN_LANES_SHORT, "lanes", ""); + AddOptions(CABLE_PRBS_CH_RATE, CABLE_PRBS_CH_RATE_SHORT, "rate", ""); + AddOptions(CABLE_PRBS_CH_PAT, CABLE_PRBS_CH_PAT_SHORT, "pattern",""); + AddOptions(CABLE_PRBS_CH_SWAP, CABLE_PRBS_CH_SWAP_SHORT, "",""); + AddOptions(CABLE_PRBS_CH_INV, CABLE_PRBS_CH_INV_SHORT, "", ""); + AddOptions(CABLE_PRBS_CH_LANES, CABLE_PRBS_CH_LANES_SHORT, "lanes", ""); + AddOptions(CABLE_PRBS_SHOW_DIAG, CABLE_PRBS_SHOW_DIAG_SHORT, "", ""); + AddOptions(CABLE_PRBS_CLEAR_DIAG, CABLE_PRBS_CLEAR_DIAG_SHORT, "", ""); + AddOptions(SHOW_TX_GROUP_MAP_FLAG, SHOW_TX_GROUP_MAP_FLAG_SHORT, "group_num", "Display all label ports mapped to group "); AddOptions(SET_TX_GROUP_MAP_FLAG, SET_TX_GROUP_MAP_FLAG_SHORT, "group_num", "Map ports to group "); AddOptions(TX_GROUP_PORTS_FLAG, TX_GROUP_PORTS_FLAG_SHORT, "ports", "Ports to be mapped [1,2,3,4,..,128]"); @@ -794,7 +882,11 @@ void MlxlinkUi::commandsCaller() break; case RS_FEC_HISTOGRAM: PRINT_LOG(_mlxlinkCommander->_mlxlinkLogger,"-> FEC histogram info"); - _mlxlinkCommander-> initPortInfo(); + _mlxlinkCommander->initPortInfo(); + break; + case CABLE_PRBS_CMDS: + PRINT_LOG(_mlxlinkCommander->_mlxlinkLogger,"-> Cable PRBS Commands"); + _mlxlinkCommander->performModulePrbsCommands(); break; default: break; @@ -1087,6 +1179,74 @@ ParseStatus MlxlinkUi::HandleOption(string name, string value) } else if (name == PPHCR_CLEAR_HISTOGRAM_FLAG) { _mlxlinkCommander->_userInput.clearFecHistogram = true; return PARSE_OK; + } else if (name == CABLE_PRBS_SELECT) { + addCmd(CABLE_PRBS_CMDS); + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_SELECT] = toUpperCase(value); + _mlxlinkCommander->_userInput.isPrbsSelProvided = true; + _mlxlinkCommander->_uniqueCableCmds++; + return PARSE_OK; + } else if (name == CABLE_PRBS_MODE) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_MODE] = toUpperCase(value); + _mlxlinkCommander->_userInput.isPrbsModeProvided = true; + return PARSE_OK; + } else if (name == CABLE_PRBS_GEN_RATE) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_GEN_RATE] = toUpperCase(value); + _mlxlinkCommander->_userInput.isPrbsGenProvided = true; + return PARSE_OK; + } else if (name == CABLE_PRBS_GEN_PAT) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_GEN_PAT] = toUpperCase(value); + _mlxlinkCommander->_userInput.isPrbsGenProvided = true; + return PARSE_OK; + } else if (name == CABLE_PRBS_GEN_SWAP) { + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_GEN_SWAP] = "SWAP"; + _mlxlinkCommander->_userInput.isPrbsGenProvided = true; + return PARSE_OK; + } else if (name == CABLE_PRBS_GEN_INV) { + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_GEN_INV] = "INV"; + _mlxlinkCommander->_userInput.isPrbsGenProvided = true; + return PARSE_OK; + } else if (name == CABLE_PRBS_GEN_LANES) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_GEN_LANES] = value; + _mlxlinkCommander->_userInput.isPrbsGenProvided = true; + return PARSE_OK; + } else if (name == CABLE_PRBS_CH_RATE) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_CH_RATE] = toUpperCase(value); + _mlxlinkCommander->_userInput.isPrbsChProvided = true; + return PARSE_OK; + } else if (name == CABLE_PRBS_CH_PAT) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_CH_PAT] = toUpperCase(value); + _mlxlinkCommander->_userInput.isPrbsChProvided = true; + return PARSE_OK; + } else if (name == CABLE_PRBS_CH_SWAP) { + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_CH_SWAP] = "SWAP"; + _mlxlinkCommander->_userInput.isPrbsChProvided = true; + return PARSE_OK; + } else if (name == CABLE_PRBS_CH_INV) { + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_CH_INV] = "INV"; + _mlxlinkCommander->_userInput.isPrbsChProvided = true; + return PARSE_OK; + } else if (name == CABLE_PRBS_CH_LANES) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_CH_LANES] = value; + _mlxlinkCommander->_userInput.isPrbsChProvided = true; + return PARSE_OK; + } else if (name == CABLE_PRBS_SHOW_DIAG) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_SHOW_DIAG] = value; + _mlxlinkCommander->_userInput.isPrbsShowDiagProvided = true; + return PARSE_OK; + } else if (name == CABLE_PRBS_CLEAR_DIAG) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_CLEAR_DIAG] = value; + _mlxlinkCommander->_userInput.isPrbsClearDiagProvided = true; + return PARSE_OK; } return PARSE_ERROR; } @@ -1097,6 +1257,7 @@ int MlxlinkUi::run(int argc, char **argv) createMlxlinkCommander(); initCmdParser(); ParseStatus rc = _cmdParser.ParseOptions(argc, argv); + if (rc == PARSE_OK_WITH_EXIT) { return exit_code; } else if ((rc == PARSE_ERROR) || (rc == PARSE_ERROR_SHOW_USAGE)) { @@ -1123,6 +1284,7 @@ int MlxlinkUi::run(int argc, char **argv) MlxlinkRecord::printWar("Warning: AccessRegisterGMP Get() method is not supported.\n" " mlxlink has limited functionality", _mlxlinkCommander->_jsonRoot); } + _mlxlinkCommander->_gvmiAddress = _mlxlinkCommander->_userInput._gvmiAddress; _mlxlinkCommander->_devID = _mlxlinkCommander->_regLib->getDevId(); _mlxlinkCommander->_isHCA = dm_dev_is_hca(_mlxlinkCommander->_devID); @@ -1141,8 +1303,7 @@ int MlxlinkUi::run(int argc, char **argv) } if (_mlxlinkCommander->_userInput._logFilePath != "") { - _mlxlinkCommander->_mlxlinkLogger = new MlxlinkLogger( - _mlxlinkCommander->_userInput._logFilePath); + _mlxlinkCommander->_mlxlinkLogger = new MlxlinkLogger(_mlxlinkCommander->_userInput._logFilePath); } commandsCaller(); if (_mlxlinkCommander->_allUnhandledErrors != "") { diff --git a/mlxlink/modules/mlxlink_ui.h b/mlxlink/modules/mlxlink_ui.h index acc4c0ad..7e21c851 100644 --- a/mlxlink/modules/mlxlink_ui.h +++ b/mlxlink/modules/mlxlink_ui.h @@ -58,6 +58,7 @@ class MlxlinkUi : public CommandLineRequester { virtual void validatePCIeParams(); virtual void validateGeneralCmdsParams(); virtual void validatePRBSParams(); + virtual void validateModulePRBSParams(); virtual void validateSpeedAndCSVBerParams(); virtual void validateCableParams(); virtual void validateTxGroupParams(); diff --git a/mlxlink/modules/mlxlink_user_input.cpp b/mlxlink/modules/mlxlink_user_input.cpp index 108e4f35..f131376d 100644 --- a/mlxlink/modules/mlxlink_user_input.cpp +++ b/mlxlink/modules/mlxlink_user_input.cpp @@ -119,4 +119,12 @@ UserInput::UserInput() enableFecHistogram = false; showFecHistogram = false; clearFecHistogram = false; + + isPrbsSelProvided = false; + isPrbsModeProvided = false; + isPrbsChProvided = false; + isPrbsGenProvided = false; + isPrbsShowDiagProvided = false; + isPrbsClearDiagProvided = false; + prbsModuleAccess = MODULE_PRBS_ACCESS_BOTH; } diff --git a/mlxlink/modules/mlxlink_user_input.h b/mlxlink/modules/mlxlink_user_input.h index 2b894507..ae17cba4 100644 --- a/mlxlink/modules/mlxlink_user_input.h +++ b/mlxlink/modules/mlxlink_user_input.h @@ -40,6 +40,7 @@ #include #include #include +#include "mlxlink_enums.h" using namespace std; @@ -135,6 +136,15 @@ class UserInput { bool enableFecHistogram; bool showFecHistogram; bool clearFecHistogram; + + map modulePrbsParams; + bool isPrbsSelProvided; + bool isPrbsModeProvided; + bool isPrbsChProvided; + bool isPrbsGenProvided; + bool isPrbsShowDiagProvided; + bool isPrbsClearDiagProvided; + ModuleAccess_t prbsModuleAccess; }; #endif /* MLXLINK_USER_INPUT_H */ diff --git a/mlxlink/modules/mlxlink_utils.cpp b/mlxlink/modules/mlxlink_utils.cpp index dca90796..27906986 100644 --- a/mlxlink/modules/mlxlink_utils.cpp +++ b/mlxlink/modules/mlxlink_utils.cpp @@ -221,6 +221,9 @@ string EthSupportedSpeeds2Str(u_int32_t int_mask) if (int_mask & ETH_LINK_SPEED_100_BaseTx) { maskStr += "100M,"; } + if (int_mask & ETH_LINK_SPEED_10M) { + maskStr += "10M,"; + } return deleteLastChar(maskStr); } @@ -279,6 +282,9 @@ string EthExtSupportedSpeeds2Str(u_int32_t int_mask) if (int_mask & ETH_LINK_SPEED_EXT_SGMII_100M) { maskStr += "100M,"; } + if (int_mask & ETH_LINK_SPEED_EXT_SGMII_10M) { + maskStr += "10M,"; + } return deleteLastChar(maskStr); } @@ -358,6 +364,9 @@ string getPowerClass(MlxlinkMaps *mlxlinkMaps, u_int32_t cableIdentifier, u_int3 int ptysSpeedToExtMaskETH(const string & speed) { + if (speed == "10M") { + return (ETH_LINK_SPEED_EXT_SGMII_10M); + } if (speed == "100M") { return (ETH_LINK_SPEED_EXT_SGMII_100M); } @@ -440,9 +449,12 @@ int ptysSpeedToMaskETH(const string &speed) return (ETH_LINK_SPEED_100G_CR4 | ETH_LINK_SPEED_100G_KR4 | ETH_LINK_SPEED_100G_LR4 | ETH_LINK_SPEED_100G_SR4); } - if (speed == "100") { + if (speed == "100M") { return ETH_LINK_SPEED_100_BaseTx; } + if (speed == "10M") { + return ETH_LINK_SPEED_10M; + } if (speed == "25G") { return (ETH_LINK_SPEED_25G_CR | ETH_LINK_SPEED_25G_KR | ETH_LINK_SPEED_25G_SR); diff --git a/mlxlink/modules/printutil/mlxlink_record.cpp b/mlxlink/modules/printutil/mlxlink_record.cpp index 9a4cdace..cd537799 100644 --- a/mlxlink/modules/printutil/mlxlink_record.cpp +++ b/mlxlink/modules/printutil/mlxlink_record.cpp @@ -34,8 +34,9 @@ #include "mlxlink_record.h" -#define MAX_LEN_OF_GRADE 6 -#define MAX_LEN_OF_DDM_FIELD 14 +#define MAX_LEN_OF_GRADE 6 +#define MAX_LEN_OF_DDM_FIELD 14 +#define MAX_LEN_OF_MODULE_PRBS_FIELD 15 bool MlxlinkRecord::jsonFormat = false; std::ostream* MlxlinkRecord::cOut = &std::cout; @@ -212,6 +213,11 @@ std::string MlxlinkRecord::addSpaceForDDM(const std::string &str) return MlxlinkRecord::addSpace(str, MAX_LEN_OF_DDM_FIELD, false); } +std::string MlxlinkRecord::addSpaceForModulePrbs(const std::string &str) +{ + return MlxlinkRecord::addSpace(str, MAX_LEN_OF_MODULE_PRBS_FIELD, false); +} + void MlxlinkRecord::printErrorsSection(const std::string &title, const std::string &lines) { changeColorOS(ANSI_COLOR_RED, true); diff --git a/mlxlink/modules/printutil/mlxlink_record.h b/mlxlink/modules/printutil/mlxlink_record.h index fd3ec4cb..560c973f 100644 --- a/mlxlink/modules/printutil/mlxlink_record.h +++ b/mlxlink/modules/printutil/mlxlink_record.h @@ -72,7 +72,7 @@ #define IDENT " " #define IDENT2 IDENT IDENT -#define IDENT3 "\t\t" +#define IDENT3 IDENT IDENT2 #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" @@ -113,6 +113,8 @@ enum STATUS_DDM_FLAGS_TYPE { #define BER_MONITOR_INFO_LAST 2 #define EXT_PHY_INFO_INFO_LAST 1 #define LINK_DOWN_BLAME_INFO_LAST 2 +#define MODULE_PMPT_INFO_LAST 8 +#define MODULE_PMPD_INFO_LAST 6 class MlxlinkRecord { @@ -131,6 +133,7 @@ class MlxlinkRecord { static std::string addSpace(const std::string &str, u_int32_t size, bool right = true); static std::string addSpaceForDDM(const std::string &str); static std::string addSpaceForSlrg(const std::string &str); + static std::string addSpaceForModulePrbs(const std::string &str); static void printErrorsSection(const std::string &title, const std::string &lines); static void printCmdLine(const std::string &line, Json::Value &jsonRoot); static void printErr(const std::string &err); From 3f3679ed20e61656f8f066e4098d83a9e9cbc7bc Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Wed, 9 Feb 2022 11:29:08 +0200 Subject: [PATCH 089/184] Secure BOOT - Multiple slots for public key hashes, and the ability to revoke Description: Added a new command to flint "rsa_inject_new_key", which will inject data to a new section in the image called "new_key_and_signatures". The new section contains: 1) the new public key for the fw key transition. 2) secure boot signatures using the private key pair of the new public key 3) fw update signatures using the private key pair of the new public key The command will sign using openssl or hsm, depending on the flags being used. Tested OS: Linux Tested devices: None Tested flows: Inject new key and read bytes Known gaps (with RM ticket): N/A Issue: 2954382 Change-Id: I7102345e3dc47bf81d2c807bf4acf38e42f6528a Signed-off-by: ashargorodsk --- flint/cmd_line_parser.cpp | 1 + flint/flint.cpp | 3 +- flint/flint_params.h | 1 + flint/subcommands.cpp | 73 +++ flint/subcommands.h | 8 + mlxfwops/lib/flint_base.h | 127 +++--- mlxfwops/lib/fs3_ops.cpp | 1 + mlxfwops/lib/fs4_ops.cpp | 208 ++++++++- mlxfwops/lib/fs4_ops.h | 8 + mlxfwops/lib/fw_ops.cpp | 8 + mlxfwops/lib/fw_ops.h | 2 + mlxsign_lib/mlxsign_signer_interface.h | 3 + tools_layouts/image_layout_layouts.c | 598 +++++++++++++++++++++++++ tools_layouts/image_layout_layouts.h | 255 ++++++++++- 14 files changed, 1218 insertions(+), 78 deletions(-) diff --git a/flint/cmd_line_parser.cpp b/flint/cmd_line_parser.cpp index 39d74cf8..90a68db7 100644 --- a/flint/cmd_line_parser.cpp +++ b/flint/cmd_line_parser.cpp @@ -123,6 +123,7 @@ SubCmdMetaData::SubCmdMetaData() _sCmds.push_back(new SubCmd("", "rsa_sign", SC_RSA_Sign)); _sCmds.push_back(new SubCmd("", "import_hsm_key", SC_Import_Hsm_Key)); _sCmds.push_back(new SubCmd("", "export_public_key", SC_Export_Public_Key)); + _sCmds.push_back(new SubCmd("", "rsa_inject_new_key", SC_RSA_Inject_New_Key)); } SubCmdMetaData::~SubCmdMetaData() diff --git a/flint/flint.cpp b/flint/flint.cpp index a4bffbe5..bf303fa2 100644 --- a/flint/flint.cpp +++ b/flint/flint.cpp @@ -186,6 +186,7 @@ map_sub_cmd_t_to_subcommand Flint::initSubcommandMap() #ifndef NO_OPEN_SSL cmdMap[SC_Export_Public_Key] = new ExportPublicSubCommand(); #endif + cmdMap[SC_RSA_Inject_New_Key] = new RSAInjectNewKey(); return cmdMap; } @@ -256,7 +257,7 @@ FlintStatus Flint::run(int argc, char *argv[]) //Step 4 execute command from the correct subcommand class if (_subcommands.count(_flintParams.cmd) == 0) { // should not be reached - printf("-E- FATAL: command object not found."); + printf("-E- FATAL: command object not found.\n"); return FLINT_FAILED; } _subcommands[_flintParams.cmd]->setParams(_flintParams); diff --git a/flint/flint_params.h b/flint/flint_params.h index 696e1925..6458576b 100644 --- a/flint/flint_params.h +++ b/flint/flint_params.h @@ -89,6 +89,7 @@ typedef enum { SC_Set_Forbidden_Versions, SC_Image_Reactivation, SC_RSA_Sign, + SC_RSA_Inject_New_Key, SC_Binary_Compare, SC_Import_Hsm_Key, SC_Export_Public_Key diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index 4853a130..19e1e00f 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -2004,6 +2004,79 @@ bool SignRSASubCommand::verifyParams() return true; } +/*********************** + * Class: RSAInjectNewKey + **********************/ + +RSAInjectNewKey::RSAInjectNewKey() +{ + _name = "rsa_inject_new_key"; + _desc = "Inject new public key for key revoke"; + _extendedDesc = "Inject new public key for key revoke"; + _flagLong = "rsa_inject_new_key"; + _flagShort = ""; + _paramExp = "None"; + _example = FLINT_NAME " -i fw_image.bin [--private_key file.pem] OR [--private_key_label

  • [[SQLITE_FCNTL_EXTERNAL_READER]] +** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect +** whether or not there is a database client in another process with a wal-mode +** transaction open on the database or not. It is only available on unix.The +** (void*) argument passed with this file-control should be a pointer to a +** value of type (int). The integer value is set to 1 if the database is a wal +** mode database and there exists at least one client in another process that +** currently has an SQL transaction open on the database. It is set to 0 if +** the database is not a wal-mode db, or if there is no such connection in any +** other process. This opcode cannot be used to detect transactions opened +** by clients within the current process, only within other processes. +** +** +**
  • [[SQLITE_FCNTL_CKSM_FILE]] +** Used by the cksmvfs VFS module only. +** */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 @@ -2214,6 +1528,8 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 +#define SQLITE_FCNTL_EXTERNAL_READER 40 +#define SQLITE_FCNTL_CKSM_FILE 41 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -3162,7 +2478,13 @@ struct sqlite3_mem_methods { ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in -** which case the trigger setting is not reported back. +** which case the trigger setting is not reported back. +** +**

    Originally this option disabled all triggers. ^(However, since +** SQLite version 3.35.0, TEMP triggers are still allowed even if +** this option is off. So, in other words, this option now only disables +** triggers in the main database schema or in the schemas of ATTACH-ed +** databases.)^ ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] **

    SQLITE_DBCONFIG_ENABLE_VIEW
    @@ -3173,7 +2495,13 @@ struct sqlite3_mem_methods { ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether views are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in -** which case the view setting is not reported back. +** which case the view setting is not reported back. +** +**

    Originally this option disabled all views. ^(However, since +** SQLite version 3.35.0, TEMP views are still allowed even if +** this option is off. So, in other words, this option now only disables +** views in the main database schema or in the schemas of ATTACH-ed +** databases.)^ ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] **

    SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
    @@ -3480,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], @@ -3533,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 @@ -3570,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 @@ -4399,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
    ** )^ @@ -4406,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 @@ -4546,6 +3899,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** that uses dot-files in place of posix advisory locking. ** file:data.db?mode=readonly ** An error. "readonly" is not a valid option for the "mode" parameter. +** Use "ro" instead: "file:data.db?mode=ro". ** ** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and @@ -4744,7 +4098,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); ** If the Y parameter to sqlite3_free_filename(Y) is anything other ** than a NULL pointer or a pointer previously acquired from ** sqlite3_create_filename(), then bad things such as heap -** corruption or segfaults may occur. The value Y should be +** corruption or segfaults may occur. The value Y should not be ** used again after sqlite3_free_filename(Y) has been called. This means ** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y, ** then the corresponding [sqlite3_module.xClose() method should also be @@ -4776,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 @@ -4797,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. @@ -4816,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 @@ -5173,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 @@ -5213,6 +4581,19 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); ** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and ** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so ** sqlite3_stmt_readonly() returns false for those commands. +** +** ^This routine returns false if there is any possibility that the +** statement might change the database file. ^A false return does +** not guarantee that the statement will change the database file. +** ^For example, an UPDATE statement might have a WHERE clause that +** makes it a no-op, but the sqlite3_stmt_readonly() result would still +** 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); @@ -5281,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 @@ -5382,18 +4765,22 @@ typedef struct sqlite3_context sqlite3_context; ** contain embedded NULs. The result of expressions involving strings ** with embedded NULs is undefined. ** -** ^The fifth argument to the BLOB and string binding interfaces -** is a destructor used to dispose of the BLOB or -** string after SQLite has finished with it. ^The destructor is called -** to dispose of the BLOB or string even if the call to the bind API fails, -** except the destructor is not called if the third parameter is a NULL -** pointer or the fourth parameter is negative. -** ^If the fifth argument is -** the special value [SQLITE_STATIC], then SQLite assumes that the -** information is in static, unmanaged space and does not need to be freed. -** ^If the fifth argument has the value [SQLITE_TRANSIENT], then -** SQLite makes its own private copy of the data immediately, before -** the sqlite3_bind_*() routine returns. +** ^The fifth argument to the BLOB and string binding interfaces controls +** or indicates the lifetime of the object referenced by the third parameter. +** These three options exist: +** ^ (1) A destructor to dispose of the BLOB or string after SQLite has finished +** with it may be passed. ^It is called to dispose of the BLOB or string even +** if the call to the bind API fails, except the destructor is not called if +** the third parameter is a NULL pointer or the fourth parameter is negative. +** ^ (2) The special constant, [SQLITE_STATIC], may be passsed to indicate that +** the application remains responsible for disposing of the object. ^In this +** case, the object and the provided pointer to it must remain valid until +** either the prepared statement is finalized or the same SQL parameter is +** bound to something else, whichever occurs sooner. +** ^ (3) The constant, [SQLITE_TRANSIENT], may be passed to indicate that the +** object is to be copied prior to the return from sqlite3_bind_*(). ^The +** object and pointer to it must remain valid until then. ^SQLite will then +** manage the lifetime of its private copy. ** ** ^The sixth argument to sqlite3_bind_text64() must be one of ** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] @@ -6135,7 +5522,6 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, ** index expressions, or the WHERE clause of partial indexes. ** -** ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** all application-defined SQL functions that do not need to be ** used inside of triggers, view, CHECK constraints, or other elements of @@ -6145,7 +5531,6 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** a database file to include invocations of the function with parameters ** chosen by the attacker, which the application will then execute when ** the database file is opened and read. -** ** ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ @@ -7234,6 +6619,57 @@ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); */ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); +/* +** CAPI3REF: Determine the transaction state of a database +** METHOD: sqlite3 +** +** ^The sqlite3_txn_state(D,S) interface returns the current +** [transaction state] of schema S in database connection D. ^If S is NULL, +** then the highest transaction state of any schema on database connection D +** is returned. Transaction states are (in order of lowest to highest): +**
      +**
    1. SQLITE_TXN_NONE +**
    2. SQLITE_TXN_READ +**
    3. SQLITE_TXN_WRITE +**
    +** ^If the S argument to sqlite3_txn_state(D,S) is not the name of +** a valid schema, then -1 is returned. +*/ +SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); + +/* +** CAPI3REF: Allowed return values from [sqlite3_txn_state()] +** KEYWORDS: {transaction state} +** +** These constants define the current transaction state of a database file. +** ^The [sqlite3_txn_state(D,S)] interface returns one of these +** constants in order to describe the transaction state of schema S +** in [database connection] D. +** +**
    +** [[SQLITE_TXN_NONE]]
    SQLITE_TXN_NONE
    +**
    The SQLITE_TXN_NONE state means that no transaction is currently +** pending.
    +** +** [[SQLITE_TXN_READ]]
    SQLITE_TXN_READ
    +**
    The SQLITE_TXN_READ state means that the database is currently +** in a read transaction. Content has been read from the database file +** but nothing in the database file has changed. The transaction state +** will advanced to SQLITE_TXN_WRITE if any changes occur and there are +** no other conflicting concurrent write transactions. The transaction +** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or +** [COMMIT].
    +** +** [[SQLITE_TXN_WRITE]]
    SQLITE_TXN_WRITE
    +**
    The SQLITE_TXN_WRITE state means that the database is currently +** in a write transaction. Content has been written to the database file +** but has not yet committed. The transaction state will change to +** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].
    +*/ +#define SQLITE_TXN_NONE 0 +#define SQLITE_TXN_READ 1 +#define SQLITE_TXN_WRITE 2 + /* ** CAPI3REF: Find the next prepared statement ** METHOD: sqlite3 @@ -7300,6 +6736,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 @@ -7941,24 +7443,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]. -*/ -#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 +** +** ^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_LIMIT 73 +#define SQLITE_INDEX_CONSTRAINT_OFFSET 74 +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 /* ** CAPI3REF: Register A Virtual Table Implementation @@ -7987,7 +7521,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()] @@ -8760,7 +8294,11 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_RESULT_INTREAL 27 #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 -#define SQLITE_TESTCTRL_LAST 29 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_SEEK_COUNT 30 +#define SQLITE_TESTCTRL_TRACEFLAGS 31 +#define SQLITE_TESTCTRL_TUNE 32 +#define SQLITE_TESTCTRL_LOGEST 33 +#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -9283,6 +8821,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 @@ -9297,6 +8845,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 /* @@ -9960,8 +9510,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. */ @@ -10240,10 +9791,11 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); ** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE ** ** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] -** method of a [virtual table], then it returns true if and only if the +** method of a [virtual table], then it might return true if the ** column is being fetched as part of an UPDATE operation during which the -** column value will not change. Applications might use this to substitute -** a return value that is less expensive to compute and that the corresponding +** column value will not change. The virtual table implementation can use +** this hint as permission to substitute a return value that is less +** expensive to compute and that the corresponding ** [xUpdate] method understands as a "no-change" value. ** ** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that @@ -10252,24 +9804,280 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); ** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. ** In that case, [sqlite3_value_nochange(X)] will return true for the ** same column in the [xUpdate] method. +** +** The sqlite3_vtab_nochange() routine is an optimization. Virtual table +** implementations should continue to give a correct answer even if the +** sqlite3_vtab_nochange() interface were to always return false. In the +** current implementation, the sqlite3_vtab_nochange() interface does always +** returns false for the enhanced [UPDATE FROM] statement. */ 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 appreviation 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} @@ -10393,6 +10201,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* ** CAPI3REF: Flush caches to disk mid-transaction +** METHOD: sqlite3 ** ** ^If a write-transaction is open on [database connection] D when the ** [sqlite3_db_cacheflush(D)] interface invoked, any dirty @@ -10425,6 +10234,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); /* ** CAPI3REF: The pre-update hook. +** METHOD: sqlite3 ** ** ^These interfaces are only available if SQLite is compiled using the ** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option. @@ -10465,7 +10275,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** seventh parameter is the final rowid value of the row being inserted ** or updated. The value of the seventh parameter passed to the callback ** function is not defined for operations on WITHOUT ROWID tables, or for -** INSERT operations on rowid tables. +** DELETE operations on rowid tables. ** ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces @@ -10503,6 +10313,15 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** triggers; or 2 for changes resulting from triggers called by top-level ** triggers; and so forth. ** +** When the [sqlite3_blob_write()] API is used to update a blob column, +** the pre-update hook is invoked with SQLITE_DELETE. This is because the +** in this case the new values are not available. In this case, when a +** callback made with op==SQLITE_DELETE is actuall a write using the +** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns +** the index of the column being written. In other cases, where the +** pre-update hook is being invoked for some other reason, including a +** regular DELETE, sqlite3_preupdate_blobwrite() returns -1. +** ** See also: [sqlite3_update_hook()] */ #if defined(SQLITE_ENABLE_PREUPDATE_HOOK) @@ -10523,10 +10342,12 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); SQLITE_API int sqlite3_preupdate_count(sqlite3 *); SQLITE_API int sqlite3_preupdate_depth(sqlite3 *); SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); +SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *); #endif /* ** CAPI3REF: Low-level system error code +** METHOD: sqlite3 ** ** ^Attempt to return the underlying operating system error code or error ** number that caused the most recent I/O error or failure to open a file. @@ -10760,8 +10581,8 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c ** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory ** allocation error occurs. ** -** This interface is only available if SQLite is compiled with the -** [SQLITE_ENABLE_DESERIALIZE] option. +** This interface is omitted if SQLite is compiled with the +** [SQLITE_OMIT_DESERIALIZE] option. */ SQLITE_API unsigned char *sqlite3_serialize( sqlite3 *db, /* The database connection */ @@ -10808,12 +10629,16 @@ 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. ** -** This interface is only available if SQLite is compiled with the -** [SQLITE_ENABLE_DESERIALIZE] option. +** This interface is omitted if SQLite is compiled with the +** [SQLITE_OMIT_DESERIALIZE] option. */ SQLITE_API int sqlite3_deserialize( sqlite3 *db, /* The database connection */ @@ -11062,6 +10887,38 @@ SQLITE_API int sqlite3session_create( */ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); +/* +** CAPIREF: Conigure a Session Object +** METHOD: sqlite3_session +** +** This method is used to configure a session object after it has been +** created. At present the only valid value for the second parameter is +** [SQLITE_SESSION_OBJCONFIG_SIZE]. +** +** Arguments for sqlite3session_object_config() +** +** The following values may passed as the the 4th parameter to +** sqlite3session_object_config(). +** +**
    SQLITE_SESSION_OBJCONFIG_SIZE
    +** This option is used to set, clear or query the flag that enables +** the [sqlite3session_changeset_size()] API. Because it imposes some +** computational overhead, this API is disabled by default. Argument +** pArg must point to a value of type (int). If the value is initially +** 0, then the sqlite3session_changeset_size() API is disabled. If it +** is greater than 0, then the same API is enabled. Or, if the initial +** value is less than zero, no change is made. In all cases the (int) +** variable is set to 1 if the sqlite3session_changeset_size() API is +** enabled following the current call, or 0 otherwise. +** +** It is an error (SQLITE_MISUSE) to attempt to modify this setting after +** the first table has been attached to the session object. +*/ +SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); + +/* +*/ +#define SQLITE_SESSION_OBJCONFIG_SIZE 1 /* ** CAPI3REF: Enable Or Disable A Session Object @@ -11306,6 +11163,22 @@ SQLITE_API int sqlite3session_changeset( void **ppChangeset /* OUT: Buffer containing changeset */ ); +/* +** CAPI3REF: Return An Upper-limit For The Size Of The Changeset +** METHOD: sqlite3_session +** +** By default, this function always returns 0. For it to return +** a useful result, the sqlite3_session object must have been configured +** to enable this API using sqlite3session_object_config() with the +** SQLITE_SESSION_OBJCONFIG_SIZE verb. +** +** When enabled, this function returns an upper limit, in bytes, for the size +** of the changeset that might be produced if sqlite3session_changeset() were +** called. The final changeset size might be equal to or smaller than the +** size in bytes returned by this function. +*/ +SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession); + /* ** CAPI3REF: Load The Difference Between Tables Into A Session ** METHOD: sqlite3_session @@ -11423,6 +11296,14 @@ SQLITE_API int sqlite3session_patchset( */ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession); +/* +** CAPI3REF: Query for the amount of heap memory used by a session object. +** +** This API returns the total amount of heap memory in bytes currently +** used by the session object passed as the only argument. +*/ +SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession); + /* ** CAPI3REF: Create An Iterator To Traverse A Changeset ** CONSTRUCTOR: sqlite3_changeset_iter @@ -11525,18 +11406,23 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter); ** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this ** is not the case, this function returns [SQLITE_MISUSE]. ** -** If argument pzTab is not NULL, then *pzTab is set to point to a -** nul-terminated utf-8 encoded string containing the name of the table -** affected by the current change. The buffer remains valid until either -** sqlite3changeset_next() is called on the iterator or until the -** conflict-handler function returns. If pnCol is not NULL, then *pnCol is -** set to the number of columns in the table affected by the change. If -** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change +** Arguments pOp, pnCol and pzTab may not be NULL. Upon return, three +** outputs are set through these pointers: +** +** *pOp is set to one of [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], +** depending on the type of change that the iterator currently points to; +** +** *pnCol is set to the number of columns in the table affected by the change; and +** +** *pzTab is set to point to a nul-terminated utf-8 encoded string containing +** the name of the table affected by the current change. The buffer remains +** valid until either sqlite3changeset_next() is called on the iterator +** or until the conflict-handler function returns. +** +** If pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change ** is an indirect change, or false (0) otherwise. See the documentation for ** [sqlite3session_indirect()] for a description of direct and indirect -** changes. Finally, if pOp is not NULL, then *pOp is set to one of -** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the -** type of change that the iterator currently points to. +** changes. ** ** If no error occurs, SQLITE_OK is returned. If an error does occur, an ** SQLite error code is returned. The values of the output variables may not @@ -13229,7 +13115,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 @@ -13297,11 +13183,7 @@ struct fts5_api { ** The maximum depth of an expression tree. This is limited to ** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might ** want to place more severe limits on the complexity of an -** expression. -** -** A value of 0 used to mean that the limit was not enforced. -** But that is no longer true. The limit is now strictly enforced -** at all times. +** expression. A value of 0 means that there is no limit. */ #ifndef SQLITE_MAX_EXPR_DEPTH # define SQLITE_MAX_EXPR_DEPTH 1000 @@ -13470,9 +13352,11 @@ struct fts5_api { # define __has_extension(x) 0 /* compatibility with non-clang compilers */ #endif #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 @@ -13677,11 +13561,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 @@ -13711,6 +13596,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 @@ -13726,7 +13619,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) @@ -13737,26 +13630,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 @@ -13820,6 +13693,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() @@ -13932,7 +13812,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 */ @@ -13964,8 +13844,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 @@ -14036,90 +13916,94 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_TIES 94 #define TK_GENERATED 95 #define TK_ALWAYS 96 -#define TK_REINDEX 97 -#define TK_RENAME 98 -#define TK_CTIME_KW 99 -#define TK_ANY 100 -#define TK_BITAND 101 -#define TK_BITOR 102 -#define TK_LSHIFT 103 -#define TK_RSHIFT 104 -#define TK_PLUS 105 -#define TK_MINUS 106 -#define TK_STAR 107 -#define TK_SLASH 108 -#define TK_REM 109 -#define TK_CONCAT 110 -#define TK_COLLATE 111 -#define TK_BITNOT 112 -#define TK_ON 113 -#define TK_INDEXED 114 -#define TK_STRING 115 -#define TK_JOIN_KW 116 -#define TK_CONSTRAINT 117 -#define TK_DEFAULT 118 -#define TK_NULL 119 -#define TK_PRIMARY 120 -#define TK_UNIQUE 121 -#define TK_CHECK 122 -#define TK_REFERENCES 123 -#define TK_AUTOINCR 124 -#define TK_INSERT 125 -#define TK_DELETE 126 -#define TK_UPDATE 127 -#define TK_SET 128 -#define TK_DEFERRABLE 129 -#define TK_FOREIGN 130 -#define TK_DROP 131 -#define TK_UNION 132 -#define TK_ALL 133 -#define TK_EXCEPT 134 -#define TK_INTERSECT 135 -#define TK_SELECT 136 -#define TK_VALUES 137 -#define TK_DISTINCT 138 -#define TK_DOT 139 -#define TK_FROM 140 -#define TK_JOIN 141 -#define TK_USING 142 -#define TK_ORDER 143 -#define TK_GROUP 144 -#define TK_HAVING 145 -#define TK_LIMIT 146 -#define TK_WHERE 147 -#define TK_INTO 148 -#define TK_NOTHING 149 -#define TK_FLOAT 150 -#define TK_BLOB 151 -#define TK_INTEGER 152 -#define TK_VARIABLE 153 -#define TK_CASE 154 -#define TK_WHEN 155 -#define TK_THEN 156 -#define TK_ELSE 157 -#define TK_INDEX 158 -#define TK_ALTER 159 -#define TK_ADD 160 -#define TK_WINDOW 161 -#define TK_OVER 162 -#define TK_FILTER 163 -#define TK_COLUMN 164 -#define TK_AGG_FUNCTION 165 -#define TK_AGG_COLUMN 166 -#define TK_TRUEFALSE 167 -#define TK_ISNOT 168 -#define TK_FUNCTION 169 -#define TK_UMINUS 170 -#define TK_UPLUS 171 -#define TK_TRUTH 172 -#define TK_REGISTER 173 -#define TK_VECTOR 174 -#define TK_SELECT_COLUMN 175 -#define TK_IF_NULL_ROW 176 -#define TK_ASTERISK 177 -#define TK_SPAN 178 -#define TK_SPACE 179 -#define TK_ILLEGAL 180 +#define TK_MATERIALIZED 97 +#define TK_REINDEX 98 +#define TK_RENAME 99 +#define TK_CTIME_KW 100 +#define TK_ANY 101 +#define TK_BITAND 102 +#define TK_BITOR 103 +#define TK_LSHIFT 104 +#define TK_RSHIFT 105 +#define TK_PLUS 106 +#define TK_MINUS 107 +#define TK_STAR 108 +#define TK_SLASH 109 +#define TK_REM 110 +#define TK_CONCAT 111 +#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 ******************/ @@ -14225,7 +14109,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 @@ -14387,6 +14271,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 @@ -14535,15 +14420,14 @@ typedef INT16_TYPE LogEst; ** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not ** the Select query generator tracing logic is turned on. */ -#if defined(SQLITE_ENABLE_SELECTTRACE) -# define SELECTTRACE_ENABLED 1 -#else -# define SELECTTRACE_ENABLED 0 +#if !defined(SQLITE_AMALGAMATION) +SQLITE_PRIVATE u32 sqlite3SelectTrace; #endif -#if defined(SQLITE_ENABLE_SELECTTRACE) +#if defined(SQLITE_DEBUG) \ + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE)) # define SELECTTRACE_ENABLED 1 # define SELECTTRACE(K,P,S,X) \ - if(sqlite3_unsupported_selecttrace&(K)) \ + if(sqlite3SelectTrace&(K)) \ sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ sqlite3DebugPrintf X #else @@ -14551,6 +14435,19 @@ typedef INT16_TYPE LogEst; # define SELECTTRACE_ENABLED 0 #endif +/* +** Macros for "wheretrace" +*/ +SQLITE_PRIVATE u32 sqlite3WhereTrace; +#if defined(SQLITE_DEBUG) \ + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) +# define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X +# define WHERETRACE_ENABLED 1 +#else +# define WHERETRACE(K,X) +#endif + + /* ** An instance of the following structure is used to store the busy-handler ** callback for a given sqlite handle. @@ -14569,11 +14466,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" /* @@ -14585,7 +14496,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 @@ -14662,7 +14573,10 @@ typedef struct AutoincInfo AutoincInfo; typedef struct Bitvec Bitvec; typedef struct CollSeq CollSeq; typedef struct Column Column; +typedef struct Cte Cte; +typedef struct CteUse CteUse; typedef struct Db Db; +typedef struct DbFixer DbFixer; typedef struct Schema Schema; typedef struct Expr Expr; typedef struct ExprList ExprList; @@ -14680,14 +14594,17 @@ typedef struct LookasideSlot LookasideSlot; typedef struct Module Module; typedef struct NameContext NameContext; typedef struct Parse Parse; +typedef struct ParseCleanup ParseCleanup; typedef struct PreUpdate PreUpdate; typedef struct PrintfArguments PrintfArguments; typedef struct RenameToken RenameToken; +typedef struct Returning Returning; typedef struct RowSet RowSet; typedef struct Savepoint Savepoint; typedef struct Select Select; typedef struct SQLiteThread SQLiteThread; typedef struct SelectDest SelectDest; +typedef struct SrcItem SrcItem; typedef struct SrcList SrcList; typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ typedef struct Table Table; @@ -14728,10 +14645,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 @@ -15082,16 +15000,24 @@ SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*); SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int,int); SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int); SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, Pgno*, int flags); -SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*); -SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*); +SQLITE_PRIVATE int sqlite3BtreeTxnState(Btree*); SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*); + SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree); #ifndef SQLITE_OMIT_SHARED_CACHE SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock); #endif + +/* Savepoints are named, nestable SQL transactions mostly implemented */ +/* in vdbe.c and pager.c See https://sqlite.org/lang_savepoint.html */ SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int); +/* "Checkpoint" only refers to WAL. See https://sqlite.org/wal.html#ckpt */ +#ifndef SQLITE_OMIT_WAL +SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); +#endif + SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *); SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *); SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *); @@ -15112,7 +15038,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); @@ -15236,13 +15162,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); @@ -15251,6 +15181,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags); #define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ #define BTREE_AUXDELETE 0x04 /* not the primary delete operation */ #define BTREE_APPEND 0x08 /* Insert is likely an append */ +#define BTREE_PREFORMAT 0x80 /* Inserted data is a preformated cell */ /* An instance of the BtreePayload object describes the content of a single ** entry in either an index or table btree. @@ -15328,6 +15259,12 @@ SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask); SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt); SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void); +#ifdef SQLITE_DEBUG +SQLITE_PRIVATE sqlite3_uint64 sqlite3BtreeSeekCount(Btree*); +#else +# define sqlite3BtreeSeekCount(X) 0 +#endif + #ifndef NDEBUG SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); #endif @@ -15344,6 +15281,8 @@ SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*); SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); #endif +SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor*, BtCursor*, i64); + /* ** If we are not using shared cache, then there is no need to ** use mutexes to access the BtShared structures. So make the @@ -15584,35 +15523,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] */ @@ -15621,124 +15560,133 @@ typedef struct VdbeOpList VdbeOpList; #define OP_Le 55 /* jump, same as TK_LE, synopsis: IF r[P3]<=r[P1] */ #define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */ -#define OP_ElseNotEq 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_ResultRow 80 /* synopsis: output=r[P1@P2] */ -#define OP_CollSeq 81 -#define OP_AddImm 82 /* synopsis: r[P1]=r[P1]+P2 */ -#define OP_RealAffinity 83 -#define OP_Cast 84 /* synopsis: affinity(r[P1]) */ -#define OP_Permutation 85 -#define OP_Compare 86 /* synopsis: r[P1@P3] <-> r[P2@P3] */ -#define OP_IsTrue 87 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ -#define OP_Offset 88 /* synopsis: r[P3] = sqlite_offset(P1) */ -#define OP_Column 89 /* synopsis: r[P3]=PX */ -#define OP_Affinity 90 /* synopsis: affinity(r[P1@P2]) */ -#define OP_MakeRecord 91 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ -#define OP_Count 92 /* synopsis: r[P2]=count() */ -#define OP_ReadCookie 93 -#define OP_SetCookie 94 -#define OP_ReopenIdx 95 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenRead 96 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenWrite 97 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenDup 98 -#define OP_OpenAutoindex 99 /* synopsis: nColumn=P2 */ -#define OP_OpenEphemeral 100 /* synopsis: nColumn=P2 */ -#define OP_BitAnd 101 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ -#define OP_BitOr 102 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ -#define OP_ShiftLeft 103 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ -#define OP_Add 105 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ -#define OP_Subtract 106 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ -#define OP_Multiply 107 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ -#define OP_Divide 108 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ -#define OP_Remainder 109 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ -#define OP_Concat 110 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ -#define OP_SorterOpen 111 -#define OP_BitNot 112 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ -#define OP_SequenceTest 113 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ -#define OP_OpenPseudo 114 /* synopsis: P3 columns in r[P2] */ -#define OP_String8 115 /* same as TK_STRING, synopsis: r[P2]='P4' */ -#define OP_Close 116 -#define OP_ColumnsUsed 117 -#define OP_SeekHit 118 /* synopsis: seekHit=P2 */ -#define OP_Sequence 119 /* synopsis: r[P2]=cursor[P1].ctr++ */ -#define OP_NewRowid 120 /* synopsis: r[P2]=rowid */ -#define OP_Insert 121 /* synopsis: intkey=r[P3] data=r[P2] */ -#define OP_Delete 122 -#define OP_ResetCount 123 -#define OP_SorterCompare 124 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ -#define OP_SorterData 125 /* synopsis: r[P2]=data */ -#define OP_RowData 126 /* synopsis: r[P2]=data */ -#define OP_Rowid 127 /* synopsis: r[P2]=rowid */ -#define OP_NullRow 128 -#define OP_SeekEnd 129 -#define OP_IdxInsert 130 /* synopsis: key=r[P2] */ -#define OP_SorterInsert 131 /* synopsis: key=r[P2] */ -#define OP_IdxDelete 132 /* synopsis: key=r[P2@P3] */ -#define OP_DeferredSeek 133 /* synopsis: Move P3 to P1.rowid if needed */ -#define OP_IdxRowid 134 /* synopsis: r[P2]=rowid */ -#define OP_FinishSeek 135 -#define OP_Destroy 136 -#define OP_Clear 137 -#define OP_ResetSorter 138 -#define OP_CreateBtree 139 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ -#define OP_SqlExec 140 -#define OP_ParseSchema 141 -#define OP_LoadAnalysis 142 -#define OP_DropTable 143 -#define OP_DropIndex 144 -#define OP_DropTrigger 145 -#define OP_IntegrityCk 146 -#define OP_RowSetAdd 147 /* synopsis: rowset(P1)=r[P2] */ -#define OP_Param 148 -#define OP_FkCounter 149 /* synopsis: fkctr[P1]+=P2 */ -#define OP_Real 150 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_MemMax 151 /* synopsis: r[P1]=max(r[P1],r[P2]) */ -#define OP_OffsetLimit 152 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -#define OP_AggInverse 153 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ -#define OP_AggStep 154 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggStep1 155 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggValue 156 /* synopsis: r[P3]=value N=P2 */ -#define OP_AggFinal 157 /* synopsis: accum=r[P1] N=P2 */ -#define OP_Expire 158 -#define OP_CursorLock 159 -#define OP_CursorUnlock 160 -#define OP_TableLock 161 /* synopsis: iDb=P1 root=P2 write=P3 */ -#define OP_VBegin 162 -#define OP_VCreate 163 -#define OP_VDestroy 164 -#define OP_VOpen 165 -#define OP_VColumn 166 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VRename 167 -#define OP_Pagecount 168 -#define OP_MaxPgcnt 169 -#define OP_Trace 170 -#define OP_CursorHint 171 -#define OP_ReleaseReg 172 /* synopsis: release r[P1@P2] mask P3 */ -#define OP_Noop 173 -#define OP_Explain 174 -#define OP_Abortable 175 +#define OP_ElseEq 58 /* jump, same as TK_ESCAPE */ +#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]<>r[P1] */ +#define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ +#define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ +#define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ +#define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ +#define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ +#define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ +#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 @@ -15753,35 +15701,36 @@ 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, 0x02, 0x02, 0x02, 0x00, 0x00, 0x12,\ -/* 88 */ 0x20, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ -/* 96 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x26, 0x26,\ -/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00,\ -/* 112 */ 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,\ -/* 120 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\ -/* 128 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\ -/* 136 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ -/* 144 */ 0x00, 0x00, 0x00, 0x06, 0x10, 0x00, 0x10, 0x04,\ -/* 152 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 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, 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 */ 0x10, 0x10, 0x00, 0x00, 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 sqlite3P2Values() routine is able to run faster if it knows +/* The resolve3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum ** JUMP opcode the better, so the mkopcodeh.tcl script that ** 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 ***********************/ @@ -15841,7 +15790,7 @@ SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char*,const char*); #else # define sqlite3ExplainBreakpoint(A,B) /*no-op*/ #endif -SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); +SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*, int, char*, u16); SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8); SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1); SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); @@ -16308,6 +16257,12 @@ SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache); # define SET_FULLSYNC(x,y) #endif +/* Maximum pathname length. Note: FILENAME_MAX defined by stdio.h +*/ +#ifndef SQLITE_MAX_PATHLEN +# define SQLITE_MAX_PATHLEN FILENAME_MAX +#endif + /* ** The default size of a disk sector */ @@ -16813,6 +16768,11 @@ SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); #endif /* SQLITE_OMIT_DEPRECATED */ #define SQLITE_TRACE_NONLEGACY_MASK 0x0f /* Normal flags */ +/* +** Maximum number of sqlite3.aDb[] entries. This is the number of attached +** databases plus 2 for "main" and "temp". +*/ +#define SQLITE_MAX_DB (SQLITE_MAX_ATTACHED+2) /* ** Each database connection is an instance of the following structure. @@ -16831,9 +16791,10 @@ 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 */ - u16 dbOptFlags; /* Flags to enable/disable optimizations */ + u32 dbOptFlags; /* Flags to enable/disable optimizations */ u8 enc; /* Text encoding */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ @@ -16847,10 +16808,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 */ @@ -16860,7 +16821,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 */ @@ -16870,10 +16831,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 */ @@ -16884,6 +16845,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 */ @@ -17013,6 +16977,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 @@ -17040,24 +17005,31 @@ struct sqlite3 { ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to ** selectively disable various optimizations. */ -#define SQLITE_QueryFlattener 0x0001 /* Query flattening */ -#define SQLITE_WindowFunc 0x0002 /* Use xInverse for window functions */ -#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */ -#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */ -#define SQLITE_DistinctOpt 0x0010 /* DISTINCT using indexes */ -#define SQLITE_CoverIdxScan 0x0020 /* Covering index scans */ -#define SQLITE_OrderByIdxJoin 0x0040 /* ORDER BY of joins via index */ -#define SQLITE_Transitive 0x0080 /* Transitive constraints */ -#define SQLITE_OmitNoopJoin 0x0100 /* Omit unused tables in joins */ -#define SQLITE_CountOfView 0x0200 /* The count-of-view optimization */ -#define SQLITE_CursorHints 0x0400 /* Add OP_CursorHint opcodes */ -#define SQLITE_Stat4 0x0800 /* Use STAT4 data */ - /* TH3 expects the Stat4 ^^^^^^ value to be 0x0800. Don't change it */ -#define SQLITE_PushDown 0x1000 /* The push-down optimization */ -#define SQLITE_SimplifyJoin 0x2000 /* Convert LEFT JOIN to JOIN */ -#define SQLITE_SkipScan 0x4000 /* Skip-scans */ -#define SQLITE_PropagateConst 0x8000 /* The constant propagation opt */ -#define SQLITE_AllOpts 0xffff /* All optimizations */ +#define SQLITE_QueryFlattener 0x00000001 /* Query flattening */ +#define SQLITE_WindowFunc 0x00000002 /* Use xInverse for window functions */ +#define SQLITE_GroupByOrder 0x00000004 /* GROUPBY cover of ORDERBY */ +#define SQLITE_FactorOutConst 0x00000008 /* Constant factoring */ +#define SQLITE_DistinctOpt 0x00000010 /* DISTINCT using indexes */ +#define SQLITE_CoverIdxScan 0x00000020 /* Covering index scans */ +#define SQLITE_OrderByIdxJoin 0x00000040 /* ORDER BY of joins via index */ +#define SQLITE_Transitive 0x00000080 /* Transitive constraints */ +#define SQLITE_OmitNoopJoin 0x00000100 /* Omit unused tables in joins */ +#define SQLITE_CountOfView 0x00000200 /* The count-of-view optimization */ +#define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */ +#define SQLITE_Stat4 0x00000800 /* Use STAT4 data */ + /* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */ +#define SQLITE_PushDown 0x00001000 /* The push-down optimization */ +#define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */ +#define SQLITE_SkipScan 0x00004000 /* Skip-scans */ +#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 */ /* ** Macros for testing whether or not optimizations are enabled or disabled. @@ -17071,17 +17043,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 @@ -17106,7 +17077,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 */ }; /* @@ -17136,12 +17107,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 */ @@ -17166,6 +17138,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 @@ -17213,6 +17187,9 @@ struct FuncDestructor { ** a single query. The iArg is ignored. The user-data is always set ** to a NULL pointer. The bNC parameter is not used. ** +** MFUNCTION(zName, nArg, xPtr, xFunc) +** For math-library functions. xPtr is an arbitrary pointer. +** ** PURE_DATE(zName, nArg, iArg, bNC, xFunc) ** Used for "pure" date/time functions, this macro is like DFUNCTION ** except that it does set the SQLITE_FUNC_CONSTANT flags. iArg is @@ -17225,7 +17202,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 @@ -17240,41 +17217,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_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} } @@ -17330,19 +17321,48 @@ 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.colFlags: +/* 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: +** TF_HasVirtual == COLFLAG_VIRTUAL +** TF_HasStored == COLFLAG_STORED +** TF_HasHidden == COLFLAG_HIDDEN */ #define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ #define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ @@ -17353,6 +17373,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 */ @@ -17418,9 +17439,7 @@ struct CollSeq { ** operator is NULL. It is added to certain comparison operators to ** prove that the operands are always NOT NULL. */ -#define SQLITE_KEEPNULL 0x08 /* Used by vector == or <> */ #define SQLITE_JUMPIFNULL 0x10 /* jumps if either operand is NULL */ -#define SQLITE_STOREP2 0x20 /* Store result in reg[P2] rather than jump */ #define SQLITE_NULLEQ 0x80 /* NULL=NULL */ #define SQLITE_NOTNULL 0x90 /* Assert that operands are never NULL */ @@ -17484,15 +17503,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 */ @@ -17508,17 +17525,25 @@ 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 */ - Table *pNextZombie; /* Next on the Parse.pZombieTab list */ }; /* @@ -17532,24 +17557,39 @@ struct Table { ** ** Constraints: ** -** TF_HasVirtual == COLFLAG_Virtual -** TF_HasStored == COLFLAG_Stored -*/ -#define TF_Readonly 0x0001 /* Read-only system table */ -#define TF_Ephemeral 0x0002 /* An ephemeral table */ -#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 +** TF_HasVirtual == COLFLAG_VIRTUAL +** TF_HasStored == COLFLAG_STORED +** TF_HasHidden == COLFLAG_HIDDEN +*/ +#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_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 @@ -17557,9 +17597,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 @@ -17646,16 +17686,22 @@ struct FKey { ** is returned. REPLACE means that preexisting database rows that caused ** a UNIQUE constraint violation are removed so that the new insert or ** update can proceed. Processing continues and no error is reported. +** UPDATE applies to insert operations only and means that the insert +** is omitted and the DO UPDATE clause of an upsert is run instead. ** -** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys. +** RESTRICT, SETNULL, SETDFLT, and CASCADE actions apply only to foreign keys. ** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the ** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign -** key is set to NULL. CASCADE means that a DELETE or UPDATE of the +** key is set to NULL. SETDFLT means that the foreign key is set +** to its default value. CASCADE means that a DELETE or UPDATE of the ** referenced table row is propagated into the row that holds the ** foreign key. ** +** The OE_Default value is a place holder that means to use whatever +** conflict resolution algorthm is required from context. +** ** The following symbolic values are used to record which type -** of action to take. +** of conflict resolution action to take. */ #define OE_None 0 /* There is no constraint to check */ #define OE_Rollback 1 /* Fail the operation and rollback the transaction */ @@ -17909,10 +17955,10 @@ struct AggInfo { FuncDef *pFunc; /* The aggregate function implementation */ int iMem; /* Memory location that acts as accumulator */ int iDistinct; /* Ephemeral table used to enforce DISTINCT */ + int iDistAddr; /* Address of OP_OpenEphemeral */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ - AggInfo *pNext; /* Next in list of them all */ }; /* @@ -17942,10 +17988,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. @@ -17985,7 +18031,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 @@ -18041,7 +18087,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[] */ - i16 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 @@ -18054,8 +18103,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 @@ -18078,12 +18126,12 @@ struct Expr { #define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ #define EP_Win 0x008000 /* Contains window functions */ #define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ - /* 0x020000 // available for reuse */ +#define EP_IfNullRow 0x020000 /* The TK_IF_NULL_ROW opcode */ #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ -#define EP_Alias 0x400000 /* Is an alias for a result set column */ + /* 0x400000 // Available */ #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ @@ -18094,14 +18142,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) @@ -18111,6 +18157,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 */ @@ -18182,6 +18238,7 @@ struct Expr { */ struct ExprList { int nExpr; /* Number of expressions on the list */ + int nAlloc; /* Number of a[] slots allocated */ struct ExprList_item { /* For each expression in the list */ Expr *pExpr; /* The parse tree for this expression */ char *zEName; /* Token associated with this expression */ @@ -18192,11 +18249,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 */ }; @@ -18231,6 +18289,53 @@ struct IdList { int nId; /* Number of identifiers on the list */ }; +/* +** 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 */ + char *zDatabase; /* Name of database holding this table */ + char *zName; /* Name of the table */ + char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ + Table *pTab; /* An SQL table corresponding to zName */ + Select *pSelect; /* A SELECT statement used in place of a table name */ + int addrFillSub; /* Address of subroutine to manifest a subquery */ + int regReturn; /* Register holding return address of addrFillSub */ + int regResult; /* Registers holding results of a co-routine */ + struct { + u8 jointype; /* Type of join between this table and the previous */ + unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ + unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ + unsigned isTabFunc :1; /* True if table-valued-function syntax */ + unsigned isCorrelated :1; /* True if sub-query is correlated */ + unsigned viaCoroutine :1; /* Implemented as a co-routine */ + unsigned isRecursive :1; /* True for recursive reference in WITH */ + unsigned fromDDL :1; /* Comes from sqlite_schema */ + unsigned isCte :1; /* This is a CTE */ + unsigned notCte :1; /* This item may not match a CTE */ + } fg; + int iCursor; /* The VDBE cursor number used to access this table */ + Expr *pOn; /* The ON clause of a join */ + IdList *pUsing; /* The USING clause of a join */ + Bitmask colUsed; /* Bit N (1<" clause */ + ExprList *pFuncArg; /* Arguments to table-valued-function */ + } u1; + union { + Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ + CteUse *pCteUse; /* CTE Usage info info fg.isCte is true */ + } u2; +}; + /* ** The following structure describes the FROM clause of a SELECT statement. ** Each table or subquery in the FROM clause is a separate element of @@ -18253,36 +18358,7 @@ struct IdList { struct SrcList { int nSrc; /* Number of tables or subqueries in the FROM clause */ u32 nAlloc; /* Number of entries allocated in a[] below */ - struct SrcList_item { - Schema *pSchema; /* Schema to which this item is fixed */ - char *zDatabase; /* Name of database holding this table */ - char *zName; /* Name of the table */ - char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ - Table *pTab; /* An SQL table corresponding to zName */ - Select *pSelect; /* A SELECT statement used in place of a table name */ - int addrFillSub; /* Address of subroutine to manifest a subquery */ - int regReturn; /* Register holding return address of addrFillSub */ - int regResult; /* Registers holding results of a co-routine */ - struct { - u8 jointype; /* Type of join between this table and the previous */ - unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ - unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ - unsigned isTabFunc :1; /* True if table-valued-function syntax */ - unsigned isCorrelated :1; /* True if sub-query is correlated */ - unsigned viaCoroutine :1; /* Implemented as a co-routine */ - unsigned isRecursive :1; /* True for recursive reference in WITH */ - unsigned fromDDL :1; /* Comes from sqlite_schema */ - } fg; - int iCursor; /* The VDBE cursor number used to access this table */ - Expr *pOn; /* The ON clause of a join */ - IdList *pUsing; /* The USING clause of a join */ - Bitmask colUsed; /* Bit N (1<" clause */ - ExprList *pFuncArg; /* Arguments to table-valued-function */ - } u1; - Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ - } a[1]; /* One entry for each identifier on the list */ + SrcItem a[1]; /* One entry for each identifier on the list */ }; /* @@ -18316,9 +18392,9 @@ struct SrcList { #define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */ #define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */ #define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */ -#define WHERE_SEEK_TABLE 0x0400 /* Do not defer seeks on main table */ +#define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */ #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ -#define WHERE_SEEK_UNIQ_TABLE 0x1000 /* Do not defer seeks if unique */ + /* 0x1000 not currently used */ /* 0x2000 not currently used */ #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ /* 0x8000 not currently used */ @@ -18358,10 +18434,11 @@ struct NameContext { ExprList *pEList; /* Optional list of result-set columns */ AggInfo *pAggInfo; /* Information about aggregates at this level */ Upsert *pUpsert; /* ON CONFLICT clause information from an upsert */ + int iBaseReg; /* For TK_REGISTER when parsing RETURNING */ } uNC; NameContext *pNext; /* Next outer name context. NULL for outermost */ int nRef; /* Number of names resolved by this context */ - int nErr; /* Number of errors encountered while resolving names */ + int nNcErr; /* Number of errors encountered while resolving names */ int ncFlags; /* Zero or more NC_* flags defined below */ Select *pWinSelect; /* SELECT statement for any window functions */ }; @@ -18370,29 +18447,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_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_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 @@ -18409,15 +18490,21 @@ struct NameContext { ** WHERE clause is omitted. */ struct Upsert { - ExprList *pUpsertTarget; /* Optional description of conflicting index */ + ExprList *pUpsertTarget; /* Optional description of conflict target */ Expr *pUpsertTargetWhere; /* WHERE clause for partial index targets */ ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */ Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ - /* The fields above comprise the parse tree for the upsert clause. - ** The fields below are used to transfer information from the INSERT - ** processing down into the UPDATE processing while generating code. - ** Upsert owns the memory allocated above, but not the memory below. */ - Index *pUpsertIdx; /* Constraint that pUpsertTarget identifies */ + Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */ + u8 isDoUpdate; /* True for DO UPDATE. False for DO NOTHING */ + /* Above this point is the parse tree for the ON CONFLICT clauses. + ** The next group of fields stores intermediate data. */ + void *pToFree; /* Free memory when deleting the Upsert object */ + /* All fields above are owned by the Upsert object and must be freed + ** when the Upsert is destroyed. The fields below are used to transfer + ** information from the INSERT processing down into the UPDATE processing + ** while generating code. The fields below are owned by the INSERT + ** statement and will be freed by INSERT processing. */ + Index *pUpsertIdx; /* UNIQUE constraint specified by pUpsertTarget */ SrcList *pUpsertSrc; /* Table to be updated */ int regData; /* First register holding array of VALUES */ int iDataCur; /* Index of the data cursor */ @@ -18469,9 +18556,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 */ @@ -18496,7 +18584,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 @@ -18515,9 +18607,6 @@ struct Select { ** statements within triggers whose only purpose is ** the side-effects of functions. ** -** All of the above are free to ignore their ORDER BY clause. Those that -** follow must honor the ORDER BY clause. -** ** SRT_Output Generate a row of output (using the OP_ResultRow ** opcode) for each row in the result set. ** @@ -18574,13 +18663,18 @@ struct Select { #define SRT_Except 2 /* Remove result from a UNION index */ #define SRT_Exists 3 /* Store 1 if the result is not empty */ #define SRT_Discard 4 /* Do not save the results anywhere */ -#define SRT_Fifo 5 /* Store result as data with an automatic rowid */ -#define SRT_DistFifo 6 /* Like SRT_Fifo, but unique results only */ +#define SRT_DistFifo 5 /* Like SRT_Fifo, but unique results only */ +#define SRT_DistQueue 6 /* Like SRT_Queue, but unique results only */ + +/* The DISTINCT clause is ignored for all of the above. Not that +** IgnorableDistinct() implies IgnorableOrderby() */ +#define IgnorableDistinct(X) ((X->eDest)<=SRT_DistQueue) + #define SRT_Queue 7 /* Store result in an queue */ -#define SRT_DistQueue 8 /* Like SRT_Queue, but unique results only */ +#define SRT_Fifo 8 /* Store result as data with an automatic rowid */ /* The ORDER BY clause is ignored for all of the above */ -#define IgnorableOrderby(X) ((X->eDest)<=SRT_DistQueue) +#define IgnorableOrderby(X) ((X->eDest)<=SRT_Fifo) #define SRT_Output 9 /* Output each row of result */ #define SRT_Mem 10 /* Store result in a memory cell */ @@ -18665,6 +18759,17 @@ struct TriggerPrg { # define DbMaskNonZero(M) (M)!=0 #endif +/* +** An instance of the ParseCleanup object specifies an operation that +** should be performed after parsing to deallocation resources obtained +** during the parse and which are no longer needed. +*/ +struct ParseCleanup { + ParseCleanup *pNext; /* Next cleanup task */ + void *pPtr; /* Pointer to object to deallocate */ + void (*xCleanup)(sqlite3*,void*); /* Deallocation routine */ +}; + /* ** An SQL parser context. A copy of this structure is passed through ** the parser and down into all the parser action routine in order to @@ -18696,6 +18801,9 @@ struct Parse { u8 okConstFactor; /* OK to factor out constants */ u8 disableLookaside; /* Number of times lookaside has been disabled */ u8 disableVtab; /* Disable all virtual tables for this parse */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) + u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ +#endif int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ @@ -18722,13 +18830,17 @@ 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 */ - AggInfo *pAggList; /* List of all AggInfo objects */ - int addrCrTab; /* Address of OP_CreateBtree opcode on CREATE TABLE */ + 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 */ + } u1; u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ u32 oldmask; /* Mask of old.* columns referenced */ u32 newmask; /* Mask of new.* columns referenced */ u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ + u8 bReturning; /* Coding a RETURNING trigger */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ @@ -18740,6 +18852,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 */ /************************************************************************ @@ -18774,15 +18887,14 @@ struct Parse { Token sArg; /* Complete text of a module argument */ Table **apVtabLock; /* Pointer to virtual tables needing locking */ #endif - Table *pZombieTab; /* List of Table objects to delete after code gen */ - TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ With *pWith; /* Current WITH clause, or NULL */ - With *pWithToFree; /* Free this WITH object at the end of the 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 @@ -18791,7 +18903,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 */ @@ -18857,6 +18970,7 @@ struct AuthContext { #define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */ #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ #define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */ +#define OPFLAG_PREFORMAT 0x80 /* OP_Insert uses preformatted cell */ /* * Each trigger present in the database schema is stored as an instance of @@ -18878,6 +18992,7 @@ struct Trigger { char *table; /* The table or view to which the trigger applies */ u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */ u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ + u8 bReturning; /* This trigger implements a RETURNING clause */ Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */ IdList *pColumns; /* If this is an UPDATE OF trigger, the is stored here */ @@ -18936,14 +19051,15 @@ struct Trigger { * */ struct TriggerStep { - u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */ + u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT, + ** or TK_RETURNING */ u8 orconf; /* OE_Rollback etc. */ Trigger *pTrig; /* The trigger that this step is a part of */ Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */ char *zTarget; /* Target table for DELETE, UPDATE, INSERT */ SrcList *pFrom; /* FROM clause for UPDATE statement (if any) */ Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */ - ExprList *pExprList; /* SET clause for UPDATE */ + ExprList *pExprList; /* SET clause for UPDATE, or RETURNING clause */ IdList *pIdList; /* Column names for INSERT */ Upsert *pUpsert; /* Upsert clauses on an INSERT */ char *zSpan; /* Original SQL text of this command */ @@ -18952,18 +19068,16 @@ struct TriggerStep { }; /* -** The following structure contains information used by the sqliteFix... -** routines as they walk the parse tree to make database references -** explicit. +** Information about a RETURNING clause */ -typedef struct DbFixer DbFixer; -struct DbFixer { - Parse *pParse; /* The parsing context. Error messages written here */ - Schema *pSchema; /* Fix items to this schema */ - u8 bTemp; /* True for TEMP schema entries */ - const char *zDb; /* Make sure all objects are contained in this database */ - const char *zType; /* Type of the container - used for error messages */ - const Token *pName; /* Name of the container - used for error messages */ +struct Returning { + Parse *pParse; /* The parse that includes the RETURNING clause */ + ExprList *pReturnEL; /* List of expressions to return */ + Trigger retTrig; /* The transient trigger that implements RETURNING */ + TriggerStep retTStep; /* The trigger step */ + int iRetCur; /* Transient table holding RETURNING results */ + int nRetCol; /* Number of in pReturnEL after expansion */ + int iRetReg; /* Register array for holding a row of RETURNING */ }; /* @@ -19003,7 +19117,26 @@ typedef struct { /* ** Allowed values for mInitFlags */ -#define INITFLAG_AlterTable 0x0001 /* This is a reparse after ALTER TABLE */ +#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 +** parameters are for temporary use during development, to help find +** optimial values for parameters in the query planner. The should not +** be used on trunk check-ins. They are a temporary mechanism available +** for transient development builds only. +** +** Tuning parameters are numbered starting with 1. +*/ +#define SQLITE_NTUNE 6 /* Should be zero for all trunk check-ins */ +#ifdef SQLITE_DEBUG +# define Tuning(X) (sqlite3Config.aTune[(X)-1]) +#else +# define Tuning(X) 0 +#endif /* ** Structure containing global configuration data for the SQLite library. @@ -19059,16 +19192,21 @@ struct Sqlite3Config { void (*xVdbeBranch)(void*,unsigned iSrcLine,u8 eThis,u8 eMx); /* Callback */ void *pVdbeBranchArg; /* 1st argument */ #endif -#ifdef SQLITE_ENABLE_DESERIALIZE +#ifndef SQLITE_OMIT_DESERIALIZE sqlite3_int64 mxMemdbSize; /* Default max memdb size */ #endif #ifndef SQLITE_UNTESTABLE 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 */ + /* vvvv--- must be last ---vvv */ +#ifdef SQLITE_DEBUG + sqlite3_int64 aTune[SQLITE_NTUNE]; /* Tuning parameters */ +#endif }; /* @@ -19104,8 +19242,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 */ @@ -19115,10 +19253,26 @@ struct Walker { struct WhereConst *pConst; /* WHERE clause constants */ struct RenameCtx *pRename; /* RENAME COLUMN context */ struct Table *pTab; /* Table of generated column */ - struct SrcList_item *pSrcItem; /* A single FROM clause item */ + SrcItem *pSrcItem; /* A single FROM clause item */ + DbFixer *pFix; } u; }; +/* +** The following structure contains information used by the sqliteFix... +** routines as they walk the parse tree to make database references +** explicit. +*/ +struct DbFixer { + Parse *pParse; /* The parsing context. Error messages written here */ + Walker w; /* Walker object */ + Schema *pSchema; /* Fix items to this schema */ + u8 bTemp; /* True for TEMP schema entries */ + const char *zDb; /* Make sure all objects are contained in this database */ + const char *zType; /* Type of the container - used for error messages */ + const Token *pName; /* Name of the container - used for error messages */ +}; + /* Forward declarations */ SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*); @@ -19130,11 +19284,18 @@ SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*); SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*); SQLITE_PRIVATE int sqlite3WalkerDepthIncrease(Walker*,Select*); SQLITE_PRIVATE void sqlite3WalkerDepthDecrease(Walker*,Select*); +SQLITE_PRIVATE void sqlite3WalkWinDefnDummyCallback(Walker*,Select*); #ifdef SQLITE_DEBUG SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*); #endif +#ifndef SQLITE_OMIT_CTE +SQLITE_PRIVATE void sqlite3SelectPopWith(Walker*, Select*); +#else +# define sqlite3SelectPopWith 0 +#endif + /* ** Return code from the parse-tree walking primitives and their ** callbacks. @@ -19144,20 +19305,56 @@ SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*); #define WRC_Abort 2 /* Abandon the tree walk */ /* -** An instance of this structure represents a set of one or more CTEs -** (common table expressions) created by a single WITH clause. +** A single common table expression +*/ +struct Cte { + char *zName; /* Name of this CTE */ + ExprList *pCols; /* List of explicit column names, or NULL */ + Select *pSelect; /* The definition of this CTE */ + const char *zCteErr; /* Error message for circular references */ + CteUse *pUse; /* Usage information for this CTE */ + u8 eM10d; /* The MATERIALIZED flag */ +}; + +/* +** Allowed values for the materialized flag (eM10d): +*/ +#define M10d_Yes 0 /* AS MATERIALIZED */ +#define M10d_Any 1 /* Not specified. Query planner's choice */ +#define M10d_No 2 /* AS NOT MATERIALIZED */ + +/* +** An instance of the With object represents a WITH clause containing +** one or more CTEs (common table expressions). */ struct With { - int nCte; /* Number of CTEs in the WITH clause */ - With *pOuter; /* Containing WITH clause, or NULL */ - struct Cte { /* For each CTE in the WITH clause.... */ - char *zName; /* Name of this CTE */ - ExprList *pCols; /* List of explicit column names, or NULL */ - Select *pSelect; /* The definition of this CTE */ - const char *zCteErr; /* Error message for circular references */ - } a[1]; + int nCte; /* Number of CTEs in the WITH clause */ + int bView; /* Belongs to the outermost Select of a view */ + With *pOuter; /* Containing WITH clause, or NULL */ + Cte a[1]; /* For each CTE in the WITH clause.... */ +}; + +/* +** The Cte object is not guaranteed to persist for the entire duration +** of code generation. (The query flattener or other parser tree +** edits might delete it.) The following object records information +** about each Common Table Expression that must be preserved for the +** duration of the parse. +** +** The CteUse objects are freed using sqlite3ParserAddCleanup() rather +** than sqlite3SelectDelete(), which is what enables them to persist +** until the end of code generation. +*/ +struct CteUse { + int nUse; /* Number of users of this CTE */ + int addrM9e; /* Start of subroutine to compute materialization */ + int regRtn; /* Return address register for addrM9e subroutine */ + int iCur; /* Ephemeral table holding the materialization */ + LogEst nRowEst; /* Estimated number of rows in the table */ + u8 eM10d; /* The MATERIALIZED flag */ }; + #ifdef SQLITE_DEBUG /* ** An instance of the TreeView object is used for printing the content of @@ -19231,11 +19428,10 @@ 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*); -SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, struct SrcList_item*); SQLITE_PRIVATE void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*); SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p); SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p); @@ -19364,8 +19560,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); @@ -19481,9 +19677,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); @@ -19500,15 +19697,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*); @@ -19524,7 +19723,12 @@ 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**); SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char); SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); @@ -19544,14 +19748,15 @@ 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*); +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 **); #define sqlite3CodecQueryParameters(A,B,C) 0 @@ -19617,7 +19822,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, T Token*, Select*, Expr*, IdList*); SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); -SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *); +SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *); SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*); SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); @@ -19636,15 +19841,18 @@ 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*); SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*); +SQLITE_PRIVATE void sqlite3WhereMinMaxOptEarlyOut(Vdbe*,WhereInfo*); SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*); @@ -19659,7 +19867,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); @@ -19678,23 +19886,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 Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); +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); @@ -19719,7 +19928,7 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); #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*); @@ -19744,20 +19953,26 @@ 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); +SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p); #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); @@ -19806,6 +20021,7 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc(Parse*, TriggerStep*); #endif SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*); +SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol); SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr*,int); SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int); @@ -19828,7 +20044,6 @@ SQLITE_PRIVATE void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Tok SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*); SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*); SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*); -SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*); SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64); SQLITE_PRIVATE void sqlite3Int64ToText(i64,char*); @@ -19843,14 +20058,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); @@ -19885,12 +20094,13 @@ 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*); SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); +SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3*); SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int); SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); SQLITE_PRIVATE u8 sqlite3HexToInt(int h); @@ -19900,7 +20110,7 @@ SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); SQLITE_PRIVATE const char *sqlite3ErrName(int); #endif -#ifdef SQLITE_ENABLE_DESERIALIZE +#ifndef SQLITE_OMIT_DESERIALIZE SQLITE_PRIVATE int sqlite3MemdbInit(void); #endif @@ -19913,14 +20123,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); @@ -19945,16 +20155,22 @@ 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; +SQLITE_PRIVATE const unsigned char *sqlite3aGTb; SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[]; SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config; SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions; -SQLITE_API extern u32 sqlite3_unsupported_selecttrace; #ifndef SQLITE_OMIT_WSD SQLITE_PRIVATE int sqlite3PendingByte; #endif @@ -19973,6 +20189,7 @@ SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int); SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int); SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*); SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); +SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, SrcItem*); SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); SQLITE_PRIVATE int sqlite3MatchEName( const struct ExprList_item*, @@ -19990,8 +20207,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 *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*); @@ -20013,6 +20231,7 @@ SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); +SQLITE_PRIVATE const char *sqlite3SelectOpName(int); SQLITE_PRIVATE int sqlite3HasExplicitNulls(Parse*, ExprList*); #ifdef SQLITE_DEBUG @@ -20027,15 +20246,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 *); @@ -20086,7 +20310,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) @@ -20123,9 +20347,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*); @@ -20142,7 +20368,9 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg 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*); #endif @@ -20157,23 +20385,32 @@ SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif #ifndef SQLITE_OMIT_CTE -SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*); +SQLITE_PRIVATE Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8); +SQLITE_PRIVATE void sqlite3CteDelete(sqlite3*,Cte*); +SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Cte*); SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*); -SQLITE_PRIVATE void sqlite3WithPush(Parse*, With*, u8); +SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8); #else -#define sqlite3WithPush(x,y,z) -#define sqlite3WithDelete(x,y) +# define sqlite3CteNew(P,T,E,S) ((void*)0) +# define sqlite3CteDelete(D,C) +# define sqlite3CteWithAdd(P,W,C) ((void*)0) +# define sqlite3WithDelete(x,y) +# define sqlite3WithPush(x,y,z) ((void*)0) #endif #ifndef SQLITE_OMIT_UPSERT -SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*); +SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*); SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*); SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*); SQLITE_PRIVATE void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); +SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert*,Index*); +SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert*); #else -#define sqlite3UpsertNew(v,w,x,y,z) ((Upsert*)0) +#define sqlite3UpsertNew(u,v,w,x,y,z) ((Upsert*)0) #define sqlite3UpsertDelete(x,y) -#define sqlite3UpsertDup(x,y) ((Upsert*)0) +#define sqlite3UpsertDup(x,y) ((Upsert*)0) +#define sqlite3UpsertOfIndex(x,y) ((Upsert*)0) +#define sqlite3UpsertNextIsIPK(x) 0 #endif @@ -20191,6 +20428,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) @@ -20198,6 +20436,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*); @@ -20255,7 +20494,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 @@ -20326,8 +20565,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 @@ -20352,10 +20591,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 @@ -20365,6 +20604,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 @@ -20405,7 +21631,7 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = { 198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215, 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233, 234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251, - 252,253,254,255 + 252,253,254,255, #endif #ifdef SQLITE_EBCDIC 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 0x */ @@ -20425,7 +21651,35 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = { 224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */ #endif +/* All of the upper-to-lower conversion data is above. The following +** 18 integers are completely unrelated. They are appended to the +** sqlite3UpperToLower[] array to avoid UBSAN warnings. Here's what is +** going on: +** +** The SQL comparison operators (<>, =, >, <=, <, and >=) are implemented +** by invoking sqlite3MemCompare(A,B) which compares values A and B and +** returns negative, zero, or positive if A is less then, equal to, or +** greater than B, respectively. Then the true false results is found by +** consulting sqlite3aLTb[opcode], sqlite3aEQb[opcode], or +** sqlite3aGTb[opcode] depending on whether the result of compare(A,B) +** is negative, zero, or positive, where opcode is the specific opcode. +** The only works because the comparison opcodes are consecutive and in +** this order: NE EQ GT LE LT GE. Various assert()s throughout the code +** ensure that is the case. +** +** These elements must be appended to another array. Otherwise the +** index (here shown as [256-OP_Ne]) would be out-of-bounds and thus +** be undefined behavior. That's goofy, but the C-standards people thought +** it was a good idea, so here we are. +*/ +/* NE EQ GT LE LT GE */ + 1, 0, 0, 1, 1, 0, /* aLTb[]: Use when compare(A,B) less than zero */ + 0, 1, 0, 1, 0, 1, /* aEQb[]: Use when compare(A,B) equals zero */ + 1, 0, 1, 0, 0, 1 /* aGTb[]: Use when compare(A,B) greater than zero*/ }; +SQLITE_PRIVATE const unsigned char *sqlite3aLTb = &sqlite3UpperToLower[256-OP_Ne]; +SQLITE_PRIVATE const unsigned char *sqlite3aEQb = &sqlite3UpperToLower[256+6-OP_Ne]; +SQLITE_PRIVATE const unsigned char *sqlite3aGTb = &sqlite3UpperToLower[256+12-OP_Ne]; /* ** The following 256 byte lookup table is used to support SQLites built-in @@ -20619,13 +21873,14 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, /* xVdbeBranch */ 0, /* pVbeBranchArg */ #endif -#ifdef SQLITE_ENABLE_DESERIALIZE +#ifndef SQLITE_OMIT_DESERIALIZE SQLITE_MEMDB_DEFAULT_MAXSIZE, /* mxMemdbSize */ #endif #ifndef SQLITE_UNTESTABLE 0, /* xTestCallback */ #endif 0, /* bLocaltimeFault */ + 0, /* xAltLocaltime */ 0x7ffffffe, /* iOnceResetThreshold */ SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ 0, /* iPrngSeed */ @@ -20638,6 +21893,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 @@ -20669,9 +21936,10 @@ SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000; #endif /* -** Flags for select tracing and the ".selecttrace" macro of the CLI +** Tracing flags set by SQLITE_TESTCTRL_TRACEFLAGS. */ -SQLITE_API u32 sqlite3_unsupported_selecttrace = 0; +SQLITE_PRIVATE u32 sqlite3SelectTrace = 0; +SQLITE_PRIVATE u32 sqlite3WhereTrace = 0; /* #include "opcodes.h" */ /* @@ -20687,6 +21955,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 ******************************************/ /* @@ -20784,7 +22094,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 */ @@ -20795,10 +22105,13 @@ struct VdbeCursor { Bool isEphemeral:1; /* True for an ephemeral table */ Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ - Bool seekHit:1; /* See the OP_SeekHit and OP_IfNoHope opcodes */ - Btree *pBtx; /* Separate file holding temporary table */ + Bool hasBeenDuped:1; /* This cursor was source or target of OP_OpenDup */ + u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ + 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 @@ -20888,8 +22201,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 */ @@ -21090,13 +22403,13 @@ struct Vdbe { Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ Parse *pParse; /* Parsing context used to create this Vdbe */ ynVar nVar; /* Number of entries in aVar[] */ - u32 magic; /* Magic number for sanity checking */ + u32 iVdbeMagic; /* Magic number defining state of the SQL statement */ int nMem; /* Number of memory locations currently allocated */ int nCursor; /* Number of slots in apCsr[] */ 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 */ @@ -21138,7 +22451,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 */ @@ -21180,6 +22493,7 @@ struct PreUpdate { UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */ UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */ int iNewReg; /* Register for new.* values */ + int iBlobWrite; /* Value returned by preupdate_blobwrite() */ i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ Mem *aNew; /* Array of new.* values */ @@ -21187,6 +22501,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 */ @@ -21199,7 +22531,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 *); @@ -21223,7 +22555,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*); SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*); SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*); -SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*)); +SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, i64, u8, void(*)(void*)); SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64); #ifdef SQLITE_OMIT_FLOATING_POINT # define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64 @@ -21233,14 +22565,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); @@ -21268,7 +22605,8 @@ SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */ SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK -SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int); +SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( + Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int,int); #endif SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p); @@ -22217,8 +23555,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 @@ -22234,14 +23574,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; @@ -22256,67 +23612,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->validYMD = 1; + p->validHMS = 1; + p->validJD = 0; + p->rawS = 0; + p->validTZ = 0; + p->isError = 0; + return SQLITE_OK; } #endif /* SQLITE_OMIT_LOCALTIME */ @@ -22329,18 +23674,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 }, }; /* @@ -22371,11 +23715,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 @@ -22384,9 +23772,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; } @@ -22399,6 +23785,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); @@ -22411,18 +23798,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; @@ -22538,9 +23938,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; @@ -22550,8 +23951,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; @@ -22560,7 +23962,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; } @@ -22595,6 +23997,7 @@ static int isDate( int eType; memset(p, 0, sizeof(*p)); if( argc==0 ){ + if( !sqlite3NotPureFunc(context) ) return 1; return setDateTimeToCurrent(context, p); } if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT @@ -22609,7 +24012,7 @@ static int isDate( for(i=1; iisError || !validJulianDay(p->iJD) ) return 1; @@ -22639,6 +24042,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, ...) ** @@ -22651,11 +24072,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); + } } } @@ -22671,10 +24119,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); } } @@ -22690,10 +24148,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); + } } } @@ -22722,131 +24198,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; - } - 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; + 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); } - 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 @@ -23188,7 +24642,7 @@ SQLITE_PRIVATE int sqlite3OsOpen( SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ DO_OS_MALLOC_TEST(0); assert( dirSync==0 || dirSync==1 ); - return pVfs->xDelete(pVfs, zPath, dirSync); + return pVfs->xDelete!=0 ? pVfs->xDelete(pVfs, zPath, dirSync) : SQLITE_OK; } SQLITE_PRIVATE int sqlite3OsAccess( sqlite3_vfs *pVfs, @@ -23211,6 +24665,8 @@ SQLITE_PRIVATE int sqlite3OsFullPathname( } #ifndef SQLITE_OMIT_LOAD_EXTENSION SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ + assert( zPath!=0 ); + assert( strlen(zPath)<=SQLITE_MAX_PATHLEN ); /* tag-20210611-1 */ return pVfs->xDlOpen(pVfs, zPath); } SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ @@ -23272,12 +24728,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){ @@ -23995,7 +25454,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; @@ -24242,7 +25701,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; @@ -24264,7 +25723,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; @@ -26642,205 +28101,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. @@ -27478,7 +28739,6 @@ SQLITE_PRIVATE int sqlite3MallocInit(void){ if( sqlite3GlobalConfig.m.xMalloc==0 ){ sqlite3MemSetDefault(); } - memset(&mem0, 0, sizeof(mem0)); mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512 || sqlite3GlobalConfig.nPage<=0 ){ @@ -27634,7 +28894,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 @@ -27645,18 +28905,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) ){ @@ -27683,7 +28943,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) ); @@ -27791,12 +29051,17 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ if( nOld==nNew ){ pNew = pOld; }else if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_int64 nUsed; sqlite3_mutex_enter(mem0.mutex); sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes); nDiff = nNew - nOld; - if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= + if( nDiff>0 && (nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)) >= mem0.alarmThreshold-nDiff ){ sqlite3MallocAlarm(nDiff); + if( mem0.hardLimit>0 && nUsed >= mem0.hardLimit - nDiff ){ + sqlite3_mutex_leave(mem0.mutex); + return 0; + } } pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT @@ -28072,8 +29337,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 ){ @@ -28081,9 +29353,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; } /* @@ -28103,12 +29377,15 @@ SQLITE_PRIVATE void sqlite3OomClear(sqlite3 *db){ } /* -** Take actions at the end of an API call to indicate an OOM error +** Take actions at the end of an API call to deal with error codes. */ -static SQLITE_NOINLINE int apiOomError(sqlite3 *db){ - sqlite3OomClear(db); - sqlite3Error(db, SQLITE_NOMEM); - return SQLITE_NOMEM_BKPT; +static SQLITE_NOINLINE int apiHandleError(sqlite3 *db, int rc){ + if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){ + sqlite3OomClear(db); + sqlite3Error(db, SQLITE_NOMEM); + return SQLITE_NOMEM_BKPT; + } + return rc & db->errMask; } /* @@ -28130,8 +29407,8 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ */ assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); - if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){ - return apiOomError(db); + if( db->mallocFailed || rc ){ + return apiHandleError(db, rc); } return rc & db->errMask; } @@ -28169,7 +29446,7 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ #define etSQLESCAPE2 10 /* Strings with '\'' doubled and enclosed in '', NULL pointers replaced by SQL NULL. %Q */ #define etTOKEN 11 /* a pointer to a Token structure */ -#define etSRCLIST 12 /* a pointer to a SrcList */ +#define etSRCITEM 12 /* a pointer to a SrcItem */ #define etPOINTER 13 /* The %p conversion */ #define etSQLESCAPE3 14 /* %w -> Strings with '\"' doubled */ #define etORDINAL 15 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */ @@ -28235,10 +29512,16 @@ static const et_info fmtinfo[] = { /* All the rest are undocumented and are for internal use only */ { 'T', 0, 0, etTOKEN, 0, 0 }, - { 'S', 0, 0, etSRCLIST, 0, 0 }, + { 'S', 0, 0, etSRCITEM, 0, 0 }, { 'r', 10, 1, etORDINAL, 0, 0 }, }; +/* Notes: +** +** %S Takes a pointer to SrcItem. Shows name or database.name +** %!S Like %S but prefer the zName over the zAlias +*/ + /* Floating point constants used for rounding */ static const double arRound[] = { 5.0e-01, 5.0e-02, 5.0e-03, 5.0e-04, 5.0e-05, @@ -28279,7 +29562,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); @@ -28315,12 +29598,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; } @@ -28567,11 +29850,10 @@ SQLITE_API void sqlite3_str_vappendf( v = va_arg(ap,int); } if( v<0 ){ - if( v==SMALLEST_INT64 ){ - longvalue = ((u64)1)<<63; - }else{ - longvalue = -v; - } + testcase( v==SMALLEST_INT64 ); + testcase( v==(-1) ); + longvalue = ~v; + longvalue++; prefix = '-'; }else{ longvalue = v; @@ -28984,31 +30266,44 @@ 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; } - case etSRCLIST: { - SrcList *pSrc; - int k; - struct SrcList_item *pItem; + case etSRCITEM: { + SrcItem *pItem; if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; - pSrc = va_arg(ap, SrcList*); - k = va_arg(ap, int); - pItem = &pSrc->a[k]; + pItem = va_arg(ap, SrcItem*); assert( bArgList==0 ); - assert( k>=0 && knSrc ); - if( pItem->zDatabase ){ - sqlite3_str_appendall(pAccum, pItem->zDatabase); - sqlite3_str_append(pAccum, ".", 1); + if( pItem->zAlias && !flag_altform2 ){ + sqlite3_str_appendall(pAccum, pItem->zAlias); + }else if( pItem->zName ){ + if( pItem->zDatabase ){ + sqlite3_str_appendall(pAccum, pItem->zDatabase); + sqlite3_str_append(pAccum, ".", 1); + } + sqlite3_str_appendall(pAccum, pItem->zName); + }else if( pItem->zAlias ){ + sqlite3_str_appendall(pAccum, pItem->zAlias); + }else if( ALWAYS(pItem->pSelect) ){ + sqlite3_str_appendf(pAccum, "SUBQUERY %u", pItem->pSelect->selId); } - sqlite3_str_appendall(pAccum, pItem->zName); length = width = 0; break; } @@ -29041,6 +30336,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. @@ -29048,7 +30379,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 ){ @@ -29057,12 +30388,12 @@ 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; i64 szNew = p->nChar; - szNew += N + 1; + szNew += (sqlite3_int64)N + 1; if( szNew+p->nChar<=p->mxAlloc ){ /* Force exponential buffer size growth as long as it does not overflow, ** to avoid having to call this routine too often */ @@ -29070,7 +30401,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; @@ -29088,7 +30419,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; } } @@ -29161,7 +30492,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; @@ -29176,6 +30507,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 @@ -29565,7 +30912,10 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m } sqlite3_str_appendf(&x, ")"); } - sqlite3_str_appendf(&x, " AS"); + if( pCte->pUse ){ + sqlite3_str_appendf(&x, " (pUse=0x%p, nUse=%d)", pCte->pUse, + pCte->pUse->nUse); + } sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inCte-1); sqlite3TreeViewSelect(pView, pCte->pSelect, 0); @@ -29581,29 +30931,27 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ int i; for(i=0; inSrc; i++){ - const struct SrcList_item *pItem = &pSrc->a[i]; + const SrcItem *pItem = &pSrc->a[i]; StrAccum x; char zLine[100]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); - sqlite3_str_appendf(&x, "{%d:*}", pItem->iCursor); - if( pItem->zDatabase ){ - sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName); - }else if( pItem->zName ){ - sqlite3_str_appendf(&x, " %s", pItem->zName); - } + x.printfFlags |= SQLITE_PRINTF_INTERNAL; + sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem); if( pItem->pTab ){ sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx", pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed); } - if( pItem->zAlias ){ - sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias); - } 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"); } + if( pItem->fg.isCte ){ + sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); + } sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inSrc-1); if( pItem->pSelect ){ @@ -29865,7 +31213,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"); @@ -29895,6 +31243,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); @@ -29914,11 +31263,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; } @@ -29927,17 +31278,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; @@ -29947,12 +31300,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; @@ -30002,6 +31357,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; @@ -30013,6 +31369,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); @@ -30028,6 +31385,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; @@ -30035,6 +31393,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, @@ -30066,11 +31425,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; @@ -30078,7 +31439,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); @@ -30099,9 +31460,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); @@ -30123,6 +31487,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; } @@ -30135,6 +31500,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; } @@ -30147,12 +31513,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; } @@ -30161,6 +31531,23 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } + case TK_ERROR: { + Expr tmp; + sqlite3TreeViewLine(pView, "ERROR"); + tmp = *pExpr; + tmp.op = pExpr->op2; + 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; @@ -30310,11 +31697,16 @@ SQLITE_API void sqlite3_randomness(int N, void *pBuf){ ** number generator) not as an encryption device. */ if( !wsdPrng.isInit ){ + sqlite3_vfs *pVfs = sqlite3_vfs_find(0); int i; char k[256]; wsdPrng.j = 0; wsdPrng.i = 0; - sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k); + if( NEVER(pVfs==0) ){ + memset(k, 0, sizeof(k)); + }else{ + sqlite3OsRandomness(pVfs, 256, k); + } for(i=0; i<256; i++){ wsdPrng.s[i] = (u8)i; } @@ -31207,16 +32599,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 @@ -31246,11 +32628,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 */ @@ -31275,8 +32667,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; + } } /* @@ -31297,7 +32695,22 @@ 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; + } +} + +/* +** The equivalent of sqlite3Error(db, SQLITE_OK). Clear the error state +** and error message. +*/ +SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3 *db){ + assert( db!=0 ); + db->errCode = SQLITE_OK; + db->errByteOffset = -1; + if( db->pErr ) sqlite3ValueSetNull(db->pErr); } /* @@ -31317,17 +32730,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 @@ -31351,13 +32755,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 @@ -31370,11 +32767,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); @@ -31437,11 +32842,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 */ @@ -31867,6 +33295,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc incr = 1; }else{ incr = 2; + length &= ~1; assert( SQLITE_UTF16LE==2 && SQLITE_UTF16BE==3 ); for(i=3-enc; imagic; - if( magic!=SQLITE_MAGIC_OPEN ){ + eOpenState = db->eOpenState; + if( eOpenState!=SQLITE_STATE_OPEN ){ if( sqlite3SafetyCheckSickOrOk(db) ){ testcase( sqlite3GlobalConfig.xLog!=0 ); logBadConnection("unopened"); @@ -32563,11 +33992,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; @@ -32732,7 +34161,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). @@ -32747,16 +34175,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; @@ -32764,17 +34185,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 @@ -33186,35 +34599,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]"), @@ -33223,124 +34636,133 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 55 */ "Le" OpHelp("IF r[P3]<=r[P1]"), /* 56 */ "Lt" OpHelp("IF r[P3]=r[P1]"), - /* 58 */ "ElseNotEq" 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 */ "ResultRow" OpHelp("output=r[P1@P2]"), - /* 81 */ "CollSeq" OpHelp(""), - /* 82 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), - /* 83 */ "RealAffinity" OpHelp(""), - /* 84 */ "Cast" OpHelp("affinity(r[P1])"), - /* 85 */ "Permutation" OpHelp(""), - /* 86 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), - /* 87 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), - /* 88 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), - /* 89 */ "Column" OpHelp("r[P3]=PX"), - /* 90 */ "Affinity" OpHelp("affinity(r[P1@P2])"), - /* 91 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), - /* 92 */ "Count" OpHelp("r[P2]=count()"), - /* 93 */ "ReadCookie" OpHelp(""), - /* 94 */ "SetCookie" OpHelp(""), - /* 95 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), - /* 96 */ "OpenRead" OpHelp("root=P2 iDb=P3"), - /* 97 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), - /* 98 */ "OpenDup" OpHelp(""), - /* 99 */ "OpenAutoindex" OpHelp("nColumn=P2"), - /* 100 */ "OpenEphemeral" OpHelp("nColumn=P2"), - /* 101 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), - /* 102 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), - /* 103 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), - /* 105 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), - /* 106 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), - /* 107 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), - /* 108 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), - /* 109 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), - /* 110 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), - /* 111 */ "SorterOpen" OpHelp(""), - /* 112 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), - /* 113 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), - /* 114 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), - /* 115 */ "String8" OpHelp("r[P2]='P4'"), - /* 116 */ "Close" OpHelp(""), - /* 117 */ "ColumnsUsed" OpHelp(""), - /* 118 */ "SeekHit" OpHelp("seekHit=P2"), - /* 119 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), - /* 120 */ "NewRowid" OpHelp("r[P2]=rowid"), - /* 121 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), - /* 122 */ "Delete" OpHelp(""), - /* 123 */ "ResetCount" OpHelp(""), - /* 124 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), - /* 125 */ "SorterData" OpHelp("r[P2]=data"), - /* 126 */ "RowData" OpHelp("r[P2]=data"), - /* 127 */ "Rowid" OpHelp("r[P2]=rowid"), - /* 128 */ "NullRow" OpHelp(""), - /* 129 */ "SeekEnd" OpHelp(""), - /* 130 */ "IdxInsert" OpHelp("key=r[P2]"), - /* 131 */ "SorterInsert" OpHelp("key=r[P2]"), - /* 132 */ "IdxDelete" OpHelp("key=r[P2@P3]"), - /* 133 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), - /* 134 */ "IdxRowid" OpHelp("r[P2]=rowid"), - /* 135 */ "FinishSeek" OpHelp(""), - /* 136 */ "Destroy" OpHelp(""), - /* 137 */ "Clear" OpHelp(""), - /* 138 */ "ResetSorter" OpHelp(""), - /* 139 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), - /* 140 */ "SqlExec" OpHelp(""), - /* 141 */ "ParseSchema" OpHelp(""), - /* 142 */ "LoadAnalysis" OpHelp(""), - /* 143 */ "DropTable" OpHelp(""), - /* 144 */ "DropIndex" OpHelp(""), - /* 145 */ "DropTrigger" OpHelp(""), - /* 146 */ "IntegrityCk" OpHelp(""), - /* 147 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), - /* 148 */ "Param" OpHelp(""), - /* 149 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), - /* 150 */ "Real" OpHelp("r[P2]=P4"), - /* 151 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), - /* 152 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), - /* 153 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), - /* 154 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 155 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 156 */ "AggValue" OpHelp("r[P3]=value N=P2"), - /* 157 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 158 */ "Expire" OpHelp(""), - /* 159 */ "CursorLock" OpHelp(""), - /* 160 */ "CursorUnlock" OpHelp(""), - /* 161 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), - /* 162 */ "VBegin" OpHelp(""), - /* 163 */ "VCreate" OpHelp(""), - /* 164 */ "VDestroy" OpHelp(""), - /* 165 */ "VOpen" OpHelp(""), - /* 166 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 167 */ "VRename" OpHelp(""), - /* 168 */ "Pagecount" OpHelp(""), - /* 169 */ "MaxPgcnt" OpHelp(""), - /* 170 */ "Trace" OpHelp(""), - /* 171 */ "CursorHint" OpHelp(""), - /* 172 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), - /* 173 */ "Noop" OpHelp(""), - /* 174 */ "Explain" OpHelp(""), - /* 175 */ "Abortable" OpHelp(""), + /* 58 */ "ElseEq" OpHelp(""), + /* 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]<>r[P1]"), + /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), + /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), + /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), + /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), + /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), + /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), + /* 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]; } @@ -33472,7 +34894,8 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ # if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \ (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000)) # if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \ - && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0)) + && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))\ + && (!defined(TARGET_OS_MACCATALYST) || (TARGET_OS_MACCATALYST==0)) # undef HAVE_GETHOSTUUID # define HAVE_GETHOSTUUID 1 # else @@ -33646,205 +35069,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. @@ -35092,6 +36317,9 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ return rc; } +/* Forward declaration*/ +static int unixSleep(sqlite3_vfs*,int); + /* ** Set a posix-advisory-lock. ** @@ -35121,7 +36349,7 @@ static int osSetPosixAdvisoryLock( ** generic posix, however, there is no such API. So we simply try the ** lock once every millisecond until either the timeout expires, or until ** the lock is obtained. */ - usleep(1000); + unixSleep(0,1000); rc = osFcntl(h,F_SETLK,pLock); tm--; } @@ -35692,6 +36920,7 @@ static int unixClose(sqlite3_file *id){ } sqlite3_mutex_leave(pInode->pLockMutex); releaseInodeInfo(pFile); + assert( pFile->pShm==0 ); rc = closeUnixFile(id); unixLeaveMutex(); return rc; @@ -36918,7 +38147,24 @@ static int unixRead( if( got==amt ){ return SQLITE_OK; }else if( got<0 ){ - /* lastErrno set by seekAndRead */ + /* pFile->lastErrno has been set by seekAndRead(). + ** Usually we return SQLITE_IOERR_READ here, though for some + ** kinds of errors we return SQLITE_IOERR_CORRUPTFS. The + ** SQLITE_IOERR_CORRUPTFS will be converted into SQLITE_CORRUPT + ** prior to returning to the application by the sqlite3ApiExit() + ** routine. + */ + switch( pFile->lastErrno ){ + case ERANGE: + case EIO: +#ifdef ENXIO + case ENXIO: +#endif +#ifdef EDEVERR + case EDEVERR: +#endif + return SQLITE_IOERR_CORRUPTFS; + } return SQLITE_IOERR_READ; }else{ storeLastErrno(pFile, 0); /* not a system error */ @@ -37477,6 +38723,9 @@ static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ /* Forward declaration */ static int unixGetTempname(int nBuf, char *zBuf); +#ifndef SQLITE_OMIT_WAL + static int unixFcntlExternalReader(unixFile*, int*); +#endif /* ** Information and control of an open file handle. @@ -37593,6 +38842,15 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ return proxyFileControl(id,op,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; } @@ -37802,6 +39060,7 @@ struct unixShmNode { char **apRegion; /* Array of mapped shared-memory regions */ int nRef; /* Number of unixShm objects pointing to this */ unixShm *pFirst; /* All unixShm objects pointing to this */ + int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */ #ifdef SQLITE_DEBUG u8 exclMask; /* Mask of exclusive locks held */ u8 sharedMask; /* Mask of shared locks held */ @@ -37837,6 +39096,40 @@ struct unixShm { #define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ #define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ +/* +** Use F_GETLK to check whether or not there are any readers with open +** wal-mode transactions in other processes on database file pFile. If +** no error occurs, return SQLITE_OK and set (*piOut) to 1 if there are +** such transactions, or 0 otherwise. If an error occurs, return an +** SQLite error code. The final value of *piOut is undefined in this +** case. +*/ +static int unixFcntlExternalReader(unixFile *pFile, int *piOut){ + int rc = SQLITE_OK; + *piOut = 0; + if( pFile->pShm){ + unixShmNode *pShmNode = pFile->pShm->pShmNode; + struct flock f; + + memset(&f, 0, sizeof(f)); + f.l_type = F_WRLCK; + f.l_whence = SEEK_SET; + f.l_start = UNIX_SHM_BASE + 3; + f.l_len = SQLITE_SHM_NLOCK - 3; + + sqlite3_mutex_enter(pShmNode->pShmMutex); + if( osFcntl(pShmNode->hShm, F_GETLK, &f)<0 ){ + rc = SQLITE_IOERR_LOCK; + }else{ + *piOut = (f.l_type!=F_UNLCK); + } + sqlite3_mutex_leave(pShmNode->pShmMutex); + } + + return rc; +} + + /* ** Apply posix advisory locks for all bytes from ofst through ofst+n-1. ** @@ -38342,6 +39635,38 @@ static int unixShmMap( return rc; } +/* +** Check that the pShmNode->aLock[] array comports with the locking bitmasks +** held by each client. Return true if it does, or false otherwise. This +** is to be used in an assert(). e.g. +** +** assert( assertLockingArrayOk(pShmNode) ); +*/ +#ifdef SQLITE_DEBUG +static int assertLockingArrayOk(unixShmNode *pShmNode){ + unixShm *pX; + int aLock[SQLITE_SHM_NLOCK]; + assert( sqlite3_mutex_held(pShmNode->pShmMutex) ); + + memset(aLock, 0, sizeof(aLock)); + for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ + int i; + for(i=0; iexclMask & (1<sharedMask & (1<=0 ); + aLock[i]++; + } + } + } + + assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) ); + return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0); +} +#endif + /* ** Change the lock state for a shared-memory segment. ** @@ -38358,10 +39683,10 @@ static int unixShmLock( ){ unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */ unixShm *p = pDbFd->pShm; /* The shared memory being locked */ - unixShm *pX; /* For looping over all siblings */ unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */ int rc = SQLITE_OK; /* Result code */ u16 mask; /* Mask of locks to take or release */ + int *aLock = pShmNode->aLock; assert( pShmNode==pDbFd->pInode->pShmNode ); assert( pShmNode->pInode==pDbFd->pInode ); @@ -38400,78 +39725,76 @@ static int unixShmLock( mask = (1<<(ofst+n)) - (1<1 || mask==(1<pShmMutex); + assert( assertLockingArrayOk(pShmNode) ); if( flags & SQLITE_SHM_UNLOCK ){ - u16 allMask = 0; /* Mask of locks held by siblings */ + if( (p->exclMask|p->sharedMask) & mask ){ + int ii; + int bUnlock = 1; - /* See if any siblings hold this same lock */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( pX==p ) continue; - assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 ); - allMask |= pX->sharedMask; - } + for(ii=ofst; ii((p->sharedMask & (1<sharedMask & (1<1 ); + aLock[ofst]--; + } - /* Undo the local locks */ - if( rc==SQLITE_OK ){ - p->exclMask &= ~mask; - p->sharedMask &= ~mask; + /* Undo the local locks */ + if( rc==SQLITE_OK ){ + p->exclMask &= ~mask; + p->sharedMask &= ~mask; + } } }else if( flags & SQLITE_SHM_SHARED ){ - u16 allShared = 0; /* Union of locks held by connections other than "p" */ - - /* Find out which shared locks are already held by sibling connections. - ** If any sibling already holds an exclusive lock, go ahead and return - ** SQLITE_BUSY. - */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( (pX->exclMask & mask)!=0 ){ + assert( n==1 ); + assert( (p->exclMask & (1<sharedMask & mask)==0 ){ + if( aLock[ofst]<0 ){ rc = SQLITE_BUSY; - break; - } - allShared |= pX->sharedMask; - } - - /* Get shared locks at the system level, if necessary */ - if( rc==SQLITE_OK ){ - if( (allShared & mask)==0 ){ + }else if( aLock[ofst]==0 ){ rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); - }else{ - rc = SQLITE_OK; } - } - /* Get the local shared locks */ - if( rc==SQLITE_OK ){ - p->sharedMask |= mask; + /* Get the local shared locks */ + if( rc==SQLITE_OK ){ + p->sharedMask |= mask; + aLock[ofst]++; + } } }else{ /* Make sure no sibling connections hold locks that will block this - ** lock. If any do, return SQLITE_BUSY right away. - */ - for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ - if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){ + ** lock. If any do, return SQLITE_BUSY right away. */ + int ii; + for(ii=ofst; iisharedMask & mask)==0 ); + if( ALWAYS((p->exclMask & (1<sharedMask & mask)==0 ); p->exclMask |= mask; + for(ii=ofst; iipShmMutex); OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", p->id, osGetpid(0), p->sharedMask, p->exclMask)); @@ -39247,25 +40570,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 @@ -39274,8 +40607,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; } @@ -39581,6 +40914,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); @@ -39848,7 +41186,27 @@ static int unixAccess( } /* +** If the last component of the pathname in z[0]..z[j-1] is something +** other than ".." then back it out and return true. If the last +** component is empty or if it is ".." then return false. +*/ +static int unixBackupDir(const char *z, int *pJ){ + int j = *pJ; + int i; + if( j<=0 ) return 0; + for(i=j-1; i>0 && z[i-1]!='/'; i--){} + if( i==0 ) return 0; + if( z[i]=='.' && i==j-2 && z[i+1]=='.' ) return 0; + *pJ = i-1; + return 1; +} + +/* +** Convert a relative pathname into a full pathname. Also +** simplify the pathname as follows: ** +** Remove all instances of /./ +** Remove all isntances of /X/../ for any X */ static int mkFullPathname( const char *zPath, /* Input path */ @@ -39857,6 +41215,7 @@ static int mkFullPathname( ){ int nPath = sqlite3Strlen30(zPath); int iOff = 0; + int i, j; if( zPath[0]!='/' ){ if( osGetcwd(zOut, nOut-2)==0 ){ return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); @@ -39871,6 +41230,41 @@ static int mkFullPathname( return SQLITE_CANTOPEN_BKPT; } sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); + + /* Remove duplicate '/' characters. Except, two // at the beginning + ** of a pathname is allowed since this is important on windows. */ + for(i=j=1; zOut[i]; i++){ + zOut[j++] = zOut[i]; + while( zOut[i]=='/' && zOut[i+1]=='/' ) i++; + } + zOut[j] = 0; + + assert( zOut[0]=='/' ); + for(i=j=0; zOut[i]; i++){ + if( zOut[i]=='/' ){ + /* Skip over internal "/." directory components */ + if( zOut[i+1]=='.' && zOut[i+2]=='/' ){ + i += 1; + continue; + } + + /* If this is a "/.." directory component then back out the + ** previous term of the directory if it is something other than "..". + */ + if( zOut[i+1]=='.' + && zOut[i+2]=='.' + && zOut[i+3]=='/' + && unixBackupDir(zOut, &j) + ){ + i += 2; + continue; + } + } + if( ALWAYS(j>=0) ) zOut[j] = zOut[i]; + j++; + } + if( NEVER(j==0) ) zOut[j++] = '/'; + zOut[j] = 0; return SQLITE_OK; } @@ -40091,7 +41485,8 @@ static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ UNUSED_PARAMETER(NotUsed); return microseconds; #elif defined(HAVE_USLEEP) && HAVE_USLEEP - usleep(microseconds); + if( microseconds>=1000000 ) sleep(microseconds/1000000); + if( microseconds%1000000 ) usleep(microseconds%1000000); UNUSED_PARAMETER(NotUsed); return microseconds; #else @@ -40664,7 +42059,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ if( nTries==1 ){ conchModTime = buf.st_mtimespec; - usleep(500000); /* wait 0.5 sec and try the lock again*/ + unixSleep(0,500000); /* wait 0.5 sec and try the lock again*/ continue; } @@ -40690,7 +42085,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ /* don't break the lock on short read or a version mismatch */ return SQLITE_BUSY; } - usleep(10000000); /* wait 10 sec and try the lock again */ + unixSleep(0,10000000); /* wait 10 sec and try the lock again */ continue; } @@ -41466,6 +42861,28 @@ SQLITE_API int sqlite3_os_init(void){ sqlite3_vfs_register(&aVfs[i], i==0); } unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); + +#ifndef SQLITE_OMIT_WAL + /* Validate lock assumptions */ + assert( SQLITE_SHM_NLOCK==8 ); /* Number of available locks */ + assert( UNIX_SHM_BASE==120 ); /* Start of locking area */ + /* Locks: + ** WRITE UNIX_SHM_BASE 120 + ** CKPT UNIX_SHM_BASE+1 121 + ** RECOVER UNIX_SHM_BASE+2 122 + ** READ-0 UNIX_SHM_BASE+3 123 + ** READ-1 UNIX_SHM_BASE+4 124 + ** READ-2 UNIX_SHM_BASE+5 125 + ** READ-3 UNIX_SHM_BASE+6 126 + ** READ-4 UNIX_SHM_BASE+7 127 + ** DMS UNIX_SHM_BASE+8 128 + */ + assert( UNIX_SHM_DMS==128 ); /* Byte offset of the deadman-switch */ +#endif + + /* Initialize temp file dir array. */ + unixTempFileInit(); + return SQLITE_OK; } @@ -41505,205 +42922,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. @@ -46811,7 +48030,11 @@ static int winOpen( dwCreationDisposition = OPEN_EXISTING; } - dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + if( 0==sqlite3_uri_boolean(zName, "exclusive", 0) ){ + dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + }else{ + dwShareMode = 0; + } if( isDelete ){ #if SQLITE_OS_WINCE @@ -47855,31 +49078,88 @@ SQLITE_API int sqlite3_os_end(void){ ** sqlite3_deserialize(). */ /* #include "sqliteInt.h" */ -#ifdef SQLITE_ENABLE_DESERIALIZE +#ifndef SQLITE_OMIT_DESERIALIZE /* ** Forward declaration of objects used by this utility */ typedef struct sqlite3_vfs MemVfs; typedef struct MemFile MemFile; +typedef struct MemStore MemStore; /* Access to a lower-level VFS that (might) implement dynamic loading, ** access to randomness, etc. */ #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) -/* An open file */ -struct MemFile { - sqlite3_file base; /* IO methods */ +/* Storage for a memdb file. +** +** An memdb object can be shared or separate. Shared memdb objects can be +** used by more than one database connection. Mutexes are used by shared +** memdb objects to coordinate access. Separate memdb objects are only +** connected to a single database connection and do not require additional +** mutexes. +** +** Shared memdb objects have .zFName!=0 and .pMutex!=0. They are created +** using "file:/name?vfs=memdb". The first character of the name must be +** "/" or else the object will be a separate memdb object. All shared +** memdb objects are stored in memdb_g.apMemStore[] in an arbitrary order. +** +** Separate memdb objects are created using a name that does not begin +** with "/" or using sqlite3_deserialize(). +** +** Access rules for shared MemStore objects: +** +** * .zFName is initialized when the object is created and afterwards +** is unchanged until the object is destroyed. So it can be accessed +** at any time as long as we know the object is not being destroyed, +** which means while either the SQLITE_MUTEX_STATIC_VFS1 or +** .pMutex is held or the object is not part of memdb_g.apMemStore[]. +** +** * Can .pMutex can only be changed while holding the +** SQLITE_MUTEX_STATIC_VFS1 mutex or while the object is not part +** of memdb_g.apMemStore[]. +** +** * Other fields can only be changed while holding the .pMutex mutex +** or when the .nRef is less than zero and the object is not part of +** memdb_g.apMemStore[]. +** +** * The .aData pointer has the added requirement that it can can only +** be changed (for resizing) when nMmap is zero. +** +*/ +struct MemStore { sqlite3_int64 sz; /* Size of the file */ sqlite3_int64 szAlloc; /* Space allocated to aData */ sqlite3_int64 szMax; /* Maximum allowed size of the file */ unsigned char *aData; /* content of the file */ + sqlite3_mutex *pMutex; /* Used by shared stores only */ int nMmap; /* Number of memory mapped pages */ unsigned mFlags; /* Flags */ + int nRdLock; /* Number of readers */ + int nWrLock; /* Number of writers. (Always 0 or 1) */ + int nRef; /* Number of users of this MemStore */ + char *zFName; /* The filename for shared stores */ +}; + +/* An open file */ +struct MemFile { + sqlite3_file base; /* IO methods */ + MemStore *pStore; /* The storage */ int eLock; /* Most recent lock against this file */ }; +/* +** File-scope variables for holding the memdb files that are accessible +** to multiple database connections in separate threads. +** +** Must hold SQLITE_MUTEX_STATIC_VFS1 to access any part of this object. +*/ +static struct MemFS { + int nMemStore; /* Number of shared MemStore objects */ + MemStore **apMemStore; /* Array of all shared MemStore objects */ +} memdb_g; + /* ** Methods for MemFile */ @@ -47933,7 +49213,10 @@ static sqlite3_vfs memdb_vfs = { memdbSleep, /* xSleep */ 0, /* memdbCurrentTime, */ /* xCurrentTime */ memdbGetLastError, /* xGetLastError */ - memdbCurrentTimeInt64 /* xCurrentTimeInt64 */ + memdbCurrentTimeInt64, /* xCurrentTimeInt64 */ + 0, /* xSetSystemCall */ + 0, /* xGetSystemCall */ + 0, /* xNextSystemCall */ }; static const sqlite3_io_methods memdb_io_methods = { @@ -47958,17 +49241,68 @@ static const sqlite3_io_methods memdb_io_methods = { memdbUnfetch /* xUnfetch */ }; +/* +** Enter/leave the mutex on a MemStore +*/ +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0 +static void memdbEnter(MemStore *p){ + UNUSED_PARAMETER(p); +} +static void memdbLeave(MemStore *p){ + UNUSED_PARAMETER(p); +} +#else +static void memdbEnter(MemStore *p){ + sqlite3_mutex_enter(p->pMutex); +} +static void memdbLeave(MemStore *p){ + sqlite3_mutex_leave(p->pMutex); +} +#endif + /* ** Close an memdb-file. -** -** The pData pointer is owned by the application, so there is nothing -** to free. +** Free the underlying MemStore object when its refcount drops to zero +** or less. */ static int memdbClose(sqlite3_file *pFile){ - MemFile *p = (MemFile *)pFile; - if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData); + MemStore *p = ((MemFile*)pFile)->pStore; + if( p->zFName ){ + int i; +#ifndef SQLITE_MUTEX_OMIT + sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); +#endif + sqlite3_mutex_enter(pVfsMutex); + for(i=0; ALWAYS(inRef==1 ){ + memdb_g.apMemStore[i] = memdb_g.apMemStore[--memdb_g.nMemStore]; + if( memdb_g.nMemStore==0 ){ + sqlite3_free(memdb_g.apMemStore); + memdb_g.apMemStore = 0; + } + } + break; + } + } + sqlite3_mutex_leave(pVfsMutex); + }else{ + memdbEnter(p); + } + p->nRef--; + if( p->nRef<=0 ){ + if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ){ + sqlite3_free(p->aData); + } + memdbLeave(p); + sqlite3_mutex_free(p->pMutex); + sqlite3_free(p); + }else{ + memdbLeave(p); + } return SQLITE_OK; } @@ -47981,22 +49315,25 @@ static int memdbRead( int iAmt, sqlite_int64 iOfst ){ - MemFile *p = (MemFile *)pFile; + MemStore *p = ((MemFile*)pFile)->pStore; + memdbEnter(p); if( iOfst+iAmt>p->sz ){ memset(zBuf, 0, iAmt); if( iOfstsz ) memcpy(zBuf, p->aData+iOfst, p->sz - iOfst); + memdbLeave(p); return SQLITE_IOERR_SHORT_READ; } memcpy(zBuf, p->aData+iOfst, iAmt); + memdbLeave(p); return SQLITE_OK; } /* ** Try to enlarge the memory allocation to hold at least sz bytes */ -static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){ +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 ){ @@ -48005,7 +49342,7 @@ static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){ newSz *= 2; if( newSz>p->szMax ) newSz = p->szMax; pNew = sqlite3Realloc(p->aData, newSz); - if( pNew==0 ) return SQLITE_NOMEM; + if( pNew==0 ) return SQLITE_IOERR_NOMEM; p->aData = pNew; p->szAlloc = newSz; return SQLITE_OK; @@ -48020,19 +49357,27 @@ static int memdbWrite( int iAmt, sqlite_int64 iOfst ){ - MemFile *p = (MemFile *)pFile; - if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ) return SQLITE_READONLY; + MemStore *p = ((MemFile*)pFile)->pStore; + memdbEnter(p); + if( NEVER(p->mFlags & SQLITE_DESERIALIZE_READONLY) ){ + /* Can't happen: memdbLock() will return SQLITE_READONLY before + ** reaching this point */ + memdbLeave(p); + return SQLITE_IOERR_WRITE; + } if( iOfst+iAmt>p->sz ){ int rc; if( iOfst+iAmt>p->szAlloc && (rc = memdbEnlarge(p, iOfst+iAmt))!=SQLITE_OK ){ + memdbLeave(p); return rc; } if( iOfst>p->sz ) memset(p->aData+p->sz, 0, iOfst-p->sz); p->sz = iOfst+iAmt; } memcpy(p->aData+iOfst, z, iAmt); + memdbLeave(p); return SQLITE_OK; } @@ -48044,16 +49389,25 @@ static int memdbWrite( ** the size of a file, never to increase the size. */ static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){ - MemFile *p = (MemFile *)pFile; - if( NEVER(size>p->sz) ) return SQLITE_FULL; - p->sz = size; - return SQLITE_OK; + MemStore *p = ((MemFile*)pFile)->pStore; + int rc = SQLITE_OK; + memdbEnter(p); + if( size>p->sz ){ + /* This can only happen with a corrupt wal mode db */ + rc = SQLITE_CORRUPT; + }else{ + p->sz = size; + } + memdbLeave(p); + return rc; } /* ** Sync an memdb-file. */ static int memdbSync(sqlite3_file *pFile, int flags){ + UNUSED_PARAMETER(pFile); + UNUSED_PARAMETER(flags); return SQLITE_OK; } @@ -48061,8 +49415,10 @@ static int memdbSync(sqlite3_file *pFile, int flags){ ** Return the current file-size of an memdb-file. */ static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ - MemFile *p = (MemFile *)pFile; + MemStore *p = ((MemFile*)pFile)->pStore; + memdbEnter(p); *pSize = p->sz; + memdbLeave(p); return SQLITE_OK; } @@ -48070,19 +49426,48 @@ static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ ** Lock an memdb-file. */ static int memdbLock(sqlite3_file *pFile, int eLock){ - MemFile *p = (MemFile *)pFile; - if( eLock>SQLITE_LOCK_SHARED - && (p->mFlags & SQLITE_DESERIALIZE_READONLY)!=0 - ){ - return SQLITE_READONLY; + MemFile *pThis = (MemFile*)pFile; + MemStore *p = pThis->pStore; + int rc = SQLITE_OK; + if( eLock==pThis->eLock ) return SQLITE_OK; + memdbEnter(p); + if( eLock>SQLITE_LOCK_SHARED ){ + if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){ + rc = SQLITE_READONLY; + }else if( pThis->eLock<=SQLITE_LOCK_SHARED ){ + if( p->nWrLock ){ + rc = SQLITE_BUSY; + }else{ + p->nWrLock = 1; + } + } + }else if( eLock==SQLITE_LOCK_SHARED ){ + if( pThis->eLock > SQLITE_LOCK_SHARED ){ + assert( p->nWrLock==1 ); + p->nWrLock = 0; + }else if( p->nWrLock ){ + rc = SQLITE_BUSY; + }else{ + p->nRdLock++; + } + }else{ + assert( eLock==SQLITE_LOCK_NONE ); + if( pThis->eLock>SQLITE_LOCK_SHARED ){ + assert( p->nWrLock==1 ); + p->nWrLock = 0; + } + assert( p->nRdLock>0 ); + p->nRdLock--; } - p->eLock = eLock; - return SQLITE_OK; + if( rc==SQLITE_OK ) pThis->eLock = eLock; + memdbLeave(p); + return rc; } -#if 0 /* Never used because memdbAccess() always returns false */ +#if 0 /* -** Check if another file-handle holds a RESERVED lock on an memdb-file. +** This interface is only used for crash recovery, which does not +** occur on an in-memory database. */ static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){ *pResOut = 0; @@ -48090,12 +49475,14 @@ static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){ } #endif + /* ** File control method. For custom operations on an memdb-file. */ static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){ - MemFile *p = (MemFile *)pFile; + MemStore *p = ((MemFile*)pFile)->pStore; int rc = SQLITE_NOTFOUND; + memdbEnter(p); if( op==SQLITE_FCNTL_VFSNAME ){ *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz); rc = SQLITE_OK; @@ -48113,6 +49500,7 @@ static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){ *(sqlite3_int64*)pArg = iLimit; rc = SQLITE_OK; } + memdbLeave(p); return rc; } @@ -48129,6 +49517,7 @@ static int memdbSectorSize(sqlite3_file *pFile){ ** Return the device characteristic flags supported by an memdb-file. */ static int memdbDeviceCharacteristics(sqlite3_file *pFile){ + UNUSED_PARAMETER(pFile); return SQLITE_IOCAP_ATOMIC | SQLITE_IOCAP_POWERSAFE_OVERWRITE | SQLITE_IOCAP_SAFE_APPEND | @@ -48142,20 +49531,26 @@ static int memdbFetch( int iAmt, void **pp ){ - MemFile *p = (MemFile *)pFile; - if( iOfst+iAmt>p->sz ){ + MemStore *p = ((MemFile*)pFile)->pStore; + memdbEnter(p); + if( iOfst+iAmt>p->sz || (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)!=0 ){ *pp = 0; }else{ p->nMmap++; *pp = (void*)(p->aData + iOfst); } + memdbLeave(p); return SQLITE_OK; } /* Release a memory-mapped page */ static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ - MemFile *p = (MemFile *)pFile; + MemStore *p = ((MemFile*)pFile)->pStore; + UNUSED_PARAMETER(iOfst); + UNUSED_PARAMETER(pPage); + memdbEnter(p); p->nMmap--; + memdbLeave(p); return SQLITE_OK; } @@ -48165,20 +49560,79 @@ static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ static int memdbOpen( sqlite3_vfs *pVfs, const char *zName, - sqlite3_file *pFile, + sqlite3_file *pFd, int flags, int *pOutFlags ){ - MemFile *p = (MemFile*)pFile; - if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){ - return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFile, flags, pOutFlags); + MemFile *pFile = (MemFile*)pFd; + MemStore *p = 0; + int szName; + UNUSED_PARAMETER(pVfs); + + memset(pFile, 0, sizeof(*pFile)); + szName = sqlite3Strlen30(zName); + if( szName>1 && zName[0]=='/' ){ + int i; +#ifndef SQLITE_MUTEX_OMIT + sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); +#endif + sqlite3_mutex_enter(pVfsMutex); + for(i=0; izFName,zName)==0 ){ + p = memdb_g.apMemStore[i]; + break; + } + } + if( p==0 ){ + MemStore **apNew; + p = sqlite3Malloc( sizeof(*p) + szName + 3 ); + if( p==0 ){ + sqlite3_mutex_leave(pVfsMutex); + return SQLITE_NOMEM; + } + apNew = sqlite3Realloc(memdb_g.apMemStore, + sizeof(apNew[0])*(memdb_g.nMemStore+1) ); + if( apNew==0 ){ + sqlite3_free(p); + sqlite3_mutex_leave(pVfsMutex); + return SQLITE_NOMEM; + } + apNew[memdb_g.nMemStore++] = p; + memdb_g.apMemStore = apNew; + memset(p, 0, sizeof(*p)); + p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE|SQLITE_DESERIALIZE_FREEONCLOSE; + p->szMax = sqlite3GlobalConfig.mxMemdbSize; + p->zFName = (char*)&p[1]; + memcpy(p->zFName, zName, szName+1); + p->pMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( p->pMutex==0 ){ + memdb_g.nMemStore--; + sqlite3_free(p); + sqlite3_mutex_leave(pVfsMutex); + return SQLITE_NOMEM; + } + p->nRef = 1; + memdbEnter(p); + }else{ + memdbEnter(p); + p->nRef++; + } + sqlite3_mutex_leave(pVfsMutex); + }else{ + p = sqlite3Malloc( sizeof(*p) ); + if( p==0 ){ + return SQLITE_NOMEM; + } + memset(p, 0, sizeof(*p)); + p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE; + p->szMax = sqlite3GlobalConfig.mxMemdbSize; } - memset(p, 0, sizeof(*p)); - p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE; - assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */ - *pOutFlags = flags | SQLITE_OPEN_MEMORY; - pFile->pMethods = &memdb_io_methods; - p->szMax = sqlite3GlobalConfig.mxMemdbSize; + pFile->pStore = p; + if( pOutFlags!=0 ){ + *pOutFlags = flags | SQLITE_OPEN_MEMORY; + } + pFd->pMethods = &memdb_io_methods; + memdbLeave(p); return SQLITE_OK; } @@ -48206,6 +49660,9 @@ static int memdbAccess( int flags, int *pResOut ){ + UNUSED_PARAMETER(pVfs); + UNUSED_PARAMETER(zPath); + UNUSED_PARAMETER(flags); *pResOut = 0; return SQLITE_OK; } @@ -48221,6 +49678,7 @@ static int memdbFullPathname( int nOut, char *zOut ){ + UNUSED_PARAMETER(pVfs); sqlite3_snprintf(nOut, zOut, "%s", zPath); return SQLITE_OK; } @@ -48293,9 +49751,14 @@ static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ */ static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){ MemFile *p = 0; + MemStore *pStore; int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p); if( rc ) return 0; if( p->base.pMethods!=&memdb_io_methods ) return 0; + pStore = p->pStore; + memdbEnter(pStore); + if( pStore->zFName!=0 ) p = 0; + memdbLeave(pStore); return p; } @@ -48331,12 +49794,14 @@ SQLITE_API unsigned char *sqlite3_serialize( if( piSize ) *piSize = -1; if( iDb<0 ) return 0; if( p ){ - if( piSize ) *piSize = p->sz; + MemStore *pStore = p->pStore; + assert( pStore->pMutex==0 ); + if( piSize ) *piSize = pStore->sz; if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ - pOut = p->aData; + pOut = pStore->aData; }else{ - pOut = sqlite3_malloc64( p->sz ); - if( pOut ) memcpy(pOut, p->aData, p->sz); + pOut = sqlite3_malloc64( pStore->sz ); + if( pOut ) memcpy(pOut, pStore->aData, pStore->sz); } return pOut; } @@ -48406,13 +49871,18 @@ 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; } zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema); - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + } if( rc ) goto end_deserialize; db->init.iDb = (u8)iDb; db->init.reopenMemdb = 1; @@ -48426,19 +49896,24 @@ SQLITE_API int sqlite3_deserialize( if( p==0 ){ rc = SQLITE_ERROR; }else{ - p->aData = pData; - p->sz = szDb; - p->szAlloc = szBuf; - p->szMax = szBuf; - if( p->szMaxszMax = sqlite3GlobalConfig.mxMemdbSize; + MemStore *pStore = p->pStore; + pStore->aData = pData; + pData = 0; + pStore->sz = szDb; + pStore->szAlloc = szBuf; + pStore->szMax = szBuf; + if( pStore->szMaxszMax = sqlite3GlobalConfig.mxMemdbSize; } - p->mFlags = mFlags; + pStore->mFlags = mFlags; rc = SQLITE_OK; } end_deserialize: sqlite3_finalize(pStmt); + if( pData && (mFlags & SQLITE_DESERIALIZE_FREEONCLOSE)!=0 ){ + sqlite3_free(pData); + } sqlite3_mutex_leave(db->mutex); return rc; } @@ -48449,7 +49924,9 @@ SQLITE_API int sqlite3_deserialize( */ SQLITE_PRIVATE int sqlite3MemdbInit(void){ sqlite3_vfs *pLower = sqlite3_vfs_find(0); - int sz = pLower->szOsFile; + unsigned int sz; + if( NEVER(pLower==0) ) return SQLITE_ERROR; + sz = pLower->szOsFile; memdb_vfs.pAppData = pLower; /* The following conditional can only be true when compiled for ** Windows x86 and SQLITE_MAX_MMAP_SIZE=0. We always leave @@ -48459,7 +49936,7 @@ SQLITE_PRIVATE int sqlite3MemdbInit(void){ memdb_vfs.szOsFile = sz; return sqlite3_vfs_register(&memdb_vfs, 0); } -#endif /* SQLITE_ENABLE_DESERIALIZE */ +#endif /* SQLITE_OMIT_DESERIALIZE */ /************** End of memdb.c ***********************************************/ /************** Begin file bitvec.c ******************************************/ @@ -48818,7 +50295,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: @@ -49122,11 +50599,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; } } @@ -50225,6 +51705,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ p->page.pExtra = &p[1]; p->isBulkLocal = 0; p->isAnchor = 0; + p->pLruPrev = 0; /* Initializing this saves a valgrind error */ } (*pCache->pnPurgeable)++; return p; @@ -50580,12 +52061,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); @@ -50601,7 +52088,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; @@ -52143,6 +53630,7 @@ struct PagerSavepoint { Bitvec *pInSavepoint; /* Set of pages in this savepoint */ Pgno nOrig; /* Original number of pages in file */ Pgno iSubRec; /* Index of first record in sub-journal */ + int bTruncateOnRelease; /* If stmt journal may be truncated on RELEASE */ #ifndef SQLITE_OMIT_WAL u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ #endif @@ -52337,6 +53825,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 @@ -52386,8 +53875,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 */ @@ -52778,6 +54267,9 @@ static int subjRequiresPage(PgHdr *pPg){ for(i=0; inSavepoint; i++){ p = &pPager->aSavepoint[i]; if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){ + for(i=i+1; inSavepoint; i++){ + pPager->aSavepoint[i].bTruncateOnRelease = 0; + } return 1; } } @@ -54194,6 +55686,7 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ i64 nSuperJournal; /* Size of super-journal file */ char *zJournal; /* Pointer to one journal within MJ file */ char *zSuperPtr; /* Space to hold super-journal filename */ + char *zFree = 0; /* Free this buffer */ int nSuperPtr; /* Amount of space allocated to zSuperPtr[] */ /* Allocate space for both the pJournal and pSuper file descriptors. @@ -54218,11 +55711,13 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ rc = sqlite3OsFileSize(pSuper, &nSuperJournal); if( rc!=SQLITE_OK ) goto delsuper_out; nSuperPtr = pVfs->mxPathname+1; - zSuperJournal = sqlite3Malloc(nSuperJournal + nSuperPtr + 2); - if( !zSuperJournal ){ + zFree = sqlite3Malloc(4 + nSuperJournal + nSuperPtr + 2); + if( !zFree ){ rc = SQLITE_NOMEM_BKPT; goto delsuper_out; } + zFree[0] = zFree[1] = zFree[2] = zFree[3] = 0; + zSuperJournal = &zFree[4]; zSuperPtr = &zSuperJournal[nSuperJournal+2]; rc = sqlite3OsRead(pSuper, zSuperJournal, (int)nSuperJournal, 0); if( rc!=SQLITE_OK ) goto delsuper_out; @@ -54270,7 +55765,7 @@ static int pager_delsuper(Pager *pPager, const char *zSuper){ rc = sqlite3OsDelete(pVfs, zSuper, 0); delsuper_out: - sqlite3_free(zSuperJournal); + sqlite3_free(zFree); if( pSuper ){ sqlite3OsClose(pSuper); assert( !isOpen(pJournal) ); @@ -54608,7 +56103,11 @@ static int pager_playback(Pager *pPager, int isHot){ pPager->changeCountDone = pPager->tempFile; if( rc==SQLITE_OK ){ - zSuper = pPager->pTmpSpace; + /* Leave 4 bytes of space before the super-journal filename in memory. + ** This is because it may end up being passed to sqlite3OsOpen(), in + ** which case it requires 4 0x00 bytes in memory immediately before + ** the filename. */ + zSuper = &pPager->pTmpSpace[4]; rc = readSuperJournal(pPager->jfd, zSuper, pPager->pVfs->mxPathname+1); testcase( rc!=SQLITE_OK ); } @@ -54625,6 +56124,8 @@ static int pager_playback(Pager *pPager, int isHot){ /* If there was a super-journal and this routine will return success, ** see if it is possible to delete the super-journal. */ + assert( zSuper==&pPager->pTmpSpace[4] ); + memset(&zSuper[-4], 0, 4); rc = pager_delsuper(pPager, zSuper); testcase( rc!=SQLITE_OK ); } @@ -54719,6 +56220,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; @@ -55593,8 +57095,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() @@ -55609,8 +57110,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); @@ -55631,7 +57140,7 @@ static void assertTruncateConstraint(Pager *pPager){ ** then continue writing to the database. */ SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ - assert( pPager->dbSize>=nPage ); + assert( pPager->dbSize>=nPage || CORRUPT_DB ); assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); pPager->dbSize = nPage; @@ -56359,7 +57868,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( int rc = SQLITE_OK; /* Return code */ int tempFile = 0; /* True for temp files (incl. in-memory files) */ int memDb = 0; /* True if this is an in-memory file */ -#ifdef SQLITE_ENABLE_DESERIALIZE +#ifndef SQLITE_OMIT_DESERIALIZE int memJM = 0; /* Memory journal mode */ #else # define memJM 0 @@ -56552,6 +58061,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; @@ -56563,8 +58073,8 @@ SQLITE_PRIVATE int sqlite3PagerOpen( int fout = 0; /* VFS flags returned by xOpen() */ rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); assert( !memDb ); -#ifdef SQLITE_ENABLE_DESERIALIZE - memJM = (fout&SQLITE_OPEN_MEMORY)!=0; +#ifndef SQLITE_OMIT_DESERIALIZE + pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; #endif readOnly = (fout&SQLITE_OPEN_READONLY)!=0; @@ -56949,7 +58459,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( @@ -57351,6 +58861,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); } @@ -57531,7 +59042,7 @@ SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory assert( pPager->eState>=PAGER_READER && pPager->eStatesubjInMemory = (u8)subjInMemory; - if( ALWAYS(pPager->eState==PAGER_READER) ){ + if( pPager->eState==PAGER_READER ){ assert( pPager->pInJournal==0 ); if( pagerUseWal(pPager) ){ @@ -58431,8 +59942,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; @@ -58501,7 +60012,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; } /* @@ -58547,6 +60058,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){ } aNew[ii].iSubRec = pPager->nSubRec; aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize); + aNew[ii].bTruncateOnRelease = 1; if( !aNew[ii].pInSavepoint ){ return SQLITE_NOMEM_BKPT; } @@ -58625,16 +60137,18 @@ 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 ){ - if( nNew==0 && isOpen(pPager->sjfd) ){ + 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) ){ - rc = sqlite3OsTruncate(pPager->sjfd, 0); + i64 sz = (pPager->pageSize+4)*(i64)pRel->iSubRec; + rc = sqlite3OsTruncate(pPager->sjfd, sz); assert( rc==SQLITE_OK ); } - pPager->nSubRec = 0; + pPager->nSubRec = pRel->iSubRec; } } /* Else this is a rollback operation, playback the specified savepoint. @@ -58818,7 +60332,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; } @@ -58953,12 +60467,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 @@ -58995,7 +60509,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. @@ -59107,6 +60620,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), @@ -59564,7 +61089,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 @@ -59800,6 +61328,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 @@ -59956,9 +61548,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 */ @@ -59991,7 +61587,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; @@ -60330,8 +61928,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 */ @@ -60343,7 +61941,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)]; @@ -60351,7 +61949,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; } @@ -60402,7 +62001,6 @@ static void walCleanupHash(Wal *pWal){ int iLimit = 0; /* Zero values greater than this */ int nByte; /* Number of bytes to zero in aPgno[] */ int i; /* Used to iterate through aHash[] */ - int rc; /* Return code form walHashGet() */ assert( pWal->writeLock ); testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 ); @@ -60417,8 +62015,8 @@ static void walCleanupHash(Wal *pWal){ */ assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) ); assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] ); - rc = walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc); - if( NEVER(rc) ) return; /* Defense-in-depth, in case (1) above is wrong */ + i = walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &sLoc); + if( NEVER(i) ) return; /* Defense-in-depth, in case (1) above is wrong */ /* Zero all hash-table entries that correspond to frame numbers greater ** than pWal->hdr.mxFrame. @@ -60434,8 +62032,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 @@ -60444,11 +62043,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 @@ -60491,9 +62090,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. */ @@ -60501,7 +62100,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 @@ -60522,19 +62121,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++){ @@ -60814,14 +62413,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 @@ -61123,7 +62751,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{ @@ -61904,7 +63531,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; @@ -61918,7 +63547,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 ){ @@ -62262,7 +63891,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 ){ @@ -62495,7 +64125,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; } @@ -63747,7 +65377,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 */ @@ -63825,9 +65454,12 @@ struct Btree { u8 hasIncrblobCur; /* True if there are one or more Incrblob cursors */ int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */ int nBackup; /* Number of backup operations reading this btree */ - u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */ + u32 iBDataVersion; /* Combines with pBt->pPager->iDataVersion */ Btree *pNext; /* List of other sharable Btrees from the same db */ Btree *pPrev; /* Back pointer of the same list */ +#ifdef SQLITE_DEBUG + u64 nSeek; /* Calls to sqlite3BtreeMovetoUnpacked() */ +#endif #ifndef SQLITE_OMIT_SHARED_CACHE BtLock lock; /* Object used to lock page 1 */ #endif @@ -63839,11 +65471,25 @@ struct Btree { ** If the shared-data extension is enabled, there may be multiple users ** of the Btree structure. At most one of these may open a write transaction, ** but any number may have active read transactions. +** +** These values must match SQLITE_TXN_NONE, SQLITE_TXN_READ, and +** SQLITE_TXN_WRITE */ #define TRANS_NONE 0 #define TRANS_READ 1 #define TRANS_WRITE 2 +#if TRANS_NONE!=SQLITE_TXN_NONE +# error wrong numeric code for no-transaction +#endif +#if TRANS_READ!=SQLITE_TXN_READ +# error wrong numeric code for read-transaction +#endif +#if TRANS_WRITE!=SQLITE_TXN_WRITE +# error wrong numeric code for write-transaction +#endif + + /* ** An instance of this object represents a single database file. ** @@ -63913,6 +65559,7 @@ struct BtShared { Btree *pWriter; /* Btree with currently open write transaction */ #endif u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */ + int nPreformatSize; /* Size of last cell written by TransferRow() */ }; /* @@ -64595,6 +66242,17 @@ SQLITE_API int sqlite3_enable_shared_cache(int enable){ #define hasReadConflicts(a, b) 0 #endif +#ifdef SQLITE_DEBUG +/* +** Return and reset the seek counter for a Btree object. +*/ +SQLITE_PRIVATE sqlite3_uint64 sqlite3BtreeSeekCount(Btree *pBt){ + u64 n = pBt->nSeek; + pBt->nSeek = 0; + return n; +} +#endif + /* ** Implementation of the SQLITE_CORRUPT_PAGE() macro. Takes a single ** (MemPage*) as an argument. The (MemPage*) must not be NULL. @@ -65019,7 +66677,7 @@ static void invalidateIncrblobCursors( int isClearTable /* True if all rows are being deleted */ ){ BtCursor *p; - if( pBtree->hasIncrblobCur==0 ) return; + assert( pBtree->hasIncrblobCur ); assert( sqlite3BtreeHoldsMutex(pBtree) ); pBtree->hasIncrblobCur = 0; for(p=pBtree->pBt->pCursor; p; p=p->pNext){ @@ -65299,15 +66957,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; } @@ -65615,6 +67271,24 @@ static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow( pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4; } +/* +** Given a record with nPayload bytes of payload stored within btree +** page pPage, return the number of bytes of payload stored locally. +*/ +static int btreePayloadToLocal(MemPage *pPage, i64 nPayload){ + int maxLocal; /* Maximum amount of payload held locally */ + maxLocal = pPage->maxLocal; + if( nPayload<=maxLocal ){ + return nPayload; + }else{ + int minLocal; /* Minimum amount of payload held locally */ + int surplus; /* Overflow payload available for local storage */ + minLocal = pPage->minLocal; + surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize-4); + return ( surplus <= maxLocal ) ? surplus : minLocal; + } +} + /* ** The following routines are implementations of the MemPage.xParseCell() ** method. @@ -65681,18 +67355,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); + } + } + } + } + } } } } @@ -65702,7 +67390,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. @@ -65739,7 +67427,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. @@ -65802,7 +67490,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; @@ -65810,7 +67498,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; } @@ -65902,6 +67590,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ unsigned char *src; /* Source of content */ int iCellFirst; /* First allowable cell index */ int iCellLast; /* Last possible cell index */ + int iCellStart; /* First cell offset in input */ assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt!=0 ); @@ -65962,6 +67651,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ cbrk = usableSize; iCellLast = usableSize - 4; + iCellStart = get2byte(&data[hdr+5]); for(i=0; iiCellLast ){ + if( pciCellLast ){ return SQLITE_CORRUPT_PAGE(pPage); } - assert( pc>=iCellFirst && pc<=iCellLast ); + assert( pc>=iCellStart && pc<=iCellLast ); size = pPage->xCellSize(pPage, &src[pc]); cbrk -= size; - if( cbrkusableSize ){ + if( cbrkusableSize ){ return SQLITE_CORRUPT_PAGE(pPage); } - assert( cbrk+size<=usableSize && cbrk>=iCellFirst ); + assert( cbrk+size<=usableSize && cbrk>=iCellStart ); testcase( cbrk+size==usableSize ); testcase( pc+size==usableSize ); put2byte(pAddr, cbrk); if( temp==0 ){ - int x; if( cbrk==pc ) continue; temp = sqlite3PagerTempSpace(pPage->pBt->pPager); - x = get2byte(&data[hdr+5]); - memcpy(&temp[x], &data[x], (cbrk+size) - x); + memcpy(&temp[iCellStart], &data[iCellStart], usableSize - iCellStart); src = temp; } memcpy(&data[cbrk], &src[pc], size); @@ -66138,7 +67826,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; @@ -66224,7 +67912,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 @@ -67088,7 +68776,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( ** do not change the pager-cache size. */ if( sqlite3BtreeSchema(p, 0, 0)==0 ){ - sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE); + sqlite3BtreeSetCacheSize(p, SQLITE_DEFAULT_CACHE_SIZE); } pFile = sqlite3PagerFile(pBt->pPager); @@ -67149,30 +68837,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; } /* @@ -67191,19 +68887,23 @@ static void freeTempSpace(BtShared *pBt){ */ SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){ BtShared *pBt = p->pBt; - BtCursor *pCur; /* Close all cursors opened via this handle. */ assert( sqlite3_mutex_held(p->db->mutex) ); sqlite3BtreeEnter(p); - pCur = pBt->pCursor; - while( pCur ){ - BtCursor *pTmp = pCur; - pCur = pCur->pNext; - if( pTmp->pBtree==p ){ - sqlite3BtreeCloseCursor(pTmp); + + /* Verify that no other cursors have this Btree open */ +#ifdef SQLITE_DEBUG + { + BtCursor *pCur = pBt->pCursor; + while( pCur ){ + BtCursor *pTmp = pCur; + pCur = pCur->pNext; + assert( pTmp->pBtree!=p ); + } } +#endif /* Rollback any active transaction and free the handle structure. ** The call to sqlite3BtreeRollback() drops any table-locks held by @@ -67355,6 +69055,7 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, ((pageSize-1)&pageSize)==0 ){ assert( (pageSize & 7)==0 ); assert( !pBt->pCursor ); + if( nReserve>32 && pageSize==512 ) pageSize = 1024; pBt->pageSize = (u32)pageSize; freeTempSpace(pBt); } @@ -67546,7 +69247,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 ); @@ -67558,7 +69258,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; @@ -67593,7 +69293,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 @@ -67665,9 +69365,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 @@ -68391,16 +70095,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); @@ -68408,6 +70114,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 */ @@ -68421,18 +70128,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; @@ -68483,7 +70214,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; @@ -68584,7 +70315,7 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ sqlite3BtreeLeave(p); return rc; } - p->iDataVersion--; /* Compensate for pPager->iDataVersion++; */ + p->iBDataVersion--; /* Compensate for pPager->iDataVersion++; */ pBt->inTransaction = TRANS_READ; btreeClearHasContent(pBt); } @@ -68670,7 +70401,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; } @@ -68882,10 +70613,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; @@ -68902,19 +70629,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( @@ -68994,7 +70727,14 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){ unlockBtreeIfUnused(pBt); sqlite3_free(pCur->aOverflow); sqlite3_free(pCur->pKey); - sqlite3BtreeLeave(pBtree); + if( (pBt->openFlags & BTREE_SINGLE) && pBt->pCursor==0 ){ + /* Since the BtShared is not sharable, there is no need to + ** worry about the missing sqlite3BtreeLeave() call here. */ + assert( pBtree->sharable==0 ); + sqlite3BtreeClose(pBtree); + }else{ + sqlite3BtreeLeave(pBtree); + } pCur->pBtree = 0; } return SQLITE_OK; @@ -69281,7 +71021,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); @@ -69468,7 +71210,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); } @@ -69530,7 +71271,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); @@ -69681,7 +71422,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 ){ @@ -69728,7 +71469,6 @@ static int moveToRoot(BtCursor *pCur){ 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 ){ @@ -69836,7 +71576,9 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ for(ii=0; iiiPage; ii++){ assert( pCur->aiIdx[ii]==pCur->apPage[ii]->nCell ); } - assert( pCur->ix==pCur->pPage->nCell-1 ); + assert( pCur->ix==pCur->pPage->nCell-1 || CORRUPT_DB ); + testcase( pCur->ix!=pCur->pPage->nCell-1 ); + /* ^-- dbsqlfuzz b92b72e4de80b5140c30ab71372ca719b8feb618 */ assert( pCur->pPage->leaf ); #endif *pRes = 0; @@ -69861,12 +71603,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 @@ -69879,39 +71617,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; @@ -69933,25 +71664,16 @@ 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; } } } } - 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 */ - } +#ifdef SQLITE_DEBUG + pCur->pBtree->nSeek++; /* Performance measurement during testing */ +#endif rc = moveToRoot(pCur); if( rc ){ @@ -69967,7 +71689,8 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( assert( pCur->eState==CURSOR_VALID ); assert( pCur->pPage->nCell > 0 ); assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey ); - assert( pCur->curIntKey || pIdxKey ); + assert( pCur->curIntKey ); + for(;;){ int lwr, upr, idx, c; Pgno chldPg; @@ -69981,133 +71704,236 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( ** 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==(pIdxKey==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; */ - 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); - } + 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; } + } + 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{ - 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; - } + 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>=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{ - 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); - sqlite3_free(pCellKey); + 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 ){ + 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 || pIdxKey ); + 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==(pIdxKey==0) ); + lwr = 0; + upr = pPage->nCell-1; + 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_index_finish; + } + pCellKey = sqlite3Malloc( nCell+nOverrun ); + if( pCellKey==0 ){ + rc = SQLITE_NOMEM_BKPT; + 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; + 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; } - 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 ); @@ -70116,9 +71942,8 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( 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{ @@ -70128,7 +71953,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( rc = moveToChild(pCur, chldPg); if( rc ) break; } -moveto_finish: +moveto_index_finish: pCur->info.nSize = 0; assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); return rc; @@ -70218,7 +72043,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ pPage = pCur->pPage; idx = ++pCur->ix; - if( !pPage->isInit ){ + if( !pPage->isInit || sqlite3FaultSim(412) ){ /* The only known way for this to happen is for there to be a ** recursive SQL function that does a DELETE operation as part of a ** SELECT which deletes content out from under an active cursor @@ -70229,16 +72054,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])); @@ -70599,7 +72414,7 @@ static int allocateBtreePage( iPage = get4byte(&aData[8+closest*4]); testcase( iPage==mxPage ); - if( iPage>mxPage ){ + if( iPage>mxPage || iPage<2 ){ rc = SQLITE_CORRUPT_PGNO(iTrunk); goto end_allocate_page; } @@ -70855,10 +72670,9 @@ static void freePage(MemPage *pPage, int *pRC){ } /* -** Free any overflow pages associated with the given Cell. Store -** size information about the cell in pInfo. +** Free the overflow pages associated with the given Cell. */ -static int clearCell( +static SQLITE_NOINLINE int clearCellOverflow( MemPage *pPage, /* The page that contains the Cell */ unsigned char *pCell, /* First byte of the Cell */ CellInfo *pInfo /* Size information about the cell */ @@ -70870,10 +72684,7 @@ static int clearCell( u32 ovflPageSize; assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - pPage->xParseCell(pPage, pCell, pInfo); - if( pInfo->nLocal==pInfo->nPayload ){ - return SQLITE_OK; /* No overflow pages. Return without doing anything */ - } + assert( pInfo->nLocal!=pInfo->nPayload ); testcase( pCell + pInfo->nSize == pPage->aDataEnd ); testcase( pCell + (pInfo->nSize-1) == pPage->aDataEnd ); if( pCell + pInfo->nSize > pPage->aDataEnd ){ @@ -70929,6 +72740,21 @@ static int clearCell( return SQLITE_OK; } +/* Call xParseCell to compute the size of a cell. If the cell contains +** overflow, then invoke cellClearOverflow to clear out that overflow. +** STore the result code (SQLITE_OK or some error code) in rc. +** +** Implemented as macro to force inlining for performance. +*/ +#define BTREE_CLEAR_CELL(rc, pPage, pCell, sInfo) \ + pPage->xParseCell(pPage, pCell, &sInfo); \ + if( sInfo.nLocal!=sInfo.nPayload ){ \ + rc = clearCellOverflow(pPage, pCell, &sInfo); \ + }else{ \ + rc = SQLITE_OK; \ + } + + /* ** Create the byte sequence used to represent a cell on page pPage ** and write that byte sequence into pCell[]. Overflow pages are @@ -71139,16 +72965,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; @@ -71440,7 +73274,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(kapCell[i]; u16 sz = pCArray->szCell[i]; assert( sz>0 ); - if( SQLITE_WITHIN(pCell,aData,pEnd) ){ + if( SQLITE_WITHIN(pCell,aData+j,pEnd) ){ if( ((uptr)(pCell+sz))>(uptr)pEnd ) return SQLITE_CORRUPT_BKPT; pCell = &pTmp[pCell - aData]; }else if( (uptr)(pCell+sz)>(uptr)pSrcEnd @@ -71464,9 +73298,8 @@ static int rebuildPage( put2byte(pCellptr, (pData - aData)); pCellptr += 2; if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT; - memcpy(pData, pCell, sz); + memmove(pData, pCell, sz); assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB ); - testcase( sz!=pPg->xCellSize(pPg,pCell) ) i++; if( i>=iEnd ) break; if( pCArray->ixNx[k]<=i ){ @@ -71605,7 +73438,9 @@ static int pageFreeArray( } pFree = pCell; szFree = sz; - if( pFree+sz>pEnd ) return 0; + if( pFree+sz>pEnd ){ + return 0; + } }else{ pFree = pCell; szFree += sz; @@ -71670,6 +73505,7 @@ static int editPage( pData = &aData[get2byteNotZero(&aData[hdr+5])]; if( pDatapPg->aDataEnd ) goto editpage_fail; /* Add cells to the start of the page */ if( iNewpBt; assert( sqlite3_mutex_held(pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); @@ -72086,7 +73921,9 @@ static int balance_nonroot( } pgno = get4byte(pRight); while( 1 ){ - rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0); + if( rc==SQLITE_OK ){ + rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0); + } if( rc ){ memset(apOld, 0, (i+1)*sizeof(MemPage*)); goto balance_cleanup; @@ -72098,6 +73935,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] ){ @@ -72125,12 +73963,10 @@ static int balance_nonroot( if( pBt->btsFlags & BTS_FAST_SECURE ){ int iOff; + /* If the following if() condition is not true, the db is corrupted. + ** The call to dropCell() below will detect this. */ iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData); - if( (iOff+szNew[i])>(int)pBt->usableSize ){ - rc = SQLITE_CORRUPT_BKPT; - memset(apOld, 0, (i+1)*sizeof(MemPage*)); - goto balance_cleanup; - }else{ + if( (iOff+szNew[i])<=(int)pBt->usableSize ){ memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]); apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData]; } @@ -72141,7 +73977,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; /* @@ -72258,7 +74093,7 @@ static int balance_nonroot( b.szCell[b.nCell] = b.szCell[b.nCell] - leafCorrection; if( !pOld->leaf ){ assert( leafCorrection==0 ); - assert( pOld->hdrOffset==0 ); + assert( pOld->hdrOffset==0 || CORRUPT_DB ); /* The right pointer of the child page pOld becomes the left ** pointer of the divider cell */ memcpy(b.apCell[b.nCell], &pOld->aData[8], 4); @@ -72424,6 +74259,11 @@ static int balance_nonroot( apOld[i] = 0; rc = sqlite3PagerWrite(pNew->pDbPage); nNew++; + if( sqlite3PagerPageRefcount(pNew->pDbPage)!=1+(i==(iParentIdx-nxDiv)) + && rc==SQLITE_OK + ){ + rc = SQLITE_CORRUPT_BKPT; + } if( rc ) goto balance_cleanup; }else{ assert( i>0 ); @@ -72460,7 +74300,7 @@ static int balance_nonroot( aPgOrder[i] = aPgno[i] = apNew[i]->pgno; aPgFlags[i] = apNew[i]->pDbPage->flags; for(j=0; jmaxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); + for(k=0; b.ixNx[k]<=i && ALWAYS(kpgno, &rc); if( rc!=SQLITE_OK ) goto balance_cleanup; assert( sqlite3PagerIswriteable(pParent->pDbPage) ); @@ -72834,7 +74681,7 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ ** Return SQLITE_CORRUPT if any cursor other than pCur is currently valid ** on the same B-tree as pCur. ** -** This can if a database is corrupt with two or more SQL tables +** This can occur if a database is corrupt with two or more SQL tables ** pointing to the same b-tree. If an insert occurs on one SQL table ** and causes a BEFORE TRIGGER to do a secondary insert on the other SQL ** table linked to the same b-tree. If the secondary insert causes a @@ -73063,7 +74910,7 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ do{ rc = btreeGetPage(pBt, ovflPgno, &pPage, 0); if( rc ) return rc; - if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 ){ + if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 || pPage->isInit ){ rc = SQLITE_CORRUPT_BKPT; }else{ if( iOffset+ovflPageSize<(u32)nTotal ){ @@ -73128,7 +74975,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( unsigned char *oldCell; unsigned char *newCell = 0; - assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND))==flags ); + 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 ); @@ -73146,7 +74994,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( ** 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( (pX->pKey==0)==(pCur->pKeyInfo==0) ); + assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) ); /* Save the positions of any other cursors open on this table. ** @@ -73162,13 +75010,23 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( if( pCur->curFlags & BTCF_Multiple ){ rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); if( rc ) return rc; + if( loc && pCur->iPage<0 ){ + /* This can only happen if the schema is corrupt such that there is more + ** than one table or index with the same root page as used by the cursor. + ** Which can only happen if the SQLITE_NoSchemaError flag was set when + ** the schema was loaded. This cannot be asserted though, as a user might + ** set the flag, load the schema, and then unset the flag. */ + return SQLITE_CORRUPT_BKPT; + } } if( pCur->pKeyInfo==0 ){ assert( pX->pKey==0 ); /* If this is an insert into a table b-tree, invalidate any incrblob ** cursors open on the row being replaced */ - invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0); + if( p->hasIncrblobCur ){ + invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0); + } /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing ** to a row with the same key as the new entry being inserted. @@ -73201,7 +75059,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{ @@ -73224,13 +75083,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; } @@ -73249,17 +75106,16 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( return btreeOverwriteCell(pCur, &x2); } } - } assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) || CORRUPT_DB ); pPage = pCur->pPage; - assert( pPage->intKey || pX->nKey>=0 ); + assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); assert( pPage->leaf || !pPage->intKey ); if( pPage->nFree<0 ){ - if( pCur->eState>CURSOR_INVALID ){ + if( NEVER(pCur->eState>CURSOR_INVALID) ){ rc = SQLITE_CORRUPT_BKPT; }else{ rc = btreeComputeFreeSpace(pPage); @@ -73273,14 +75129,31 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( assert( pPage->isInit ); newCell = pBt->pTmpSpace; assert( newCell!=0 ); - rc = fillInCell(pPage, newCell, pX, &szNew); + if( flags & BTREE_PREFORMAT ){ + rc = SQLITE_OK; + szNew = pBt->nPreformatSize; + if( szNew<4 ) szNew = 4; + if( ISAUTOVACUUM && szNew>pPage->maxLocal ){ + CellInfo info; + pPage->xParseCell(pPage, newCell, &info); + if( info.nPayload!=info.nLocal ){ + Pgno ovfl = get4byte(&newCell[szNew-4]); + ptrmapPut(pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc); + } + } + }else{ + rc = fillInCell(pPage, newCell, pX, &szNew); + } if( rc ) goto end_insert; assert( szNew==pPage->xCellSize(pPage, newCell) ); assert( szNew <= MX_CELL_SIZE(pBt) ); 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; @@ -73289,7 +75162,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( if( !pPage->leaf ){ memcpy(newCell, oldCell, 4); } - rc = clearCell(pPage, oldCell, &info); + BTREE_CLEAR_CELL(rc, pPage, oldCell, info); testcase( pCur->curFlags & BTCF_ValidOvfl ); invalidateOverflowCache(pCur); if( info.nSize==szNew && info.nLocal==info.nPayload @@ -73380,6 +75253,114 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( return rc; } +/* +** This function is used as part of copying the current row from cursor +** pSrc into cursor pDest. If the cursors are open on intkey tables, then +** parameter iKey is used as the rowid value when the record is copied +** into pDest. Otherwise, the record is copied verbatim. +** +** This function does not actually write the new value to cursor pDest. +** Instead, it creates and populates any required overflow pages and +** writes the data for the new cell into the BtShared.pTmpSpace buffer +** for the destination database. The size of the cell, in bytes, is left +** in BtShared.nPreformatSize. The caller completes the insertion by +** calling sqlite3BtreeInsert() with the BTREE_PREFORMAT flag specified. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ + int rc = SQLITE_OK; + BtShared *pBt = pDest->pBt; + u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ + const u8 *aIn; /* Pointer to next input buffer */ + u32 nIn; /* Size of input buffer aIn[] */ + u32 nRem; /* Bytes of data still to copy */ + + getCellInfo(pSrc); + aOut += putVarint32(aOut, pSrc->info.nPayload); + if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey); + nIn = pSrc->info.nLocal; + aIn = pSrc->info.pPayload; + if( aIn+nIn>pSrc->pPage->aDataEnd ){ + return SQLITE_CORRUPT_BKPT; + } + nRem = pSrc->info.nPayload; + if( nIn==nRem && nInpPage->maxLocal ){ + memcpy(aOut, aIn, nIn); + pBt->nPreformatSize = nIn + (aOut - pBt->pTmpSpace); + }else{ + Pager *pSrcPager = pSrc->pBt->pPager; + u8 *pPgnoOut = 0; + Pgno ovflIn = 0; + DbPage *pPageIn = 0; + MemPage *pPageOut = 0; + u32 nOut; /* Size of output buffer aOut[] */ + + nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); + pBt->nPreformatSize = nOut + (aOut - pBt->pTmpSpace); + if( nOutinfo.nPayload ){ + pPgnoOut = &aOut[nOut]; + pBt->nPreformatSize += 4; + } + + if( nRem>nIn ){ + if( aIn+nIn+4>pSrc->pPage->aDataEnd ){ + return SQLITE_CORRUPT_BKPT; + } + ovflIn = get4byte(&pSrc->info.pPayload[nIn]); + } + + do { + nRem -= nOut; + do{ + assert( nOut>0 ); + if( nIn>0 ){ + int nCopy = MIN(nOut, nIn); + memcpy(aOut, aIn, nCopy); + nOut -= nCopy; + nIn -= nCopy; + aOut += nCopy; + aIn += nCopy; + } + if( nOut>0 ){ + sqlite3PagerUnref(pPageIn); + pPageIn = 0; + rc = sqlite3PagerGet(pSrcPager, ovflIn, &pPageIn, PAGER_GET_READONLY); + if( rc==SQLITE_OK ){ + aIn = (const u8*)sqlite3PagerGetData(pPageIn); + ovflIn = get4byte(aIn); + aIn += 4; + nIn = pSrc->pBt->usableSize - 4; + } + } + }while( rc==SQLITE_OK && nOut>0 ); + + if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){ + Pgno pgnoNew; + MemPage *pNew = 0; + rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); + put4byte(pPgnoOut, pgnoNew); + if( ISAUTOVACUUM && pPageOut ){ + ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc); + } + releasePage(pPageOut); + pPageOut = pNew; + if( pPageOut ){ + pPgnoOut = pPageOut->aData; + put4byte(pPgnoOut, 0); + aOut = &pPgnoOut[4]; + nOut = MIN(pBt->usableSize - 4, nRem); + } + } + }while( nRem>0 && rc==SQLITE_OK ); + + releasePage(pPageOut); + sqlite3PagerUnref(pPageIn); + } + + return rc; +} + /* ** Delete the entry that the cursor is pointing to. ** @@ -73400,14 +75381,13 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( 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 ); @@ -73418,25 +75398,39 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); if( pCur->eState==CURSOR_REQUIRESEEK ){ rc = btreeRestoreCursorPosition(pCur); - if( rc ) return rc; + assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); + if( rc || pCur->eState!=CURSOR_VALID ) return rc; } - assert( pCur->eState==CURSOR_VALID ); + assert( CORRUPT_DB || 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) @@ -73447,7 +75441,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ rc = saveCursorKey(pCur); if( rc ) return rc; }else{ - bSkipnext = 1; + bPreserve = 2; } } @@ -73473,7 +75467,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ /* If this is a delete operation to remove a row from a table b-tree, ** invalidate any incrblob cursors open on the row being deleted. */ - if( pCur->pKeyInfo==0 ){ + if( pCur->pKeyInfo==0 && p->hasIncrblobCur ){ invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0); } @@ -73482,7 +75476,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ ** itself from within the page. */ rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; - rc = clearCell(pPage, pCell, &info); + BTREE_CLEAR_CELL(rc, pPage, pCell, info); dropCell(pPage, iCellIdx, info.nSize, &rc); if( rc ) return rc; @@ -73547,8 +75541,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; @@ -73742,7 +75736,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; @@ -73757,11 +75751,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); @@ -73769,14 +75764,15 @@ static int clearDatabasePage( rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange); if( rc ) goto cleardatabasepage_out; } - rc = clearCell(pPage, pCell, &info); + BTREE_CLEAR_CELL(rc, pPage, pCell, info); if( rc ) goto cleardatabasepage_out; } if( !pPage->leaf ){ rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange); if( rc ) goto cleardatabasepage_out; - }else if( pnChange ){ - assert( pPage->intKey || CORRUPT_DB ); + if( pPage->intKey ) pnChange = 0; + } + if( pnChange ){ testcase( !pPage->intKey ); *pnChange += pPage->nCell; } @@ -73787,7 +75783,6 @@ static int clearDatabasePage( } cleardatabasepage_out: - pPage->bBusy = 0; releasePage(pPage); return rc; } @@ -73801,11 +75796,10 @@ static int clearDatabasePage( ** read cursors on the table. Open write cursors are moved to the ** root of the table. ** -** If pnChange is not NULL, then table iTable must be an intkey table. The -** integer value pointed to by pnChange is incremented by the number of -** entries in the table. +** 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); @@ -73817,7 +75811,9 @@ SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ /* Invalidate all incrblob cursors open on table iTable (assuming iTable ** is the root of a table b-tree - if it is not, the following call is ** a no-op). */ - invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1); + if( p->hasIncrblobCur ){ + invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1); + } rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); } sqlite3BtreeLeave(p); @@ -73865,10 +75861,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; } @@ -73977,7 +75973,7 @@ SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ assert( idx>=0 && idx<=15 ); if( idx==BTREE_DATA_VERSION ){ - *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iDataVersion; + *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iBDataVersion; }else{ *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]); } @@ -74793,11 +76789,12 @@ SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *p){ } /* -** Return non-zero if a transaction is active. +** Return one of SQLITE_TXN_NONE, SQLITE_TXN_READ, or SQLITE_TXN_WRITE +** to describe the current transaction state of Btree p. */ -SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeTxnState(Btree *p){ assert( p==0 || sqlite3_mutex_held(p->db->mutex) ); - return (p && (p->inTrans==TRANS_WRITE)); + return p ? p->inTrans : 0; } #ifndef SQLITE_OMIT_WAL @@ -74826,14 +76823,8 @@ SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int * #endif /* -** Return non-zero if a read (or write) transaction is active. +** Return true if there is currently a backup running on Btree p. */ -SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree *p){ - assert( p ); - assert( sqlite3_mutex_held(p->db->mutex) ); - return p->inTrans!=TRANS_NONE; -} - SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){ assert( p ); assert( sqlite3_mutex_held(p->db->mutex) ); @@ -75141,14 +77132,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; } @@ -75179,7 +77169,7 @@ static int setDestPgsz(sqlite3_backup *p){ ** message in database handle db. */ static int checkReadTransaction(sqlite3 *db, Btree *p){ - if( sqlite3BtreeIsInReadTrans(p) ){ + if( sqlite3BtreeTxnState(p)!=SQLITE_TXN_NONE ){ sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use"); return SQLITE_ERROR; } @@ -75410,7 +77400,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ ** one now. If a transaction is opened here, then it will be closed ** before this function exits. */ - if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){ + if( rc==SQLITE_OK && SQLITE_TXN_NONE==sqlite3BtreeTxnState(p->pSrc) ){ rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0); bCloseTrans = 1; } @@ -75782,7 +77772,7 @@ SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ sqlite3BtreeEnter(pTo); sqlite3BtreeEnter(pFrom); - assert( sqlite3BtreeIsInTrans(pTo) ); + assert( sqlite3BtreeTxnState(pTo)==SQLITE_TXN_WRITE ); pFd = sqlite3PagerFile(sqlite3BtreePager(pTo)); if( pFd->pMethods ){ i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom); @@ -75818,7 +77808,7 @@ SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ sqlite3PagerClearCache(sqlite3BtreePager(b.pDest)); } - assert( sqlite3BtreeIsInTrans(pTo)==0 ); + assert( sqlite3BtreeTxnState(pTo)!=SQLITE_TXN_WRITE ); copy_finished: sqlite3BtreeLeave(pFrom); sqlite3BtreeLeave(pTo); @@ -75905,7 +77895,9 @@ SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){ /* The szMalloc field holds the correct memory allocation size */ assert( p->szMalloc==0 - || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) ); + || (p->flags==MEM_Undefined + && p->szMalloc<=sqlite3DbMallocSize(p->db,p->zMalloc)) + || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc)); /* If p holds a string or blob, the Mem.z must point to exactly ** one of the following: @@ -76028,6 +78020,7 @@ 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 ); @@ -76069,7 +78062,9 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPre testcase( bPreserve && pMem->z==0 ); assert( pMem->szMalloc==0 - || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) ); + || (pMem->flags==MEM_Undefined + && pMem->szMalloc<=sqlite3DbMallocSize(pMem->db,pMem->zMalloc)) + || pMem->szMalloc==sqlite3DbMallocSize(pMem->db,pMem->zMalloc)); if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){ if( pMem->db ){ pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); @@ -76158,6 +78153,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 ){ @@ -76182,6 +78178,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) ); @@ -76197,6 +78194,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; @@ -76209,6 +78208,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 ); @@ -76236,6 +78236,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)) ); @@ -76271,6 +78272,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) ); @@ -76414,13 +78416,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; @@ -76449,6 +78452,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 ){ @@ -76481,6 +78485,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) ); @@ -76508,6 +78513,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) ); @@ -76522,6 +78528,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) ); @@ -76555,6 +78562,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 ); @@ -76664,6 +78672,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; @@ -76673,6 +78682,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 @@ -76898,14 +78922,15 @@ SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( Mem *pMem, /* Memory cell to set to string value */ const char *z, /* String pointer */ - int n, /* Bytes in string, or negative */ + i64 n, /* Bytes in string, or negative */ u8 enc, /* Encoding of z. 0 for BLOBs */ void (*xDel)(void*) /* Destructor function */ ){ - int nByte = n; /* New value for pMem->n */ + i64 nByte = n; /* New value for pMem->n */ 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) ); @@ -76924,7 +78949,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( if( nByte<0 ){ assert( enc!=0 ); if( enc==SQLITE_UTF8 ){ - nByte = 0x7fffffff & (int)strlen(z); + nByte = strlen(z); }else{ for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} } @@ -76936,7 +78961,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( ** management (one of MEM_Dyn or MEM_Static). */ if( xDel==SQLITE_TRANSIENT ){ - u32 nAlloc = nByte; + i64 nAlloc = nByte; if( flags&MEM_Term ){ nAlloc += (enc==SQLITE_UTF8?1:2); } @@ -76962,7 +78987,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( } } - pMem->n = nByte; + pMem->n = (int)(nByte & 0x7fffffff); pMem->flags = flags; if( enc ){ pMem->enc = enc; @@ -76982,7 +79007,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( #endif if( nByte>iLimit ){ - return SQLITE_TOOBIG; + return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); } return SQLITE_OK; @@ -77214,7 +79239,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 */ @@ -77231,8 +79256,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 @@ -77308,7 +79335,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 */ @@ -77323,11 +79350,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 @@ -77336,7 +79359,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 ){ @@ -77409,6 +79434,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); @@ -77426,6 +79452,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; @@ -77438,7 +79465,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); @@ -77463,7 +79490,7 @@ static int valueFromExpr( */ 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 */ @@ -77773,7 +79800,7 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){ p->pNext = db->pVdbe; p->pPrev = 0; db->pVdbe = p; - p->magic = VDBE_MAGIC_INIT; + p->iVdbeMagic = VDBE_MAGIC_INIT; p->pParse = pParse; pParse->pVdbe = p; assert( pParse->aLabel==0 ); @@ -77974,13 +80001,15 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ VdbeOp *pOp; i = p->nOp; - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); assert( op>=0 && op<0xff ); 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; @@ -78209,10 +80238,12 @@ SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){ ** The zWhere string must have been obtained from sqlite3_malloc(). ** This routine will take ownership of the allocated memory. */ -SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){ +SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere, u16 p5){ int j; sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); + sqlite3VdbeChangeP5(p, p5); for(j=0; jdb->nDb; j++) sqlite3VdbeUsesBtree(p, j); + sqlite3MayAbort(p->pParse); } /* @@ -78302,7 +80333,7 @@ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){ Parse *p = v->pParse; int j = ADDR(x); - assert( v->magic==VDBE_MAGIC_INIT ); + assert( v->iVdbeMagic==VDBE_MAGIC_INIT ); assert( j<-p->nLabel ); assert( j>=0 ); #ifdef SQLITE_DEBUG @@ -78441,7 +80472,7 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename || opcode==OP_VDestroy || opcode==OP_VCreate - || (opcode==OP_ParseSchema && pOp->p4.z==0) + || opcode==OP_ParseSchema || ((opcode==OP_Halt || opcode==OP_HaltIfNull) && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort)) ){ @@ -78627,7 +80658,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ ** Return the address of the next instruction to be inserted. */ SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){ - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); return p->nOp; } @@ -78712,7 +80743,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList( int i; VdbeOp *pOut, *pFirst; assert( nOp>0 ); - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){ return 0; } @@ -79036,7 +81067,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int sqlite3 *db; assert( p!=0 ); db = p->db; - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); assert( p->aOp!=0 || db->mallocFailed ); if( db->mallocFailed ){ if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4); @@ -79112,8 +81143,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); @@ -79165,7 +81195,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ /* C89 specifies that the constant "dummy" will be initialized to all ** zeros, which is correct. MSVC generates a warning, nevertheless. */ static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); if( addr<0 ){ addr = p->nOp - 1; } @@ -79221,13 +81251,9 @@ 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 ){ - if( pOp->p5 & SQLITE_STOREP2 ){ - sqlite3_snprintf(sizeof(zAlt), zAlt, "r[P2] = (%s)", zSynopsis+3); - }else{ - sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3); - } + sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3); zSynopsis = zAlt; } for(ii=0; (c = zSynopsis[ii])!=0; ii++){ @@ -79259,7 +81285,7 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayComment( sqlite3_str_appendf(&x, "%d", v1); }else if( pCtx->argc>1 ){ sqlite3_str_appendf(&x, "%d..%d", v1, v1+pCtx->argc-1); - }else{ + }else if( x.accError==0 ){ assert( x.nChar>2 ); x.nChar -= 2; ii++; @@ -79298,6 +81324,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: @@ -79400,7 +81427,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; @@ -79644,8 +81671,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); @@ -79850,7 +81877,7 @@ SQLITE_PRIVATE int sqlite3VdbeList( Op *pOp; /* Current opcode */ assert( p->explain ); - assert( p->magic==VDBE_MAGIC_RUN ); + assert( p->iVdbeMagic==VDBE_MAGIC_RUN ); assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM ); /* Even though this opcode does not use dynamic strings for @@ -80030,14 +82057,14 @@ SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ int i; #endif assert( p!=0 ); - assert( p->magic==VDBE_MAGIC_INIT || p->magic==VDBE_MAGIC_RESET ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT || p->iVdbeMagic==VDBE_MAGIC_RESET ); /* There should be at least one opcode. */ assert( p->nOp>0 ); /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ - p->magic = VDBE_MAGIC_RUN; + p->iVdbeMagic = VDBE_MAGIC_RUN; #ifdef SQLITE_DEBUG for(i=0; inMem; i++){ @@ -80093,8 +82120,10 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( assert( p!=0 ); assert( p->nOp>0 ); assert( pParse!=0 ); - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); assert( pParse==p->pParse ); + p->pVList = pParse->pVList; + pParse->pVList = 0; db = p->db; assert( db->mallocFailed==0 ); nVar = pParse->nVar; @@ -80179,8 +82208,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( } } - p->pVList = pParse->pVList; - pParse->pVList = 0; if( db->mallocFailed ){ p->nVar = 0; p->nCursor = 0; @@ -80207,21 +82234,14 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ if( pCx==0 ){ return; } - assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE ); switch( pCx->eCurType ){ case CURTYPE_SORTER: { sqlite3VdbeSorterClose(p->db, pCx); break; } case CURTYPE_BTREE: { - if( pCx->isEphemeral ){ - if( pCx->pBtx ) sqlite3BtreeClose(pCx->pBtx); - /* The pCx->pCursor will be close automatically, if it exists, by - ** the call above. */ - }else{ - assert( pCx->uc.pCursor!=0 ); - sqlite3BtreeCloseCursor(pCx->uc.pCursor); - } + assert( pCx->uc.pCursor!=0 ); + sqlite3BtreeCloseCursor(pCx->uc.pCursor); break; } #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -80401,7 +82421,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ */ for(i=0; rc==SQLITE_OK && inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( sqlite3BtreeIsInTrans(pBt) ){ + if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){ /* Whether or not a database might need a super-journal depends upon ** its journal mode (among other things). This matrix determines which ** journal modes use a super-journal and which do not */ @@ -80536,7 +82556,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ */ for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( sqlite3BtreeIsInTrans(pBt) ){ + if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){ char const *zFile = sqlite3BtreeGetJournalname(pBt); if( zFile==0 ){ continue; /* Ignore TEMP and :memory: databases */ @@ -80750,9 +82770,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 @@ -80778,7 +82798,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ ** one, or the complete transaction if there is no statement transaction. */ - if( p->magic!=VDBE_MAGIC_RUN ){ + if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){ return SQLITE_OK; } if( db->mallocFailed ){ @@ -80798,9 +82818,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 @@ -80852,6 +82878,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 @@ -80936,7 +82965,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ assert( db->nVdbeRead>=db->nVdbeWrite ); assert( db->nVdbeWrite>=0 ); } - p->magic = VDBE_MAGIC_HALT; + p->iVdbeMagic = VDBE_MAGIC_HALT; checkActiveVdbeCnt(db); if( db->mallocFailed ){ p->rc = SQLITE_NOMEM_BKPT; @@ -80985,6 +83014,7 @@ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){ sqlite3ValueSetNull(db->pErr); } db->errCode = rc; + db->errByteOffset = -1; return rc; } @@ -81109,7 +83139,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ } } #endif - p->magic = VDBE_MAGIC_RESET; + p->iVdbeMagic = VDBE_MAGIC_RESET; return p->rc & db->errMask; } @@ -81119,7 +83149,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ */ SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; - if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ + if( p->iVdbeMagic==VDBE_MAGIC_RUN || p->iVdbeMagic==VDBE_MAGIC_HALT ){ rc = sqlite3VdbeReset(p); assert( (rc & p->db->errMask)==rc ); } @@ -81180,7 +83210,7 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); sqlite3DbFree(db, pSub); } - if( p->magic!=VDBE_MAGIC_INIT ){ + if( p->iVdbeMagic!=VDBE_MAGIC_INIT ){ releaseMemArray(p->aVar, p->nVar); sqlite3DbFree(db, p->pVList); sqlite3DbFree(db, p->pFree); @@ -81228,7 +83258,7 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ if( p->pNext ){ p->pNext->pPrev = p->pPrev; } - p->magic = VDBE_MAGIC_DEAD; + p->iVdbeMagic = VDBE_MAGIC_DEAD; p->db = 0; sqlite3DbFreeNN(db, p); } @@ -81246,7 +83276,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 @@ -81305,7 +83335,8 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){ assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); if( p->deferredMoveto ){ u32 iMap; - if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 && !p->nullRow ){ + assert( !p->isEphemeral ); + if( p->ub.aAltMap && (iMap = p->ub.aAltMap[1+*piCol])>0 && !p->nullRow ){ *pp = p->pAltCursor; *piCol = iMap - 1; return SQLITE_OK; @@ -81583,14 +83614,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 */ @@ -81624,9 +83655,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 */ @@ -81637,13 +83667,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 @@ -81651,7 +83681,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 @@ -81659,7 +83689,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 @@ -81667,7 +83697,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 @@ -81679,7 +83709,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 @@ -81687,13 +83717,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 */ @@ -81701,7 +83732,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 @@ -81712,10 +83743,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 @@ -81778,7 +83809,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; } @@ -81862,7 +83894,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 */ @@ -82029,12 +84062,15 @@ 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( xr ); + testcase( x==r ); if( xr ) return +1; - return 0; + if( x>r ) return +1; /*NO_TEST*/ /* work around bugs in gcov */ + return 0; /*NO_TEST*/ /* work around bugs in gcov */ }else{ i64 y; double s; @@ -82663,7 +84699,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ /* The index entry must begin with a header size */ getVarint32NR((u8*)m.z, szHdr); testcase( szHdr==3 ); - testcase( szHdr==m.n ); + testcase( szHdr==(u32)m.n ); testcase( szHdr>0x7fffffff ); assert( m.n>=0 ); if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){ @@ -82750,7 +84786,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; @@ -82930,7 +84966,8 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( const char *zDb, /* Database name */ Table *pTab, /* Modified table */ i64 iKey1, /* Initial key value */ - int iReg /* Register for new.* record */ + int iReg, /* Register for new.* record */ + int iBlobWrite ){ sqlite3 *db = v->db; i64 iKey2; @@ -82951,6 +84988,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) ); @@ -82966,6 +85005,7 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( preupdate.iKey1 = iKey1; preupdate.iKey2 = iKey2; preupdate.pTab = pTab; + preupdate.iBlobWrite = iBlobWrite; db->pPreUpdate = &preupdate; db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); @@ -83349,8 +85389,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. @@ -83362,8 +85402,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( @@ -83379,7 +85427,7 @@ static int invokeValueDestructor( }else{ xDel((void*)p); } - if( pCtx ) sqlite3_result_error_toobig(pCtx); + sqlite3_result_error_toobig(pCtx); return SQLITE_TOOBIG; } SQLITE_API void sqlite3_result_blob( @@ -83520,8 +85568,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; @@ -83604,7 +85656,7 @@ static int sqlite3Step(Vdbe *p){ int rc; assert(p); - if( p->magic!=VDBE_MAGIC_RUN ){ + if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){ /* We used to require that sqlite3_reset() be called before retrying ** sqlite3_step() after any error or after SQLITE_DONE. But beginning ** with version 3.7.0, we changed this so that sqlite3_reset() would @@ -83821,6 +85873,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 @@ -84320,7 +86436,7 @@ static int vdbeUnbind(Vdbe *p, int i){ return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(p->db->mutex); - if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){ + if( p->iVdbeMagic!=VDBE_MAGIC_RUN || p->pc>=0 ){ sqlite3Error(p->db, SQLITE_MISUSE); sqlite3_mutex_leave(p->db->mutex); sqlite3_log(SQLITE_MISUSE, @@ -84361,7 +86477,7 @@ static int bindText( sqlite3_stmt *pStmt, /* The statement to bind against */ int i, /* Index of the parameter to bind */ const void *zData, /* Pointer to the data to be bound */ - int nData, /* Number of bytes of data to be bound */ + i64 nData, /* Number of bytes of data to be bound */ void (*xDel)(void*), /* Destructor for the data */ u8 encoding /* Encoding for the data */ ){ @@ -84413,11 +86529,7 @@ SQLITE_API int sqlite3_bind_blob64( void (*xDel)(void*) ){ assert( xDel!=SQLITE_DYNAMIC ); - if( nData>0x7fffffff ){ - return invokeValueDestructor(zData, xDel, 0); - }else{ - return bindText(pStmt, i, zData, (int)nData, xDel, 0); - } + return bindText(pStmt, i, zData, nData, xDel, 0); } SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ int rc; @@ -84487,12 +86599,8 @@ SQLITE_API int sqlite3_bind_text64( unsigned char enc ){ assert( xDel!=SQLITE_DYNAMIC ); - if( nData>0x7fffffff ){ - return invokeValueDestructor(zData, xDel, 0); - }else{ - if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; - return bindText(pStmt, i, zData, (int)nData, xDel, enc); - } + if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; + return bindText(pStmt, i, zData, nData, xDel, enc); } #ifndef SQLITE_OMIT_UTF16 SQLITE_API int sqlite3_bind_text16( @@ -84513,7 +86621,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: { @@ -84541,7 +86652,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; @@ -84674,7 +86789,7 @@ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ */ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ Vdbe *v = (Vdbe*)pStmt; - return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0; + return v!=0 && v->iVdbeMagic==VDBE_MAGIC_RUN && v->pc>=0; } /* @@ -84829,6 +86944,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; @@ -84892,6 +87008,17 @@ SQLITE_API int sqlite3_preupdate_depth(sqlite3 *db){ } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** This function is designed to be called from within a pre-update callback +** only. +*/ +SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *db){ + PreUpdate *p = db->pPreUpdate; + return (p ? p->iBlobWrite : -1); +} +#endif + #ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** This function is called from within a pre-update callback to retrieve @@ -85125,11 +87252,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; @@ -85166,7 +87291,7 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( assert( idx>0 ); } zRawSql += nToken; - nextIndex = idx + 1; + nextIndex = MAX(idx + 1, nextIndex); assert( idx>0 && idx<=p->nVar ); pVar = &p->aVar[idx-1]; if( pVar->flags & MEM_Null ){ @@ -85479,7 +87604,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 @@ -85510,26 +87634,38 @@ static VdbeCursor *allocateCursor( assert( iCur>=0 && iCurnCursor ); if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ - /* Before calling sqlite3VdbeFreeCursor(), ensure the isEphemeral flag - ** is clear. Otherwise, if this is an ephemeral cursor created by - ** OP_OpenDup, the cursor will not be closed and will still be part - ** of a BtShared.pCursor list. */ - if( p->apCsr[iCur]->pBtx==0 ) p->apCsr[iCur]->isEphemeral = 0; sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; } - if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ - p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; - memset(pCx, 0, offsetof(VdbeCursor,pAltCursor)); - pCx->eCurType = eCurType; - pCx->iDb = iDb; - pCx->nField = nField; - pCx->aOffset = &pCx->aType[nField]; - if( eCurType==CURTYPE_BTREE ){ - pCx->uc.pCursor = (BtCursor*) - &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; - sqlite3BtreeCursorZero(pCx->uc.pCursor); + + /* There used to be a call to sqlite3VdbeMemClearAndResize() to make sure + ** the pMem used to hold space for the cursor has enough storage available + ** in pMem->zMalloc. But for the special case of the aMem[] entries used + ** to hold cursors, it is faster to in-line the logic. */ + assert( pMem->flags==MEM_Undefined ); + assert( (pMem->flags & MEM_Dyn)==0 ); + assert( pMem->szMalloc==0 || pMem->z==pMem->zMalloc ); + if( pMem->szMallocszMalloc>0 ){ + sqlite3DbFreeNN(pMem->db, pMem->zMalloc); + } + pMem->z = pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, nByte); + if( pMem->zMalloc==0 ){ + pMem->szMalloc = 0; + return 0; } + pMem->szMalloc = nByte; + } + + p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->zMalloc; + memset(pCx, 0, offsetof(VdbeCursor,pAltCursor)); + pCx->eCurType = eCurType; + pCx->nField = nField; + pCx->aOffset = &pCx->aType[nField]; + if( eCurType==CURTYPE_BTREE ){ + pCx->uc.pCursor = (BtCursor*) + &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; + sqlite3BtreeCursorZero(pCx->uc.pCursor); } return pCx; } @@ -85676,7 +87812,10 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ sqlite3_int64 ix; assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ); assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); - ExpandBlob(pMem); + if( ExpandBlob(pMem) ){ + pMem->u.i = 0; + return MEM_Int; + } rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); if( rc<=0 ){ if( rc==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){ @@ -85814,6 +87953,11 @@ static void registerTrace(int iReg, Mem *p){ printf("\n"); sqlite3VdbeCheckMemInvariants(p); } +/**/ void sqlite3PrintMem(Mem *pMem){ + memTracePrint(pMem); + printf("\n"); + fflush(stdout); +} #endif #ifdef SQLITE_DEBUG @@ -85841,96 +87985,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 @@ -85977,6 +88032,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. @@ -86012,7 +88103,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec( #endif /*** INSERT STACK UNION HERE ***/ - assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ + assert( p->iVdbeMagic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ sqlite3VdbeEnter(p); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ @@ -86618,12 +88709,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; @@ -86772,6 +88869,24 @@ case OP_IntCopy: { /* out2 */ break; } +/* Opcode: FkCheck * * * * * +** +** 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. +** +** 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_FkCheck: { + if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){ + goto abort_due_to_error; + } + break; +} + /* Opcode: ResultRow P1 P2 * * * ** Synopsis: output=r[P1@P2] ** @@ -86785,37 +88900,9 @@ case OP_ResultRow: { Mem *pMem; int i; assert( p->nResColumn==pOp->p2 ); - assert( pOp->p1>0 ); + assert( pOp->p1>0 || CORRUPT_DB ); assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); - /* If this statement has violated immediate foreign key constraints, do - ** not return the number of rows modified. And do not RELEASE the statement - ** transaction. It needs to be rolled back. */ - if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ - assert( db->flags&SQLITE_CountRows ); - assert( p->usesStmtJournal ); - goto abort_due_to_error; - } - - /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then - ** DML statements invoke this opcode to return the number of rows - ** modified to the user. This is the only way that a VM that - ** opens a statement transaction may invoke this opcode. - ** - ** In case this is such a statement, close any statement transaction - ** opened by this VM before returning control to the user. This is to - ** ensure that statement-transactions are always nested, not overlapping. - ** If the open statement-transaction is not closed here, then the user - ** may step another VM that opens its own statement transaction. This - ** may lead to overlapping statement transactions. - ** - ** The statement transaction is never a top-level transaction. Hence - ** the RELEASE call below can never fail. - */ - assert( p->iStatement==0 || db->flags&SQLITE_CountRows ); - rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE); - assert( rc==SQLITE_OK ); - /* Invalidate all ephemeral cursor row caches */ p->cacheCtr = (p->cacheCtr + 2)|1; @@ -87255,8 +89342,7 @@ case OP_Cast: { /* in1 */ ** Synopsis: IF r[P3]==r[P1] ** ** Compare the values in register P1 and P3. If reg(P3)==reg(P1) then -** jump to address P2. Or if the SQLITE_STOREP2 flag is set in P5, then -** store the result of comparison in register P2. +** jump to address P2. ** ** The SQLITE_AFF_MASK portion of P5 must be an affinity character - ** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made @@ -87282,9 +89368,8 @@ case OP_Cast: { /* in1 */ ** If neither operand is NULL the result is the same as it would be if ** the SQLITE_NULLEQ flag were omitted from P5. ** -** If both SQLITE_STOREP2 and SQLITE_KEEPNULL flags are set then the -** content of r[P2] is only changed if the new value is NULL or 0 (false). -** In other words, a prior r[P2] value will not be overwritten by 1 (true). +** This opcode saves the result of comparison for use by the new +** OP_Jump opcode. */ /* Opcode: Ne P1 P2 P3 P4 P5 ** Synopsis: IF r[P3]!=r[P1] @@ -87292,17 +89377,12 @@ case OP_Cast: { /* in1 */ ** This works just like the Eq opcode except that the jump is taken if ** the operands in registers P1 and P3 are not equal. See the Eq opcode for ** additional information. -** -** If both SQLITE_STOREP2 and SQLITE_KEEPNULL flags are set then the -** content of r[P2] is only changed if the new value is NULL or 1 (true). -** In other words, a prior r[P2] value will not be overwritten by 0 (false). */ /* Opcode: Lt P1 P2 P3 P4 P5 ** Synopsis: IF r[P3]p3]; flags1 = pIn1->flags; flags3 = pIn3->flags; + if( (flags1 & flags3 & MEM_Int)!=0 ){ + assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT || CORRUPT_DB ); + /* Common case of comparison of two integers */ + if( pIn3->u.i > pIn1->u.i ){ + iCompare = +1; + if( sqlite3aGTb[pOp->opcode] ){ + VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); + goto jump_to_p2; + } + }else if( pIn3->u.i < pIn1->u.i ){ + iCompare = -1; + if( sqlite3aLTb[pOp->opcode] ){ + VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); + goto jump_to_p2; + } + }else{ + iCompare = 0; + if( sqlite3aEQb[pOp->opcode] ){ + VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); + goto jump_to_p2; + } + } + VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3); + break; + } if( (flags1 | flags3)&MEM_Null ){ /* One or both operands are NULL */ if( pOp->p5 & SQLITE_NULLEQ ){ @@ -87384,22 +89492,16 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ ** then the result is always NULL. ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. */ - if( pOp->p5 & SQLITE_STOREP2 ){ - pOut = &aMem[pOp->p2]; - iCompare = 1; /* Operands are not equal */ - memAboutToChange(p, pOut); - MemSetTypeFlag(pOut, MEM_Null); - REGISTER_TRACE(pOp->p2, pOut); - }else{ - VdbeBranchTaken(2,3); - if( pOp->p5 & SQLITE_JUMPIFNULL ){ - goto jump_to_p2; - } + iCompare = 1; /* Operands are not equal */ + VdbeBranchTaken(2,3); + if( pOp->p5 & SQLITE_JUMPIFNULL ){ + goto jump_to_p2; } break; } }else{ - /* Neither operand is NULL. Do a comparison. */ + /* Neither operand is NULL and we couldn't do the special high-speed + ** integer comparison case. So do a general-case comparison. */ affinity = pOp->p5 & SQLITE_AFF_MASK; if( affinity>=SQLITE_AFF_NUMERIC ){ if( (flags1 | flags3)&MEM_Str ){ @@ -87412,14 +89514,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ applyNumericAffinity(pIn3,0); } } - /* Handle the common case of integer comparison here, as an - ** optimization, to avoid a call to sqlite3MemCompare() */ - if( (pIn1->flags & pIn3->flags & MEM_Int)!=0 ){ - if( pIn3->u.i > pIn1->u.i ){ res = +1; goto compare_op; } - if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; } - res = 0; - goto compare_op; - } }else if( affinity==SQLITE_AFF_TEXT ){ if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn1->flags & MEM_Int ); @@ -87428,7 +89522,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 ); @@ -87442,7 +89536,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); } -compare_op: + /* At this point, res is negative, zero, or positive if reg[P1] is ** less than, equal to, or greater than reg[P3], respectively. Compute ** the answer to this operator in res2, depending on what the comparison @@ -87451,16 +89545,14 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ ** order: NE, EQ, GT, LE, LT, GE */ assert( OP_Eq==OP_Ne+1 ); assert( OP_Gt==OP_Ne+2 ); assert( OP_Le==OP_Ne+3 ); assert( OP_Lt==OP_Ne+4 ); assert( OP_Ge==OP_Ne+5 ); - if( res<0 ){ /* ne, eq, gt, le, lt, ge */ - static const unsigned char aLTb[] = { 1, 0, 0, 1, 1, 0 }; - res2 = aLTb[pOp->opcode - OP_Ne]; + if( res<0 ){ + res2 = sqlite3aLTb[pOp->opcode]; }else if( res==0 ){ - static const unsigned char aEQb[] = { 0, 1, 0, 1, 0, 1 }; - res2 = aEQb[pOp->opcode - OP_Ne]; + res2 = sqlite3aEQb[pOp->opcode]; }else{ - static const unsigned char aGTb[] = { 1, 0, 1, 0, 0, 1 }; - res2 = aGTb[pOp->opcode - OP_Ne]; + res2 = sqlite3aGTb[pOp->opcode]; } + iCompare = res; /* Undo any changes made by applyAffinity() to the input registers. */ assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) ); @@ -87468,67 +89560,39 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); pIn1->flags = flags1; - if( pOp->p5 & SQLITE_STOREP2 ){ - pOut = &aMem[pOp->p2]; - iCompare = res; - if( (pOp->p5 & SQLITE_KEEPNULL)!=0 ){ - /* The KEEPNULL flag prevents OP_Eq from overwriting a NULL with 1 - ** and prevents OP_Ne from overwriting NULL with 0. This flag - ** is only used in contexts where either: - ** (1) op==OP_Eq && (r[P2]==NULL || r[P2]==0) - ** (2) op==OP_Ne && (r[P2]==NULL || r[P2]==1) - ** Therefore it is not necessary to check the content of r[P2] for - ** NULL. */ - assert( pOp->opcode==OP_Ne || pOp->opcode==OP_Eq ); - assert( res2==0 || res2==1 ); - testcase( res2==0 && pOp->opcode==OP_Eq ); - testcase( res2==1 && pOp->opcode==OP_Eq ); - testcase( res2==0 && pOp->opcode==OP_Ne ); - testcase( res2==1 && pOp->opcode==OP_Ne ); - if( (pOp->opcode==OP_Eq)==res2 ) break; - } - memAboutToChange(p, pOut); - MemSetTypeFlag(pOut, MEM_Int); - pOut->u.i = res2; - REGISTER_TRACE(pOp->p2, pOut); - }else{ - VdbeBranchTaken(res2!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3); - if( res2 ){ - goto jump_to_p2; - } + VdbeBranchTaken(res2!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3); + if( res2 ){ + goto jump_to_p2; } break; } -/* Opcode: ElseNotEq * P2 * * * +/* Opcode: ElseEq * P2 * * * ** ** This opcode must follow an OP_Lt or OP_Gt comparison operator. There ** can be zero or more OP_ReleaseReg opcodes intervening, but no other ** opcodes are allowed to occur between this instruction and the previous -** OP_Lt or OP_Gt. Furthermore, the prior OP_Lt or OP_Gt must have the -** SQLITE_STOREP2 bit set in the P5 field. +** OP_Lt or OP_Gt. ** ** If result of an OP_Eq comparison on the same two operands as the -** prior OP_Lt or OP_Gt would have been NULL or false (0), then then -** jump to P2. If the result of an OP_Eq comparison on the two previous -** operands would have been true (1), then fall through. +** prior OP_Lt or OP_Gt would have been true, then jump to P2. +** If the result of an OP_Eq comparison on the two previous +** operands would have been false or NULL, then fall through. */ -case OP_ElseNotEq: { /* same as TK_ESCAPE, jump */ +case OP_ElseEq: { /* same as TK_ESCAPE, jump */ #ifdef SQLITE_DEBUG /* Verify the preconditions of this opcode - that it follows an OP_Lt or - ** OP_Gt with the SQLITE_STOREP2 flag set, with zero or more intervening - ** OP_ReleaseReg opcodes */ + ** OP_Gt with zero or more intervening OP_ReleaseReg opcodes */ int iAddr; for(iAddr = (int)(pOp - aOp) - 1; ALWAYS(iAddr>=0); iAddr--){ if( aOp[iAddr].opcode==OP_ReleaseReg ) continue; assert( aOp[iAddr].opcode==OP_Lt || aOp[iAddr].opcode==OP_Gt ); - assert( aOp[iAddr].p5 & SQLITE_STOREP2 ); break; } #endif /* SQLITE_DEBUG */ - VdbeBranchTaken(iCompare!=0, 2); - if( iCompare!=0 ) goto jump_to_p2; + VdbeBranchTaken(iCompare==0, 2); + if( iCompare==0 ) goto jump_to_p2; break; } @@ -87839,6 +89903,40 @@ 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 +** +** If all both registers P1 and P3 are NOT NULL, then store a zero in +** register P2. If either registers P1 or P3 are NULL then put +** a NULL in register P2. +*/ +case OP_ZeroOrNull: { /* in1, in2, out2, in3 */ + if( (aMem[pOp->p1].flags & MEM_Null)!=0 + || (aMem[pOp->p3].flags & MEM_Null)!=0 + ){ + sqlite3VdbeMemSetNull(aMem + pOp->p2); + }else{ + sqlite3VdbeMemSetInt64(aMem + pOp->p2, 0); + } + break; +} + /* Opcode: NotNull P1 P2 * * * ** Synopsis: if r[P1]!=NULL goto P2 ** @@ -87954,6 +90052,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 ); @@ -88189,6 +90288,110 @@ case OP_Column: { } } +/* 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]) ** @@ -88403,7 +90606,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 ){ @@ -88531,7 +90734,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 @@ -88814,7 +91017,8 @@ case OP_AutoCommit: { ** active. ** If P2 is non-zero, then a write-transaction is started, or if a ** read-transaction is already active, it is upgraded to a write-transaction. -** If P2 is zero, then a read-transaction is started. +** If P2 is zero, then a read-transaction is started. If P2 is 2 or more +** then an exclusive transaction is started. ** ** P1 is the index of the database file on which the transaction is ** started. Index 0 is the main database file and index 1 is the @@ -88848,10 +91052,19 @@ case OP_Transaction: { assert( p->bIsReader ); assert( p->readOnly==0 || pOp->p2==0 ); + 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; @@ -88873,7 +91086,7 @@ case OP_Transaction: { && pOp->p2 && (db->autoCommit==0 || db->nVdbeRead>1) ){ - assert( sqlite3BtreeIsInTrans(pBt) ); + assert( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ); if( p->iStatement==0 ){ assert( db->nStatement>=0 && db->nSavepoint>=0 ); db->nStatement++; @@ -88893,7 +91106,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) ){ @@ -88990,6 +91204,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; @@ -89103,6 +91318,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 @@ -89165,8 +91382,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; @@ -89206,9 +91424,9 @@ case OP_OpenDup: { pOrig = p->apCsr[pOp->p2]; assert( pOrig ); - assert( pOrig->pBtx!=0 ); /* Only ephemeral cursors can be duplicated */ + 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; @@ -89216,7 +91434,10 @@ case OP_OpenDup: { pCx->isTable = pOrig->isTable; pCx->pgnoRoot = pOrig->pgnoRoot; pCx->isOrdered = pOrig->isOrdered; - rc = sqlite3BtreeCursor(pOrig->pBtx, pCx->pgnoRoot, BTREE_WRCSR, + pCx->ub.pBtx = pOrig->ub.pBtx; + pCx->hasBeenDuped = 1; + pOrig->hasBeenDuped = 1; + 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 @@ -89226,7 +91447,7 @@ case OP_OpenDup: { } -/* Opcode: OpenEphemeral P1 P2 * P4 P5 +/* Opcode: OpenEphemeral P1 P2 P3 P4 P5 ** Synopsis: nColumn=P2 ** ** Open a new cursor P1 to a transient table. @@ -89246,6 +91467,10 @@ case OP_OpenDup: { ** in btree.h. These flags control aspects of the operation of ** the btree. The BTREE_OMIT_JOURNAL and BTREE_SINGLE flags are ** added automatically. +** +** If P3 is positive, then reg[P3] is modified slightly so that it +** can be used as zero-length data for OP_Insert. This is an optimization +** that avoids an extra OP_Blob opcode to initialize that register. */ /* Opcode: OpenAutoindex P1 P2 * P4 * ** Synopsis: nColumn=P2 @@ -89268,50 +91493,63 @@ case OP_OpenEphemeral: { SQLITE_OPEN_TRANSIENT_DB; assert( pOp->p1>=0 ); assert( pOp->p2>=0 ); + if( pOp->p3>0 ){ + /* Make register reg[P3] into a value that can be used as the data + ** form sqlite3BtreeInsert() where the length of the data is zero. */ + assert( pOp->p2==0 ); /* Only used when number of columns is zero */ + assert( pOp->opcode==OP_OpenEphemeral ); + assert( aMem[pOp->p3].flags & MEM_Null ); + aMem[pOp->p3].n = 0; + aMem[pOp->p3].z = ""; + } pCx = p->apCsr[pOp->p1]; - if( pCx && pCx->pBtx ){ - /* If the ephermeral table is already open, erase all existing content - ** so that the table is empty again, rather than creating a new table. */ + 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); - } - if( rc==SQLITE_OK ){ - /* If a transient index is required, create it by calling - ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before - ** opening it. If a transient table is required, just use the - ** automatically created table with root-page 1 (an BLOB_INTKEY table). - */ - if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ - assert( pOp->p4type==P4_KEYINFO ); - rc = sqlite3BtreeCreateTable(pCx->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, - pKeyInfo, pCx->uc.pCursor); + 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 + ** opening it. If a transient table is required, just use the + ** automatically created table with root-page 1 (an BLOB_INTKEY table). + */ + if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ + assert( pOp->p4type==P4_KEYINFO ); + 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->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, + pKeyInfo, pCx->uc.pCursor); + } + pCx->isTable = 0; + }else{ + pCx->pgnoRoot = SCHEMA_ROOT; + rc = sqlite3BtreeCursor(pCx->ub.pBtx, SCHEMA_ROOT, BTREE_WRCSR, + 0, pCx->uc.pCursor); + pCx->isTable = 1; } - pCx->isTable = 0; - }else{ - pCx->pgnoRoot = SCHEMA_ROOT; - rc = sqlite3BtreeCursor(pCx->pBtx, SCHEMA_ROOT, BTREE_WRCSR, - 0, pCx->uc.pCursor); - pCx->isTable = 1; + } + pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); + if( rc ){ + sqlite3BtreeClose(pCx->ub.pBtx); } } - pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); } if( rc ) goto abort_due_to_error; pCx->nullRow = 1; @@ -89333,7 +91571,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 ); @@ -89382,7 +91620,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; @@ -89570,6 +91808,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); @@ -89579,7 +91818,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 @@ -89588,7 +91828,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) ); @@ -89597,14 +91837,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; @@ -89651,7 +91891,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; } @@ -89710,22 +91950,183 @@ case OP_SeekGT: { /* jump, in3, group */ break; } -/* Opcode: SeekHit P1 P2 * * * -** Synopsis: seekHit=P2 + +/* Opcode: SeekScan P1 P2 * * * +** Synopsis: Scan-ahead up to P1 rows +** +** This opcode is a prefix opcode to OP_SeekGE. In other words, this +** opcode must be immediately followed by OP_SeekGE. This constraint is +** checked by assert() statements. +** +** This opcode uses the P1 through P4 operands of the subsequent +** OP_SeekGE. In the text that follows, the operands of the subsequent +** OP_SeekGE opcode are denoted as SeekOP.P1 through SeekOP.P4. Only +** the P1 and P2 operands of this opcode are also used, and are called +** This.P1 and This.P2. +** +** This opcode helps to optimize IN operators on a multi-column index +** where the IN operator is on the later terms of the index by avoiding +** unnecessary seeks on the btree, substituting steps to the next row +** of the b-tree instead. A correct answer is obtained if this opcode +** is omitted or is a no-op. +** +** The SeekGE.P3 and SeekGE.P4 operands identify an unpacked key which +** is the desired entry that we want the cursor SeekGE.P1 to be pointing +** to. Call this SeekGE.P4/P5 row the "target". +** +** If the SeekGE.P1 cursor is not currently pointing to a valid row, +** then this opcode is a no-op and control passes through into the OP_SeekGE. +** +** If the SeekGE.P1 cursor is pointing to a valid row, then that row +** might be the target row, or it might be near and slightly before the +** target row. This opcode attempts to position the cursor on the target +** row by, perhaps by invoking sqlite3BtreeStep() on the cursor +** between 0 and This.P1 times. +** +** There are three possible outcomes from this opcode:
      +** +**
    1. If after This.P1 steps, the cursor is still pointing to a place that +** is earlier in the btree than the target row, then fall through +** into the subsquence OP_SeekGE opcode. ** -** Set the seekHit flag on cursor P1 to the value in P2. -** The seekHit flag is used by the IfNoHope opcode. +**
    2. If the cursor is successfully moved to the target row by 0 or more +** sqlite3BtreeNext() calls, then jump to This.P2, which will land just +** past the OP_IdxGT or OP_IdxGE opcode that follows the OP_SeekGE. ** -** P1 must be a valid b-tree cursor. P2 must be a boolean value, -** either 0 or 1. +**
    3. If the cursor ends up past the target row (indicating the the target +** row does not exist in the btree) then jump to SeekOP.P2. +**
    +*/ +case OP_SeekScan: { + VdbeCursor *pC; + int res; + int nStep; + UnpackedRecord r; + + assert( pOp[1].opcode==OP_SeekGE ); + + /* pOp->p2 points to the first instruction past the OP_IdxGT that + ** follows the OP_SeekGE. */ + assert( pOp->p2>=(int)(pOp-aOp)+2 ); + assert( aOp[pOp->p2-1].opcode==OP_IdxGT || aOp[pOp->p2-1].opcode==OP_IdxGE ); + testcase( aOp[pOp->p2-1].opcode==OP_IdxGE ); + assert( pOp[1].p1==aOp[pOp->p2-1].p1 ); + assert( pOp[1].p2==aOp[pOp->p2-1].p2 ); + assert( pOp[1].p3==aOp[pOp->p2-1].p3 ); + + assert( pOp->p1>0 ); + pC = p->apCsr[pOp[1].p1]; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + assert( !pC->isTable ); + if( !sqlite3BtreeCursorIsValidNN(pC->uc.pCursor) ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... cursor not valid - fall through\n"); + } +#endif + break; + } + nStep = pOp->p1; + assert( nStep>=1 ); + r.pKeyInfo = pC->pKeyInfo; + r.nField = (u16)pOp[1].p4.i; + r.default_rc = 0; + r.aMem = &aMem[pOp[1].p3]; +#ifdef SQLITE_DEBUG + { + int i; + for(i=0; i0 ){ + seekscan_search_fail: +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... %d steps and then skip\n", pOp->p1 - nStep); + } +#endif + VdbeBranchTaken(1,3); + pOp++; + goto jump_to_p2; + } + if( res==0 ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... %d steps and then success\n", pOp->p1 - nStep); + } +#endif + VdbeBranchTaken(2,3); + goto jump_to_p2; + break; + } + if( nStep<=0 ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("... fall through after %d steps\n", pOp->p1); + } +#endif + VdbeBranchTaken(0,3); + break; + } + nStep--; + rc = sqlite3BtreeNext(pC->uc.pCursor, 0); + if( rc ){ + if( rc==SQLITE_DONE ){ + rc = SQLITE_OK; + goto seekscan_search_fail; + }else{ + goto abort_due_to_error; + } + } + } + + break; +} + + +/* Opcode: SeekHit P1 P2 P3 * * +** Synopsis: set P2<=seekHit<=P3 +** +** Increase or decrease the seekHit value for cursor P1, if necessary, +** so that it is no less than P2 and no greater than P3. +** +** The seekHit integer represents the maximum of terms in an index for which +** there is known to be at least one match. If the seekHit value is smaller +** than the total number of equality terms in an index lookup, then the +** OP_IfNoHope opcode might run to see if the IN loop can be abandoned +** early, thus saving work. This is part of the IN-early-out optimization. +** +** P1 must be a valid b-tree cursor. */ case OP_SeekHit: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pOp->p2==0 || pOp->p2==1 ); - pC->seekHit = pOp->p2 & 1; + assert( pOp->p3>=pOp->p2 ); + if( pC->seekHitp2 ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("seekHit changes from %d to %d\n", pC->seekHit, pOp->p2); + } +#endif + pC->seekHit = pOp->p2; + }else if( pC->seekHit>pOp->p3 ){ +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("seekHit changes from %d to %d\n", pC->seekHit, pOp->p3); + } +#endif + pC->seekHit = pOp->p3; + } break; } @@ -89783,16 +92184,20 @@ case OP_IfNotOpen: { /* jump */ ** Synopsis: key=r[P3@P4] ** ** Register P3 is the first of P4 registers that form an unpacked -** record. +** record. Cursor P1 is an index btree. P2 is a jump destination. +** In other words, the operands to this opcode are the same as the +** operands to OP_NotFound and OP_IdxGT. ** -** Cursor P1 is on an index btree. If the seekHit flag is set on P1, then -** this opcode is a no-op. But if the seekHit flag of P1 is clear, then -** check to see if there is any entry in P1 that matches the -** prefix identified by P3 and P4. If no entry matches the prefix, -** jump to P2. Otherwise fall through. +** This opcode is an optimization attempt only. If this opcode always +** falls through, the correct answer is still obtained, but extra works +** is performed. ** -** This opcode behaves like OP_NotFound if the seekHit -** flag is clear and it behaves like OP_Noop if the seekHit flag is set. +** A value of N in the seekHit flag of cursor P1 means that there exists +** a key P3:N that will match some record in the index. We want to know +** if it is possible for a record P3:P4 to match some record in the +** index. If it is not possible, we can skips some work. So if seekHit +** is less than P4, attempt to find out if a match is possible by running +** OP_NotFound. ** ** This opcode is used in IN clause processing for a multi-column key. ** If an IN clause is attached to an element of the key other than the @@ -89834,7 +92239,12 @@ case OP_IfNoHope: { /* jump, in3 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - if( pC->seekHit ) break; +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + printf("seekHit is %d\n", pC->seekHit); + } +#endif + if( pC->seekHit>=pOp->p4.i ) break; /* Fall through into OP_NotFound */ /* no break */ deliberate_fall_through } @@ -89900,7 +92310,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; @@ -89916,6 +92326,7 @@ case OP_Found: { /* jump, in3 */ }else{ VdbeBranchTaken(takeJump||alreadyExists==0,2); if( takeJump || !alreadyExists ) goto jump_to_p2; + if( pOp->opcode==OP_IfNoHope ) pC->seekHit = pOp->p4.i; } break; } @@ -90008,7 +92419,7 @@ case OP_NotExists: /* jump, in3 */ 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; @@ -90066,8 +92477,10 @@ case OP_NewRowid: { /* out2 */ VdbeCursor *pC; /* Cursor of table to get the new rowid */ int res; /* Result of an sqlite3BtreeLast() */ int cnt; /* Counter to limit the number of searches */ +#ifndef SQLITE_OMIT_AUTOINCREMENT Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ VdbeFrame *pFrame; /* Root frame of VDBE */ +#endif v = 0; res = 0; @@ -90163,7 +92576,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)); @@ -90253,14 +92666,14 @@ 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 /* Invoke the pre-update hook, if any */ if( pTab ){ if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){ - sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey,pOp->p2); + sqlite3VdbePreUpdateHook(p,pC,SQLITE_INSERT,zDb,pTab,x.nKey,pOp->p2,-1); } if( db->xUpdateCallback==0 || pTab->aCol==0 ){ /* Prevent post-update hook from running in cases when it should not */ @@ -90272,7 +92685,7 @@ case OP_Insert: { if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey; - assert( pData->flags & (MEM_Blob|MEM_Str) ); + assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 ); x.pData = pData->z; x.nData = pData->n; seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0); @@ -90283,7 +92696,8 @@ case OP_Insert: { } x.pKey = 0; rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, - (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), seekResult + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), + seekResult ); pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; @@ -90300,6 +92714,33 @@ case OP_Insert: { break; } +/* Opcode: RowCell P1 P2 P3 * * +** +** P1 and P2 are both open cursors. Both must be opened on the same type +** of table - intkey or index. This opcode is used as part of copying +** the current row from P2 into P1. If the cursors are opened on intkey +** tables, register P3 contains the rowid to use with the new record in +** P1. If they are opened on index tables, P3 is not used. +** +** This opcode must be followed by either an Insert or InsertIdx opcode +** with the OPFLAG_PREFORMAT flag set to complete the insert operation. +*/ +case OP_RowCell: { + VdbeCursor *pDest; /* Cursor to write to */ + VdbeCursor *pSrc; /* Cursor to read from */ + i64 iKey; /* Rowid value to insert with */ + assert( pOp[1].opcode==OP_Insert || pOp[1].opcode==OP_IdxInsert ); + assert( pOp[1].opcode==OP_Insert || pOp->p3==0 ); + assert( pOp[1].opcode==OP_IdxInsert || pOp->p3>0 ); + assert( pOp[1].p5 & OPFLAG_PREFORMAT ); + pDest = p->apCsr[pOp->p1]; + pSrc = p->apCsr[pOp->p2]; + iKey = pOp->p3 ? aMem[pOp->p3].u.i : 0; + rc = sqlite3BtreeTransferRow(pDest->uc.pCursor, pSrc->uc.pCursor, iKey); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + break; +}; + /* Opcode: Delete P1 P2 P3 P4 P5 ** ** Delete the record at which the P1 cursor is currently pointing. @@ -90378,13 +92819,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) @@ -90392,7 +92834,7 @@ case OP_Delete: { sqlite3VdbePreUpdateHook(p, pC, (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, zDb, pTab, pC->movetoTarget, - pOp->p3 + pOp->p3, -1 ); } if( opflags & OPFLAG_ISNOOP ) break; @@ -90425,7 +92867,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 ); @@ -90955,7 +93397,7 @@ case OP_IdxInsert: { /* in2 */ assert( pC!=0 ); assert( !isSorter(pC) ); pIn2 = &aMem[pOp->p2]; - assert( pIn2->flags & MEM_Blob ); + assert( (pIn2->flags & MEM_Blob) || (pOp->p5 & OPFLAG_PREFORMAT) ); if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->isTable==0 ); @@ -90966,7 +93408,7 @@ case OP_IdxInsert: { /* in2 */ x.aMem = aMem + pOp->p3; x.nMem = (u16)pOp->p4.i; rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, - (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) ); assert( pC->deferredMoveto==0 ); @@ -91012,7 +93454,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; @@ -91033,13 +93476,13 @@ 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 ){ - rc = SQLITE_CORRUPT_INDEX; + }else if( pOp->p5 && !sqlite3WritableSchema(db) ){ + rc = sqlite3ReportError(SQLITE_CORRUPT_INDEX, __LINE__, "index corruption"); goto abort_due_to_error; } assert( pC->deferredMoveto==0 ); @@ -91117,7 +93560,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( !pTabCur->isEphemeral ); + pTabCur->ub.aAltMap = pOp->p4.ai; + assert( !pC->isEphemeral ); pTabCur->pAltCursor = pC; }else{ pOut = out2Prerelease(p, pOp); @@ -91148,7 +93593,7 @@ case OP_FinishSeek: { break; } -/* Opcode: IdxGE P1 P2 P3 P4 P5 +/* Opcode: IdxGE P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** ** The P4 register values beginning with P3 form an unpacked index @@ -91159,7 +93604,7 @@ case OP_FinishSeek: { ** If the P1 index entry is greater than or equal to the key value ** then jump to P2. Otherwise fall through to the next instruction. */ -/* Opcode: IdxGT P1 P2 P3 P4 P5 +/* Opcode: IdxGT P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** ** The P4 register values beginning with P3 form an unpacked index @@ -91170,7 +93615,7 @@ case OP_FinishSeek: { ** If the P1 index entry is greater than the key value ** then jump to P2. Otherwise fall through to the next instruction. */ -/* Opcode: IdxLT P1 P2 P3 P4 P5 +/* Opcode: IdxLT P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** ** The P4 register values beginning with P3 form an unpacked index @@ -91181,7 +93626,7 @@ case OP_FinishSeek: { ** If the P1 index entry is less than the key value then jump to P2. ** Otherwise fall through to the next instruction. */ -/* Opcode: IdxLE P1 P2 P3 P4 P5 +/* Opcode: IdxLE P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** ** The P4 register values beginning with P3 form an unpacked index @@ -91207,7 +93652,6 @@ case OP_IdxGE: { /* jump */ assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->uc.pCursor!=0); assert( pC->deferredMoveto==0 ); - assert( pOp->p5==0 || pOp->p5==1 ); assert( pOp->p4type==P4_INT32 ); r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p4.i; @@ -91228,8 +93672,31 @@ case OP_IdxGE: { /* jump */ } } #endif - res = 0; /* Not needed. Only used to silence a warning. */ - rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res); + + /* Inlined version of sqlite3VdbeIdxKeyCompare() */ + { + i64 nCellKey = 0; + BtCursor *pCur; + Mem m; + + assert( pC->eCurType==CURTYPE_BTREE ); + pCur = pC->uc.pCursor; + assert( sqlite3BtreeCursorIsValid(pCur) ); + nCellKey = sqlite3BtreePayloadSize(pCur); + /* nCellKey will always be between 0 and 0xffffffff because of the way + ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */ + if( nCellKey<=0 || nCellKey>0x7fffffff ){ + rc = SQLITE_CORRUPT_BKPT; + goto abort_due_to_error; + } + sqlite3VdbeMemInit(&m, db, 0); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m); + if( rc ) goto abort_due_to_error; + res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0); + sqlite3VdbeMemRelease(&m); + } + /* End of inlined sqlite3VdbeIdxKeyCompare() */ + assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) ); if( (pOp->opcode&1)==(OP_IdxLT&1) ){ assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT ); @@ -91239,7 +93706,7 @@ case OP_IdxGE: { /* jump */ res++; } VdbeBranchTaken(res>0,2); - if( rc ) goto abort_due_to_error; + assert( rc==SQLITE_OK ); if( res>0 ) goto jump_to_p2; break; } @@ -91314,24 +93781,21 @@ case OP_Destroy: { /* out2 */ ** P2==1 then the table to be clear is in the auxiliary database file ** that is used to store tables create using CREATE TEMPORARY TABLE. ** -** If the P3 value is non-zero, then the table referred to must be an -** intkey table (an SQL table, not an index). In this case the row change -** count is incremented by the number of rows in the table being cleared. -** If P3 is greater than zero, then the value stored in register P3 is -** also incremented by the number of rows in the table being cleared. +** If the P3 value is non-zero, then the row change count is incremented +** by the number of rows in the table being cleared. If P3 is greater +** than zero, then the value stored in register P3 is also incremented +** by the number of rows in the table being cleared. ** ** See also: Destroy */ case OP_Clear: { - int nChange; + i64 nChange; sqlite3VdbeIncrWriteCounter(p, 0); nChange = 0; assert( p->readOnly==0 ); assert( DbMaskTest(p->btreeMask, pOp->p2) ); - rc = sqlite3BtreeClearTable( - db->aDb[pOp->p2].pBt, (u32)pOp->p1, (pOp->p3 ? &nChange : 0) - ); + rc = sqlite3BtreeClearTable(db->aDb[pOp->p2].pBt, (u32)pOp->p1, &nChange); if( pOp->p3 ){ p->nChange += nChange; if( pOp->p3>0 ){ @@ -91437,19 +93901,21 @@ case OP_ParseSchema: { iDb = pOp->p1; assert( iDb>=0 && iDbnDb ); - assert( DbHasProperty(db, iDb, DB_SchemaLoaded) ); + assert( DbHasProperty(db, iDb, DB_SchemaLoaded) + || db->mallocFailed + || (CORRUPT_DB && (db->flags & SQLITE_NoSchemaError)!=0) ); #ifndef SQLITE_OMIT_ALTERTABLE if( pOp->p4.z==0 ){ sqlite3SchemaClear(db->aDb[iDb].pSchema); db->mDbFlags &= ~DBFLAG_SchemaKnownOk; - rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable); + rc = sqlite3InitOne(db, iDb, &p->zErrMsg, pOp->p5); db->mDbFlags |= DBFLAG_SchemaChange; p->expired = 0; }else #endif { - zSchema = DFLT_SCHEMA_TABLE; + zSchema = LEGACY_SCHEMA_TABLE; initData.db = db; initData.iDb = iDb; initData.pzErrMsg = &p->zErrMsg; @@ -92319,6 +94785,7 @@ case OP_JournalMode: { /* out2 */ pPager = sqlite3BtreePager(pBt); eOld = sqlite3PagerGetJournalMode(pPager); if( eNew==PAGER_JOURNALMODE_QUERY ) eNew = eOld; + assert( sqlite3BtreeHoldsMutex(pBt) ); if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld; #ifndef SQLITE_OMIT_WAL @@ -92365,7 +94832,7 @@ case OP_JournalMode: { /* out2 */ /* Open a transaction on the database file. Regardless of the journal ** mode, this transaction always uses a rollback journal. */ - assert( sqlite3BtreeIsInTrans(pBt)==0 ); + assert( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE ); if( rc==SQLITE_OK ){ rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); } @@ -92617,7 +95084,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++; @@ -92630,6 +95097,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' @@ -92668,6 +95163,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; @@ -92679,7 +95175,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]; @@ -92769,8 +95265,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; @@ -92866,7 +95362,7 @@ case OP_VUpdate: { const sqlite3_module *pModule; int nArg; int i; - sqlite_int64 rowid; + sqlite_int64 rowid = 0; Mem **apArg; Mem *pX; @@ -93054,6 +95550,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 @@ -93305,8 +95872,24 @@ default: { /* This is really OP_Noop, OP_Explain */ ** an error of some kind. */ abort_due_to_error: - if( db->mallocFailed ) rc = SQLITE_NOMEM_BKPT; + if( db->mallocFailed ){ + rc = SQLITE_NOMEM_BKPT; + }else if( rc==SQLITE_IOERR_CORRUPTFS ){ + 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)); } @@ -93317,6 +95900,9 @@ default: { /* This is really OP_Noop, OP_Explain */ (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); @@ -93448,7 +96034,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 ){ @@ -93522,10 +96111,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; @@ -93540,7 +96128,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); } @@ -93560,7 +96148,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; } } @@ -93585,7 +96173,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 ){ @@ -93701,7 +96290,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 ){ @@ -93712,7 +96303,7 @@ SQLITE_API int sqlite3_blob_open( } 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; @@ -93792,8 +96383,10 @@ 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 + v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol ); } #endif @@ -93864,6 +96457,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ rc = SQLITE_ABORT; }else{ char *zErr; + ((Vdbe*)p->pStmt)->rc = SQLITE_OK; rc = blobSeekToRow(p, iRow, &zErr); if( rc!=SQLITE_OK ){ sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); @@ -94844,7 +97438,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); @@ -94854,13 +97449,16 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit( if( pSorter==0 ){ rc = SQLITE_NOMEM_BKPT; }else{ + Btree *pBt = db->aDb[0].pBt; pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz); memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo); pKeyInfo->db = 0; if( nField && nWorker==0 ){ pKeyInfo->nKeyField = nField; } - pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); + sqlite3BtreeEnter(pBt); + pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(pBt); + sqlite3BtreeLeave(pBt); pSorter->nTask = nWorker + 1; pSorter->iPrev = (u8)(nWorker - 1); pSorter->bUseThreads = (pSorter->nTask>1); @@ -94954,8 +97552,9 @@ static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){ fprintf(stderr, "%lld:%d %s\n", t, iTask, zEvent); } static void vdbeSorterRewindDebug(const char *zEvent){ - i64 t; - sqlite3OsCurrentTimeInt64(sqlite3_vfs_find(0), &t); + i64 t = 0; + sqlite3_vfs *pVfs = sqlite3_vfs_find(0); + if( ALWAYS(pVfs) ) sqlite3OsCurrentTimeInt64(pVfs, &t); fprintf(stderr, "%lld:X %s\n", t, zEvent); } static void vdbeSorterPopulateDebug( @@ -95169,7 +97768,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 @@ -95887,6 +98486,7 @@ static int vdbeIncrMergerNew( vdbeMergeEngineFree(pMerger); rc = SQLITE_NOMEM_BKPT; } + assert( *ppOut!=0 || rc!=SQLITE_OK ); return rc; } @@ -97144,7 +99744,6 @@ struct MemJournal { int nChunkSize; /* In-memory chunk-size */ int nSpill; /* Bytes of data before flushing */ - int nSize; /* Bytes of data currently in memory */ FileChunk *pFirst; /* Head of in-memory chunk-list */ FilePoint endpoint; /* Pointer to the end of the file */ FilePoint readpoint; /* Pointer to the end of the last xRead() */ @@ -97205,14 +99804,13 @@ static int memjrnlRead( /* ** Free the list of FileChunk structures headed at MemJournal.pFirst. */ -static void memjrnlFreeChunks(MemJournal *p){ +static void memjrnlFreeChunks(FileChunk *pFirst){ FileChunk *pIter; FileChunk *pNext; - for(pIter=p->pFirst; pIter; pIter=pNext){ + for(pIter=pFirst; pIter; pIter=pNext){ pNext = pIter->pNext; sqlite3_free(pIter); } - p->pFirst = 0; } /* @@ -97239,7 +99837,7 @@ static int memjrnlCreateFile(MemJournal *p){ } if( rc==SQLITE_OK ){ /* No error has occurred. Free the in-memory buffers. */ - memjrnlFreeChunks(©); + memjrnlFreeChunks(copy.pFirst); } } if( rc!=SQLITE_OK ){ @@ -97254,6 +99852,9 @@ static int memjrnlCreateFile(MemJournal *p){ } +/* Forward reference */ +static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size); + /* ** Write data to the file. */ @@ -97284,22 +99885,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)); @@ -97314,15 +99913,15 @@ 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; } - p->nSize = iAmt + iOfst; } } @@ -97330,19 +99929,29 @@ static int memjrnlWrite( } /* -** Truncate the file. -** -** If the journal file is already on disk, truncate it there. Or, if it -** is still in main memory but is being truncated to zero bytes in size, -** ignore +** Truncate the in-memory file. */ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ MemJournal *p = (MemJournal *)pJfd; - if( ALWAYS(size==0) ){ - memjrnlFreeChunks(p); - p->nSize = 0; - p->endpoint.pChunk = 0; - p->endpoint.iOffset = 0; + assert( p->endpoint.pChunk==0 || p->endpoint.pChunk->pNext==0 ); + if( sizeendpoint.iOffset ){ + FileChunk *pIter = 0; + if( size==0 ){ + memjrnlFreeChunks(p->pFirst); + p->pFirst = 0; + }else{ + i64 iOff = p->nChunkSize; + for(pIter=p->pFirst; ALWAYS(pIter) && iOffpNext){ + iOff += p->nChunkSize; + } + if( ALWAYS(pIter) ){ + memjrnlFreeChunks(pIter->pNext); + pIter->pNext = 0; + } + } + + p->endpoint.pChunk = pIter; + p->endpoint.iOffset = size; p->readpoint.pChunk = 0; p->readpoint.iOffset = 0; } @@ -97354,7 +99963,7 @@ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ */ static int memjrnlClose(sqlite3_file *pJfd){ MemJournal *p = (MemJournal *)pJfd; - memjrnlFreeChunks(p); + memjrnlFreeChunks(p->pFirst); return SQLITE_OK; } @@ -97528,7 +100137,7 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){ ** Walk all expressions linked into the list of Window objects passed ** as the second argument. */ -static int walkWindowList(Walker *pWalker, Window *pList){ +static int walkWindowList(Walker *pWalker, Window *pList, int bOneOnly){ Window *pWin; for(pWin=pList; pWin; pWin=pWin->pNextWin){ int rc; @@ -97538,15 +100147,11 @@ static int walkWindowList(Walker *pWalker, Window *pList){ if( rc ) return WRC_Abort; rc = sqlite3WalkExpr(pWalker, pWin->pFilter); if( rc ) return WRC_Abort; - - /* The next two are purely for calls to sqlite3RenameExprUnmap() - ** within sqlite3WindowOffsetExpr(). Because of constraints imposed - ** by sqlite3WindowOffsetExpr(), they can never fail. The results do - ** not matter anyhow. */ rc = sqlite3WalkExpr(pWalker, pWin->pStart); - if( NEVER(rc) ) return WRC_Abort; + if( rc ) return WRC_Abort; rc = sqlite3WalkExpr(pWalker, pWin->pEnd); - if( NEVER(rc) ) return WRC_Abort; + if( rc ) return WRC_Abort; + if( bOneOnly ) break; } return WRC_Continue; } @@ -97585,7 +100190,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{ @@ -97594,7 +100199,7 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ - if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort; + if( walkWindowList(pWalker, pExpr->y.pWin, 1) ) return WRC_Abort; } #endif } @@ -97622,6 +100227,16 @@ SQLITE_PRIVATE int sqlite3WalkExprList(Walker *pWalker, ExprList *p){ return WRC_Continue; } +/* +** This is a no-op callback for Walker->xSelectCallback2. If this +** callback is set, then the Select->pWinDefn list is traversed. +*/ +SQLITE_PRIVATE void sqlite3WalkWinDefnDummyCallback(Walker *pWalker, Select *p){ + UNUSED_PARAMETER(pWalker); + UNUSED_PARAMETER(p); + /* No-op */ +} + /* ** Walk all expressions associated with SELECT statement p. Do ** not invoke the SELECT callback on p, but do (of course) invoke @@ -97635,13 +100250,18 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; -#if !defined(SQLITE_OMIT_WINDOWFUNC) && !defined(SQLITE_OMIT_ALTERTABLE) - { - Parse *pParse = pWalker->pParse; - if( pParse && IN_RENAME_OBJECT ){ +#if !defined(SQLITE_OMIT_WINDOWFUNC) + if( p->pWinDefn ){ + Parse *pParse; + if( pWalker->xSelectCallback2==sqlite3WalkWinDefnDummyCallback + || ((pParse = pWalker->pParse)!=0 && IN_RENAME_OBJECT) +#ifndef SQLITE_OMIT_CTE + || pWalker->xSelectCallback2==sqlite3SelectPopWith +#endif + ){ /* The following may return WRC_Abort if there are unresolvable ** symbols (e.g. a table that does not exist) in a window definition. */ - int rc = walkWindowList(pWalker, p->pWinDefn); + int rc = walkWindowList(pWalker, p->pWinDefn, 0); return rc; } } @@ -97659,10 +100279,10 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ SrcList *pSrc; int i; - struct SrcList_item *pItem; + SrcItem *pItem; pSrc = p->pSrc; - if( pSrc ){ + if( ALWAYS(pSrc) ){ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ return WRC_Abort; @@ -97825,7 +100445,6 @@ static void resolveAlias( ExprList *pEList, /* A result set */ int iCol, /* A column in the result set. 0..pEList->nExpr-1 */ Expr *pExpr, /* Transform this into an alias to the result set */ - const char *zType, /* "GROUP" or "ORDER" or "" */ int nSubquery /* Number of subqueries that the label is moving */ ){ Expr *pOrig; /* The iCol-th column of the result set */ @@ -97837,9 +100456,13 @@ static void resolveAlias( assert( pOrig!=0 ); db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); - if( pDup!=0 ){ - if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + pDup = 0; + }else{ + incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } @@ -97859,15 +100482,12 @@ static void resolveAlias( pExpr->flags |= EP_MemToken; } if( ExprHasProperty(pExpr, EP_WinFunc) ){ - if( pExpr->y.pWin!=0 ){ + if( ALWAYS(pExpr->y.pWin!=0) ){ pExpr->y.pWin->pOwner = pExpr; - }else{ - assert( db->mallocFailed ); } } sqlite3DbFree(db, pDup); } - ExprSetProperty(pExpr, EP_Alias); } @@ -97946,6 +100566,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 @@ -98002,8 +100623,8 @@ static int lookupName( int cntTab = 0; /* Number of matching table names */ int nSubquery = 0; /* How many levels of subquery */ sqlite3 *db = pParse->db; /* The database connection */ - struct SrcList_item *pItem; /* Use for looping over pSrcList items */ - struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ + SrcItem *pItem; /* Use for looping over pSrcList items */ + SrcItem *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ Schema *pSchema = 0; /* Schema of the expression */ int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */ @@ -98059,7 +100680,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; @@ -98074,8 +100695,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; @@ -98083,16 +100705,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. @@ -98108,9 +100730,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 ); @@ -98124,25 +100751,33 @@ static int lookupName( #if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) /* If we have not already resolved the name, then maybe ** it is a new.* or old.* trigger argument reference. Or - ** maybe it is an excluded.* from an upsert. + ** maybe it is an excluded.* from an upsert. Or maybe it is + ** a reference in the RETURNING clause to a table being modified. */ - if( zDb==0 && zTab!=0 && cntTab==0 ){ + if( cnt==0 && zDb==0 ){ pTab = 0; #ifndef SQLITE_OMIT_TRIGGER if( pParse->pTriggerTab!=0 ){ int op = pParse->eTriggerOp; assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); - if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){ + if( pParse->bReturning ){ + if( (pNC->ncFlags & NC_UBaseReg)!=0 + && (zTab==0 || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0) + ){ + pExpr->iTable = op!=TK_DELETE; + pTab = pParse->pTriggerTab; + } + }else if( op!=TK_DELETE && zTab && sqlite3StrICmp("new",zTab) == 0 ){ pExpr->iTable = 1; pTab = pParse->pTriggerTab; - }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){ + }else if( op!=TK_INSERT && zTab && sqlite3StrICmp("old",zTab)==0 ){ pExpr->iTable = 0; pTab = pParse->pTriggerTab; } } #endif /* SQLITE_OMIT_TRIGGER */ #ifndef SQLITE_OMIT_UPSERT - if( (pNC->ncFlags & NC_UUpsert)!=0 ){ + if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){ Upsert *pUpsert = pNC->uNC.pUpsert; if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ pTab = pUpsert->pUpsertSrc->a[0].pTab; @@ -98157,7 +100792,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; } @@ -98170,9 +100807,11 @@ static int lookupName( } if( iColnCol ){ cnt++; + pMatch = 0; #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; @@ -98181,27 +100820,34 @@ static int lookupName( pExpr->iTable = pNC->uNC.pUpsert->regData + sqlite3TableColumnToStorage(pTab, iCol); eNewExprOp = TK_REGISTER; - ExprSetProperty(pExpr, EP_Alias); } }else #endif /* SQLITE_OMIT_UPSERT */ { -#ifndef SQLITE_OMIT_TRIGGER - if( iCol<0 ){ - pExpr->affExpr = SQLITE_AFF_INTEGER; - }else if( pExpr->iTable==0 ){ - testcase( iCol==31 ); - testcase( iCol==32 ); - pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<y.pTab = pTab; - pExpr->iColumn = (i16)iCol; - eNewExprOp = TK_TRIGGER; + 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{ + pExpr->iColumn = (i16)iCol; + eNewExprOp = TK_TRIGGER; +#ifndef SQLITE_OMIT_TRIGGER + if( iCol<0 ){ + pExpr->affExpr = SQLITE_AFF_INTEGER; + }else if( pExpr->iTable==0 ){ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<ncFlags & (NC_IdxExpr|NC_GenCol))==0 && sqlite3IsRowid(zCol) - && VisibleRowid(pMatch->pTab) + && ALWAYS(VisibleRowid(pMatch->pTab)) ){ cnt = 1; pExpr->iColumn = -1; @@ -98241,8 +100887,8 @@ static int lookupName( ** is supported for backwards compatibility only. Hence, we issue a warning ** on sqlite3_log() whenever the capability is used. */ - if( (pNC->ncFlags & NC_UEList)!=0 - && cnt==0 + if( cnt==0 + && (pNC->ncFlags & NC_UEList)!=0 && zTab==0 ){ pEList = pNC->uNC.pEList; @@ -98254,8 +100900,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); @@ -98271,7 +100917,7 @@ static int lookupName( sqlite3ErrorMsg(pParse, "row value misused"); return WRC_Abort; } - resolveAlias(pParse, pEList, j, pExpr, "", nSubquery); + resolveAlias(pParse, pEList, j, pExpr, nSubquery); cnt = 1; pMatch = 0; assert( zTab==0 && zDb==0 ); @@ -98327,7 +100973,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) ){ @@ -98349,8 +100995,9 @@ static int lookupName( }else{ sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); } + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); pParse->checkSchema = 1; - pTopNC->nErr++; + pTopNC->nNcErr++; } /* If a column from a table in pSrcList is referenced, then record @@ -98373,18 +101020,24 @@ static int lookupName( /* Clean up and return */ - sqlite3ExprDelete(db, pExpr->pLeft); - pExpr->pLeft = 0; - sqlite3ExprDelete(db, pExpr->pRight); - pExpr->pRight = 0; + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + sqlite3ExprDelete(db, pExpr->pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + } pExpr->op = eNewExprOp; ExprSetProperty(pExpr, EP_Leaf); lookupname_end: if( cnt==1 ){ assert( pNC!=0 ); - if( !ExprHasProperty(pExpr, EP_Alias) ){ +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pParse->db->xAuth + && (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER) + ){ sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); } +#endif /* Increment the nRef value on all name contexts from TopNC up to ** the point where the name matched. */ for(;;){ @@ -98406,8 +101059,10 @@ static int lookupName( SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); if( p ){ - struct SrcList_item *pItem = &pSrc->a[iSrc]; - Table *pTab = p->y.pTab = pItem->pTab; + SrcItem *pItem = &pSrc->a[iSrc]; + Table *pTab; + assert( ExprUseYTab(p) ); + pTab = p->y.pTab = pItem->pTab; p->iTable = pItem->iCursor; if( p->y.pTab->iPKey==iCol ){ p->iColumn = -1; @@ -98449,7 +101104,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"; @@ -98461,10 +101117,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. @@ -98474,6 +101131,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; @@ -98518,10 +101176,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ */ case TK_ROW: { SrcList *pSrcList = pNC->pSrcList; - struct SrcList_item *pItem; + SrcItem *pItem; 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--; @@ -98529,6 +101188,49 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ break; } + /* An optimization: Attempt to convert + ** + ** "expr IS NOT NULL" --> "TRUE" + ** "expr IS NULL" --> "FALSE" + ** + ** if we can prove that "expr" is never NULL. Call this the + ** "NOT NULL strength reduction optimization". + ** + ** If this optimization occurs, also restore the NameContext ref-counts + ** to the state they where in before the "column" LHS expression was + ** resolved. This prevents "column" from being counted as having been + ** referenced, which might prevent a SELECT from being erroneously + ** marked as correlated. + */ + case TK_NOTNULL: + case TK_ISNULL: { + int anRef[8]; + NameContext *p; + int i; + for(i=0, p=pNC; p && ipNext, i++){ + anRef[i] = p->nRef; + } + 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); + }else{ + pExpr->u.zToken = "false"; + ExprSetProperty(pExpr, EP_IsFalse); + } + pExpr->op = TK_TRUEFALSE; + for(i=0, p=pNC; p && ipNext, i++){ + p->nRef = anRef[i]; + } + sqlite3ExprDelete(pParse->db, pExpr->pLeft); + pExpr->pLeft = 0; + } + return WRC_Prune; + } + /* A column name: ID ** Or table name and column name: ID.ID ** Or a database, table and column: ID.ID.ID @@ -98547,24 +101249,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); @@ -98581,7 +101287,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 */ @@ -98589,9 +101294,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); @@ -98608,9 +101312,9 @@ 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"); - pNC->nErr++; + "second argument to %#T() must be a " + "constant between 0.0 and 1.0", pExpr); + pNC->nNcErr++; } }else{ /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is @@ -98630,9 +101334,9 @@ 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); - pNC->nErr++; + sqlite3ErrorMsg(pParse, "not authorized to use function: %#T", + pExpr); + pNC->nNcErr++; } pExpr->op = TK_NULL; return WRC_Prune; @@ -98654,7 +101358,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; @@ -98667,7 +101371,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 @@ -98686,9 +101390,9 @@ 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->nErr++; + pNC->nNcErr++; }else if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin) @@ -98700,14 +101404,14 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ }else{ zType = "aggregate"; } - sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId); - pNC->nErr++; + 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); - pNC->nErr++; + sqlite3ErrorMsg(pParse,"misuse of aggregate function %#T()",pExpr); + pNC->nNcErr++; is_agg = 0; } #endif @@ -98716,20 +101420,20 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ && pParse->explain==0 #endif ){ - sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); - pNC->nErr++; + 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); - pNC->nErr++; + 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->nErr++; + pNC->nNcErr++; } #endif if( is_agg ){ @@ -98753,9 +101457,10 @@ 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; } sqlite3WalkExprList(pWalker, pWin->pPartition); sqlite3WalkExprList(pWalker, pWin->pOrderBy); @@ -98765,7 +101470,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 @@ -98773,16 +101478,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; @@ -98798,15 +101509,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); @@ -98821,7 +101534,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: @@ -98830,7 +101543,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( !ExprHasProperty(pExpr, EP_Reduced) ); /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", ** and "x IS NOT FALSE". */ - if( pRight && pRight->op==TK_ID ){ + if( ALWAYS(pRight) && (pRight->op==TK_ID || pRight->op==TK_TRUEFALSE) ){ int rc = resolveExprStep(pWalker, pRight); if( rc==WRC_Abort ) return WRC_Abort; if( pRight->op==TK_TRUEFALSE ){ @@ -98853,6 +101566,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); @@ -98872,11 +101586,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; } /* @@ -98901,7 +101617,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 @@ -98952,11 +101670,11 @@ static int resolveOrderByTermToExprList( nc.pParse = pParse; nc.pSrcList = pSelect->pSrc; nc.uNC.pEList = pEList; - nc.ncFlags = NC_AllowAgg|NC_UEList; - nc.nErr = 0; + nc.ncFlags = NC_AllowAgg|NC_UEList|NC_NoSelect; + nc.nNcErr = 0; db = pParse->db; savedSuppErr = db->suppressErr; - if( IN_RENAME_OBJECT==0 ) db->suppressErr = 1; + db->suppressErr = 1; rc = sqlite3ResolveExprNames(&nc, pE); db->suppressErr = savedSuppErr; if( rc ) return 0; @@ -98982,11 +101700,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); } /* @@ -99039,9 +101759,10 @@ static int resolveCompoundOrderBy( Expr *pE, *pDup; if( pItem->done ) continue; pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); + 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{ @@ -99054,29 +101775,24 @@ static int resolveCompoundOrderBy( ** Once the comparisons are finished, the duplicate expression ** is deleted. ** - ** Or, if this is running as part of an ALTER TABLE operation, - ** resolve the symbols in the actual expression, not a duplicate. - ** And, if one of the comparisons is successful, leave the expression - ** as is instead of transforming it to an integer as in the usual - ** case. This allows the code in alter.c to modify column - ** refererences within the ORDER BY expression as required. */ - if( IN_RENAME_OBJECT ){ - pDup = pE; - }else{ - pDup = sqlite3ExprDup(db, pE, 0); - } + ** If this is running as part of an ALTER TABLE operation and + ** the symbols resolve successfully, also resolve the symbols in the + ** actual expression. This allows the code in alter.c to modify + ** column references within the ORDER BY expression as required. */ + pDup = sqlite3ExprDup(db, pE, 0); if( !db->mallocFailed ){ assert(pDup); iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup); + if( IN_RENAME_OBJECT && iCol>0 ){ + resolveOrderByTermToExprList(pParse, pSelect, pE); + } } - if( !IN_RENAME_OBJECT ){ - sqlite3ExprDelete(db, pDup); - } + sqlite3ExprDelete(db, pDup); } } if( iCol>0 ){ /* Convert the ORDER BY term into an integer column number iCol, - ** taking care to preserve the COLLATE clause if it exists */ + ** taking care to preserve the COLLATE clause if it exists. */ if( !IN_RENAME_OBJECT ){ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); if( pNew==0 ) return 1; @@ -99142,11 +101858,10 @@ 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, - zType,0); + resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0); } } return 0; @@ -99212,12 +101927,13 @@ static int resolveOrderGroupBy( Parse *pParse; /* Parsing context */ int nResult; /* Number of terms in the result set */ - if( pOrderBy==0 ) return 0; + assert( pOrderBy!=0 ); nResult = pSelect->pEList->nExpr; pParse = pNC->pParse; for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ Expr *pE = pItem->pExpr; Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pE); + if( NEVER(pE2==0) ) continue; if( zType[0]!='G' ){ iCol = resolveAsName(pParse, pSelect->pEList, pE2); if( iCol>0 ){ @@ -99234,7 +101950,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; @@ -99292,7 +102008,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; @@ -99301,8 +102017,10 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ while( p ){ assert( (p->selFlags & SF_Expanded)!=0 ); assert( (p->selFlags & SF_Resolved)==0 ); + assert( db->suppressErr==0 ); /* SF_Resolved not set if errors suppressed */ p->selFlags |= SF_Resolved; + /* Resolve the expressions in the LIMIT and OFFSET clauses. These ** are not allowed to refer to any names, so pass an empty NameContext. */ @@ -99327,30 +102045,30 @@ 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++){ - struct SrcList_item *pItem = &p->pSrc->a[i]; + SrcItem *pItem = &p->pSrc->a[i]; if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ - NameContext *pNC; /* Used to iterate name contexts */ - int nRef = 0; /* Refcount for pOuterNC and outer contexts */ + int nRef = pOuterNC ? pOuterNC->nRef : 0; const char *zSavedContext = pParse->zAuthContext; - /* Count the total number of references to pOuterNC and all of its - ** parent contexts. After resolving references to expressions in - ** pItem->pSelect, check if this value has changed. If so, then - ** SELECT statement pItem->pSelect must be correlated. Set the - ** pItem->fg.isCorrelated flag if this is the case. */ - for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef; - 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 ); - for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef; - assert( pItem->fg.isCorrelated==0 && nRef<=0 ); - pItem->fg.isCorrelated = (nRef!=0); + /* If the number of references to the outer context changed when + ** expressions in the sub-select were resolved, the sub-select + ** is correlated. It is not required to check the refcount on any + ** but the innermost outer context object, as lookupName() increments + ** the refcount on all contexts between the current one and the + ** context containing the column when it resolves a name. */ + if( pOuterNC ){ + assert( pItem->fg.isCorrelated==0 && pOuterNC->nRef>=nRef ); + pItem->fg.isCorrelated = (pOuterNC->nRef>nRef); + } } } @@ -99372,18 +102090,12 @@ 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; } - /* If a HAVING clause is present, then there must be a GROUP BY clause. - */ - if( p->pHaving && !pGroupBy ){ - sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); - return WRC_Abort; - } - /* Add the output column list to the name-context before parsing the ** other expressions in the SELECT statement. This is so that ** expressions in the WHERE clause (etc.) can refer to expressions by @@ -99392,15 +102104,21 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** Minor point: If this is the case, then the expression will be ** re-evaluated for each reference to it. */ - assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert))==0 ); + assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert|NC_UBaseReg))==0 ); sNC.uNC.pEList = p->pEList; sNC.ncFlags |= NC_UEList; - if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; + if( p->pHaving ){ + if( !pGroupBy ){ + sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); + return WRC_Abort; + } + if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; + } if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; /* Resolve names in table-valued-function arguments */ for(i=0; ipSrc->nSrc; i++){ - struct SrcList_item *pItem = &p->pSrc->a[i]; + SrcItem *pItem = &p->pSrc->a[i]; if( pItem->fg.isTabFunc && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) ){ @@ -99408,6 +102126,19 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } } +#ifndef SQLITE_OMIT_WINDOWFUNC + if( IN_RENAME_OBJECT ){ + Window *pWin; + for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){ + if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy) + || sqlite3ResolveExprListNames(&sNC, pWin->pPartition) + ){ + return WRC_Abort; + } + } + } +#endif + /* The ORDER BY and GROUP BY clauses may not refer to terms in ** outer queries */ @@ -99435,7 +102166,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** is not detected until much later, and so we need to go ahead and ** resolve those symbols on the incorrect ORDER BY for consistency. */ - if( isCompound<=nCompound /* Defer right-most ORDER BY of a compound */ + if( p->pOrderBy!=0 + && isCompound<=nCompound /* Defer right-most ORDER BY of a compound */ && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){ return WRC_Abort; @@ -99463,19 +102195,6 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } } -#ifndef SQLITE_OMIT_WINDOWFUNC - if( IN_RENAME_OBJECT ){ - Window *pWin; - for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){ - if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy) - || sqlite3ResolveExprListNames(&sNC, pWin->pPartition) - ){ - return WRC_Abort; - } - } - } -#endif - /* If this is part of a compound SELECT, check that it has the right ** number of expressions in the select list. */ if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){ @@ -99555,11 +102274,11 @@ 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 = resolveSelectStep; + w.xSelectCallback = (pNC->ncFlags & NC_NoSelect) ? 0 : resolveSelectStep; w.xSelectCallback2 = 0; w.u.pNC = pNC; #if SQLITE_MAX_EXPR_DEPTH>0 @@ -99578,7 +102297,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames( testcase( pNC->ncFlags & NC_HasWin ); ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) ); pNC->ncFlags |= savedHasAgg; - return pNC->nErr>0 || w.pParse->nErr>0; + return pNC->nNcErr>0 || w.pParse->nErr>0; } /* @@ -99599,8 +102318,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; @@ -99618,12 +102337,13 @@ 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( pNC->nErr>0 || w.pParse->nErr>0 ) return WRC_Abort; + if( w.pParse->nErr>0 ) return WRC_Abort; } pNC->ncFlags |= savedHasAgg; return WRC_Continue; @@ -99735,9 +102455,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; } /* @@ -99758,36 +102478,44 @@ SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table *pTab, int iCol){ */ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ int op; - while( ExprHasProperty(pExpr, EP_Skip) ){ - assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW ); + while( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){ + assert( pExpr->op==TK_COLLATE + || pExpr->op==TK_IF_NULL_ROW + || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) ); pExpr = pExpr->pLeft; assert( pExpr!=0 ); } op = pExpr->op; + if( op==TK_REGISTER ) op = pExpr->op2; + 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 ); return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); } - if( op==TK_REGISTER ) op = pExpr->op2; #ifndef SQLITE_OMIT_CAST if( op==TK_CAST ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); return sqlite3AffinityType(pExpr->u.zToken, 0); } #endif - if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){ - return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); - } 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; @@ -99802,7 +102530,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 */ @@ -99817,7 +102545,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); @@ -99829,7 +102561,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, con */ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){ while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){ - assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW ); + assert( pExpr->op==TK_COLLATE ); pExpr = pExpr->pLeft; } return pExpr; @@ -99843,12 +102575,12 @@ 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; }else{ - assert( pExpr->op==TK_COLLATE || pExpr->op==TK_IF_NULL_ROW ); + assert( pExpr->op==TK_COLLATE ); pExpr = pExpr->pLeft; } } @@ -99876,27 +102608,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; } @@ -99906,11 +102641,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) ){ @@ -99993,7 +102726,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; @@ -100119,7 +102852,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; } @@ -100129,12 +102862,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; @@ -100157,12 +102892,14 @@ SQLITE_PRIVATE int sqlite3ExprVectorSize(Expr *pExpr){ ** been positioned. */ SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){ - assert( iop==TK_ERROR ); 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; } } @@ -100193,11 +102930,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. @@ -100216,14 +102954,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; } @@ -100273,17 +103020,22 @@ static int exprVectorRegister( int *pRegFree /* OUT: Temp register to free */ ){ u8 op = pVector->op; - assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT ); + assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT || op==TK_ERROR ); if( op==TK_REGISTER ){ *ppExpr = sqlite3VectorFieldSubexpr(pVector, iField); return pVector->iTable+iField; } if( op==TK_SELECT ){ + assert( ExprUseXSelect(pVector) ); *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr; return regSelect+iField; } - *ppExpr = pVector->x.pList->a[iField].pExpr; - return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree); + if( op==TK_VECTOR ){ + assert( ExprUseXList(pVector) ); + *ppExpr = pVector->x.pList->a[iField].pExpr; + return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree); + } + return 0; } /* @@ -100312,6 +103064,7 @@ static void codeVectorCompare( int regLeft = 0; int regRight = 0; u8 opx = op; + int addrCmp = 0; int addrDone = sqlite3VdbeMakeLabel(pParse); int isCommuted = ExprHasProperty(pExpr,EP_Commuted); @@ -100331,21 +103084,24 @@ static void codeVectorCompare( assert( p5==0 || pExpr->op!=op ); assert( p5==SQLITE_NULLEQ || pExpr->op==op ); - p5 |= SQLITE_STOREP2; - if( opx==TK_LE ) opx = TK_LT; - if( opx==TK_GE ) opx = TK_GT; + if( op==TK_LE ) opx = TK_LT; + if( op==TK_GE ) opx = TK_GT; + if( op==TK_NE ) opx = TK_EQ; regLeft = exprCodeSubselect(pParse, pLeft); regRight = exprCodeSubselect(pParse, pRight); + sqlite3VdbeAddOp2(v, OP_Integer, 1, dest); for(i=0; 1 /*Loop exits by "break"*/; i++){ int regFree1 = 0, regFree2 = 0; - Expr *pL, *pR; + Expr *pL = 0, *pR = 0; int r1, r2; assert( i>=0 && i0 @@ -100403,14 +103165,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++){ @@ -100418,8 +103180,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); @@ -100441,10 +103203,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); @@ -100471,7 +103232,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; @@ -100482,7 +103243,8 @@ SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){ ** Expr.flags. */ SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ - if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){ + if( pParse->nErr ) return; + if( p && ExprUseXList(p) && p->x.pList ){ p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); } } @@ -100640,6 +103402,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 @@ -100658,8 +103477,8 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ }else if( (ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight)) && !IN_RENAME_OBJECT ){ - sqlite3ExprDelete(db, pLeft); - sqlite3ExprDelete(db, pRight); + sqlite3ExprDeferredDelete(pParse, pLeft); + sqlite3ExprDeferredDelete(pParse, pRight); return sqlite3Expr(db, TK_INTEGER, "0"); }else{ return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); @@ -100673,7 +103492,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; @@ -100684,12 +103503,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; @@ -100708,8 +103531,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 ); @@ -100724,7 +103547,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); } } } @@ -100780,6 +103603,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; @@ -100807,6 +103631,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); } } @@ -100815,27 +103640,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{ @@ -100847,7 +103671,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); } @@ -100856,6 +103683,22 @@ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ if( p ) sqlite3ExprDeleteNN(db, p); } + +/* +** Arrange to cause pExpr to be deleted when the pParse is deleted. +** This is similar to sqlite3ExprDelete() except that the delete is +** deferred untilthe pParse is deleted. +** +** The pExpr might be deleted immediately on an OOM error. +** +** The deferred delete is (currently) implemented by adding the +** pExpr to the pParse->pConstExpr list with a register number of 0. +*/ +SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ + pParse->pConstExpr = + sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr); +} + /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the ** expression. */ @@ -100873,7 +103716,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; @@ -100913,7 +103756,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 ); @@ -100944,7 +103787,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; @@ -100965,7 +103808,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); @@ -100984,7 +103827,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 */ @@ -100998,6 +103841,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ if( pzBuffer ){ zAlloc = *pzBuffer; staticFlag = EP_Static; + assert( zAlloc!=0 ); }else{ zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags)); staticFlag = 0; @@ -101046,7 +103890,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); @@ -101075,8 +103919,8 @@ 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 ); + assert( p->pRight==0 || p->pRight==p->pLeft + || ExprHasProperty(p->pLeft, EP_Subquery) ); }else{ pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); } @@ -101093,7 +103937,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ ** and the db->mallocFailed flag set. */ #ifndef SQLITE_OMIT_CTE -static With *withDup(sqlite3 *db, With *p){ +SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p){ With *pRet = 0; if( p ){ sqlite3_int64 nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1); @@ -101111,7 +103955,7 @@ static With *withDup(sqlite3 *db, With *p){ return pRet; } #else -# define withDup(x,y) 0 +# define sqlite3WithDup(x,y) 0 #endif #ifndef SQLITE_OMIT_WINDOWFUNC @@ -101164,20 +104008,23 @@ 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)); if( pNew==0 ) return 0; pNew->nExpr = p->nExpr; + pNew->nAlloc = p->nAlloc; pItem = pNew->a; pOldItem = p->a; for(i=0; inExpr; i++, pItem++, pOldItem++){ @@ -101188,16 +104035,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 ); - 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); @@ -101219,7 +104067,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; @@ -101230,8 +104078,8 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; inSrc; i++){ - struct SrcList_item *pNewItem = &pNew->a[i]; - struct SrcList_item *pOldItem = &p->a[i]; + SrcItem *pNewItem = &pNew->a[i]; + const SrcItem *pOldItem = &p->a[i]; Table *pTab; pNewItem->pSchema = pOldItem->pSchema; pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); @@ -101244,7 +104092,10 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ if( pNewItem->fg.isIndexedBy ){ pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); } - pNewItem->pIBIndex = pOldItem->pIBIndex; + pNewItem->u2 = pOldItem->u2; + if( pNewItem->fg.isCte ){ + pNewItem->u2.pCteUse->nUse++; + } if( pNewItem->fg.isTabFunc ){ pNewItem->u1.pFuncArg = sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); @@ -101260,7 +104111,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 ); @@ -101284,11 +104135,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){ @@ -101310,13 +104161,21 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = p->nSelectRow; - pNew->pWith = withDup(db, p->pWith); + pNew->pWith = sqlite3WithDup(db, p->pWith); #ifndef SQLITE_OMIT_WINDOWFUNC pNew->pWin = 0; pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew); #endif pNew->selId = p->selId; + if( db->mallocFailed ){ + /* Any prior OOM might have left the Select object incomplete. + ** Delete the whole thing rather than allow an incomplete Select + ** to be used by the code generator. */ + pNew->pNext = 0; + sqlite3SelectDelete(db, pNew); + break; + } *pp = pNew; pp = &pNew->pPrior; pNext = pNew; @@ -101325,7 +104184,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; } @@ -101347,41 +104206,64 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ ** NULL is returned. If non-NULL is returned, then it is guaranteed ** that the new entry was successfully appended. */ +static const struct ExprList_item zeroItem = {0}; +SQLITE_PRIVATE SQLITE_NOINLINE ExprList *sqlite3ExprListAppendNew( + sqlite3 *db, /* Database handle. Used for memory allocation */ + Expr *pExpr /* Expression to be appended. Might be NULL */ +){ + struct ExprList_item *pItem; + ExprList *pList; + + pList = sqlite3DbMallocRawNN(db, sizeof(ExprList)+sizeof(pList->a[0])*4 ); + if( pList==0 ){ + sqlite3ExprDelete(db, pExpr); + return 0; + } + pList->nAlloc = 4; + pList->nExpr = 1; + pItem = &pList->a[0]; + *pItem = zeroItem; + pItem->pExpr = pExpr; + return pList; +} +SQLITE_PRIVATE SQLITE_NOINLINE ExprList *sqlite3ExprListAppendGrow( + sqlite3 *db, /* Database handle. Used for memory allocation */ + ExprList *pList, /* List to which to append. Might be NULL */ + Expr *pExpr /* Expression to be appended. Might be NULL */ +){ + struct ExprList_item *pItem; + ExprList *pNew; + pList->nAlloc *= 2; + pNew = sqlite3DbRealloc(db, pList, + sizeof(*pList)+(pList->nAlloc-1)*sizeof(pList->a[0])); + if( pNew==0 ){ + sqlite3ExprListDelete(db, pList); + sqlite3ExprDelete(db, pExpr); + return 0; + }else{ + pList = pNew; + } + pItem = &pList->a[pList->nExpr++]; + *pItem = zeroItem; + pItem->pExpr = pExpr; + return pList; +} SQLITE_PRIVATE ExprList *sqlite3ExprListAppend( Parse *pParse, /* Parsing context */ ExprList *pList, /* List to which to append. Might be NULL */ Expr *pExpr /* Expression to be appended. Might be NULL */ ){ struct ExprList_item *pItem; - sqlite3 *db = pParse->db; - assert( db!=0 ); if( pList==0 ){ - pList = sqlite3DbMallocRawNN(db, sizeof(ExprList) ); - if( pList==0 ){ - goto no_mem; - } - pList->nExpr = 0; - }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ - ExprList *pNew; - pNew = sqlite3DbRealloc(db, pList, - sizeof(*pList)+(2*(sqlite3_int64)pList->nExpr-1)*sizeof(pList->a[0])); - if( pNew==0 ){ - goto no_mem; - } - pList = pNew; + return sqlite3ExprListAppendNew(pParse->db,pExpr); + } + if( pList->nAllocnExpr+1 ){ + return sqlite3ExprListAppendGrow(pParse->db,pList,pExpr); } pItem = &pList->a[pList->nExpr++]; - assert( offsetof(struct ExprList_item,zEName)==sizeof(pItem->pExpr) ); - assert( offsetof(struct ExprList_item,pExpr)==0 ); - memset(&pItem->zEName,0,sizeof(*pItem)-offsetof(struct ExprList_item,zEName)); + *pItem = zeroItem; pItem->pExpr = pExpr; return pList; - -no_mem: - /* Avoid leaking memory if malloc has failed. */ - sqlite3ExprDelete(db, pExpr); - sqlite3ExprListDelete(db, pList); - return 0; } /* @@ -101422,11 +104304,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 ); @@ -101500,7 +104380,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 ); @@ -101518,7 +104398,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); } } } @@ -101637,7 +104517,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; @@ -101654,6 +104534,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; @@ -101858,7 +104739,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; } @@ -101946,7 +104827,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 */ @@ -101965,9 +104846,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; } @@ -101994,8 +104875,10 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){ */ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ u8 op; + assert( p!=0 ); while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; + assert( p!=0 ); } op = p->op; if( op==TK_REGISTER ) op = p->op2; @@ -102006,10 +104889,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; @@ -102077,13 +104961,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 */ @@ -102101,7 +104985,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 ); @@ -102254,7 +105138,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++){ @@ -102282,7 +105166,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( /* Code an OP_Transaction and OP_TableLock for . */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iDb>=0 && iDb=0 && iDbtnum, 0, pTab->zName); @@ -102410,7 +105294,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; @@ -102455,10 +105339,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 ); @@ -102508,7 +105392,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 @@ -102572,10 +105456,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); @@ -102584,6 +105469,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; @@ -102604,7 +105490,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")); @@ -102612,7 +105498,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 @@ -102627,19 +105513,23 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( /* If the LHS and RHS of the IN operator do not match, that ** error will have been caught long before we reach this point. */ if( ALWAYS(pEList->nExpr==nVal) ){ + Select *pCopy; SelectDest dest; int i; + int rc; sqlite3SelectDestInit(&dest, SRT_Set, iTab); dest.zAffSdst = exprINAffinity(pParse, pExpr); pSelect->iLimit = 0; testcase( pSelect->selFlags & SF_Distinct ); testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ - if( sqlite3Select(pParse, pSelect, &dest) ){ - sqlite3DbFree(pParse->db, dest.zAffSdst); + pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); + rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); + sqlite3SelectDelete(pParse->db, pCopy); + sqlite3DbFree(pParse->db, dest.zAffSdst); + if( rc ){ sqlite3KeyInfoUnref(pKeyInfo); return; } - sqlite3DbFree(pParse->db, dest.zAffSdst); assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ assert( pEList!=0 ); assert( pEList->nExpr>0 ); @@ -102706,6 +105596,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); @@ -102738,12 +105629,33 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ Vdbe *v = pParse->pVdbe; assert( v!=0 ); + if( pParse->nErr ) return 0; 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 = + sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1; + VdbeComment((v, "return address")); + + /* The evaluation of the EXISTS/SELECT must be repeated every time it ** is encountered if any of the following is true: ** @@ -102755,22 +105667,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ** save the results, and reuse the same result on subsequent invocations. */ if( !ExprHasProperty(pExpr, EP_VarSelect) ){ - /* 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)); - sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, - pExpr->y.sub.iAddr); - return pExpr->iTable; - } - - /* Begin coding the subroutine */ - ExprSetProperty(pExpr, EP_Subrtn); - pExpr->y.sub.regReturn = ++pParse->nMem; - pExpr->y.sub.iAddr = - sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1; - VdbeComment((v, "return address")); - addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } @@ -102819,19 +105715,21 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ } pSel->iLimit = 0; if( sqlite3Select(pParse, pSel, &dest) ){ + pExpr->op2 = pExpr->op; + pExpr->op = TK_ERROR; return 0; } pExpr->iTable = rReg = dest.iSDParm; ExprSetVVAProperty(pExpr, EP_NoReduce); if( addrOnce ){ sqlite3VdbeJumpHere(v, addrOnce); - - /* Subroutine return */ - sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); - sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); - sqlite3ClearTempRegCache(pParse); } + /* 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); return rReg; } #endif /* SQLITE_OMIT_SUBQUERY */ @@ -102845,7 +105743,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) ){ + if( ExprUseXSelect(pIn) && !pParse->db->mallocFailed ){ if( nVector!=pIn->x.pSelect->pEList->nExpr ){ sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector); return 1; @@ -102979,13 +105877,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); @@ -103033,9 +105933,9 @@ static void sqlite3ExprCodeIN( }else{ destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse); } - if( pParse->nErr ) goto sqlite3ExprCodeIN_finished; for(i=0; ipLeft, i); + if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error; if( sqlite3ExprCanBeNull(p) ){ sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2); VdbeCoverage(v); @@ -103173,11 +106073,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 { @@ -103221,9 +106122,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; @@ -103234,7 +106136,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); } @@ -103270,12 +106172,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; } @@ -103334,6 +106237,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int n */ static void exprToRegister(Expr *pExpr, int iReg){ Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); + if( NEVER(p==0) ) return; p->op2 = p->op; p->op = TK_REGISTER; p->iTable = iReg; @@ -103367,6 +106271,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); } @@ -103441,6 +106346,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 ); @@ -103474,7 +106380,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 @@ -103488,7 +106393,7 @@ static int exprCodeInlineFunction( (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]); break; } -#endif +#endif /* !defined(SQLITE_UNTESTABLE) */ } return target; } @@ -103542,7 +106447,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) 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); } @@ -103564,6 +106470,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) */ int aff; iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); + assert( ExprUseYTab(pExpr) ); if( pExpr->y.pTab ){ aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); }else{ @@ -103587,9 +106494,11 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) ** 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 ); @@ -103603,12 +106512,12 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) 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; @@ -103627,6 +106536,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) iTab = pParse->iSelfTab - 1; } } + assert( ExprUseYTab(pExpr) ); iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, pExpr->iColumn, iTab, target, pExpr->op2); @@ -103660,7 +106570,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) ** Expr node to be passed into this function, it will be handled ** sanely and not crash. But keep the assert() to bring the problem ** to the attention of the developers. */ - assert( op==TK_NULL ); + assert( op==TK_NULL || op==TK_ERROR || pParse->db->mallocFailed ); sqlite3VdbeAddOp2(v, OP_Null, 0, target); return target; } @@ -103704,6 +106614,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) 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; @@ -103726,8 +106637,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) }else{ r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); - codeCompare(pParse, pLeft, pExpr->pRight, op, - r1, r2, inReg, SQLITE_STOREP2 | p5, + sqlite3VdbeAddOp2(v, OP_Integer, 1, inReg); + codeCompare(pParse, pLeft, pExpr->pRight, op, r1, r2, + sqlite3VdbeCurrentAddr(v)+2, p5, ExprHasProperty(pExpr,EP_Commuted)); assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le); @@ -103735,6 +106647,11 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); + if( p5==SQLITE_NULLEQ ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, inReg); + }else{ + sqlite3VdbeAddOp3(v, OP_ZeroOrNull, r1, inReg, r2); + } testcase( regFree1==0 ); testcase( regFree2==0 ); } @@ -103837,7 +106754,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) || 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; } @@ -103865,8 +106782,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) ** 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) ); @@ -103878,7 +106795,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) } #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 ){ @@ -103955,7 +106872,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) 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); @@ -103985,7 +106902,10 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) 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); @@ -103997,10 +106917,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) if( pExpr->pLeft->iTable==0 ){ pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft); } - assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT ); - 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); } @@ -104068,9 +106987,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) ** 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 ); @@ -104081,7 +107005,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) 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 @@ -104158,7 +107082,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) 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; @@ -104321,6 +107245,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ int r2; pExpr = sqlite3ExprSkipCollateAndLikely(pExpr); if( ConstFactorOk(pParse) + && ALWAYS(pExpr!=0) && pExpr->op!=TK_REGISTER && sqlite3ExprIsConstantNotJoin(pExpr) ){ @@ -104354,7 +107279,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; @@ -104502,7 +107427,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; @@ -104892,7 +107817,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; @@ -104944,7 +107873,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; @@ -104968,7 +107902,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 @@ -104986,7 +107922,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; } } @@ -105028,7 +107969,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; @@ -105047,7 +107988,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), @@ -105061,9 +108002,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 */ ){ @@ -105075,12 +108016,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; @@ -105156,7 +108098,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; } @@ -105252,10 +108199,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; } @@ -105364,88 +108315,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. -*/ -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 */ +/* Structure used to pass information throught the Walker in order to +** implement sqlite3ReferencesSrcList(). +*/ +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; + } } /* @@ -105476,8 +108464,7 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ pExpr = sqlite3ExprDup(db, pExpr, 0); if( pExpr ){ pAggInfo->aCol[iAgg].pCExpr = pExpr; - pParse->pConstExpr = - sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr); + sqlite3ExprDeferredDelete(pParse, pExpr); } } }else{ @@ -105486,8 +108473,7 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ pExpr = sqlite3ExprDup(db, pExpr, 0); if( pExpr ){ pAggInfo->aFunc[iAgg].pFExpr = pExpr; - pParse->pConstExpr = - sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr); + sqlite3ExprDeferredDelete(pParse, pExpr); } } } @@ -105559,7 +108545,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ /* Check to see if the column is in one of the tables in the FROM ** clause of the aggregate query */ if( ALWAYS(pSrcList!=0) ){ - struct SrcList_item *pItem = pSrcList->a; + SrcItem *pItem = pSrcList->a; for(i=0; inSrc; i++, pItem++){ struct AggInfo_col *pCol; assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); @@ -105582,6 +108568,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; @@ -105630,6 +108617,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ */ struct AggInfo_func *pItem = pAggInfo->aFunc; for(i=0; inFunc; i++, pItem++){ + if( pItem->pFExpr==pExpr ) break; if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){ break; } @@ -105644,7 +108632,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); @@ -105830,6 +108818,7 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){ static int isAlterableTable(Parse *pParse, Table *pTab){ if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) #ifndef SQLITE_OMIT_VIRTUALTABLE + || (pTab->tabFlags & TF_Eponymous)!=0 || ( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(pParse->db) ) @@ -105848,25 +108837,56 @@ static int isAlterableTable(Parse *pParse, Table *pTab){ ** statement to ensure that the operation has not rendered any schema ** objects unusable. */ -static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ +static void renameTestSchema( + Parse *pParse, /* Parse context */ + const char *zDb, /* Name of db to verify schema of */ + int bTemp, /* True if this is the temp db */ + const char *zWhen, /* "when" part of error message */ + int bNoDQS /* Do not allow DQS in the schema */ +){ + 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)=NULL ", + " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %d)=NULL ", zDb, - zDb, bTemp + zDb, bTemp, zWhen, bNoDQS ); 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)=NULL ", - zDb + " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %d)=NULL ", + zDb, zWhen, bNoDQS + ); + } +} + +/* +** Generate VM code to replace any double-quoted strings (but not double-quoted +** identifiers) within the "sql" column of the sqlite_schema table in +** database zDb with their single-quoted equivalents. If argument bTemp is +** not true, similarly update all SQL statements in the sqlite_schema table +** of the temp db. +*/ +static void renameFixQuotes(Parse *pParse, const char *zDb, int bTemp){ + sqlite3NestedParse(pParse, + "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." LEGACY_SCHEMA_TABLE + " SET sql = sqlite_rename_quotefix('temp', sql)" + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" + " AND sql NOT LIKE 'create virtual%%'" ); } } @@ -105875,12 +108895,12 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ ** Generate code to reload the schema for database iDb. And, if iDb!=1, for ** the temp database as well. */ -static void renameReloadSchema(Parse *pParse, int iDb){ +static void renameReloadSchema(Parse *pParse, int iDb, u16 p5){ Vdbe *v = pParse->pVdbe; if( v ){ sqlite3ChangeCookie(pParse, iDb); - sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0); - if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0); + sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0, p5); + if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0, p5); } } @@ -105902,9 +108922,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) ); @@ -105913,7 +108931,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); @@ -105942,7 +108959,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; } @@ -105984,7 +109001,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'" @@ -105994,7 +109011,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 " @@ -106029,7 +109046,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), " "tbl_name = " "CASE WHEN tbl_name=%Q COLLATE nocase AND " - " sqlite_rename_test(%Q, sql, type, name, 1) " + " sqlite_rename_test(%Q, sql, type, name, 1, 'after rename', 0) " "THEN %Q ELSE tbl_name END " "WHERE type IN ('view', 'trigger')" , zDb, zTabName, zName, zTabName, zDb, zName); @@ -106048,13 +109065,12 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( } #endif - renameReloadSchema(pParse, iDb); - renameTestSchema(pParse, zDb, iDb==1); + renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); + renameTestSchema(pParse, zDb, iDb==1, "after rename", 0); exit_rename_table: sqlite3SrcListDelete(db, pSrc); sqlite3DbFree(db, zName); - db->mDbFlags = savedDbFlags; } /* @@ -106095,7 +109111,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 ); @@ -106104,7 +109122,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 ); @@ -106138,7 +109156,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"); } @@ -106175,28 +109194,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 " - "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " + "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+1, + 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); @@ -106205,10 +109226,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); + /* 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 + ); + } + } } /* @@ -106249,7 +109285,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; } @@ -106258,7 +109294,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 @@ -106285,13 +109322,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: @@ -106308,10 +109345,10 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ ** Or, if pTab is not a view or virtual table, zero is returned. */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) -static int isRealTable(Parse *pParse, Table *pTab){ +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 @@ -106321,15 +109358,16 @@ static int isRealTable(Parse *pParse, Table *pTab){ } #endif if( zType ){ - sqlite3ErrorMsg( - pParse, "cannot rename columns of %s \"%s\"", zType, pTab->zName + sqlite3ErrorMsg(pParse, "cannot %s %s \"%s\"", + (bDrop ? "drop column from" : "rename columns of"), + zType, pTab->zName ); return 1; } return 0; } #else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ -# define isRealTable(x,y) (0) +# define isRealTable(x,y,z) (0) #endif /* @@ -106358,7 +109396,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( /* Cannot alter a system table */ if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column; - if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column; + if( SQLITE_OK!=isRealTable(pParse, pTab, 0) ) goto exit_rename_column; /* Which schema holds the table to be altered */ iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -106377,13 +109415,17 @@ 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; } + /* Ensure the schema contains no double-quoted strings */ + renameTestSchema(pParse, zDb, iSchema==1, "", 0); + renameFixQuotes(pParse, zDb, iSchema==1); + /* Do the rename operation using a recursive UPDATE statement that ** uses the sqlite_rename_column() SQL function to compute the new ** CREATE statement text for the sqlite_schema table. @@ -106394,26 +109436,25 @@ 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 ); /* Drop and reload the database schema. */ - renameReloadSchema(pParse, iSchema); - renameTestSchema(pParse, zDb, iSchema==1); + renameReloadSchema(pParse, iSchema, INITFLAG_AlterRename); + renameTestSchema(pParse, zDb, iSchema==1, "after rename", 1); exit_rename_column: sqlite3SrcListDelete(db, pSrc); @@ -106440,7 +109481,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 */ }; @@ -106482,9 +109523,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 ){ @@ -106510,7 +109553,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); @@ -106532,7 +109579,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){ @@ -106548,7 +109595,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; } @@ -106559,15 +109609,31 @@ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ static void renameWalkWith(Walker *pWalker, Select *pSelect){ With *pWith = pSelect->pWith; if( pWith ){ + Parse *pParse = pWalker->pParse; int i; + With *pCopy = 0; + assert( pWith->nCte>0 ); + if( (pWith->a[0].pSelect->selFlags & SF_Expanded)==0 ){ + /* Push a copy of the With object onto the with-stack. We use a copy + ** here as the original will be expanded and resolved (flags SF_Expanded + ** and SF_Resolved) below. And the parser code that uses the with-stack + ** fails if the Select objects on it have already been expanded and + ** resolved. */ + pCopy = sqlite3WithDup(pParse->db, pWith); + pCopy = sqlite3WithPush(pParse, pCopy, 1); + } for(i=0; inCte; i++){ Select *p = pWith->a[i].pSelect; NameContext sNC; memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pWalker->pParse; - sqlite3SelectPrep(sNC.pParse, p, &sNC); + sNC.pParse = pParse; + if( pCopy ) sqlite3SelectPrep(sNC.pParse, p, &sNC); + if( sNC.pParse->db->mallocFailed ) return; sqlite3WalkSelect(pWalker, p); - sqlite3RenameExprlistUnmap(pWalker->pParse, pWith->a[i].pCols); + sqlite3RenameExprlistUnmap(pParse, pWith->a[i].pCols); + } + if( pCopy && pParse->pWith==pCopy ){ + pParse->pWith = pCopy->pOuter; } } } @@ -106577,12 +109643,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); } } } @@ -106594,7 +109660,11 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; int i; if( pParse->nErr ) return WRC_Abort; - if( NEVER(p->selFlags & SF_View) ) return WRC_Prune; + testcase( p->selFlags & SF_View ); + testcase( p->selFlags & SF_CopyCte ); + if( p->selFlags & (SF_View|SF_CopyCte) ){ + return WRC_Prune; + } if( ALWAYS(p->pEList) ){ ExprList *pList = p->pEList; for(i=0; inExpr; i++){ @@ -106607,7 +109677,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); } } @@ -106665,23 +109735,35 @@ static void renameTokenFree(sqlite3 *db, RenameToken *pToken){ /* ** Search the Parse object passed as the first argument for a RenameToken -** object associated with parse tree element pPtr. If found, remove it -** from the Parse object and add it to the list maintained by the -** RenameCtx object passed as the second argument. +** object associated with parse tree element pPtr. If found, return a pointer +** to it. Otherwise, return NULL. +** +** If the second argument passed to this function is not NULL and a matching +** RenameToken object is found, remove it from the Parse object and add it to +** the list maintained by the RenameCtx object. */ -static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){ +static RenameToken *renameTokenFind( + Parse *pParse, + struct RenameCtx *pCtx, + const void *pPtr +){ RenameToken **pp; - assert( pPtr!=0 ); + if( NEVER(pPtr==0) ){ + return 0; + } for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){ if( (*pp)->p==pPtr ){ RenameToken *pToken = *pp; - *pp = pToken->pNext; - pToken->pNext = pCtx->pList; - pCtx->pList = pToken; - pCtx->nList++; - break; + if( pCtx ){ + *pp = pToken->pNext; + pToken->pNext = pCtx->pList; + pCtx->pList = pToken; + pCtx->nList++; + } + return pToken; } } + return 0; } /* @@ -106690,7 +109772,11 @@ static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){ ** descend into sub-select statements. */ static int renameColumnSelectCb(Walker *pWalker, Select *p){ - if( p->selFlags & SF_View ) return WRC_Prune; + if( p->selFlags & (SF_View|SF_CopyCte) ){ + testcase( p->selFlags & SF_View ); + testcase( p->selFlags & SF_CopyCte ); + return WRC_Prune; + } renameWalkWith(pWalker, p); return WRC_Continue; } @@ -106713,6 +109799,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); @@ -106752,7 +109839,7 @@ static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ */ static void renameColumnParseError( sqlite3_context *pCtx, - int bPost, + const char *zWhen, sqlite3_value *pType, sqlite3_value *pObject, Parse *pParse @@ -106761,12 +109848,12 @@ static void renameColumnParseError( const char *zN = (const char*)sqlite3_value_text(pObject); char *zErr; - zErr = sqlite3_mprintf("error in %s %s%s: %s", - zT, zN, (bPost ? " after rename" : ""), + 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); } /* @@ -106778,18 +109865,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); } } } @@ -106803,15 +109890,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); } } } @@ -106830,21 +109917,17 @@ static int renameParseSql( int bTemp /* True if SQL is from temp schema */ ){ int rc; - char *zErr = 0; 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)); + sqlite3ParseObjectInit(p, db); p->eParseMode = PARSE_MODE_RENAME; p->db = db; p->nQueryLoop = 1; - rc = sqlite3RunParser(p, zSql, &zErr); - assert( p->zErrMsg==0 ); - assert( rc!=SQLITE_OK || zErr==0 ); - p->zErrMsg = zErr; + rc = zSql ? sqlite3RunParser(p, zSql) : SQLITE_NOMEM; if( db->mallocFailed ) rc = SQLITE_NOMEM; if( rc==SQLITE_OK && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0 @@ -106884,51 +109967,76 @@ static int renameEditSql( const char *zNew, /* New token text */ int bQuote /* True to always quote token */ ){ - int nNew = sqlite3Strlen30(zNew); - int nSql = sqlite3Strlen30(zSql); + i64 nNew = sqlite3Strlen30(zNew); + i64 nSql = sqlite3Strlen30(zSql); sqlite3 *db = sqlite3_context_db_handle(pCtx); int rc = SQLITE_OK; - char *zQuot; + char *zQuot = 0; char *zOut; - int nQuot; - - /* Set zQuot to point to a buffer containing a quoted copy of the - ** identifier zNew. If the corresponding identifier in the original - ** ALTER TABLE statement was quoted (bQuote==1), then set zNew to - ** point to zQuot so that all substitutions are made using the - ** quoted version of the new column name. */ - zQuot = sqlite3MPrintf(db, "\"%w\"", zNew); - if( zQuot==0 ){ - return SQLITE_NOMEM; + i64 nQuot = 0; + char *zBuf1 = 0; + char *zBuf2 = 0; + + if( zNew ){ + /* Set zQuot to point to a buffer containing a quoted copy of the + ** identifier zNew. If the corresponding identifier in the original + ** ALTER TABLE statement was quoted (bQuote==1), then set zNew to + ** point to zQuot so that all substitutions are made using the + ** quoted version of the new column name. */ + zQuot = sqlite3MPrintf(db, "\"%w\" ", zNew); + if( zQuot==0 ){ + return SQLITE_NOMEM; + }else{ + nQuot = sqlite3Strlen30(zQuot)-1; + } + + assert( nQuot>=nNew ); + zOut = sqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1); }else{ - nQuot = sqlite3Strlen30(zQuot); - } - if( bQuote ){ - zNew = zQuot; - nNew = nQuot; + zOut = (char*)sqlite3DbMallocZero(db, (nSql*2+1) * 3); + if( zOut ){ + zBuf1 = &zOut[nSql*2+1]; + zBuf2 = &zOut[nSql*4+2]; + } } /* At this point pRename->pList contains a list of RenameToken objects ** corresponding to all tokens in the input SQL that must be replaced - ** with the new column name. All that remains is to construct and - ** return the edited SQL string. */ - assert( nQuot>=nNew ); - zOut = sqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1); + ** with the new column name, or with single-quoted versions of themselves. + ** All that remains is to construct and return the edited SQL string. */ if( zOut ){ int nOut = nSql; memcpy(zOut, zSql, nSql); while( pRename->pList ){ int iOff; /* Offset of token to replace in zOut */ - RenameToken *pBest = renameColumnTokenNext(pRename); - u32 nReplace; const char *zReplace; - if( sqlite3IsIdChar(*pBest->t.z) ){ - nReplace = nNew; - zReplace = zNew; + RenameToken *pBest = renameColumnTokenNext(pRename); + + if( zNew ){ + if( bQuote==0 && sqlite3IsIdChar(*pBest->t.z) ){ + nReplace = nNew; + zReplace = zNew; + }else{ + nReplace = nQuot; + zReplace = zQuot; + if( pBest->t.z[pBest->t.n]=='"' ) nReplace++; + } }else{ - nReplace = nQuot; - zReplace = zQuot; + /* Dequote the double-quoted token. Then requote it again, this time + ** using single quotes. If the character immediately following the + ** original token within the input SQL was a single quote ('), then + ** add another space after the new, single-quoted version of the + ** token. This is so that (SELECT "string"'alias') maps to + ** (SELECT 'string' 'alias'), and not (SELECT 'string''alias'). */ + memcpy(zBuf1, pBest->t.z, pBest->t.n); + zBuf1[pBest->t.n] = 0; + sqlite3Dequote(zBuf1); + sqlite3_snprintf(nSql*2, zBuf2, "%Q%s", zBuf1, + pBest->t.z[pBest->t.n]=='\'' ? " " : "" + ); + zReplace = zBuf2; + nReplace = sqlite3Strlen30(zReplace); } iOff = pBest->t.z - zSql; @@ -106994,16 +110102,27 @@ static int renameResolveTrigger(Parse *pParse){ if( pSrc ){ int i; for(i=0; inSrc && rc==SQLITE_OK; i++){ - struct SrcList_item *p = &pSrc->a[i]; - p->pTab = sqlite3LocateTableItem(pParse, 0, p); + SrcItem *p = &pSrc->a[i]; p->iCursor = pParse->nTab++; - if( p->pTab==0 ){ - rc = SQLITE_ERROR; + if( p->pSelect ){ + sqlite3SelectPrep(pParse, p->pSelect, 0); + sqlite3ExpandSubquery(pParse, p); + assert( i>0 ); + assert( pStep->pFrom->a[i-1].pSelect ); + sqlite3SelectPrep(pParse, pStep->pFrom->a[i-1].pSelect, 0); }else{ - p->pTab->nTabRef++; - rc = sqlite3ViewGetColumnNames(pParse, p->pTab); + p->pTab = sqlite3LocateTableItem(pParse, 0, p); + if( p->pTab==0 ){ + rc = SQLITE_ERROR; + }else{ + p->pTab->nTabRef++; + rc = sqlite3ViewGetColumnNames(pParse, p->pTab); + } } } + if( rc==SQLITE_OK && db->mallocFailed ){ + rc = SQLITE_NOMEM; + } sNC.pSrcList = pSrc; if( rc==SQLITE_OK && pStep->pWhere ){ rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere); @@ -107012,9 +110131,8 @@ static int renameResolveTrigger(Parse *pParse){ rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList); } assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) ); - if( pStep->pUpsert ){ + if( pStep->pUpsert && rc==SQLITE_OK ){ Upsert *pUpsert = pStep->pUpsert; - assert( rc==SQLITE_OK ); pUpsert->pUpsertSrc = pSrc; sNC.uNC.pUpsert = pUpsert; sNC.ncFlags = NC_UUpsert; @@ -107063,6 +110181,12 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere); sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere); } + if( pStep->pFrom ){ + int i; + for(i=0; ipFrom->nSrc; i++){ + sqlite3WalkSelect(pWalker, pStep->pFrom->a[i].pSelect); + } + } } } @@ -107084,13 +110208,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.) @@ -107108,7 +110232,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, @@ -107146,7 +110271,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); @@ -107165,8 +110290,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); @@ -107175,16 +110300,17 @@ 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 ){ - renameTokenFind( - &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zName - ); + if( iColnCol ){ + renameTokenFind( + &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zCnName + ); + } if( sCtx.iCol<0 ){ renameTokenFind(&sParse, &sCtx, (void*)&sParse.pNewTable->iPKey); } @@ -107195,14 +110321,17 @@ static void renameColumnFunc( for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){ sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } - } #ifndef SQLITE_OMIT_GENERATED_COLUMNS - for(i=0; inCol; i++){ - sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); - } + for(i=0; inCol; i++){ + 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]); @@ -107253,8 +110382,10 @@ static void renameColumnFunc( renameColumnFunc_done: if( rc!=SQLITE_OK ){ - if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + 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); } @@ -107273,7 +110404,10 @@ static void renameColumnFunc( */ 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; @@ -107286,13 +110420,17 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ int i; RenameCtx *p = pWalker->u.pRename; SrcList *pSrc = pSelect->pSrc; - if( pSelect->selFlags & SF_View ) return WRC_Prune; - if( pSrc==0 ){ + if( pSelect->selFlags & (SF_View|SF_CopyCte) ){ + testcase( pSelect->selFlags & SF_View ); + testcase( pSelect->selFlags & SF_CopyCte ); + return WRC_Prune; + } + if( NEVER(pSrc==0) ){ assert( pWalker->pParse->db->mallocFailed ); return WRC_Abort; } for(i=0; inSrc; i++){ - struct SrcList_item *pItem = &pSrc->a[i]; + SrcItem *pItem = &pSrc->a[i]; if( pItem->pTab==p->pTab ){ renameTokenFind(pWalker->pParse, p, pItem->zName); } @@ -107364,28 +110502,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); } @@ -107442,8 +110583,10 @@ static void renameTableFunc( rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote); } if( rc!=SQLITE_OK ){ - if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + 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); } @@ -107460,7 +110603,131 @@ static void renameTableFunc( return; } -/* +static int renameQuotefixExprCb(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_STRING && (pExpr->flags & EP_DblQuoted) ){ + renameTokenFind(pWalker->pParse, pWalker->u.pRename, (const void*)pExpr); + } + return WRC_Continue; +} + +/* 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: +** +** 0: Database name ("main", "temp" etc.). +** 1: SQL statement to edit. +** +** The returned value is the modified SQL statement. For example, given +** the database schema: +** +** CREATE TABLE t1(a, b, c); +** +** SELECT sqlite_rename_quotefix('main', +** 'CREATE VIEW v1 AS SELECT "a", "string" FROM t1' +** ); +** +** 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, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + char const *zDb = (const char*)sqlite3_value_text(argv[0]); + char const *zInput = (const char*)sqlite3_value_text(argv[1]); + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + sqlite3BtreeEnterAll(db); + + UNUSED_PARAMETER(NotUsed); + if( zDb && zInput ){ + int rc; + Parse sParse; + rc = renameParseSql(&sParse, zDb, db, zInput, 0); + + if( rc==SQLITE_OK ){ + RenameCtx sCtx; + Walker sWalker; + + /* Walker to find tokens that need to be replaced. */ + memset(&sCtx, 0, sizeof(RenameCtx)); + memset(&sWalker, 0, sizeof(Walker)); + sWalker.pParse = &sParse; + sWalker.xExprCallback = renameQuotefixExprCb; + sWalker.xSelectCallback = renameColumnSelectCb; + sWalker.u.pRename = &sCtx; + + if( sParse.pNewTable ){ + if( IsView(sParse.pNewTable) ){ + Select *pSelect = sParse.pNewTable->u.view.pSelect; + pSelect->selFlags &= ~SF_View; + sParse.rc = SQLITE_OK; + sqlite3SelectPrep(&sParse, pSelect, 0); + rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); + if( rc==SQLITE_OK ){ + sqlite3WalkSelect(&sWalker, pSelect); + } + }else{ + int i; + sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); +#ifndef SQLITE_OMIT_GENERATED_COLUMNS + for(i=0; inCol; i++){ + sqlite3WalkExpr(&sWalker, + sqlite3ColumnExpr(sParse.pNewTable, + &sParse.pNewTable->aCol[i])); + } +#endif /* SQLITE_OMIT_GENERATED_COLUMNS */ + } + }else if( sParse.pNewIndex ){ + sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); + sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); + }else{ +#ifndef SQLITE_OMIT_TRIGGER + rc = renameResolveTrigger(&sParse); + if( rc==SQLITE_OK ){ + renameWalkTrigger(&sWalker, sParse.pNewTrigger); + } +#endif /* SQLITE_OMIT_TRIGGER */ + } + + if( rc==SQLITE_OK ){ + rc = renameEditSql(context, &sCtx, zInput, 0, 0); + } + renameTokenFree(db, sCtx.pList); + } + if( rc!=SQLITE_OK ){ + if( sqlite3WritableSchema(db) && rc==SQLITE_ERROR ){ + sqlite3_result_value(context, argv[1]); + }else{ + sqlite3_result_error_code(context, rc); + } + } + renameParseCleanup(&sParse); + } + +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + + 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 @@ -107472,12 +110739,16 @@ static void renameTableFunc( ** 2: Object type ("view", "table", "trigger" or "index"). ** 3: Object name. ** 4: True if object is from temp schema. +** 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, @@ -107489,6 +110760,8 @@ static void renameTableTest( char const *zInput = (const char*)sqlite3_value_text(argv[1]); int bTemp = sqlite3_value_int(argv[4]); int isLegacy = (db->flags & SQLITE_LegacyAlter); + char const *zWhen = (const char*)sqlite3_value_text(argv[5]); + int bNoDQS = sqlite3_value_int(argv[6]); #ifndef SQLITE_OMIT_AUTHORIZATION sqlite3_xauth xAuth = db->xAuth; @@ -107496,16 +110769,20 @@ static void renameTableTest( #endif UNUSED_PARAMETER(NotUsed); + if( zDb && zInput ){ int rc; Parse sParse; + int flags = db->flags; + if( bNoDQS ) db->flags &= ~(SQLITE_DqsDML|SQLITE_DqsDDL); 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; } @@ -107516,13 +110793,17 @@ 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 ){ - renameColumnParseError(context, 1, argv[2], argv[3], &sParse); + if( rc!=SQLITE_OK && zWhen && !sqlite3WritableSchema(db) ){ + /* Output case A */ + renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse); } renameParseCleanup(&sParse); } @@ -107532,14 +110813,232 @@ static void renameTableTest( #endif } +/* +** The implementation of internal UDF sqlite_drop_column(). +** +** Arguments: +** +** argv[0]: An integer - the index of the schema containing the table +** argv[1]: CREATE TABLE statement to modify. +** argv[2]: An integer - the index of the column to remove. +** +** The value returned is a string containing the CREATE TABLE statement +** with column argv[2] removed. +*/ +static void dropColumnFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + int iSchema = sqlite3_value_int(argv[0]); + const char *zSql = (const char*)sqlite3_value_text(argv[1]); + int iCol = sqlite3_value_int(argv[2]); + const char *zDb = db->aDb[iSchema].zDbSName; + int rc; + Parse sParse; + RenameToken *pCol; + Table *pTab; + const char *zEnd; + char *zNew = 0; + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + UNUSED_PARAMETER(NotUsed); + rc = renameParseSql(&sParse, zDb, db, zSql, iSchema==1); + if( rc!=SQLITE_OK ) goto drop_column_done; + pTab = sParse.pNewTable; + if( pTab==0 || pTab->nCol==1 || iCol>=pTab->nCol ){ + /* This can happen if the sqlite_schema table is corrupt */ + rc = SQLITE_CORRUPT_BKPT; + goto drop_column_done; + } + + pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zCnName); + if( iColnCol-1 ){ + RenameToken *pEnd; + pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zCnName); + zEnd = (const char*)pEnd->t.z; + }else{ + 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--; + } + + zNew = sqlite3MPrintf(db, "%.*s%s", pCol->t.z-zSql, zSql, zEnd); + sqlite3_result_text(context, zNew, -1, SQLITE_TRANSIENT); + sqlite3_free(zNew); + +drop_column_done: + renameParseCleanup(&sParse); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(context, rc); + } +} + +/* +** This function is called by the parser upon parsing an +** +** ALTER TABLE pSrc DROP COLUMN pName +** +** 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, const Token *pName){ + sqlite3 *db = pParse->db; /* Database handle */ + Table *pTab; /* Table to modify */ + int iDb; /* Index of db containing pTab in aDb[] */ + const char *zDb; /* Database containing pTab ("main" etc.) */ + char *zCol = 0; /* Name of column to drop */ + int iCol; /* Index of column zCol in pTab->aCol[] */ + + /* Look up the table being altered. */ + assert( pParse->pNewTable==0 ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + if( NEVER(db->mallocFailed) ) goto exit_drop_column; + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_drop_column; + + /* Make sure this is not an attempt to ALTER a view, virtual table or + ** system table. */ + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_drop_column; + if( SQLITE_OK!=isRealTable(pParse, pTab, 1) ) goto exit_drop_column; + + /* Find the index of the column being dropped. */ + zCol = sqlite3NameFromToken(db, pName); + if( zCol==0 ){ + assert( db->mallocFailed ); + goto exit_drop_column; + } + iCol = sqlite3ColumnIndex(pTab, zCol); + if( iCol<0 ){ + sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pName); + goto exit_drop_column; + } + + /* Do not allow the user to drop a PRIMARY KEY column or a column + ** constrained by a UNIQUE constraint. */ + if( pTab->aCol[iCol].colFlags & (COLFLAG_PRIMKEY|COLFLAG_UNIQUE) ){ + sqlite3ErrorMsg(pParse, "cannot drop %s column: \"%s\"", + (pTab->aCol[iCol].colFlags&COLFLAG_PRIMKEY) ? "PRIMARY KEY" : "UNIQUE", + zCol + ); + goto exit_drop_column; + } + + /* Do not allow the number of columns to go to zero */ + if( pTab->nCol<=1 ){ + sqlite3ErrorMsg(pParse, "cannot drop column \"%s\": no other columns exist",zCol); + goto exit_drop_column; + } + + /* Edit the sqlite_schema table */ + 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\"." 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 + ); + + /* Drop and reload the database schema. */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterDrop); + renameTestSchema(pParse, zDb, iDb==1, "after drop column", 1); + + /* Edit rows of table on disk */ + if( pParse->nErr==0 && (pTab->aCol[iCol].colFlags & COLFLAG_VIRTUAL)==0 ){ + int i; + int addr; + int reg; + int regRec; + Index *pPk = 0; + int nField = 0; /* Number of non-virtual columns after drop */ + int iCur; + Vdbe *v = sqlite3GetVdbe(pParse); + iCur = pParse->nTab++; + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); + addr = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); + reg = ++pParse->nMem; + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, reg); + pParse->nMem += pTab->nCol; + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + pParse->nMem += pPk->nColumn; + for(i=0; inKeyCol; i++){ + sqlite3VdbeAddOp3(v, OP_Column, iCur, i, reg+i+1); + } + nField = pPk->nKeyCol; + } + regRec = ++pParse->nMem; + for(i=0; inCol; i++){ + if( i!=iCol && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ + int regOut; + if( pPk ){ + int iPos = sqlite3TableColumnToIndex(pPk, i); + int iColPos = sqlite3TableColumnToIndex(pPk, iCol); + if( iPosnKeyCol ) continue; + regOut = reg+1+iPos-(iPos>iColPos); + }else{ + regOut = reg+1+nField; + } + if( i==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regOut); + }else{ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut); + } + 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); + }else{ + sqlite3VdbeAddOp3(v, OP_Insert, iCur, regRec, reg); + } + sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); + + sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr); + } + +exit_drop_column: + sqlite3DbFree(db, zCol); + sqlite3SrcListDelete(db, pSrc); +} + /* ** Register built-in functions used to help implement ALTER TABLE */ SQLITE_PRIVATE void sqlite3AlterFunctions(void){ static FuncDef aAlterTableFuncs[] = { - INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), - INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), - INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest), + INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), + INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), + INTERNAL_FUNCTION(sqlite_rename_test, 7, renameTableTest), + INTERNAL_FUNCTION(sqlite_drop_column, 3, dropColumnFunc), + INTERNAL_FUNCTION(sqlite_rename_quotefix,2, renameQuotefixFunc), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); } @@ -107982,7 +111481,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); @@ -108401,28 +111899,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 ){ @@ -108441,6 +111930,8 @@ static void statGet( } }else{ tRowcnt *aCnt = 0; + sqlite3_str sStat; + int i; assert( p->iGetnSample ); switch( eCall ){ @@ -108452,23 +111943,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 @@ -108517,7 +111997,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 @@ -108564,7 +112044,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; } @@ -109321,6 +112801,7 @@ static int loadStatTbl( } pSpace = (tRowcnt*)&pIdx->aSample[nSample]; pIdx->aAvgEq = pSpace; pSpace += nIdxCol; + pIdx->pTable->tabFlags |= TF_HasStat4; for(i=0; iaSample[i].anEq = pSpace; pSpace += nIdxCol; pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; @@ -109388,9 +112869,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", @@ -109427,6 +112911,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 ); @@ -109449,7 +112934,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 ){ @@ -109589,7 +113076,7 @@ static void attachFunc( if( zFile==0 ) zFile = ""; if( zName==0 ) zName = ""; -#ifdef SQLITE_ENABLE_DESERIALIZE +#ifndef SQLITE_OMIT_DESERIALIZE # define REOPEN_AS_MEMDB(db) (db->init.reopenMemdb) #else # define REOPEN_AS_MEMDB(db) (0) @@ -109787,7 +113274,9 @@ static void detachFunc( sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); goto detach_error; } - if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){ + if( sqlite3BtreeTxnState(pDb->pBt)!=SQLITE_TXN_NONE + || sqlite3BtreeIsInBackup(pDb->pBt) + ){ sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); goto detach_error; } @@ -109838,17 +113327,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; @@ -109925,6 +113415,65 @@ SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *p } #endif /* SQLITE_OMIT_ATTACH */ +/* +** Expression callback used by sqlite3FixAAAA() routines. +*/ +static int fixExprCb(Walker *p, Expr *pExpr){ + DbFixer *pFix = p->u.pFix; + if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL); + if( pExpr->op==TK_VARIABLE ){ + if( pFix->pParse->db->init.busy ){ + pExpr->op = TK_NULL; + }else{ + sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); + return WRC_Abort; + } + } + return WRC_Continue; +} + +/* +** Select callback used by sqlite3FixAAAA() routines. +*/ +static int fixSelectCb(Walker *p, Select *pSelect){ + DbFixer *pFix = p->u.pFix; + int i; + SrcItem *pItem; + sqlite3 *db = pFix->pParse->db; + int iDb = sqlite3FindDbName(db, pFix->zDb); + SrcList *pList = pSelect->pSrc; + + if( NEVER(pList==0) ) return WRC_Continue; + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ + if( pFix->bTemp==0 ){ + if( pItem->zDatabase ){ + if( iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ + sqlite3ErrorMsg(pFix->pParse, + "%s %T cannot reference objects in database %s", + pFix->zType, pFix->pName, pItem->zDatabase); + return WRC_Abort; + } + sqlite3DbFree(db, pItem->zDatabase); + pItem->zDatabase = 0; + pItem->fg.notCte = 1; + } + pItem->pSchema = pFix->pSchema; + pItem->fg.fromDDL = 1; + } +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) + if( sqlite3WalkExpr(&pFix->w, pList->a[i].pOn) ) return WRC_Abort; +#endif + } + if( pSelect->pWith ){ + for(i=0; ipWith->nCte; i++){ + if( sqlite3WalkSelect(p, pSelect->pWith->a[i].pSelect) ){ + return WRC_Abort; + } + } + } + return WRC_Continue; +} + /* ** Initialize a DbFixer structure. This routine must be called prior ** to passing the structure to one of the sqliteFixAAAA() routines below. @@ -109936,9 +113485,7 @@ SQLITE_PRIVATE void sqlite3FixInit( const char *zType, /* "view", "trigger", or "index" */ const Token *pName /* Name of the view, trigger, or index */ ){ - sqlite3 *db; - - db = pParse->db; + sqlite3 *db = pParse->db; assert( db->nDb>iDb ); pFix->pParse = pParse; pFix->zDb = db->aDb[iDb].zDbSName; @@ -109946,6 +113493,13 @@ SQLITE_PRIVATE void sqlite3FixInit( pFix->zType = zType; pFix->pName = pName; pFix->bTemp = (iDb==1); + pFix->w.pParse = pParse; + pFix->w.xExprCallback = fixExprCb; + pFix->w.xSelectCallback = fixSelectCb; + pFix->w.xSelectCallback2 = sqlite3WalkWinDefnDummyCallback; + pFix->w.walkerDepth = 0; + pFix->w.eCode = 0; + pFix->w.u.pFix = pFix; } /* @@ -109966,115 +113520,27 @@ SQLITE_PRIVATE int sqlite3FixSrcList( DbFixer *pFix, /* Context of the fixation */ SrcList *pList /* The Source list to check and modify */ ){ - int i; - struct SrcList_item *pItem; - sqlite3 *db = pFix->pParse->db; - int iDb = sqlite3FindDbName(db, pFix->zDb); - - if( NEVER(pList==0) ) return 0; - - for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pFix->bTemp==0 ){ - if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ - sqlite3ErrorMsg(pFix->pParse, - "%s %T cannot reference objects in database %s", - pFix->zType, pFix->pName, pItem->zDatabase); - return 1; - } - sqlite3DbFree(db, pItem->zDatabase); - pItem->zDatabase = 0; - pItem->pSchema = pFix->pSchema; - pItem->fg.fromDDL = 1; - } -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) - if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; - if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; -#endif - if( pItem->fg.isTabFunc && sqlite3FixExprList(pFix, pItem->u1.pFuncArg) ){ - return 1; - } + int res = 0; + if( pList ){ + Select s; + memset(&s, 0, sizeof(s)); + s.pSrc = pList; + res = sqlite3WalkSelect(&pFix->w, &s); } - return 0; + return res; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) SQLITE_PRIVATE int sqlite3FixSelect( DbFixer *pFix, /* Context of the fixation */ Select *pSelect /* The SELECT statement to be fixed to one database */ ){ - while( pSelect ){ - if( sqlite3FixExprList(pFix, pSelect->pEList) ){ - return 1; - } - if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ - return 1; - } - if( pSelect->pWith ){ - int i; - for(i=0; ipWith->nCte; i++){ - if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){ - return 1; - } - } - } - pSelect = pSelect->pPrior; - } - return 0; + return sqlite3WalkSelect(&pFix->w, pSelect); } SQLITE_PRIVATE int sqlite3FixExpr( DbFixer *pFix, /* Context of the fixation */ Expr *pExpr /* The expression to be fixed to one database */ ){ - while( pExpr ){ - if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL); - if( pExpr->op==TK_VARIABLE ){ - if( pFix->pParse->db->init.busy ){ - pExpr->op = TK_NULL; - }else{ - sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); - return 1; - } - } - if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break; - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; - }else{ - if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; - } - if( sqlite3FixExpr(pFix, pExpr->pRight) ){ - return 1; - } - pExpr = pExpr->pLeft; - } - return 0; -} -SQLITE_PRIVATE int sqlite3FixExprList( - DbFixer *pFix, /* Context of the fixation */ - ExprList *pList /* The expression to be fixed to one database */ -){ - int i; - struct ExprList_item *pItem; - if( pList==0 ) return 0; - for(i=0, pItem=pList->a; inExpr; i++, pItem++){ - if( sqlite3FixExpr(pFix, pItem->pExpr) ){ - return 1; - } - } - return 0; + return sqlite3WalkExpr(&pFix->w, pExpr); } #endif @@ -110084,32 +113550,30 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep( TriggerStep *pStep /* The trigger step be fixed to one database */ ){ while( pStep ){ - if( sqlite3FixSelect(pFix, pStep->pSelect) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pStep->pWhere) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pStep->pExprList) ){ - return 1; - } - if( pStep->pFrom && sqlite3FixSrcList(pFix, pStep->pFrom) ){ + if( sqlite3WalkSelect(&pFix->w, pStep->pSelect) + || sqlite3WalkExpr(&pFix->w, pStep->pWhere) + || sqlite3WalkExprList(&pFix->w, pStep->pExprList) + || sqlite3FixSrcList(pFix, pStep->pFrom) + ){ return 1; } #ifndef SQLITE_OMIT_UPSERT - if( pStep->pUpsert ){ - Upsert *pUp = pStep->pUpsert; - if( sqlite3FixExprList(pFix, pUp->pUpsertTarget) - || sqlite3FixExpr(pFix, pUp->pUpsertTargetWhere) - || sqlite3FixExprList(pFix, pUp->pUpsertSet) - || sqlite3FixExpr(pFix, pUp->pUpsertWhere) - ){ - return 1; + { + Upsert *pUp; + for(pUp=pStep->pUpsert; pUp; pUp=pUp->pNextUpsert){ + if( sqlite3WalkExprList(&pFix->w, pUp->pUpsertTarget) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertTargetWhere) + || sqlite3WalkExprList(&pFix->w, pUp->pUpsertSet) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertWhere) + ){ + return 1; + } } } #endif pStep = pStep->pNext; } + return 0; } #endif @@ -110261,7 +113725,6 @@ SQLITE_PRIVATE void sqlite3AuthRead( Schema *pSchema, /* The schema of the expression */ SrcList *pTabList /* All table that pExpr might refer to */ ){ - sqlite3 *db = pParse->db; Table *pTab = 0; /* The table being read */ const char *zCol; /* Name of the column of the table */ int iSrc; /* Index in pTabList->a[] of table being read */ @@ -110269,8 +113732,8 @@ SQLITE_PRIVATE void sqlite3AuthRead( int iCol; /* Index of column in table */ assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); - assert( !IN_RENAME_OBJECT || db->xAuth==0 ); - if( db->xAuth==0 ) return; + assert( !IN_RENAME_OBJECT ); + assert( pParse->db->xAuth!=0 ); iDb = sqlite3SchemaToIndex(pParse->db, pSchema); if( iDb<0 ){ /* An attempt to read a column out of a subquery or other @@ -110282,7 +113745,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( pTab = pParse->pTriggerTab; }else{ assert( pTabList ); - for(iSrc=0; ALWAYS(iSrcnSrc); iSrc++){ + for(iSrc=0; iSrcnSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ pTab = pTabList->a[iSrc].pTab; break; @@ -110290,18 +113753,18 @@ SQLITE_PRIVATE void sqlite3AuthRead( } } iCol = pExpr->iColumn; - if( NEVER(pTab==0) ) return; + if( pTab==0 ) return; 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"; } - assert( iDb>=0 && iDbnDb ); + assert( iDb>=0 && iDbdb->nDb ); if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ pExpr->op = TK_NULL; } @@ -110327,11 +113790,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck( ** or if the parser is being invoked from within sqlite3_declare_vtab. */ assert( !IN_RENAME_OBJECT || db->xAuth==0 ); - if( db->init.busy || IN_SPECIAL_PARSE ){ - return SQLITE_OK; - } - - if( db->xAuth==0 ){ + if( db->xAuth==0 || db->init.busy || IN_SPECIAL_PARSE ){ return SQLITE_OK; } @@ -110440,21 +113899,20 @@ struct TableLock { ** code to make the lock occur is generated by a later call to ** codeTableLocks() which occurs during sqlite3FinishCoding(). */ -SQLITE_PRIVATE void sqlite3TableLock( +static SQLITE_NOINLINE void lockTable( Parse *pParse, /* Parsing context */ int iDb, /* Index of the database containing the table to lock */ Pgno iTab, /* Root page number of the table to be locked */ u8 isWriteLock, /* True for a write lock */ const char *zName /* Name of the table to be locked */ ){ - Parse *pToplevel = sqlite3ParseToplevel(pParse); + Parse *pToplevel; int i; int nBytes; TableLock *p; assert( iDb>=0 ); - if( iDb==1 ) return; - if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return; + pToplevel = sqlite3ParseToplevel(pParse); for(i=0; inTableLock; i++){ p = &pToplevel->aTableLock[i]; if( p->iDb==iDb && p->iTab==iTab ){ @@ -110477,6 +113935,17 @@ SQLITE_PRIVATE void sqlite3TableLock( sqlite3OomFault(pToplevel->db); } } +SQLITE_PRIVATE void sqlite3TableLock( + Parse *pParse, /* Parsing context */ + int iDb, /* Index of the database containing the table to lock */ + Pgno iTab, /* Root page number of the table to be locked */ + u8 isWriteLock, /* True for a write lock */ + const char *zName /* Name of the table to be locked */ +){ + if( iDb==1 ) return; + if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return; + lockTable(pParse, iDb, iTab, isWriteLock, zName); +} /* ** Code an OP_TableLock instruction for each table locked by the @@ -110484,10 +113953,8 @@ SQLITE_PRIVATE void sqlite3TableLock( */ static void codeTableLocks(Parse *pParse){ int i; - Vdbe *pVdbe; - - pVdbe = sqlite3GetVdbe(pParse); - assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */ + Vdbe *pVdbe = pParse->pVdbe; + assert( pVdbe!=0 ); for(i=0; inTableLock; i++){ TableLock *p = &pParse->aTableLock[i]; @@ -110529,19 +113996,52 @@ 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 */ - v = sqlite3GetVdbe(pParse); + v = pParse->pVdbe; + if( v==0 ){ + if( db->init.busy ){ + pParse->rc = SQLITE_DONE; + return; + } + v = sqlite3GetVdbe(pParse); + if( v==0 ) pParse->rc = SQLITE_ERROR; + } assert( !pParse->isMultiWrite || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ + if( pParse->bReturning ){ + Returning *pReturning = pParse->u1.pReturning; + int addrRewind; + int i; + int reg; + + 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); + } + } sqlite3VdbeAddOp0(v, OP_Halt); #if SQLITE_USER_AUTHENTICATION @@ -110619,15 +114119,25 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ } } + if( pParse->bReturning ){ + Returning *pRet = pParse->u1.pReturning; + 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. */ sqlite3VdbeGoto(v, 1); } } - /* 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 ); @@ -110641,20 +114151,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; @@ -110673,8 +114184,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--; @@ -110731,17 +114245,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); } } } @@ -110759,11 +114273,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); } } } @@ -110803,12 +114317,13 @@ SQLITE_PRIVATE Table *sqlite3LocateTable( /* If zName is the not the name of a table in the schema created using ** CREATE, then check to see if it is the name of an virtual table that ** can be an eponymous virtual table. */ - if( pParse->disableVtab==0 ){ + if( pParse->disableVtab==0 && db->init.busy==0 ){ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ pMod = sqlite3PragmaVtabRegister(db, zName); } if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ + testcase( pMod->pEpoTab==0 ); return pMod->pEpoTab; } } @@ -110826,6 +114341,8 @@ SQLITE_PRIVATE Table *sqlite3LocateTable( }else{ sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); } + }else{ + assert( HasRowid(p) || p->iPKey<0 ); } return p; @@ -110843,7 +114360,7 @@ SQLITE_PRIVATE Table *sqlite3LocateTable( SQLITE_PRIVATE Table *sqlite3LocateTableItem( Parse *pParse, u32 flags, - struct SrcList_item *p + SrcItem *p ){ const char *zDb; assert( p->pSchema==0 || p->zDatabase==0 ); @@ -110856,6 +114373,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 @@ -111020,6 +114553,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). @@ -111030,12 +114641,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; + } + } } } @@ -111087,19 +114706,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 */ @@ -111145,10 +114770,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; @@ -111162,7 +114787,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; @@ -111242,7 +114867,7 @@ SQLITE_PRIVATE int sqlite3TwoPartName( return -1; } }else{ - assert( db->init.iDb==0 || db->init.busy || IN_RENAME_OBJECT + assert( db->init.iDb==0 || db->init.busy || IN_SPECIAL_PARSE || (db->mDbFlags & DBFLAG_Vacuum)!=0); iDb = db->init.iDb; *pUnqual = pName1; @@ -111411,6 +115036,23 @@ SQLITE_PRIVATE i16 sqlite3TableColumnToStorage(Table *pTab, i16 iCol){ } #endif +/* +** Insert a single OP_JournalMode query opcode in order to force the +** prepared statement to return false for sqlite3_stmt_readonly(). This +** is used by CREATE TABLE IF NOT EXISTS and similar if the table already +** exists, so that the prepared statement for CREATE TABLE IF NOT EXISTS +** will return false for sqlite3_stmt_readonly() even if that statement +** is a read-only no-op. +*/ +static void sqlite3ForceNotReadOnly(Parse *pParse){ + int iReg = ++pParse->nMem; + Vdbe *v = sqlite3GetVdbe(pParse); + if( v ){ + sqlite3VdbeAddOp3(v, OP_JournalMode, 0, iReg, PAGER_JOURNALMODE_QUERY); + sqlite3VdbeUsesBtree(v, 0); + } +} + /* ** Begin constructing a new table representation in memory. This is ** the first of several action routines that get called in response @@ -111506,10 +115148,12 @@ 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); + sqlite3ForceNotReadOnly(pParse); } goto begin_table_error; } @@ -111538,17 +115182,6 @@ SQLITE_PRIVATE void sqlite3StartTable( assert( pParse->pNewTable==0 ); pParse->pNewTable = pTable; - /* If this is the magic sqlite_sequence table used by autoincrement, - ** then record a pointer to this table in the main database structure - ** so that INSERT can find the table easily. - */ -#ifndef SQLITE_OMIT_AUTOINCREMENT - if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){ - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - pTable->pSchema->pSeqTab = pTable; - } -#endif - /* Begin generating the code that will insert the table record into ** the schema table. Note in particular that we must go ahead ** and allocate the record number for the table entry now. Before any @@ -111601,7 +115234,8 @@ SQLITE_PRIVATE void sqlite3StartTable( }else #endif { - pParse->addrCrTab = + assert( !pParse->bReturning ); + pParse->u1.addrCrTab = sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); } sqlite3OpenSchemaTable(pParse, iDb); @@ -111617,6 +115251,7 @@ SQLITE_PRIVATE void sqlite3StartTable( /* If an error occurs, we jump here */ begin_table_error: + pParse->checkSchema = 1; sqlite3DbFree(db, zName); return; } @@ -111626,14 +115261,88 @@ SQLITE_PRIVATE void sqlite3StartTable( */ #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) ){ pTab->tabFlags |= TF_OOOHidden; } } #endif +/* +** Name of the special TEMP trigger used to implement RETURNING. The +** name begins with "sqlite_" so that it is guaranteed not to collide +** with any application-generated triggers. +*/ +#define RETURNING_TRIGGER_NAME "sqlite_returning" + +/* +** Clean up the data structures associated with the RETURNING clause. +*/ +static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){ + Hash *pHash; + pHash = &(db->aDb[1].pSchema->trigHash); + sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, 0); + sqlite3ExprListDelete(db, pRet->pReturnEL); + sqlite3DbFree(db, pRet); +} + +/* +** Add the RETURNING clause to the parse currently underway. +** +** This routine creates a special TEMP trigger that will fire for each row +** of the DML statement. That TEMP trigger contains a single SELECT +** statement with a result set that is the argument of the RETURNING clause. +** The trigger has the Trigger.bReturning flag and an opcode of +** TK_RETURNING instead of TK_SELECT, so that the trigger code generator +** knows to handle it specially. The TEMP trigger is automatically +** removed at the end of the parse. +** +** When this routine is called, we do not yet know if the RETURNING clause +** is attached to a DELETE, INSERT, or UPDATE, so construct it as a +** RETURNING trigger instead. It will then be converted into the appropriate +** type on the first call to sqlite3TriggersExist(). +*/ +SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ + Returning *pRet; + Hash *pHash; + sqlite3 *db = pParse->db; + if( pParse->pNewTrigger ){ + sqlite3ErrorMsg(pParse, "cannot use RETURNING in a trigger"); + }else{ + assert( pParse->bReturning==0 ); + } + pParse->bReturning = 1; + pRet = sqlite3DbMallocZero(db, sizeof(*pRet)); + if( pRet==0 ){ + sqlite3ExprListDelete(db, pList); + return; + } + pParse->u1.pReturning = pRet; + pRet->pParse = pParse; + pRet->pReturnEL = pList; + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet); + testcase( pParse->earlyCleanup ); + if( db->mallocFailed ) return; + pRet->retTrig.zName = RETURNING_TRIGGER_NAME; + pRet->retTrig.op = TK_RETURNING; + pRet->retTrig.tr_tm = TRIGGER_AFTER; + pRet->retTrig.bReturning = 1; + pRet->retTrig.pSchema = db->aDb[1].pSchema; + pRet->retTrig.pTabSchema = db->aDb[1].pSchema; + pRet->retTrig.step_list = &pRet->retTStep; + pRet->retTStep.op = TK_RETURNING; + pRet->retTStep.pTrig = &pRet->retTrig; + pRet->retTStep.pExprList = pList; + pHash = &(db->aDb[1].pSchema->trigHash); + assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 || pParse->nErr ); + if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig) + ==&pRet->retTrig ){ + sqlite3OomFault(db); + } +} /* ** Add a new column to the table currently being constructed. @@ -111643,60 +115352,104 @@ SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ ** 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; char *zType; 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( sqlite3_stricmp(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->hName = sqlite3StrIHash(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; @@ -111851,7 +115604,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 ); @@ -111862,15 +115615,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 ){ @@ -111966,9 +115719,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; @@ -111979,7 +115734,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 ){ @@ -112012,8 +115767,10 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey( ** Add a new CHECK constraint to the table currently under construction. */ SQLITE_PRIVATE void sqlite3AddCheckConstraint( - Parse *pParse, /* Parsing context */ - Expr *pCheckExpr /* The check expression */ + Parse *pParse, /* Parsing context */ + Expr *pCheckExpr, /* The check expression */ + const char *zStart, /* Opening "(" */ + const char *zEnd /* Closing ")" */ ){ #ifndef SQLITE_OMIT_CHECK Table *pTab = pParse->pNewTable; @@ -112024,6 +115781,13 @@ SQLITE_PRIVATE void sqlite3AddCheckConstraint( pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); if( pParse->constraintName.n ){ sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1); + }else{ + Token t; + for(zStart++; sqlite3Isspace(zStart[0]); zStart++){} + while( sqlite3Isspace(zEnd[-1]) ){ zEnd--; } + t.z = zStart; + t.n = (int)(zEnd - t.z); + sqlite3ExprListSetName(pParse, pTab->pCheck, &t, 1); } }else #endif @@ -112042,7 +115806,7 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){ char *zColl; /* Dequoted name of collation sequence */ sqlite3 *db; - if( (p = pParse->pNewTable)==0 ) return; + if( (p = pParse->pNewTable)==0 || IN_RENAME_OBJECT ) return; i = p->nCol-1; db = pParse->db; zColl = sqlite3NameFromToken(db, pToken); @@ -112050,8 +115814,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 @@ -112060,12 +115823,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 @@ -112085,7 +115847,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 */ @@ -112103,13 +115865,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 @@ -112211,7 +115973,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 ){ @@ -112247,7 +116009,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 ); @@ -112277,12 +116039,15 @@ static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){ int nByte; if( pIdx->nColumn>=N ) return SQLITE_OK; assert( pIdx->isResized==0 ); - nByte = (sizeof(char*) + sizeof(i16) + 1)*N; + nByte = (sizeof(char*) + sizeof(LogEst) + sizeof(i16) + 1)*N; zExtra = sqlite3DbMallocZero(db, nByte); if( zExtra==0 ) return SQLITE_NOMEM_BKPT; memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn); pIdx->azColl = (const char**)zExtra; zExtra += sizeof(char*)*N; + memcpy(zExtra, pIdx->aiRowLogEst, sizeof(LogEst)*(pIdx->nKeyCol+1)); + pIdx->aiRowLogEst = (LogEst*)zExtra; + zExtra += sizeof(LogEst)*N; memcpy(zExtra, pIdx->aiColumn, sizeof(i16)*pIdx->nColumn); pIdx->aiColumn = (i16*)zExtra; zExtra += sizeof(i16)*N; @@ -112328,7 +116093,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; } @@ -112441,7 +116205,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; } } @@ -112451,9 +116217,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY ** into BTREE_BLOBKEY. */ - if( pParse->addrCrTab ){ + assert( !pParse->bReturning ); + if( pParse->u1.addrCrTab ){ assert( v ); - sqlite3VdbeChangeP3(v, pParse->addrCrTab, BTREE_BLOBKEY); + sqlite3VdbeChangeP3(v, pParse->u1.addrCrTab, BTREE_BLOBKEY); } /* Locate the PRIMARY KEY index. Or, if this table was originally @@ -112462,10 +116229,13 @@ 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 ) return; + if( pList==0 ){ + pTab->tabFlags &= ~TF_WithoutRowid; + return; + } if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey); } @@ -112474,7 +116244,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 ) return; + if( pParse->nErr ){ + pTab->tabFlags &= ~TF_WithoutRowid; + return; + } + assert( db->mallocFailed==0 ); pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk->nKeyCol==1 ); }else{ @@ -112586,7 +116360,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; @@ -112594,6 +116368,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 @@ -112667,7 +116476,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 */ @@ -112678,7 +116487,6 @@ SQLITE_PRIVATE void sqlite3EndTable( if( pEnd==0 && pSelect==0 ){ return; } - assert( !db->mallocFailed ); p = pParse->pNewTable; if( p==0 ) return; @@ -112696,7 +116504,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; } @@ -112704,6 +116512,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 @@ -112748,7 +116594,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) ){ @@ -112758,8 +116604,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++; @@ -112799,7 +116645,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"; @@ -112885,7 +116731,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, @@ -112903,7 +116749,7 @@ SQLITE_PRIVATE void sqlite3EndTable( /* Check to see if we need to create an sqlite_sequence table for ** keeping track of autoincrement keys. */ - if( (p->tabFlags & TF_Autoincrement)!=0 ){ + if( (p->tabFlags & TF_Autoincrement)!=0 && !IN_SPECIAL_PARSE ){ Db *pDb = &db->aDb[iDb]; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( pDb->pSchema->pSeqTab==0 ){ @@ -112917,7 +116763,7 @@ SQLITE_PRIVATE void sqlite3EndTable( /* Reparse everything to update our internal data structures */ sqlite3VdbeAddParseSchemaOp(v, iDb, - sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName)); + sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName),0); } /* Add the table to the in-memory representation of the database. @@ -112926,6 +116772,7 @@ SQLITE_PRIVATE void sqlite3EndTable( Table *pOld; Schema *pSchema = p->pSchema; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( HasRowid(p) || p->iPKey<0 ); pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p); if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ @@ -112935,19 +116782,27 @@ SQLITE_PRIVATE void sqlite3EndTable( pParse->pNewTable = 0; db->mDbFlags |= DBFLAG_SchemaChange; -#ifndef SQLITE_OMIT_ALTERTABLE - if( !p->pSelect ){ - const char *zName = (const char *)pParse->sNameToken.z; - int nName; - assert( !pSelect && pCons && pEnd ); - if( pCons->z==0 ){ - pCons = pEnd; - } - nName = (int)((const char *)pCons->z - zName); - p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName); + /* If this is the magic sqlite_sequence table used by autoincrement, + ** then record a pointer to this table in the main database structure + ** so that INSERT can find the table easily. */ + assert( !pParse->nested ); +#ifndef SQLITE_OMIT_AUTOINCREMENT + if( strcmp(p->zName, "sqlite_sequence")==0 ){ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + p->pSchema->pSeqTab = p; } #endif } + +#ifndef SQLITE_OMIT_ALTERTABLE + if( !pSelect && IsOrdinaryTable(p) ){ + assert( pCons && pEnd ); + if( pCons->z==0 ){ + pCons = pEnd; + } + p->u.tab.addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z); + } +#endif } #ifndef SQLITE_OMIT_VIEW @@ -112980,6 +116835,16 @@ SQLITE_PRIVATE void sqlite3CreateView( sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); p = pParse->pNewTable; if( p==0 || pParse->nErr ) goto create_view_fail; + + /* Legacy versions of SQLite allowed the use of the magic "rowid" column + ** on a view, even though views do not have rowids. The following flag + ** setting fixes this problem. But the fix can be disabled by compiling + ** with -DSQLITE_ALLOW_ROWID_IN_VIEW in case there are legacy apps that + ** depend upon the old buggy behavior. */ +#ifndef SQLITE_ALLOW_ROWID_IN_VIEW + p->tabFlags |= TF_NoVisibleRowid; +#endif + sqlite3TwoPartName(pParse, pName1, pName2, &pName); iDb = sqlite3SchemaToIndex(db, p->pSchema); sqlite3FixInit(&sFix, pParse, iDb, "view", pName); @@ -112992,12 +116857,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 @@ -113051,13 +116917,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 @@ -113094,8 +116959,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; @@ -113124,10 +116989,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); } @@ -113138,6 +117003,7 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable->aCol==0 ); pTable->nCol = pSelTab->nCol; pTable->aCol = pSelTab->aCol; + pTable->tabFlags |= (pSelTab->tabFlags & COLFLAG_NOINSERT); pSelTab->nCol = 0; pSelTab->aCol = 0; assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); @@ -113153,8 +117019,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; @@ -113171,10 +117035,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); @@ -113248,7 +117110,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 @@ -113383,7 +117245,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) ){ @@ -113411,6 +117273,7 @@ SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db){ if( (db->flags & SQLITE_Defensive)!=0 && db->pVtabCtx==0 && db->nVdbeExec==0 + && !sqlite3VtabInSync(db) ){ return 1; } @@ -113430,6 +117293,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; } @@ -113455,7 +117321,10 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, if( noErr ) db->suppressErr--; if( pTab==0 ){ - if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + if( noErr ){ + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + sqlite3ForceNotReadOnly(pParse); + } goto exit_drop_table; } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -113511,11 +117380,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; } @@ -113566,7 +117435,7 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( FKey *pFKey = 0; FKey *pNextTo; Table *p = pParse->pNewTable; - int nByte; + i64 nByte; int i; int nCol; char *z; @@ -113579,7 +117448,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; @@ -113602,7 +117471,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 ){ @@ -113619,7 +117489,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; } @@ -113667,7 +117537,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: @@ -113688,7 +117559,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 @@ -113738,7 +117611,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++; @@ -113902,9 +117775,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; } @@ -113968,7 +117843,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 @@ -113980,7 +117854,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; } @@ -114025,6 +117899,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( }else{ assert( !db->init.busy ); sqlite3CodeVerifySchema(pParse, iDb); + sqlite3ForceNotReadOnly(pParse); } goto exit_create_index; } @@ -114070,7 +117945,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; @@ -114088,6 +117963,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)); } } @@ -114183,6 +118059,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 ); @@ -114191,7 +118068,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) ){ @@ -114389,13 +118266,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 @@ -114405,7 +118282,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( sqlite3RefillIndex(pParse, pIndex, iMem); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddParseSchemaOp(v, iDb, - sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); + sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName), 0); sqlite3VdbeAddOp2(v, OP_Expire, 0, 1); } @@ -114426,8 +118303,12 @@ SQLITE_PRIVATE void sqlite3CreateIndex( /* Clean up before exiting */ exit_create_index: if( pIndex ) sqlite3FreeIndex(db, pIndex); - if( pTab ){ /* Ensure all REPLACE indexes are at the end of the list */ - Index **ppFrom = &pTab->pIndex; + if( pTab ){ + /* Ensure all REPLACE indexes on pTab are at the end of the pIndex list. + ** 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; Index *pThis; for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){ Index *pNext; @@ -114440,6 +118321,16 @@ SQLITE_PRIVATE void sqlite3CreateIndex( } break; } +#ifdef SQLITE_DEBUG + /* Verify that all REPLACE indexes really are now at the end + ** of the index list. In other words, no other index type ever + ** comes after a REPLACE index on the list. */ + for(pThis = pTab->pIndex; pThis; pThis=pThis->pNext){ + assert( pThis->onError!=OE_Replace + || pThis->pNext==0 + || pThis->pNext->onError==OE_Replace ); + } +#endif } sqlite3ExprDelete(db, pPIWhere); sqlite3ExprListDelete(db, pList); @@ -114491,7 +118382,7 @@ SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){ if( x<99 ){ pIdx->pTable->nRowLogEst = x = 99; } - if( pIdx->pPartIdxWhere!=0 ) x -= 10; assert( 10==sqlite3LogEst(2) ); + if( pIdx->pPartIdxWhere!=0 ){ x -= 10; assert( 10==sqlite3LogEst(2) ); } a[0] = x; /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is @@ -114515,10 +118406,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; @@ -114526,9 +118417,10 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); if( pIndex==0 ){ if( !ifExists ){ - sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0); + sqlite3ErrorMsg(pParse, "no such index: %S", pName->a); }else{ sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + sqlite3ForceNotReadOnly(pParse); } pParse->checkSchema = 1; goto exit_drop_index; @@ -114548,7 +118440,7 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ goto exit_drop_index; } - if( !OMIT_TEMPDB && iDb ) code = SQLITE_DROP_TEMP_INDEX; + if( !OMIT_TEMPDB && iDb==1 ) code = SQLITE_DROP_TEMP_INDEX; if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){ goto exit_drop_index; } @@ -114560,7 +118452,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); @@ -114798,7 +118690,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( Token *pTable, /* Table to append */ Token *pDatabase /* Database of the table */ ){ - struct SrcList_item *pItem; + SrcItem *pItem; sqlite3 *db; assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ assert( pParse!=0 ); @@ -114839,11 +118731,11 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( */ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; - struct SrcList_item *pItem; - assert(pList || pParse->db->mallocFailed ); - if( pList ){ + SrcItem *pItem; + assert( pList || pParse->db->mallocFailed ); + if( ALWAYS(pList) ){ for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pItem->iCursor>=0 ) break; + if( pItem->iCursor>=0 ) continue; pItem->iCursor = pParse->nTab++; if( pItem->pSelect ){ sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); @@ -114857,18 +118749,18 @@ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ */ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ int i; - struct SrcList_item *pItem; + SrcItem *pItem; if( pList==0 ) return; for(pItem=pList->a, i=0; inSrc; i++, pItem++){ - sqlite3DbFree(db, pItem->zDatabase); + if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase); sqlite3DbFree(db, pItem->zName); - sqlite3DbFree(db, pItem->zAlias); + if( pItem->zAlias ) sqlite3DbFreeNN(db, pItem->zAlias); if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); sqlite3DeleteTable(db, pItem->pTab); - sqlite3SelectDelete(db, pItem->pSelect); - sqlite3ExprDelete(db, pItem->pOn); - sqlite3IdListDelete(db, pItem->pUsing); + if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect); + if( pItem->pOn ) sqlite3ExprDelete(db, pItem->pOn); + if( pItem->pUsing ) sqlite3IdListDelete(db, pItem->pUsing); } sqlite3DbFreeNN(db, pList); } @@ -114899,7 +118791,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( Expr *pOn, /* The ON clause of a join */ IdList *pUsing /* The USING clause of a join */ ){ - struct SrcList_item *pItem; + SrcItem *pItem; sqlite3 *db = pParse->db; if( !p && (pOn || pUsing) ){ sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", @@ -114928,7 +118820,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); @@ -114943,7 +118835,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ assert( pIndexedBy!=0 ); if( p && pIndexedBy->n>0 ){ - struct SrcList_item *pItem; + SrcItem *pItem; assert( p->nSrc>0 ); pItem = &p->a[p->nSrc-1]; assert( pItem->fg.notIndexed==0 ); @@ -114956,6 +118848,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 */ } } } @@ -114973,7 +118866,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, Src sqlite3SrcListDelete(pParse->db, p2); }else{ p1 = pNew; - memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(struct SrcList_item)); + memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(SrcItem)); sqlite3DbFree(pParse->db, p2); } } @@ -114986,7 +118879,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, Src */ SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ if( p ){ - struct SrcList_item *pItem = &p->a[p->nSrc-1]; + SrcItem *pItem = &p->a[p->nSrc-1]; assert( pItem->fg.notIndexed==0 ); assert( pItem->fg.isIndexedBy==0 ); assert( pItem->fg.isTabFunc==0 ); @@ -115040,7 +118933,16 @@ SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){ if( !v ) return; if( type!=TK_DEFERRED ){ for(i=0; inDb; i++){ - sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1); + int eTxnType; + Btree *pBt = db->aDb[i].pBt; + if( pBt && sqlite3BtreeIsReadonly(pBt) ){ + eTxnType = 0; /* Read txn */ + }else if( type==TK_EXCLUSIVE ){ + eTxnType = 2; /* Exclusive txn */ + }else{ + eTxnType = 1; /* Write txn */ + } + sqlite3VdbeAddOp2(v, OP_Transaction, i, eTxnType); sqlite3VdbeUsesBtree(v, i); } } @@ -115129,13 +119031,11 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ ** will occur at the end of the top-level VDBE and will be generated ** later, by sqlite3FinishCoding(). */ -SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ - Parse *pToplevel = sqlite3ParseToplevel(pParse); - - assert( iDb>=0 && iDbdb->nDb ); - assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 ); - assert( iDbdb, iDb, 0) ); +static void sqlite3CodeVerifySchemaAtToplevel(Parse *pToplevel, int iDb){ + assert( iDb>=0 && iDbdb->nDb ); + assert( pToplevel->db->aDb[iDb].pBt!=0 || iDb==1 ); + assert( iDbdb, iDb, 0) ); if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ DbMaskSet(pToplevel->cookieMask, iDb); if( !OMIT_TEMPDB && iDb==1 ){ @@ -115143,6 +119043,10 @@ SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ } } } +SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ + sqlite3CodeVerifySchemaAtToplevel(sqlite3ParseToplevel(pParse), iDb); +} + /* ** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each @@ -115174,7 +119078,7 @@ SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb) */ SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ Parse *pToplevel = sqlite3ParseToplevel(pParse); - sqlite3CodeVerifySchema(pParse, iDb); + sqlite3CodeVerifySchemaAtToplevel(pToplevel, iDb); DbMaskSet(pToplevel->writeMask, iDb); pToplevel->isMultiWrite |= setStatement; } @@ -115225,7 +119129,9 @@ SQLITE_PRIVATE void sqlite3HaltConstraint( i8 p4type, /* P4_STATIC or P4_TRANSIENT */ u8 p5Errmsg /* P5_ErrMsg type */ ){ - Vdbe *v = sqlite3GetVdbe(pParse); + Vdbe *v; + assert( pParse->pVdbe!=0 ); + v = sqlite3GetVdbe(pParse); assert( (errCode&0xff)==SQLITE_CONSTRAINT || pParse->nested ); if( onError==OE_Abort ){ sqlite3MayAbort(pParse); @@ -115255,7 +119161,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); @@ -115282,7 +119188,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); @@ -115470,24 +119376,76 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ } #ifndef SQLITE_OMIT_CTE +/* +** Create a new CTE object +*/ +SQLITE_PRIVATE Cte *sqlite3CteNew( + Parse *pParse, /* Parsing context */ + Token *pName, /* Name of the common-table */ + ExprList *pArglist, /* Optional column name list for the table */ + Select *pQuery, /* Query used to initialize the table */ + u8 eM10d /* The MATERIALIZED flag */ +){ + Cte *pNew; + sqlite3 *db = pParse->db; + + pNew = sqlite3DbMallocZero(db, sizeof(*pNew)); + assert( pNew!=0 || db->mallocFailed ); + + if( db->mallocFailed ){ + sqlite3ExprListDelete(db, pArglist); + sqlite3SelectDelete(db, pQuery); + }else{ + pNew->pSelect = pQuery; + pNew->pCols = pArglist; + pNew->zName = sqlite3NameFromToken(pParse->db, pName); + pNew->eM10d = eM10d; + } + return pNew; +} + +/* +** Clear information from a Cte object, but do not deallocate storage +** for the object itself. +*/ +static void cteClear(sqlite3 *db, Cte *pCte){ + assert( pCte!=0 ); + sqlite3ExprListDelete(db, pCte->pCols); + sqlite3SelectDelete(db, pCte->pSelect); + sqlite3DbFree(db, pCte->zName); +} + +/* +** Free the contents of the CTE object passed as the second argument. +*/ +SQLITE_PRIVATE void sqlite3CteDelete(sqlite3 *db, Cte *pCte){ + assert( pCte!=0 ); + cteClear(db, pCte); + sqlite3DbFree(db, pCte); +} + /* ** This routine is invoked once per CTE by the parser while parsing a -** WITH clause. +** WITH clause. The CTE described by teh third argument is added to +** the WITH clause of the second argument. If the second argument is +** NULL, then a new WITH argument is created. */ SQLITE_PRIVATE With *sqlite3WithAdd( Parse *pParse, /* Parsing context */ With *pWith, /* Existing WITH clause, or NULL */ - Token *pName, /* Name of the common-table */ - ExprList *pArglist, /* Optional column name list for the table */ - Select *pQuery /* Query used to initialize the table */ + Cte *pCte /* CTE to add to the WITH clause */ ){ sqlite3 *db = pParse->db; With *pNew; char *zName; + if( pCte==0 ){ + return pWith; + } + /* Check that the CTE name is unique within this WITH clause. If ** not, store an error in the Parse structure. */ - zName = sqlite3NameFromToken(pParse->db, pName); + zName = pCte->zName; if( zName && pWith ){ int i; for(i=0; inCte; i++){ @@ -115506,16 +119464,11 @@ SQLITE_PRIVATE With *sqlite3WithAdd( assert( (pNew!=0 && zName!=0) || db->mallocFailed ); if( db->mallocFailed ){ - sqlite3ExprListDelete(db, pArglist); - sqlite3SelectDelete(db, pQuery); - sqlite3DbFree(db, zName); + sqlite3CteDelete(db, pCte); pNew = pWith; }else{ - pNew->a[pNew->nCte].pSelect = pQuery; - pNew->a[pNew->nCte].pCols = pArglist; - pNew->a[pNew->nCte].zName = zName; - pNew->a[pNew->nCte].zCteErr = 0; - pNew->nCte++; + pNew->a[pNew->nCte++] = *pCte; + sqlite3DbFree(db, pCte); } return pNew; @@ -115528,10 +119481,7 @@ SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ if( pWith ){ int i; for(i=0; inCte; i++){ - struct Cte *pCte = &pWith->a[i]; - sqlite3ExprListDelete(db, pCte->pCols); - sqlite3SelectDelete(db, pCte->pSelect); - sqlite3DbFree(db, pCte->zName); + cteClear(db, &pWith->a[i]); } sqlite3DbFree(db, pWith); } @@ -115879,6 +119829,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; } @@ -115899,7 +119850,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] ); @@ -116110,7 +120061,7 @@ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ ** */ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ - struct SrcList_item *pItem = pSrc->a; + SrcItem *pItem = pSrc->a; Table *pTab; assert( pItem && pSrc->nSrc>=1 ); pTab = sqlite3LocateTableItem(pParse, 0, pItem); @@ -116118,13 +120069,23 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ pItem->pTab = pTab; if( pTab ){ pTab->nTabRef++; - } - if( sqlite3IndexedByLookup(pParse, pItem) ){ - pTab = 0; + if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){ + pTab = 0; + } } 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: @@ -116165,7 +120126,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; } @@ -116269,13 +120230,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); @@ -116288,9 +120249,16 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree ** and the SELECT subtree. */ pSrc->a[0].pTab = 0; - pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); + pSelectSrc = sqlite3SrcListDup(db, pSrc, 0); pSrc->a[0].pTab = pTab; - pSrc->a[0].pIBIndex = 0; + 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); + }else if( pSrc->a[0].fg.isCte ){ + pSrc->a[0].u2.pCteUse->nUse++; + } /* generate the SELECT expression tree. */ pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, @@ -116357,9 +120325,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 ); @@ -116376,7 +120346,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 @@ -116468,6 +120438,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( if( (db->flags & SQLITE_CountRows)!=0 && !pParse->nested && !pParse->pTriggerTab + && !pParse->bReturning ){ memCnt = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); @@ -116502,11 +120473,14 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ assert( pIdx->pSchema==pTab->pSchema ); sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ + sqlite3VdbeChangeP3(v, -1, memCnt ? memCnt : -1); + } } }else #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ { - u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK|WHERE_SEEK_TABLE; + u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK; if( sNC.ncFlags & NC_VarSelect ) bComplex = 1; wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW); if( HasRowid(pTab) ){ @@ -116536,12 +120510,15 @@ 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 ); assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF ); if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse); + if( sqlite3WhereUsesDeferredSeek(pWInfo) ){ + sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur); + } /* Keep track of the number of rows to be deleted */ if( memCnt ){ @@ -116576,6 +120553,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); + addrBypass = sqlite3VdbeMakeLabel(pParse); }else{ if( pPk ){ /* Add the PK key for this row to the temporary table */ @@ -116589,13 +120567,6 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( nKey = 1; /* OP_DeferredSeek always uses a single rowid */ sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey); } - } - - /* If this DELETE cannot use the ONEPASS strategy, this is the - ** end of the WHERE loop */ - if( eOnePass!=ONEPASS_OFF ){ - addrBypass = sqlite3VdbeMakeLabel(pParse); - }else{ sqlite3WhereEnd(pWInfo); } @@ -116625,7 +120596,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); } @@ -116692,9 +120663,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( ** invoke the callback function. */ if( memCnt ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); + sqlite3CodeChangeCount(v, memCnt, "rows deleted"); } delete_from_cleanup: @@ -116859,7 +120828,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)); @@ -117016,20 +120985,18 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey( continue; } sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j); - /* If the column affinity is REAL but the number is an integer, then it - ** might be stored in the table as an integer (using a compact - ** representation) then converted to REAL by an OP_RealAffinity opcode. - ** But we are getting ready to store this value back into an index, where - ** it should be converted by to INTEGER again. So omit the OP_RealAffinity - ** opcode if it is present */ - sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity); + if( pIdx->aiColumn[j]>=0 ){ + /* If the column affinity is REAL but the number is an integer, then it + ** might be stored in the table as an integer (using a compact + ** representation) then converted to REAL by an OP_RealAffinity opcode. + ** But we are getting ready to store this value back into an index, where + ** it should be converted by to INTEGER again. So omit the + ** OP_RealAffinity opcode if it is present */ + sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity); + } } if( regOut ){ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut); - if( pIdx->pTable->pSelect ){ - const char *zAff = sqlite3IndexAffinityStr(pParse->db, pIdx); - sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT); - } } sqlite3ReleaseTempRange(pParse, regBase, nCol); return regBase; @@ -117147,6 +121114,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 @@ -117308,7 +121287,7 @@ static void instrFunc( } /* -** Implementation of the printf() function. +** Implementation of the printf() (a.k.a. format()) SQL function. */ static void printfFunc( sqlite3_context *context, @@ -117621,9 +121600,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, @@ -117632,12 +121611,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, @@ -117646,9 +121625,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)); } /* @@ -117744,7 +121723,8 @@ static int patternCompare( /* Skip over multiple "*" characters in the pattern. If there ** are also "?" characters, skip those as well, but consume a ** single character of the input string for each "?" skipped */ - while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){ + while( (c=Utf8Read(zPattern)) == matchAll + || (c == matchOne && matchOne!=0) ){ if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){ return SQLITE_NOWILDCARDMATCH; } @@ -118076,39 +122056,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]; @@ -118118,42 +122101,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. @@ -118365,10 +122354,10 @@ static void trimFunc( ){ const unsigned char *zIn; /* Input string */ const unsigned char *zCharSet; /* Set of characters to trim */ - int nIn; /* Number of bytes in input */ + unsigned int nIn; /* Number of bytes in input */ int flags; /* 1: trimleft 2: trimright 3: trim */ int i; /* Loop counter */ - unsigned char *aLen = 0; /* Length of each character in zCharSet */ + unsigned int *aLen = 0; /* Length of each character in zCharSet */ unsigned char **azChar = 0; /* Individual characters in zCharSet */ int nChar; /* Number of characters in zCharSet */ @@ -118377,13 +122366,13 @@ static void trimFunc( } zIn = sqlite3_value_text(argv[0]); if( zIn==0 ) return; - nIn = sqlite3_value_bytes(argv[0]); + nIn = (unsigned)sqlite3_value_bytes(argv[0]); assert( zIn==sqlite3_value_text(argv[0]) ); if( argc==1 ){ - static const unsigned char lenOne[] = { 1 }; + static const unsigned lenOne[] = { 1 }; static unsigned char * const azOne[] = { (u8*)" " }; nChar = 1; - aLen = (u8*)lenOne; + aLen = (unsigned*)lenOne; azChar = (unsigned char **)azOne; zCharSet = 0; }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){ @@ -118394,15 +122383,16 @@ static void trimFunc( SQLITE_SKIP_UTF8(z); } if( nChar>0 ){ - azChar = contextMalloc(context, ((i64)nChar)*(sizeof(char*)+1)); + azChar = contextMalloc(context, + ((i64)nChar)*(sizeof(char*)+sizeof(unsigned))); if( azChar==0 ){ return; } - aLen = (unsigned char*)&azChar[nChar]; + aLen = (unsigned*)&azChar[nChar]; for(z=zCharSet, nChar=0; *z; nChar++){ azChar[nChar] = (unsigned char *)z; SQLITE_SKIP_UTF8(z); - aLen[nChar] = (u8)(z - azChar[nChar]); + aLen[nChar] = (unsigned)(z - azChar[nChar]); } } } @@ -118410,7 +122400,7 @@ static void trimFunc( flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context)); if( flags & 1 ){ while( nIn>0 ){ - int len = 0; + unsigned int len = 0; for(i=0; i0 ){ - int len = 0; + unsigned int len = 0; for(i=0; imxAlloc==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, ','); + } +#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); } - if( zSep ) sqlite3_str_append(pAccum, 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); } } } @@ -118915,11 +122975,14 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive) SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ FuncDef *pDef; int nExpr; - if( pExpr->op!=TK_FUNCTION || !pExpr->x.pList ){ + 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; @@ -118943,6 +123006,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; @@ -118954,6 +123018,201 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas return 1; } +/* Mathematical Constants */ +#ifndef M_PI +# define M_PI 3.141592653589793238462643383279502884 +#endif +#ifndef M_LN10 +# define M_LN10 2.302585092994045684017991454684364208 +#endif +#ifndef M_LN2 +# define M_LN2 0.693147180559945309417232121458176568 +#endif + + +/* Extra math functions that require linking with -lm +*/ +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS +/* +** Implementation SQL functions: +** +** ceil(X) +** ceiling(X) +** floor(X) +** +** The sqlite3_user_data() pointer is a pointer to the libm implementation +** of the underlying C function. +*/ +static void ceilingFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: { + sqlite3_result_int64(context, sqlite3_value_int64(argv[0])); + break; + } + case SQLITE_FLOAT: { + double (*x)(double) = (double(*)(double))sqlite3_user_data(context); + sqlite3_result_double(context, x(sqlite3_value_double(argv[0]))); + break; + } + default: { + break; + } + } +} + +/* +** On some systems, ceil() and floor() are intrinsic function. You are +** unable to take a pointer to these functions. Hence, we here wrap them +** in our own actual functions. +*/ +static double xCeil(double x){ return ceil(x); } +static double xFloor(double x){ return floor(x); } + +/* +** Implementation of SQL functions: +** +** ln(X) - natural logarithm +** log(X) - log X base 10 +** log10(X) - log X base 10 +** log(B,X) - log X base B +*/ +static void logFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + double x, b, ans; + assert( argc==1 || argc==2 ); + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: + x = sqlite3_value_double(argv[0]); + if( x<=0.0 ) return; + break; + default: + return; + } + if( argc==2 ){ + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: + b = log(x); + if( b<=0.0 ) return; + x = sqlite3_value_double(argv[1]); + if( x<=0.0 ) return; + break; + default: + return; + } + ans = log(x)/b; + }else{ + ans = log(x); + switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){ + case 1: + /* Convert from natural logarithm to log base 10 */ + ans *= 1.0/M_LN10; + break; + case 2: + /* Convert from natural logarithm to log base 2 */ + ans *= 1.0/M_LN2; + break; + default: + break; + } + } + sqlite3_result_double(context, ans); +} + +/* +** Functions to converts degrees to radians and radians to degrees. +*/ +static double degToRad(double x){ return x*(M_PI/180.0); } +static double radToDeg(double x){ return x*(180.0/M_PI); } + +/* +** Implementation of 1-argument SQL math functions: +** +** exp(X) - Compute e to the X-th power +*/ +static void math1Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int type0; + double v0, ans; + double (*x)(double); + assert( argc==1 ); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + v0 = sqlite3_value_double(argv[0]); + x = (double(*)(double))sqlite3_user_data(context); + ans = x(v0); + sqlite3_result_double(context, ans); +} + +/* +** Implementation of 2-argument SQL math functions: +** +** power(X,Y) - Compute X to the Y-th power +*/ +static void math2Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int type0, type1; + double v0, v1, ans; + double (*x)(double,double); + assert( argc==2 ); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + type1 = sqlite3_value_numeric_type(argv[1]); + if( type1!=SQLITE_INTEGER && type1!=SQLITE_FLOAT ) return; + v0 = sqlite3_value_double(argv[0]); + v1 = sqlite3_value_double(argv[1]); + x = (double(*)(double,double))sqlite3_user_data(context); + ans = x(v0, v1); + sqlite3_result_double(context, ans); +} + +/* +** Implementation of 0-argument pi() function. +*/ +static void piFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==0 ); + sqlite3_result_double(context, M_PI); +} + +#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ + +/* +** Implementation of sign(X) function. +*/ +static void signFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int type0; + double x; + UNUSED_PARAMETER(argc); + assert( argc==1 ); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + x = sqlite3_value_double(argv[0]); + sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0); +} + /* ** All of the FuncDef structures in the aBuiltinFunc[] array above ** to the global function hash table. This occurs at start-time (as @@ -118974,12 +123233,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 ), @@ -119011,15 +123270,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 ), @@ -119045,13 +123306,16 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), FUNCTION(substr, 2, 0, 0, substrFunc ), FUNCTION(substr, 3, 0, 0, substrFunc ), + FUNCTION(substring, 2, 0, 0, substrFunc ), + FUNCTION(substring, 3, 0, 0, substrFunc ), WAGGREGATE(sum, 1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0), 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, @@ -119070,6 +123334,43 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ #endif FUNCTION(coalesce, 1, 0, 0, 0 ), FUNCTION(coalesce, 0, 0, 0, 0 ), +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS + MFUNCTION(ceil, 1, xCeil, ceilingFunc ), + MFUNCTION(ceiling, 1, xCeil, ceilingFunc ), + MFUNCTION(floor, 1, xFloor, ceilingFunc ), +#if SQLITE_HAVE_C99_MATH_FUNCS + MFUNCTION(trunc, 1, trunc, ceilingFunc ), +#endif + FUNCTION(ln, 1, 0, 0, logFunc ), + FUNCTION(log, 1, 1, 0, logFunc ), + FUNCTION(log10, 1, 1, 0, logFunc ), + FUNCTION(log2, 1, 2, 0, logFunc ), + FUNCTION(log, 2, 0, 0, logFunc ), + MFUNCTION(exp, 1, exp, math1Func ), + MFUNCTION(pow, 2, pow, math2Func ), + MFUNCTION(power, 2, pow, math2Func ), + MFUNCTION(mod, 2, fmod, math2Func ), + MFUNCTION(acos, 1, acos, math1Func ), + MFUNCTION(asin, 1, asin, math1Func ), + MFUNCTION(atan, 1, atan, math1Func ), + MFUNCTION(atan2, 2, atan2, math2Func ), + MFUNCTION(cos, 1, cos, math1Func ), + MFUNCTION(sin, 1, sin, math1Func ), + MFUNCTION(tan, 1, tan, math1Func ), + MFUNCTION(cosh, 1, cosh, math1Func ), + MFUNCTION(sinh, 1, sinh, math1Func ), + MFUNCTION(tanh, 1, tanh, math1Func ), +#if SQLITE_HAVE_C99_MATH_FUNCS + MFUNCTION(acosh, 1, acosh, math1Func ), + MFUNCTION(asinh, 1, asinh, math1Func ), + MFUNCTION(atanh, 1, atanh, math1Func ), +#endif + MFUNCTION(sqrt, 1, sqrt, math1Func ), + MFUNCTION(radians, 1, degToRad, math1Func ), + MFUNCTION(degrees, 1, radToDeg, math1Func ), + FUNCTION(pi, 0, 0, 0, piFunc ), +#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ + FUNCTION(sign, 1, 0, 0, signFunc ), INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ), INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ), }; @@ -119078,6 +123379,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 */ @@ -119089,6 +123391,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"); @@ -119316,7 +123619,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 ); @@ -119358,11 +123663,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; @@ -119586,7 +123891,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{ @@ -119609,6 +123914,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; @@ -119695,7 +124001,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); @@ -119730,7 +124036,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); } @@ -119749,7 +124055,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); @@ -119800,6 +124106,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 @@ -119819,12 +124144,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 @@ -119832,7 +124157,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; @@ -119921,7 +124246,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; } @@ -119988,13 +124313,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; @@ -120061,7 +124387,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); } @@ -120125,7 +124451,7 @@ SQLITE_PRIVATE void sqlite3FkCheck( ** child table as a SrcList for sqlite3WhereBegin() */ pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pSrc ){ - struct SrcList_item *pItem = pSrc->a; + SrcItem *pItem = pSrc->a; pItem->pTab = pFKey->pFrom; pItem->zName = pFKey->pFrom->zName; pItem->pTab->nTabRef++; @@ -120176,10 +124502,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){ @@ -120213,7 +124539,9 @@ SQLITE_PRIVATE u32 sqlite3FkOldmask( ** ** For an UPDATE, this function returns 2 if: ** -** * There are any FKs for which pTab is the child and the parent table, or +** * There are any FKs for which pTab is the child and the parent table +** and any FK processing at all is required (even of a different FK), or +** ** * the UPDATE modifies one or more parent keys for which the action is ** not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL). ** @@ -120225,23 +124553,24 @@ SQLITE_PRIVATE int sqlite3FkRequired( int *aChange, /* Non-NULL for UPDATE operations */ int chngRowid /* True for UPDATE that affects rowid */ ){ - int eRet = 0; - if( pParse->db->flags&SQLITE_ForeignKeys ){ + int eRet = 1; /* Value to return if bHaveFK is true */ + int bHaveFK = 0; /* If FK processing is required */ + 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. */ - eRet = (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){ - if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) return 2; + for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){ if( fkChildIsModified(pTab, p, aChange, chngRowid) ){ - eRet = 1; + if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) eRet = 2; + bHaveFK = 1; } } @@ -120249,12 +124578,12 @@ SQLITE_PRIVATE int sqlite3FkRequired( for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ if( fkParentIsModified(pTab, p, aChange, chngRowid) ){ if( p->aAction[1]!=OE_None ) return 2; - eRet = 1; + bHaveFK = 1; } } } } - return eRet; + return bHaveFK ? eRet : 0; } /* @@ -120331,8 +124660,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 @@ -120377,7 +124706,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); @@ -120514,9 +124843,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 ){ @@ -120585,7 +124914,8 @@ SQLITE_PRIVATE void sqlite3OpenTable( ){ Vdbe *v; assert( !IsVirtual(pTab) ); - v = sqlite3GetVdbe(pParse); + assert( pParse->pVdbe!=0 ); + v = pParse->pVdbe; assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); sqlite3TableLock(pParse, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName); @@ -120595,7 +124925,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)); @@ -120662,28 +124992,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); @@ -120709,6 +125079,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); } } @@ -120792,24 +125164,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->aCol[ii].colFlags & COLFLAG_STORED ){ - zP4[jj] = SQLITE_AFF_NONE; + 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++; } - 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; } } @@ -120845,7 +125223,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; @@ -120854,13 +125232,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; } @@ -120910,7 +125288,7 @@ static int autoIncBegin( ** Ticket d8dc2b3a58cd5dc2918a1d4acb 2018-05-23 */ if( pSeqTab==0 || !HasRowid(pSeqTab) - || IsVirtual(pSeqTab) + || NEVER(IsVirtual(pSeqTab)) || pSeqTab->nCol!=2 ){ pParse->nErr++; @@ -120922,7 +125300,9 @@ static int autoIncBegin( while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } if( pInfo==0 ){ pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo)); - if( pInfo==0 ) return 0; + sqlite3ParserAddCleanup(pToplevel, sqlite3DbFree, pInfo); + testcase( pParse->earlyCleanup ); + if( pParse->db->mallocFailed ) return 0; pInfo->pNext = pToplevel->pAinc; pToplevel->pAinc = pInfo; pInfo->pTab = pTab; @@ -121217,9 +125597,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 @@ -121253,7 +125635,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 @@ -121344,7 +125726,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 ){ @@ -121354,7 +125736,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 @@ -121367,7 +125749,7 @@ SQLITE_PRIVATE void sqlite3Insert( bIdListInOrder = 0; }else{ sqlite3ErrorMsg(pParse, "table %S has no column named %s", - pTabList, 0, pColumn->a[i].zName); + pTabList->a, pColumn->a[i].zName); pParse->checkSchema = 1; goto insert_cleanup; } @@ -121395,7 +125777,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 ); @@ -121480,19 +125864,24 @@ SQLITE_PRIVATE void sqlite3Insert( } } #endif - } - /* Make sure the number of columns in the source data matches the number - ** of columns to be inserted into the table. - */ - for(i=0; inCol; i++){ - if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++; - } - if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){ - sqlite3ErrorMsg(pParse, - "table %S has %d columns but %d values were supplied", - pTabList, 0, pTab->nCol-nHidden, nColumn); - goto insert_cleanup; + /* Make sure the number of columns in the source data matches the number + ** of columns to be inserted into the table. + */ + assert( TF_HasHidden==COLFLAG_HIDDEN ); + assert( TF_HasGenerated==COLFLAG_GENERATED ); + assert( COLFLAG_NOINSERT==(COLFLAG_GENERATED|COLFLAG_HIDDEN) ); + if( (pTab->tabFlags & (TF_HasGenerated|TF_HasHidden))!=0 ){ + for(i=0; inCol; i++){ + if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++; + } + } + if( nColumn!=(pTab->nCol-nHidden) ){ + sqlite3ErrorMsg(pParse, + "table %S has %d columns but %d values were supplied", + pTabList->a, pTab->nCol-nHidden, nColumn); + goto insert_cleanup; + } } if( pColumn!=0 && nColumn!=pColumn->nId ){ sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); @@ -121504,6 +125893,7 @@ SQLITE_PRIVATE void sqlite3Insert( if( (db->flags & SQLITE_CountRows)!=0 && !pParse->nested && !pParse->pTriggerTab + && !pParse->bReturning ){ regRowCount = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); @@ -121527,12 +125917,13 @@ SQLITE_PRIVATE void sqlite3Insert( } #ifndef SQLITE_OMIT_UPSERT if( pUpsert ){ + Upsert *pNx; if( IsVirtual(pTab) ){ sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"", pTab->zName); goto insert_cleanup; } - if( pTab->pSelect ){ + if( IsView(pTab) ){ sqlite3ErrorMsg(pParse, "cannot UPSERT a view"); goto insert_cleanup; } @@ -121540,13 +125931,19 @@ SQLITE_PRIVATE void sqlite3Insert( goto insert_cleanup; } pTabList->a[0].iCursor = iDataCur; - pUpsert->pUpsertSrc = pTabList; - pUpsert->regData = regData; - pUpsert->iDataCur = iDataCur; - pUpsert->iIdxCur = iIdxCur; - if( pUpsert->pUpsertTarget ){ - sqlite3UpsertAnalyzeTarget(pParse, pTabList, pUpsert); - } + pNx = pUpsert; + do{ + pNx->pUpsertSrc = pTabList; + pNx->regData = regData; + pNx->iDataCur = iDataCur; + pNx->iIdxCur = iIdxCur; + if( pNx->pUpsertTarget ){ + if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx) ){ + goto insert_cleanup; + } + } + pNx = pNx->pNextUpsert; + }while( pNx!=0 ); } #endif @@ -121625,7 +126022,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; } } @@ -121634,13 +126033,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; @@ -121687,11 +126090,6 @@ SQLITE_PRIVATE void sqlite3Insert( sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v); } - /* Cannot have triggers on a virtual table. If it were possible, - ** this block would have to account for hidden column. - */ - assert( !IsVirtual(pTab) ); - /* Copy the new data already generated. */ assert( pTab->nNVCol>0 ); sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1); @@ -121790,7 +126188,7 @@ SQLITE_PRIVATE void sqlite3Insert( }else #endif { - int isReplace; /* Set to true if constraints may cause a replace */ + int isReplace = 0;/* Set to true if constraints may cause a replace */ int bUseSeek; /* True to use OPFLAG_SEEKRESULT */ sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert @@ -121810,6 +126208,13 @@ SQLITE_PRIVATE void sqlite3Insert( regIns, aRegIdx, 0, appendFlag, bUseSeek ); } +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + }else if( pParse->bReturning ){ + /* If there is a RETURNING clause, populate the rowid register with + ** constant value -1, in case one or more of the returned expressions + ** refer to the "rowid" of the view. */ + sqlite3VdbeAddOp2(v, OP_Integer, -1, regRowid); +#endif } /* Update the count of rows that are inserted @@ -121846,7 +126251,9 @@ SQLITE_PRIVATE void sqlite3Insert( sqlite3VdbeJumpHere(v, addrInsTop); } +#ifndef SQLITE_OMIT_XFER_OPT insert_end: +#endif /* SQLITE_OMIT_XFER_OPT */ /* Update the sqlite_sequence table by storing the content of the ** maximum rowid counter values recorded while inserting into ** autoincrement tables. @@ -121861,9 +126268,7 @@ SQLITE_PRIVATE void sqlite3Insert( ** invoke the callback function. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); + sqlite3CodeChangeCount(v, regRowCount, "rows inserted"); } insert_cleanup: @@ -121951,6 +126356,70 @@ SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn( return w.eCode!=0; } +/* +** The sqlite3GenerateConstraintChecks() routine usually wants to visit +** the indexes of a table in the order provided in the Table->pIndex list. +** However, sometimes (rarely - when there is an upsert) it wants to visit +** the indexes in a different order. The following data structures accomplish +** this. +** +** The IndexIterator object is used to walk through all of the indexes +** of a table in either Index.pNext order, or in some other order established +** by an array of IndexListTerm objects. +*/ +typedef struct IndexListTerm IndexListTerm; +typedef struct IndexIterator IndexIterator; +struct IndexIterator { + int eType; /* 0 for Index.pNext list. 1 for an array of IndexListTerm */ + int i; /* Index of the current item from the list */ + union { + struct { /* Use this object for eType==0: A Index.pNext list */ + Index *pIdx; /* The current Index */ + } lx; + struct { /* Use this object for eType==1; Array of IndexListTerm */ + int nIdx; /* Size of the array */ + IndexListTerm *aIdx; /* Array of IndexListTerms */ + } ax; + } u; +}; + +/* When IndexIterator.eType==1, then each index is an array of instances +** of the following object +*/ +struct IndexListTerm { + Index *p; /* The index */ + int ix; /* Which entry in the original Table.pIndex list is this index*/ +}; + +/* Return the first index on the list */ +static Index *indexIteratorFirst(IndexIterator *pIter, int *pIx){ + assert( pIter->i==0 ); + if( pIter->eType ){ + *pIx = pIter->u.ax.aIdx[0].ix; + return pIter->u.ax.aIdx[0].p; + }else{ + *pIx = 0; + return pIter->u.lx.pIdx; + } +} + +/* Return the next index from the list. Return NULL when out of indexes */ +static Index *indexIteratorNext(IndexIterator *pIter, int *pIx){ + if( pIter->eType ){ + int i = ++pIter->i; + if( i>=pIter->u.ax.nIdx ){ + *pIx = i; + return 0; + } + *pIx = pIter->u.ax.aIdx[i].ix; + return pIter->u.ax.aIdx[i].p; + }else{ + ++(*pIx); + pIter->u.lx.pIdx = pIter->u.lx.pIdx->pNext; + return pIter->u.lx.pIdx; + } +} + /* ** Generate code to do constraint checks prior to an INSERT or an UPDATE ** on table pTab. @@ -122059,7 +126528,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ){ Vdbe *v; /* VDBE under constrution */ Index *pIdx; /* Pointer to one of the indices */ - Index *pPk = 0; /* The PRIMARY KEY index */ + Index *pPk = 0; /* The PRIMARY KEY index for WITHOUT ROWID tables */ sqlite3 *db; /* Database connection */ int i; /* loop counter */ int ix; /* Index loop counter */ @@ -122067,11 +126536,11 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( int onError; /* Conflict resolution strategy */ int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */ - Index *pUpIdx = 0; /* Index to which to apply the upsert */ - u8 isUpdate; /* True if this is an UPDATE operation */ + Upsert *pUpsertClause = 0; /* The specific ON CONFLICT clause for pIdx */ + u8 isUpdate; /* True if this is an UPDATE operation */ u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */ - int upsertBypass = 0; /* Address of Goto to bypass upsert subroutine */ - int upsertJump = 0; /* Address of Goto that jumps into upsert subroutine */ + int upsertIpkReturn = 0; /* Address of Goto at end of IPK uniqueness check */ + int upsertIpkDelay = 0; /* Address of Goto to bypass initial IPK check */ int ipkTop = 0; /* Top of the IPK uniqueness check */ int ipkBottom = 0; /* OP_Goto at the end of the IPK uniqueness check */ /* Variables associated with retesting uniqueness constraints after @@ -122081,12 +126550,13 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( int lblRecheckOk = 0; /* Each recheck jumps to this label if it passes */ Trigger *pTrigger; /* List of DELETE triggers on the table pTab */ int nReplaceTrig = 0; /* Number of replace triggers coded */ + IndexIterator sIdxIter; /* Index iterator */ isUpdate = regOldData!=0; db = pParse->db; - v = sqlite3GetVdbe(pParse); + 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 @@ -122137,7 +126607,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 ); @@ -122159,7 +126629,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; } @@ -122169,7 +126640,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); @@ -122238,7 +126709,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( sqlite3VdbeGoto(v, ignoreDest); }else{ char *zName = pCheck->a[i].zEName; - if( zName==0 ) zName = pTab->zName; + assert( zName!=0 || pParse->db->mallocFailed ); if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK, onError, zName, P4_TRANSIENT, @@ -122278,19 +126749,63 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** list of indexes attached to a table puts all OE_Replace indexes last ** in the list. See sqlite3CreateIndex() for where that happens. */ - + sIdxIter.eType = 0; + sIdxIter.i = 0; + sIdxIter.u.ax.aIdx = 0; /* Silence harmless compiler warning */ + sIdxIter.u.lx.pIdx = pTab->pIndex; if( pUpsert ){ if( pUpsert->pUpsertTarget==0 ){ - /* An ON CONFLICT DO NOTHING clause, without a constraint-target. - ** Make all unique constraint resolution be OE_Ignore */ - assert( pUpsert->pUpsertSet==0 ); - overrideError = OE_Ignore; - pUpsert = 0; - }else if( (pUpIdx = pUpsert->pUpsertIdx)!=0 ){ - /* If the constraint-target uniqueness check must be run first. - ** Jump to that uniqueness check now */ - upsertJump = sqlite3VdbeAddOp0(v, OP_Goto); - VdbeComment((v, "UPSERT constraint goes first")); + /* There is just on ON CONFLICT clause and it has no constraint-target */ + assert( pUpsert->pNextUpsert==0 ); + if( pUpsert->isDoUpdate==0 ){ + /* A single ON CONFLICT DO NOTHING clause, without a constraint-target. + ** Make all unique constraint resolution be OE_Ignore */ + overrideError = OE_Ignore; + pUpsert = 0; + }else{ + /* A single ON CONFLICT DO UPDATE. Make all resolutions OE_Update */ + overrideError = OE_Update; + } + }else if( pTab->pIndex!=0 ){ + /* Otherwise, we'll need to run the IndexListTerm array version of the + ** iterator to ensure that all of the ON CONFLICT conditions are + ** checked first and in order. */ + int nIdx, jj; + u64 nByte; + Upsert *pTerm; + u8 *bUsed; + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ + assert( aRegIdx[nIdx]>0 ); + } + sIdxIter.eType = 1; + sIdxIter.u.ax.nIdx = nIdx; + nByte = (sizeof(IndexListTerm)+1)*nIdx + nIdx; + sIdxIter.u.ax.aIdx = sqlite3DbMallocZero(db, nByte); + if( sIdxIter.u.ax.aIdx==0 ) return; /* OOM */ + bUsed = (u8*)&sIdxIter.u.ax.aIdx[nIdx]; + pUpsert->pToFree = sIdxIter.u.ax.aIdx; + for(i=0, pTerm=pUpsert; pTerm; pTerm=pTerm->pNextUpsert){ + if( pTerm->pUpsertTarget==0 ) break; + if( pTerm->pUpsertIdx==0 ) continue; /* Skip ON CONFLICT for the IPK */ + jj = 0; + pIdx = pTab->pIndex; + while( ALWAYS(pIdx!=0) && pIdx!=pTerm->pUpsertIdx ){ + pIdx = pIdx->pNext; + jj++; + } + if( bUsed[jj] ) continue; /* Duplicate ON CONFLICT clause ignored */ + bUsed[jj] = 1; + sIdxIter.u.ax.aIdx[i].p = pIdx; + sIdxIter.u.ax.aIdx[i].ix = jj; + i++; + } + for(jj=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, jj++){ + if( bUsed[jj] ) continue; + sIdxIter.u.ax.aIdx[i].p = pIdx; + sIdxIter.u.ax.aIdx[i].ix = jj; + i++; + } + assert( i==nIdx ); } } @@ -122353,11 +126868,20 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } /* figure out whether or not upsert applies in this case */ - if( pUpsert && pUpsert->pUpsertIdx==0 ){ - if( pUpsert->pUpsertSet==0 ){ - onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ - }else{ - onError = OE_Update; /* DO UPDATE */ + if( pUpsert ){ + pUpsertClause = sqlite3UpsertOfIndex(pUpsert,0); + if( pUpsertClause!=0 ){ + if( pUpsertClause->isDoUpdate==0 ){ + onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ + }else{ + onError = OE_Update; /* DO UPDATE */ + } + } + if( pUpsertClause!=pUpsert ){ + /* The first ON CONFLICT clause has a conflict target other than + ** the IPK. We have to jump ahead to that first ON CONFLICT clause + ** and then come back here and deal with the IPK afterwards */ + upsertIpkDelay = sqlite3VdbeAddOp0(v, OP_Goto); } } @@ -122367,8 +126891,9 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** the UNIQUE constraints have run. */ if( onError==OE_Replace /* IPK rule is REPLACE */ - && onError!=overrideError /* Rules for other contraints are different */ + && 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")); @@ -122464,7 +126989,9 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } } sqlite3VdbeResolveLabel(v, addrRowidOk); - if( ipkTop ){ + if( pUpsert && pUpsertClause!=pUpsert ){ + upsertIpkReturn = sqlite3VdbeAddOp0(v, OP_Goto); + }else if( ipkTop ){ ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, ipkTop-1); } @@ -122477,7 +127004,10 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** This loop also handles the case of the PRIMARY KEY index for a ** WITHOUT ROWID table. */ - for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){ + for(pIdx = indexIteratorFirst(&sIdxIter, &ix); + pIdx; + pIdx = indexIteratorNext(&sIdxIter, &ix) + ){ int regIdx; /* Range of registers hold conent for pIdx */ int regR; /* Range of registers holding conflicting PK */ int iThisCur; /* Cursor for this UNIQUE index */ @@ -122485,15 +127015,14 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( int addrConflictCk; /* First opcode in the conflict check logic */ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ - if( pUpIdx==pIdx ){ - addrUniqueOk = upsertJump+1; - upsertBypass = sqlite3VdbeGoto(v, 0); - VdbeComment((v, "Skip upsert subroutine")); - sqlite3VdbeJumpHere(v, upsertJump); - }else{ - addrUniqueOk = sqlite3VdbeMakeLabel(pParse); + if( pUpsert ){ + pUpsertClause = sqlite3UpsertOfIndex(pUpsert, pIdx); + if( upsertIpkDelay && pUpsertClause==pUpsert ){ + sqlite3VdbeJumpHere(v, upsertIpkDelay); + } } - if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){ + addrUniqueOk = sqlite3VdbeMakeLabel(pParse); + if( bAffinityDone==0 ){ sqlite3TableAffinity(v, pTab, regNewData+1); bAffinityDone = 1; } @@ -122530,7 +127059,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]); @@ -122564,8 +127093,8 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } /* Figure out if the upsert clause applies to this index */ - if( pUpIdx==pIdx ){ - if( pUpsert->pUpsertSet==0 ){ + if( pUpsertClause ){ + if( pUpsertClause->isDoUpdate==0 ){ onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ }else{ onError = OE_Update; /* DO UPDATE */ @@ -122582,6 +127111,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 */ @@ -122589,7 +127119,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; @@ -122603,7 +127133,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( regIdx, pIdx->nKeyCol); VdbeCoverage(v); /* Generate code to handle collisions */ - regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField); + regR = pIdx==pPk ? regIdx : sqlite3GetTempRange(pParse, nPkField); if( isUpdate || onError==OE_Replace ){ if( HasRowid(pTab) ){ sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR); @@ -122624,7 +127154,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 ){ @@ -122688,7 +127218,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); @@ -122755,19 +127286,23 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( break; } } - if( pUpIdx==pIdx ){ - sqlite3VdbeGoto(v, upsertJump+1); - sqlite3VdbeJumpHere(v, upsertBypass); - }else{ - sqlite3VdbeResolveLabel(v, addrUniqueOk); - } + sqlite3VdbeResolveLabel(v, addrUniqueOk); if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); + if( pUpsertClause + && upsertIpkReturn + && sqlite3UpsertNextIsIPK(pUpsertClause) + ){ + sqlite3VdbeGoto(v, upsertIpkDelay+1); + sqlite3VdbeJumpHere(v, upsertIpkReturn); + upsertIpkReturn = 0; + } } /* If the IPK constraint is a REPLACE, run it last */ if( ipkTop ){ sqlite3VdbeGoto(v, ipkTop); VdbeComment((v, "Do IPK REPLACE")); + assert( ipkBottom>0 ); sqlite3VdbeJumpHere(v, ipkBottom); } @@ -122820,13 +127355,39 @@ 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); } #endif +/* +** Table pTab is a WITHOUT ROWID table that is being written to. The cursor +** number is iCur, and register regData contains the new record for the +** PK index. This function adds code to invoke the pre-update hook, +** if one is registered. +*/ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +static void codeWithoutRowidPreupdate( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated */ + int iCur, /* Cursor number for table */ + int regData /* Data containing new record */ +){ + Vdbe *v = pParse->pVdbe; + int r = sqlite3GetTempReg(pParse); + assert( !HasRowid(pTab) ); + assert( 0==(pParse->db->mDbFlags & DBFLAG_Vacuum) || CORRUPT_DB ); + sqlite3VdbeAddOp2(v, OP_Integer, 0, r); + sqlite3VdbeAddOp4(v, OP_Insert, iCur, regData, r, (char*)pTab, P4_TABLE); + sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); + sqlite3ReleaseTempReg(pParse, r); +} +#else +# define codeWithoutRowidPreupdate(a,b,c,d) +#endif + /* ** This routine generates code to finish the INSERT or UPDATE operation ** that was started by a prior call to sqlite3GenerateConstraintChecks. @@ -122857,9 +127418,9 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION) ); - v = sqlite3GetVdbe(pParse); + 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 @@ -122872,20 +127433,11 @@ 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); -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK if( update_flags==0 ){ - int r = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp2(v, OP_Integer, 0, r); - sqlite3VdbeAddOp4(v, OP_Insert, - iIdxCur+i, aRegIdx[i], r, (char*)pTab, P4_TABLE - ); - sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); - sqlite3ReleaseTempReg(pParse, r); + codeWithoutRowidPreupdate(pParse, pTab, iIdxCur+i, aRegIdx[i]); } -#endif } sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i], aRegIdx[i]+1, @@ -122953,12 +127505,13 @@ 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); - v = sqlite3GetVdbe(pParse); + v = pParse->pVdbe; assert( v!=0 ); if( iBase<0 ) iBase = pParse->nTab; iDataCur = iBase++; @@ -123083,7 +127636,7 @@ static int xferOptimization( ExprList *pEList; /* The result set of the SELECT */ Table *pSrc; /* The table in the FROM clause of SELECT */ Index *pSrcIdx, *pDestIdx; /* Source and destination indices */ - struct SrcList_item *pItem; /* An element of pSelect->pSrc */ + SrcItem *pItem; /* An element of pSelect->pSrc */ int i; /* Loop counter */ int iDbSrc; /* The database of pSrc */ int iSrc, iDest; /* Cursors from source and destination */ @@ -123169,13 +127722,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 */ @@ -123183,6 +127731,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]; @@ -123219,7 +127770,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 */ @@ -123229,7 +127782,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 ){ @@ -123237,11 +127791,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 */ } @@ -123278,7 +127836,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 @@ -123300,6 +127859,7 @@ static int xferOptimization( iDest = pParse->nTab++; regAutoinc = autoIncBegin(pParse, iDbDest, pDest); regData = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, regData); regRowid = sqlite3GetTempReg(pParse); sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); assert( HasRowid(pDest) || destHasUniqueIdx ); @@ -123335,11 +127895,13 @@ static int xferOptimization( emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); if( pDest->iPKey>=0 ){ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); - sqlite3VdbeVerifyAbortable(v, onError); - addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); - VdbeCoverage(v); - sqlite3RowidConstraint(pParse, onError, pDest); - sqlite3VdbeJumpHere(v, addr2); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeVerifyAbortable(v, onError); + addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); + VdbeCoverage(v); + sqlite3RowidConstraint(pParse, onError, pDest); + sqlite3VdbeJumpHere(v, addr2); + } autoIncStep(pParse, regAutoinc, regRowid); }else if( pDest->pIndex==0 && !(db->mDbFlags & DBFLAG_VacuumInto) ){ addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid); @@ -123347,16 +127909,28 @@ static int xferOptimization( addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); assert( (pDest->tabFlags & TF_Autoincrement)==0 ); } + if( db->mDbFlags & DBFLAG_Vacuum ){ sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); - insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT; + insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; }else{ - insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND; + insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND|OPFLAG_PREFORMAT; + } +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + insFlags &= ~OPFLAG_PREFORMAT; + }else +#endif + { + sqlite3VdbeAddOp3(v, OP_RowCell, iDest, iSrc, regRowid); + } + sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeChangeP4(v, -1, (char*)pDest, P4_TABLE); } - sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); - sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid, - (char*)pDest, P4_TABLE); sqlite3VdbeChangeP5(v, insFlags); + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); @@ -123398,13 +127972,22 @@ static int xferOptimization( if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break; } if( i==pSrcIdx->nColumn ){ - idxInsFlags = OPFLAG_USESEEKRESULT; + idxInsFlags = OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); + sqlite3VdbeAddOp2(v, OP_RowCell, iDest, iSrc); } }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ idxInsFlags |= OPFLAG_NCHANGE; } - sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + if( idxInsFlags!=(OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT) ){ + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 + && !HasRowid(pDest) + && IsPrimaryKeyIndex(pDestIdx) + ){ + codeWithoutRowidPreupdate(pParse, pDest, iDest, regData); + } + } sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); @@ -123930,6 +128513,22 @@ struct sqlite3_api_routines { int,const char**); void (*free_filename)(char*); 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**); }; /* @@ -124234,6 +128833,20 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_create_filename sqlite3_api->create_filename #define sqlite3_free_filename sqlite3_api->free_filename #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) @@ -124716,6 +129329,20 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_create_filename, sqlite3_free_filename, 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 @@ -124751,7 +129378,7 @@ static int sqlite3LoadExtension( const char *zEntry; char *zAltEntry = 0; void **aHandle; - u64 nMsg = 300 + sqlite3Strlen30(zFile); + u64 nMsg = strlen(zFile); int ii; int rc; @@ -124785,6 +129412,12 @@ static int sqlite3LoadExtension( zEntry = zProc ? zProc : "sqlite3_extension_init"; + /* tag-20210611-1. Some dlopen() implementations will segfault if given + ** an oversize filename. Most filesystems have a pathname limit of 4K, + ** so limit the extension filename length to about twice that. + ** https://sqlite.org/forum/forumpost/08a0d6d9bf */ + if( nMsg>SQLITE_MAX_PATHLEN ) goto extension_not_found; + handle = sqlite3OsDlOpen(pVfs, zFile); #if SQLITE_OS_UNIX || SQLITE_OS_WIN for(ii=0; iiaExtension[db->nExtension++] = handle; return SQLITE_OK; + +extension_not_found: + if( pzErrMsg ){ + nMsg += 300; + *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg); + if( zErrmsg ){ + assert( nMsg<0x7fffffff ); /* zErrmsg would be NULL if not so */ + sqlite3_snprintf((int)nMsg, zErrmsg, + "unable to open shared library [%.*s]", SQLITE_MAX_PATHLEN, zFile); + sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); + } + } + return SQLITE_ERROR; } SQLITE_API int sqlite3_load_extension( sqlite3 *db, /* Load the extension into this database connection */ @@ -125168,13 +129805,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 */ @@ -125207,45 +129845,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 */ @@ -125296,7 +129940,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", @@ -125335,7 +129979,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) @@ -125370,14 +130014,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) @@ -125407,7 +130051,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) @@ -125450,7 +130094,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 @@ -125479,23 +130123,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 @@ -125529,7 +130173,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) @@ -125603,7 +130247,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 @@ -125668,7 +130312,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) @@ -125684,6 +130328,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, @@ -125759,7 +130408,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) @@ -125770,7 +130419,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 *********************/ @@ -125876,7 +130525,9 @@ static int getTempStore(const char *z){ static int invalidateTempStorage(Parse *pParse){ sqlite3 *db = pParse->db; if( db->aDb[1].pBt!=0 ){ - if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){ + if( !db->autoCommit + || sqlite3BtreeTxnState(db->aDb[1].pBt)!=SQLITE_TXN_NONE + ){ sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " "from within a transaction"); return SQLITE_ERROR; @@ -126210,7 +130861,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 ){ @@ -126860,6 +131515,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 @@ -126900,6 +131563,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++; @@ -126920,13 +131584,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); } @@ -126934,6 +131601,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; @@ -126943,7 +131689,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, @@ -126993,7 +131739,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], @@ -127062,11 +131808,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); } } @@ -127100,8 +131848,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; @@ -127114,7 +131862,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 */ @@ -127160,7 +131908,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); @@ -127168,7 +131916,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; @@ -127190,13 +131939,14 @@ 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; if( pParent ){ x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); - assert( x==0 ); + assert( x==0 || db->mallocFailed ); } addrOk = sqlite3VdbeMakeLabel(pParse); @@ -127204,6 +131954,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); @@ -127221,7 +131972,7 @@ SQLITE_PRIVATE void sqlite3Pragma( int jmp = sqlite3VdbeCurrentAddr(v)+2; sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v); sqlite3VdbeGoto(v, addrOk); - assert( pFK->nCol==1 ); + assert( pFK->nCol==1 || db->mallocFailed ); } /* Generate code to report an FK violation to the caller. */ @@ -127390,8 +132141,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, @@ -127411,23 +132163,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 ){ @@ -127712,7 +132489,7 @@ SQLITE_PRIVATE void sqlite3Pragma( ** Checkpoint the database. */ case PragTyp_WAL_CHECKPOINT: { - int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); + int iBt = (pId2->z?iDb:SQLITE_MAX_DB); int eMode = SQLITE_CHECKPOINT_PASSIVE; if( zRight ){ if( sqlite3StrICmp(zRight, "full")==0 ){ @@ -127961,12 +132738,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; } @@ -128360,7 +133137,7 @@ SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName) */ static void corruptSchema( InitData *pData, /* Initialization context */ - const char *zObj, /* Object being parsed at the point of error */ + char **azObj, /* Type and name of object being parsed */ const char *zExtra /* Error information */ ){ sqlite3 *db = pData->db; @@ -128368,14 +133145,23 @@ 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_AlterTable ){ - *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra); + }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], + azAlterType[(pData->mInitFlags&INITFLAG_AlterMask)-1], + zExtra + ); pData->rc = SQLITE_ERROR; }else if( db->flags & SQLITE_WriteSchema ){ pData->rc = SQLITE_CORRUPT_BKPT; }else{ char *z; - if( zObj==0 ) zObj = "?"; + const char *zObj = azObj[1] ? azObj[1] : "?"; z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); *pData->pzErrMsg = z; @@ -128431,21 +133217,28 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char UNUSED_PARAMETER2(NotUsed, argc); assert( sqlite3_mutex_held(db->mutex) ); db->mDbFlags |= DBFLAG_EncodingFixed; + if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ pData->nInitRow++; if( db->mallocFailed ){ - corruptSchema(pData, argv[1], 0); + corruptSchema(pData, argv, 0); return 1; } assert( iDb>=0 && iDbnDb ); - if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[3]==0 ){ - corruptSchema(pData, argv[1], 0); - }else if( sqlite3_strnicmp(argv[4],"create ",7)==0 ){ + corruptSchema(pData, argv, 0); + }else if( argv[4] + && 'c'==sqlite3UpperToLower[(unsigned char)argv[4][0]] + && 'r'==sqlite3UpperToLower[(unsigned char)argv[4][1]] ){ /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. + ** + ** No other valid SQL statement, other than the variable CREATE statements, + ** can begin with the letters "C" and "R". Thus, it is not possible run + ** any other kind of statement while parsing the schema, even a corrupt + ** schema. */ int rc; u8 saved_iDb = db->init.iDb; @@ -128458,11 +133251,11 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char || (db->init.newTnum>pData->mxPage && pData->mxPage>0) ){ if( sqlite3Config.bExtraSchemaChecks ){ - corruptSchema(pData, argv[1], "invalid rootpage"); + corruptSchema(pData, argv, "invalid rootpage"); } } 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; @@ -128477,13 +133270,14 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ - corruptSchema(pData, argv[1], sqlite3_errmsg(db)); + corruptSchema(pData, argv, sqlite3_errmsg(db)); } } } + 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[1], 0); + corruptSchema(pData, argv, 0); }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE @@ -128494,7 +133288,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char Index *pIndex; pIndex = sqlite3FindIndex(db, argv[1], db->aDb[iDb].zDbSName); if( pIndex==0 ){ - corruptSchema(pData, argv[1], "orphan index"); + corruptSchema(pData, argv, "orphan index"); }else if( sqlite3GetUInt32(argv[3],&pIndex->tnum)==0 || pIndex->tnum<2 @@ -128502,7 +133296,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char || sqlite3IndexHasDuplicateRootPage(pIndex) ){ if( sqlite3Config.bExtraSchemaChecks ){ - corruptSchema(pData, argv[1], "invalid rootpage"); + corruptSchema(pData, argv, "invalid rootpage"); } } } @@ -128579,7 +133373,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl ** on the b-tree database, open one now. If a transaction is opened, it ** will be closed before this function returns. */ sqlite3BtreeEnter(pDb->pBt); - if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){ + if( sqlite3BtreeTxnState(pDb->pBt)==SQLITE_TXN_NONE ){ rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0); if( rc!=SQLITE_OK ){ sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc)); @@ -128705,18 +133499,22 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl } #endif } + assert( pDb == &(db->aDb[iDb]) ); if( db->mallocFailed ){ rc = SQLITE_NOMEM_BKPT; sqlite3ResetAllSchemasOfConnection(db); - } + pDb = &db->aDb[iDb]; + }else if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){ - /* Black magic: If the SQLITE_NoSchemaError flag is set, then consider - ** the schema loaded, even if errors occurred. In this situation the - ** current sqlite3_prepare() operation will fail, but the following one - ** will attempt to compile the supplied statement against whatever subset - ** of the schema was loaded before the error occurred. The primary - ** purpose of this is to allow access to the sqlite_schema table - ** even when its contents have been corrupted. + /* 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, + ** but the following one will attempt to compile the supplied statement + ** against whatever subset of the schema was loaded before the error + ** occurred. + ** + ** The primary purpose of this is to allow access to the sqlite_schema + ** table even when its contents have been corrupted. */ DbSetProperty(db, iDb, DB_SchemaLoaded); rc = SQLITE_OK; @@ -128822,10 +133620,11 @@ static void schemaIsValid(Parse *pParse){ /* If there is not already a read-only (or read-write) transaction opened ** on the b-tree database, open one now. If a transaction is opened, it ** will be closed immediately after reading the meta-value. */ - if( !sqlite3BtreeIsInReadTrans(pBt) ){ + if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_NONE ){ rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ sqlite3OomFault(db); + pParse->rc = SQLITE_NOMEM; } if( rc!=SQLITE_OK ) return; openedTransaction = 1; @@ -128882,36 +133681,104 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ return i; } -/* -** Deallocate a single AggInfo object -*/ -static void agginfoFree(sqlite3 *db, AggInfo *p){ - sqlite3DbFree(db, p->aCol); - sqlite3DbFree(db, p->aFunc); - sqlite3DbFree(db, p); -} - /* ** Free all memory allocations in the pParse object */ -SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ +SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse *pParse){ sqlite3 *db = pParse->db; - AggInfo *pThis = pParse->pAggList; - while( pThis ){ - AggInfo *pNext = pThis->pNext; - agginfoFree(db, pThis); - pThis = pNext; + 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; + pCleanup->xCleanup(db, pCleanup->pPtr); + sqlite3DbFreeNN(db, pCleanup); } sqlite3DbFree(db, pParse->aLabel); - 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; - } + if( pParse->pConstExpr ){ + sqlite3ExprListDelete(db, pParse->pConstExpr); + } + 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; } +/* +** Add a new cleanup operation to a Parser. The cleanup should happen when +** the parser object is destroyed. But, beware: the cleanup might happen +** immediately. +** +** Use this mechanism for uncommon cleanups. There is a higher setup +** 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 +** 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 +** pParse->earlyCleanup flag is set in that case. Calling code show verify +** that test cases exist for which this happens, to guard against possible +** use-after-free errors following an OOM. The preferred way to do this is +** to immediately follow the call to this routine with: +** +** testcase( pParse->earlyCleanup ); +** +** This routine returns a copy of its pPtr input (the third parameter) +** except if an early cleanup occurs, in which case it returns NULL. So +** another way to check for early cleanup is to check the return value. +** Or, stop using the pPtr parameter with this call and use only its +** return value thereafter. Something like this: +** +** pObj = sqlite3ParserAddCleanup(pParse, destructor, pObj); +*/ +SQLITE_PRIVATE void *sqlite3ParserAddCleanup( + Parse *pParse, /* Destroy when this Parser finishes */ + void (*xCleanup)(sqlite3*,void*), /* The cleanup routine */ + void *pPtr /* Pointer to object to be cleaned up */ +){ + ParseCleanup *pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup)); + if( pCleanup ){ + pCleanup->pNext = pParse->pCleanup; + pParse->pCleanup = pCleanup; + pCleanup->pPtr = pPtr; + pCleanup->xCleanup = xCleanup; + }else{ + xCleanup(pParse->db, pPtr); + pPtr = 0; +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) + pParse->earlyCleanup = 1; +#endif + } + 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"); +} + /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ @@ -128924,16 +133791,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 @@ -128986,7 +133856,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]; @@ -128999,23 +133868,17 @@ 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 ); - if( sParse.rc==SQLITE_DONE ){ - sParse.rc = SQLITE_OK; - } - if( sParse.checkSchema ){ - schemaIsValid(&sParse); - } if( pzTail ){ *pzTail = sParse.zTail; } @@ -129025,21 +133888,30 @@ static int sqlite3Prepare( } if( db->mallocFailed ){ sParse.rc = SQLITE_NOMEM_BKPT; + sParse.checkSchema = 0; } - rc = sParse.rc; - if( rc!=SQLITE_OK ){ - if( sParse.pVdbe ) sqlite3VdbeFinalize(sParse.pVdbe); - assert(!(*ppStmt)); + if( sParse.rc!=SQLITE_OK && sParse.rc!=SQLITE_DONE ){ + if( sParse.checkSchema && db->init.busy==0 ){ + schemaIsValid(&sParse); + } + if( sParse.pVdbe ){ + sqlite3VdbeFinalize(sParse.pVdbe); + } + assert( 0==(*ppStmt) ); + rc = sParse.rc; + if( sParse.zErrMsg ){ + sqlite3ErrorWithMsg(db, rc, "%s", sParse.zErrMsg); + sqlite3DbFree(db, sParse.zErrMsg); + }else{ + sqlite3Error(db, rc); + } }else{ + assert( sParse.zErrMsg==0 ); *ppStmt = (sqlite3_stmt*)sParse.pVdbe; + rc = SQLITE_OK; + sqlite3ErrorClear(db); } - if( zErrMsg ){ - sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); - sqlite3DbFree(db, zErrMsg); - }else{ - sqlite3Error(db, rc); - } /* Delete any TriggerPrg structures allocated while parsing this statement. */ while( sParse.pTriggerPrg ){ @@ -129050,7 +133922,7 @@ static int sqlite3Prepare( end_prepare: - sqlite3ParserReset(&sParse); + sqlite3ParseObjectReset(&sParse); return rc; } static int sqlite3LockAndPrepare( @@ -129080,11 +133952,13 @@ static int sqlite3LockAndPrepare( ** reset is considered a permanent error. */ rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); assert( rc==SQLITE_OK || *ppStmt==0 ); + if( rc==SQLITE_OK || db->mallocFailed ) break; }while( rc==SQLITE_ERROR_RETRY || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) ); sqlite3BtreeLeaveAll(db); rc = sqlite3ApiExit(db, rc); assert( (rc&db->errMask)==rc ); + db->busyHandler.nBusy = 0; sqlite3_mutex_leave(db->mutex); return rc; } @@ -129384,12 +134258,16 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){ sqlite3ExprDelete(db, p->pHaving); sqlite3ExprListDelete(db, p->pOrderBy); sqlite3ExprDelete(db, p->pLimit); + if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); #ifndef SQLITE_OMIT_WINDOWFUNC if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){ sqlite3WindowListDelete(db, p->pWinDefn); } + while( p->pWin ){ + assert( p->pWin->ppThis==&p->pWin ); + sqlite3WindowUnlinkFromSelect(p->pWin); + } #endif - if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; bFree = 1; @@ -129561,12 +134439,12 @@ SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *p ** Return the index of a column in a table. Return -1 if the column ** is not contained in the table. */ -static int columnIndex(Table *pTab, const char *zCol){ +SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){ int i; u8 h = sqlite3StrIHash(zCol); Column *pCol; for(pCol=pTab->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; } @@ -129593,7 +134471,7 @@ static int tableAndColumnIndex( assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=0; ia[i].pTab, zCol); + iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol); if( iCol>=0 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) ){ @@ -129642,18 +134520,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 = (i16)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 @@ -129663,8 +134544,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: ** @@ -129682,11 +134563,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 = (i16)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); @@ -129695,7 +134579,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. @@ -129703,13 +134587,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_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_COLUMN && p->iTable==iTable ){ + ExprClearProperty(p, EP_CanBeNull); + } + 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); @@ -129734,8 +134624,8 @@ static void unsetJoinExpr(Expr *p, int iTable){ static int sqliteProcessJoin(Parse *pParse, Select *p){ SrcList *pSrc; /* All tables in the FROM clause */ int i, j; /* Loop counters */ - struct SrcList_item *pLeft; /* Left table being joined */ - struct SrcList_item *pRight; /* Right table being joined */ + SrcItem *pLeft; /* Left table being joined */ + SrcItem *pRight; /* Right table being joined */ pSrc = p->pSrc; pLeft = &pSrc->a[0]; @@ -129762,7 +134652,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); @@ -129803,7 +134693,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ int iRightCol; /* Column number of matching column on the right */ zName = pList->a[j].zName; - iRightCol = columnIndex(pRightTab, zName); + iRightCol = sqlite3ColumnIndex(pRightTab, zName); if( iRightCol<0 || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0) ){ @@ -130033,31 +134923,157 @@ static void codeOffset( } /* -** Add code that will check to make sure the N registers starting at iMem -** form a distinct entry. iTab is a sorting index that holds previously -** seen combinations of the N values. A new entry is made in iTab -** if the current N values are new. +** Add code that will check to make sure the array of registers starting at +** iMem form a distinct entry. This is used by both "SELECT DISTINCT ..." and +** distinct aggregates ("SELECT count(DISTINCT ) ..."). Three strategies +** are available. Which is used depends on the value of parameter eTnctType, +** as follows: ** -** A jump to addrRepeat is made and the N+1 values are popped from the -** stack if the top N elements are not distinct. -*/ -static void codeDistinct( +** WHERE_DISTINCT_UNORDERED/WHERE_DISTINCT_NOOP: +** Build an ephemeral table that contains all entries seen before and +** skip entries which have been seen before. +** +** Parameter iTab is the cursor number of an ephemeral table that must +** be opened before the VM code generated by this routine is executed. +** The ephemeral cursor table is queried for a record identical to the +** record formed by the current array of registers. If one is found, +** jump to VM address addrRepeat. Otherwise, insert a new record into +** the ephemeral cursor and proceed. +** +** The returned value in this case is a copy of parameter iTab. +** +** WHERE_DISTINCT_ORDERED: +** In this case rows are being delivered sorted order. The ephermal +** table is not required. Instead, the current set of values +** is compared against previous row. If they match, the new row +** is not distinct and control jumps to VM address addrRepeat. Otherwise, +** the VM program proceeds with processing the new row. +** +** The returned value in this case is the register number of the first +** in an array of registers used to store the previous result row so that +** it can be compared to the next. The caller must ensure that this +** register is initialized to NULL. (The fixDistinctOpenEph() routine +** will take care of this initialization.) +** +** WHERE_DISTINCT_UNIQUE: +** In this case it has already been determined that the rows are distinct. +** No special action is required. The return value is zero. +** +** Parameter pEList is the list of expressions used to generated the +** contents of each row. It is used by this routine to determine (a) +** how many elements there are in the array of registers and (b) the +** collation sequences that should be used for the comparisons if +** eTnctType is WHERE_DISTINCT_ORDERED. +*/ +static int codeDistinct( Parse *pParse, /* Parsing and code generating context */ + int eTnctType, /* WHERE_DISTINCT_* value */ int iTab, /* A sorting index used to test for distinctness */ int addrRepeat, /* Jump to here if not distinct */ - int N, /* Number of elements */ - int iMem /* First element */ + ExprList *pEList, /* Expression for each element */ + int regElem /* First element */ ){ - Vdbe *v; - int r1; + int iRet = 0; + int nResultCol = pEList->nExpr; + Vdbe *v = pParse->pVdbe; - v = pParse->pVdbe; - r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1); - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r1, iMem, N); - sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); - sqlite3ReleaseTempReg(pParse, r1); + switch( eTnctType ){ + case WHERE_DISTINCT_ORDERED: { + int i; + int iJump; /* Jump destination */ + int regPrev; /* Previous row content */ + + /* Allocate space for the previous row */ + iRet = regPrev = pParse->nMem+1; + pParse->nMem += nResultCol; + + iJump = sqlite3VdbeCurrentAddr(v) + nResultCol; + for(i=0; ia[i].pExpr); + if( idb->mallocFailed ); + sqlite3VdbeAddOp3(v, OP_Copy, regElem, regPrev, nResultCol-1); + break; + } + + case WHERE_DISTINCT_UNIQUE: { + /* nothing to do */ + break; + } + + default: { + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, regElem, nResultCol); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regElem, nResultCol, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r1, regElem, nResultCol); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + sqlite3ReleaseTempReg(pParse, r1); + iRet = iTab; + break; + } + } + + return iRet; +} + +/* +** This routine runs after codeDistinct(). It makes necessary +** adjustments to the OP_OpenEphemeral opcode that the codeDistinct() +** routine made use of. This processing must be done separately since +** sometimes codeDistinct is called before the OP_OpenEphemeral is actually +** laid down. +** +** WHERE_DISTINCT_NOOP: +** WHERE_DISTINCT_UNORDERED: +** +** No adjustments necessary. This function is a no-op. +** +** WHERE_DISTINCT_UNIQUE: +** +** The ephemeral table is not needed. So change the +** OP_OpenEphemeral opcode into an OP_Noop. +** +** WHERE_DISTINCT_ORDERED: +** +** The ephemeral table is not needed. But we do need register +** iVal to be initialized to NULL. So change the OP_OpenEphemeral +** into an OP_Null on the iVal register. +*/ +static void fixDistinctOpenEph( + Parse *pParse, /* Parsing and code generating context */ + int eTnctType, /* WHERE_DISTINCT_* value */ + int iVal, /* Value returned by codeDistinct() */ + int iOpenEphAddr /* Address of OP_OpenEphemeral instruction for iTab */ +){ + 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 ){ + sqlite3VdbeChangeToNoop(v, iOpenEphAddr+1); + } + if( eTnctType==WHERE_DISTINCT_ORDERED ){ + /* Change the OP_OpenEphemeral to an OP_Null that sets the MEM_Cleared + ** bit on the first register of the previous value. This will cause the + ** OP_Ne added in codeDistinct() to always fail on the first iteration of + ** the loop even if the first row is all NULLs. */ + VdbeOp *pOp = sqlite3VdbeGetOp(v, iOpenEphAddr); + pOp->opcode = OP_Null; + pOp->p1 = 1; + pOp->p2 = iVal; + } + } } #ifdef SQLITE_ENABLE_SORTER_REFERENCES @@ -130098,9 +135114,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); @@ -130305,59 +135326,11 @@ static void selectInnerLoop( ** part of the result. */ if( hasDistinct ){ - switch( pDistinct->eTnctType ){ - case WHERE_DISTINCT_ORDERED: { - VdbeOp *pOp; /* No longer required OpenEphemeral instr. */ - int iJump; /* Jump destination */ - int regPrev; /* Previous row content */ - - /* Allocate space for the previous row */ - regPrev = pParse->nMem+1; - pParse->nMem += nResultCol; - - /* Change the OP_OpenEphemeral coded earlier to an OP_Null - ** sets the MEM_Cleared bit on the first register of the - ** previous value. This will cause the OP_Ne below to always - ** fail on the first iteration of the loop even if the first - ** row is all NULLs. - */ - sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct); - pOp = sqlite3VdbeGetOp(v, pDistinct->addrTnct); - pOp->opcode = OP_Null; - pOp->p1 = 1; - pOp->p2 = regPrev; - pOp = 0; /* Ensure pOp is not used after sqlite3VdbeAddOp() */ - - iJump = sqlite3VdbeCurrentAddr(v) + nResultCol; - for(i=0; ipEList->a[i].pExpr); - if( idb->mallocFailed ); - sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nResultCol-1); - break; - } - - case WHERE_DISTINCT_UNIQUE: { - sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct); - break; - } - - default: { - assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED ); - codeDistinct(pParse, pDistinct->tabTnct, iContinue, nResultCol, - regResult); - break; - } - } + int eType = pDistinct->eTnctType; + int iTab = pDistinct->tabTnct; + assert( nResultCol==p->pEList->nExpr ); + iTab = codeDistinct(pParse, eType, iTab, iContinue, p->pEList, regResult); + fixDistinctOpenEph(pParse, eType, iTab, pDistinct->addrTnct); if( pSort==0 ){ codeOffset(v, p->iOffset, iContinue); } @@ -130604,7 +135577,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; } @@ -130682,7 +135655,7 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList( /* ** Name of the connection operator, used for error messages. */ -static const char *selectOpName(int id){ +SQLITE_PRIVATE const char *sqlite3SelectOpName(int id){ char *z; switch( id ){ case TK_ALL: z = "UNION ALL"; break; @@ -130775,6 +135748,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{ @@ -131017,13 +135993,19 @@ 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 ** data for the result-set column of the sub-select. */ - if( iCol>=0 && iColpEList->nExpr ){ + if( iColpEList->nExpr +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + && iCol>=0 +#else + && ALWAYS(iCol>=0) +#endif + ){ /* If iCol is less than zero, then the expression requests the ** rowid of the sub-select or view. This expression is legal (see ** test case misc2.2.2) - it always evaluates to NULL. @@ -131045,7 +136027,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; @@ -131071,9 +136053,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; @@ -131165,7 +136149,7 @@ static void generateColumnTypes( ** then the result column name with the table name ** prefix, ex: TABLE.COLUMN. Otherwise use zSpan. */ -static void generateColumnNames( +SQLITE_PRIVATE void sqlite3GenerateColumnNames( Parse *pParse, /* Parser context */ Select *pSelect /* Generate column names for this SELECT statement */ ){ @@ -131202,7 +136186,8 @@ static void generateColumnNames( 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; @@ -131217,7 +136202,7 @@ static void generateColumnNames( if( iCol<0 ){ zCol = "rowid"; }else{ - zCol = pTab->aCol[iCol].zName; + zCol = pTab->aCol[iCol].zCnName; } if( fullName ){ char *zName = 0; @@ -131255,7 +136240,7 @@ static void generateColumnNames( ** and will break if those assumptions changes. Hence, use extreme caution ** when modifying this routine to avoid breaking legacy. ** -** See Also: generateColumnNames() +** See Also: sqlite3GenerateColumnNames() */ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( Parse *pParse, /* Parsing context */ @@ -131271,13 +136256,14 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( char *zName; /* Column name */ int nName; /* Size of name in zName[] */ Hash ht; /* Hash table of column names */ + Table *pTab; sqlite3HashInit(&ht); if( pEList ){ nCol = pEList->nExpr; aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); testcase( aCol==0 ); - if( nCol>32767 ) nCol = 32767; + if( NEVER(nCol>32767) ) nCol = 32767; }else{ nCol = 0; aCol = 0; @@ -131293,17 +136279,18 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( /* If the column contains an "AS " phrase, use as the name */ }else{ Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr); - while( pColExpr->op==TK_DOT ){ + while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){ pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); } - if( pColExpr->op==TK_COLUMN ){ + if( pColExpr->op==TK_COLUMN + && ALWAYS( ExprUseYTab(pColExpr) ) + && (pTab = pColExpr->y.pTab)!=0 + ){ /* For columns use the column name name */ int iCol = pColExpr->iColumn; - Table *pTab = pColExpr->y.pTab; - assert( pTab!=0 ); 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; @@ -131331,7 +136318,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 ){ @@ -131341,7 +136328,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); /* pCol->szEst = ... // Column size est for SELECT tables never used */ 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 */ @@ -131566,7 +136558,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 ){ @@ -131638,7 +136630,8 @@ 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 */ int iCurrent = 0; /* The Current table */ @@ -131714,7 +136707,24 @@ static void generateWithRecursiveQuery( /* Detach the ORDER BY clause from the compound SELECT */ p->pOrderBy = 0; + /* Figure out how many elements of the compound SELECT are part of the + ** recursive query. Make sure no recursive elements use aggregate + ** functions. Mark the recursive elements as UNION ALL even if they + ** are really UNION because the distinctness will be enforced by the + ** iDistinct table. pFirstRec is left pointing to the left-most + ** recursive term of the CTE. + */ + for(pFirstRec=p; ALWAYS(pFirstRec!=0); pFirstRec=pFirstRec->pPrior){ + if( pFirstRec->selFlags & SF_Aggregate ){ + sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported"); + goto end_of_recursive_query; + } + pFirstRec->op = TK_ALL; + if( (pFirstRec->pPrior->selFlags & SF_Recursive)==0 ) break; + } + /* Store the results of the setup-query in Queue. */ + pSetup = pFirstRec->pPrior; pSetup->pNext = 0; ExplainQueryPlan((pParse, 1, "SETUP")); rc = sqlite3Select(pParse, pSetup, &destQueue); @@ -131747,15 +136757,11 @@ static void generateWithRecursiveQuery( /* Execute the recursive SELECT taking the single row in Current as ** the value for the recursive-table. Store the results in the Queue. */ - if( p->selFlags & SF_Aggregate ){ - sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported"); - }else{ - p->pPrior = 0; - ExplainQueryPlan((pParse, 1, "RECURSIVE STEP")); - sqlite3Select(pParse, p, &destQueue); - assert( p->pPrior==0 ); - p->pPrior = pSetup; - } + pFirstRec->pPrior = 0; + ExplainQueryPlan((pParse, 1, "RECURSIVE STEP")); + sqlite3Select(pParse, p, &destQueue); + assert( pFirstRec->pPrior==0 ); + pFirstRec->pPrior = pSetup; /* Keep running the loop until the Queue is empty */ sqlite3VdbeGoto(v, addrTop); @@ -131824,6 +136830,16 @@ static int multiSelectValues( return rc; } +/* +** Return true if the SELECT statement which is known to be the recursive +** part of a recursive CTE still has its anchor terms attached. If the +** anchor terms have already been removed, then return false. +*/ +static int hasAnchor(Select *p){ + while( p && (p->selFlags & SF_Recursive)!=0 ){ p = p->pPrior; } + return p!=0; +} + /* ** This routine is called to process a compound query form from ** two or more separate queries using UNION, UNION ALL, EXCEPT, or @@ -131876,12 +136892,8 @@ static int multiSelect( db = pParse->db; pPrior = p->pPrior; dest = *pDest; - if( pPrior->pOrderBy || pPrior->pLimit ){ - sqlite3ErrorMsg(pParse,"%s clause should come after %s not before", - pPrior->pOrderBy!=0 ? "ORDER BY" : "LIMIT", selectOpName(p->op)); - rc = 1; - goto multi_select_end; - } + assert( pPrior->pOrderBy==0 ); + assert( pPrior->pLimit==0 ); v = sqlite3GetVdbe(pParse); assert( v!=0 ); /* The VDBE already created by calling function */ @@ -131909,7 +136921,7 @@ static int multiSelect( assert( p->pEList->nExpr==pPrior->pEList->nExpr ); #ifndef SQLITE_OMIT_CTE - if( p->selFlags & SF_Recursive ){ + if( (p->selFlags & SF_Recursive)!=0 && hasAnchor(p) ){ generateWithRecursiveQuery(pParse, p, &dest); }else #endif @@ -131932,13 +136944,14 @@ static int multiSelect( switch( p->op ){ case TK_ALL: { int addr = 0; - int nLimit; + int nLimit = 0; /* Initialize to suppress harmless compiler warning */ assert( !pPrior->pLimit ); pPrior->iLimit = p->iLimit; pPrior->iOffset = p->iOffset; pPrior->pLimit = p->pLimit; + SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL left...\n")); rc = sqlite3Select(pParse, pPrior, &dest); - p->pLimit = 0; + pPrior->pLimit = 0; if( rc ){ goto multi_select_end; } @@ -131954,13 +136967,14 @@ static int multiSelect( } } ExplainQueryPlan((pParse, 1, "UNION ALL")); + SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL right...\n")); rc = sqlite3Select(pParse, p, &dest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); - if( pPrior->pLimit - && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit) + if( p->pLimit + && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit) && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) ){ p->nSelectRow = sqlite3LogEst((u64)nLimit); @@ -132001,10 +137015,12 @@ static int multiSelect( assert( p->pEList ); } + /* Code the SELECT statements to our left */ assert( !pPrior->pOrderBy ); sqlite3SelectDestInit(&uniondest, priorOp, unionTab); + SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION left...\n")); rc = sqlite3Select(pParse, pPrior, &uniondest); if( rc ){ goto multi_select_end; @@ -132023,7 +137039,8 @@ static int multiSelect( p->pLimit = 0; uniondest.eDest = op; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", - selectOpName(p->op))); + sqlite3SelectOpName(p->op))); + SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION right...\n")); rc = sqlite3Select(pParse, p, &uniondest); testcase( rc!=SQLITE_OK ); assert( p->pOrderBy==0 ); @@ -132084,6 +137101,7 @@ static int multiSelect( /* Code the SELECTs to our left into temporary table "tab1". */ sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); + SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT left...\n")); rc = sqlite3Select(pParse, pPrior, &intersectdest); if( rc ){ goto multi_select_end; @@ -132099,7 +137117,8 @@ static int multiSelect( p->pLimit = 0; intersectdest.iSDParm = tab2; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", - selectOpName(p->op))); + sqlite3SelectOpName(p->op))); + SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT right...\n")); rc = sqlite3Select(pParse, p, &intersectdest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; @@ -132160,6 +137179,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 ){ @@ -132194,7 +137214,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 */ @@ -132208,7 +137232,8 @@ SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){ sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); }else{ sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" - " do not have the same number of result columns", selectOpName(p->op)); + " do not have the same number of result columns", + sqlite3SelectOpName(p->op)); } } @@ -132305,10 +137330,8 @@ static int generateOutputSubroutine( ** if it is the RHS of a row-value IN operator. */ case SRT_Mem: { - if( pParse->nErr==0 ){ - testcase( pIn->nSdst>1 ); - sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, pIn->nSdst); - } + testcase( pIn->nSdst>1 ); + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, pIn->nSdst); /* The LIMIT clause will jump out of the loop for us */ break; } @@ -132449,6 +137472,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 */ @@ -132494,8 +137519,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; @@ -132508,6 +137532,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; } @@ -132534,6 +137559,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; @@ -132543,11 +137569,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). @@ -132572,12 +137593,30 @@ static int multiSelectOrderBy( /* Separate the left and the right query from one another */ - p->pPrior = 0; + 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"); - if( pPrior->pPrior==0 ){ - sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); - } + sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); /* Compute the limit registers */ computeLimitRegisters(pParse, p, labelEnd); @@ -132600,7 +137639,7 @@ static int multiSelectOrderBy( sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); - ExplainQueryPlan((pParse, 1, "MERGE (%s)", selectOpName(p->op))); + ExplainQueryPlan((pParse, 1, "MERGE (%s)", sqlite3SelectOpName(p->op))); /* Generate a coroutine to evaluate the SELECT statement to the ** left of the compound operator - the "A" select. @@ -132728,11 +137767,13 @@ 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; /*** TBD: Insert subroutine calls to close cursors on incomplete **** subqueries ****/ @@ -132780,17 +137821,20 @@ 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 && !ExprHasProperty(pExpr, EP_FixedCol) ){ +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW if( pExpr->iColumn<0 ){ pExpr->op = TK_NULL; - }else{ + }else +#endif + { Expr *pNew; Expr *pCopy = pSubst->pEList->a[pExpr->iColumn].pExpr; Expr ifNullRow; @@ -132805,32 +137849,33 @@ static Expr *substExpr( ifNullRow.op = TK_IF_NULL_ROW; ifNullRow.pLeft = pCopy; ifNullRow.iTable = pSubst->iNewTable; - ifNullRow.flags = EP_Skip; + ifNullRow.flags = EP_IfNullRow; pCopy = &ifNullRow; } testcase( ExprHasProperty(pCopy, EP_Subquery) ); pNew = sqlite3ExprDup(db, pCopy, 0); - if( pNew && pSubst->isLeftJoin ){ + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pNew); + return pExpr; + } + if( pSubst->isLeftJoin ){ ExprSetProperty(pNew, EP_CanBeNull); } - if( pNew && ExprHasProperty(pExpr,EP_FromJoin) ){ - pNew->iRightJoinTable = pExpr->iRightJoinTable; - ExprSetProperty(pNew, EP_FromJoin); + if( ExprHasProperty(pExpr,EP_FromJoin) ){ + sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable); } sqlite3ExprDelete(db, pExpr); pExpr = pNew; /* Ensure that the expression now has an implicit collation sequence, ** just as it did when it was a column of a view or sub-query. */ - if( pExpr ){ - if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){ - CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr); - pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, - (pColl ? pColl->zName : "BINARY") - ); - } - ExprClearProperty(pExpr, EP_Collate); + if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){ + CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr); + pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, + (pColl ? pColl->zName : "BINARY") + ); } + ExprClearProperty(pExpr, EP_Collate); } } }else{ @@ -132839,7 +137884,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); @@ -132871,7 +137916,7 @@ static void substSelect( int doPrior /* Do substitutes on p->pPrior too */ ){ SrcList *pSrc; - struct SrcList_item *pItem; + SrcItem *pItem; int i; if( !p ) return; do{ @@ -132901,7 +137946,7 @@ static void substSelect( ** pSrcItem->colUsed mask. */ static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){ - struct SrcList_item *pItem; + SrcItem *pItem; if( pExpr->op!=TK_COLUMN ) return WRC_Continue; pItem = pWalker->u.pSrcItem; if( pItem->iCursor!=pExpr->iTable ) return WRC_Continue; @@ -132911,7 +137956,7 @@ static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){ } static void recomputeColumnsUsed( Select *pSelect, /* The complete SELECT statement */ - struct SrcList_item *pSrcItem /* Which FROM clause item to recompute */ + SrcItem *pSrcItem /* Which FROM clause item to recompute */ ){ Walker w; if( NEVER(pSrcItem->pTab==0) ) return; @@ -132924,6 +137969,103 @@ static void recomputeColumnsUsed( } #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** Assign new cursor numbers to each of the items in pSrc. For each +** new cursor number assigned, set an entry in the aCsrMap[] array +** to map the old cursor number to the new: +** +** aCsrMap[iOld+1] = iNew; +** +** The array is guaranteed by the caller to be large enough for all +** 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. +*/ +static void srclistRenumberCursors( + Parse *pParse, /* Parse context */ + int *aCsrMap, /* Array to store cursor mappings in */ + SrcList *pSrc, /* FROM clause to renumber */ + int iExcept /* FROM clause item to skip */ +){ + int i; + SrcItem *pItem; + for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ + if( i!=iExcept ){ + Select *p; + 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+1]; + for(p=pItem->pSelect; p; p=p->pPrior){ + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); + } + } + } +} + +/* +** *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 op = pExpr->op; + if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){ + renumberCursorDoMapping(pWalker, &pExpr->iTable); + } + if( ExprHasProperty(pExpr, EP_FromJoin) ){ + renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable); + } + return WRC_Continue; +} + +/* +** Assign a new cursor number to each cursor in the FROM clause (Select.pSrc) +** of the SELECT statement passed as the second argument, and to each +** cursor in the FROM clause of any FROM clause sub-selects, recursively. +** Except, do not assign a new cursor number to the iExcept'th element in +** the FROM clause of (*p). Update all expressions and other references +** to refer to the new cursor numbers. +** +** Argument aCsrMap is an array that may be used for temporary working +** space. Two guarantees are made by the caller: +** +** * the array is larger than the largest cursor number used within the +** select statement passed as an argument, and +** +** * the array entries for all cursor numbers that do *not* appear in +** FROM clauses of the select statement as described above are +** initialized to zero. +*/ +static void renumberCursors( + Parse *pParse, /* Parse context */ + Select *p, /* Select to renumber cursors within */ + int iExcept, /* FROM clause item to skip */ + int *aCsrMap /* Working space */ +){ + Walker w; + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, iExcept); + memset(&w, 0, sizeof(w)); + w.u.aiCol = aCsrMap; + w.xExprCallback = renumberCursorsCb; + w.xSelectCallback = sqlite3SelectWalkNoop; + sqlite3WalkSelect(&w, p); +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* ** This routine attempts to flatten subqueries as a performance optimization. @@ -133018,9 +138160,9 @@ static void recomputeColumnsUsed( ** (17c) every term within the subquery compound must have a FROM clause ** (17d) the outer query may not be ** (17d1) aggregate, or -** (17d2) DISTINCT, or -** (17d3) a join. -** (17e) the subquery may not contain window functions +** (17d2) DISTINCT +** (17e) the subquery may not contain window functions, and +** (17f) the subquery must not be the RHS of a LEFT JOIN. ** ** The parent and sub-query may contain WHERE clauses. Subject to ** rules (11), (13) and (14), they may also contain ORDER BY, @@ -133036,8 +138178,8 @@ static void recomputeColumnsUsed( ** syntax error and return a detailed message. ** ** (18) If the sub-query is a compound select, then all terms of the -** ORDER BY clause of the parent must be simple references to -** columns of the sub-query. +** ORDER BY clause of the parent must be copies of a term returned +** by the parent query. ** ** (19) If the subquery uses LIMIT then the outer query may not ** have a WHERE clause. @@ -133053,9 +138195,8 @@ static void recomputeColumnsUsed( ** ** (22) The subquery may not be a recursive CTE. ** -** (**) Subsumed into restriction (17d3). Was: If the outer query is -** a recursive CTE, then the sub-query may not be a compound query. -** This restriction is because transforming the +** (23) If the outer query is a recursive CTE, then the sub-query may not be +** a compound query. This restriction is because transforming the ** parent to a compound query confuses the code that handles ** recursive queries in multiSelect(). ** @@ -133097,9 +138238,10 @@ static int flattenSubquery( int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ int i; /* Loop counter */ Expr *pWhere; /* The WHERE clause */ - struct SrcList_item *pSubitem; /* The subquery */ + SrcItem *pSubitem; /* The subquery */ sqlite3 *db = pParse->db; Walker w; /* Walker to persist agginfo data */ + int *aCsrMap = 0; /* Check to see if flattening is permitted. Return 0 if not. */ @@ -133195,13 +138337,14 @@ static int flattenSubquery( if( pSub->pOrderBy ){ return 0; /* Restriction (20) */ } - if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){ - return 0; /* (17d1), (17d2), or (17d3) */ + if( isAgg || (p->selFlags & SF_Distinct)!=0 || isLeftJoin>0 ){ + return 0; /* (17d1), (17d2), or (17f) */ } for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); assert( pSub->pSrc!=0 ); + assert( (pSub->selFlags & SF_Recursive)==0 ); assert( pSub->pEList->nExpr==pSub1->pEList->nExpr ); if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 /* (17b) */ || (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */ @@ -133222,15 +138365,16 @@ static int flattenSubquery( if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0; } } - } - /* Ex-restriction (23): - ** The only way that the recursive part of a CTE can contain a compound - ** subquery is for the subquery to be one term of a join. But if the - ** subquery is a join, then the flattening has already been stopped by - ** restriction (17d3) - */ - assert( (p->selFlags & SF_Recursive)==0 || pSub->pPrior==0 ); + /* Restriction (23) */ + if( (p->selFlags & SF_Recursive) ) return 0; + + if( pSrc->nSrc>1 ){ + if( pParse->nSelect>500 ) return 0; + aCsrMap = sqlite3DbMallocZero(db, ((i64)pParse->nTab+1)*sizeof(int)); + if( aCsrMap ) aCsrMap[0] = pParse->nTab; + } + } /***** If we reach this point, flattening is permitted. *****/ SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n", @@ -133242,6 +138386,17 @@ static int flattenSubquery( testcase( i==SQLITE_DENY ); pParse->zAuthContext = zSavedAuthContext; + /* Delete the transient structures associated with thesubquery */ + pSub1 = pSubitem->pSelect; + sqlite3DbFree(db, pSubitem->zDatabase); + sqlite3DbFree(db, pSubitem->zName); + sqlite3DbFree(db, pSubitem->zAlias); + pSubitem->zDatabase = 0; + pSubitem->zName = 0; + pSubitem->zAlias = 0; + pSubitem->pSelect = 0; + assert( pSubitem->pOn==0 ); + /* If the sub-query is a compound SELECT statement, then (by restrictions ** 17 and 18 above) it must be a UNION ALL and the parent query must ** be of the form: @@ -133280,18 +138435,23 @@ static int flattenSubquery( ExprList *pOrderBy = p->pOrderBy; Expr *pLimit = p->pLimit; Select *pPrior = p->pPrior; + Table *pItemTab = pSubitem->pTab; + pSubitem->pTab = 0; p->pOrderBy = 0; - p->pSrc = 0; p->pPrior = 0; p->pLimit = 0; pNew = sqlite3SelectDup(db, p, 0); p->pLimit = pLimit; p->pOrderBy = pOrderBy; - p->pSrc = pSrc; p->op = TK_ALL; + pSubitem->pTab = pItemTab; if( pNew==0 ){ p->pPrior = pPrior; }else{ + pNew->selId = ++pParse->nSelect; + if( aCsrMap && ALWAYS(db->mallocFailed==0) ){ + renumberCursors(pParse, pNew, iFrom, aCsrMap); + } pNew->pPrior = pPrior; if( pPrior ) pPrior->pNext = pNew; pNew->pNext = p; @@ -133299,24 +138459,13 @@ static int flattenSubquery( SELECTTRACE(2,pParse,p,("compound-subquery flattener" " creates %u as peer\n",pNew->selId)); } - if( db->mallocFailed ) return 1; + assert( pSubitem->pSelect==0 ); + } + sqlite3DbFree(db, aCsrMap); + if( db->mallocFailed ){ + pSubitem->pSelect = pSub1; + return 1; } - - /* Begin flattening the iFrom-th entry of the FROM clause - ** in the outer query. - */ - pSub = pSub1 = pSubitem->pSelect; - - /* Delete the transient table structure associated with the - ** subquery - */ - sqlite3DbFree(db, pSubitem->zDatabase); - sqlite3DbFree(db, pSubitem->zName); - sqlite3DbFree(db, pSubitem->zAlias); - pSubitem->zDatabase = 0; - pSubitem->zName = 0; - pSubitem->zAlias = 0; - pSubitem->pSelect = 0; /* Defer deleting the Table object associated with the ** subquery until code generation is @@ -133329,8 +138478,10 @@ static int flattenSubquery( Table *pTabToDel = pSubitem->pTab; if( pTabToDel->nTabRef==1 ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); - pTabToDel->pNextZombie = pToplevel->pZombieTab; - pToplevel->pZombieTab = pTabToDel; + sqlite3ParserAddCleanup(pToplevel, + (void(*)(sqlite3*,void*))sqlite3DeleteTable, + pTabToDel); + testcase( pToplevel->earlyCleanup ); }else{ pTabToDel->nTabRef--; } @@ -133350,6 +138501,7 @@ static int flattenSubquery( ** those references with expressions that resolve to the subquery FROM ** elements we are now copying in. */ + pSub = pSub1; for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){ int nSubSrc; u8 jointype = 0; @@ -133358,14 +138510,8 @@ static int flattenSubquery( nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */ pSrc = pParent->pSrc; /* FROM clause of the outer query */ - if( pSrc ){ - assert( pParent==p ); /* First time through the loop */ - jointype = pSubitem->fg.jointype; - }else{ - assert( pParent!=p ); /* 2nd and subsequent times through the loop */ - pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); - if( pSrc==0 ) break; - pParent->pSrc = pSrc; + if( pParent==p ){ + jointype = pSubitem->fg.jointype; /* First time through the loop */ } /* The subquery uses a single slot of the FROM clause of the outer @@ -133485,7 +138631,7 @@ static int flattenSubquery( sqlite3SelectDelete(db, pSub1); #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p,("After flattening:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -133502,8 +138648,10 @@ static int flattenSubquery( typedef struct WhereConst WhereConst; struct WhereConst { Parse *pParse; /* Parsing context */ + u8 *pOomFault; /* Pointer to pParse->db->mallocFailed */ int nConst; /* Number for COLUMN=CONSTANT terms */ int nChng; /* Number of times a constant is propagated */ + int bHasAffBlob; /* At least one column in apExpr[] as affinity BLOB */ Expr **apExpr; /* [i*2] is COLUMN and [i*2+1] is VALUE */ }; @@ -133542,6 +138690,9 @@ static void constInsert( return; /* Already present. Return without doing anything. */ } } + if( sqlite3ExprAffinity(pColumn)==SQLITE_AFF_BLOB ){ + pConst->bHasAffBlob = 1; + } pConst->nConst++; pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr, @@ -133562,7 +138713,7 @@ static void constInsert( */ static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ Expr *pRight, *pLeft; - if( pExpr==0 ) return; + if( NEVER(pExpr==0) ) return; if( ExprHasProperty(pExpr, EP_FromJoin) ) return; if( pExpr->op==TK_AND ){ findConstInWhere(pConst, pExpr->pRight); @@ -133583,37 +138734,83 @@ static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ } /* -** This is a Walker expression callback. pExpr is a candidate expression -** to be replaced by a value. If pExpr is equivalent to one of the -** columns named in pWalker->u.pConst, then overwrite it with its -** corresponding value. +** This is a helper function for Walker callback propagateConstantExprRewrite(). +** +** Argument pExpr is a candidate expression to be replaced by a value. If +** pExpr is equivalent to one of the columns named in pWalker->u.pConst, +** then overwrite it with the corresponding value. Except, do not do so +** if argument bIgnoreAffBlob is non-zero and the affinity of pExpr +** is SQLITE_AFF_BLOB. */ -static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ +static int propagateConstantExprRewriteOne( + WhereConst *pConst, + Expr *pExpr, + int bIgnoreAffBlob +){ int i; - WhereConst *pConst; + if( pConst->pOomFault[0] ) return WRC_Prune; if( pExpr->op!=TK_COLUMN ) return WRC_Continue; if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ){ testcase( ExprHasProperty(pExpr, EP_FixedCol) ); testcase( ExprHasProperty(pExpr, EP_FromJoin) ); return WRC_Continue; } - pConst = pWalker->u.pConst; for(i=0; inConst; i++){ Expr *pColumn = pConst->apExpr[i*2]; if( pColumn==pExpr ) continue; if( pColumn->iTable!=pExpr->iTable ) continue; if( pColumn->iColumn!=pExpr->iColumn ) continue; + if( bIgnoreAffBlob && sqlite3ExprAffinity(pColumn)==SQLITE_AFF_BLOB ){ + break; + } /* A match is found. Add the EP_FixedCol property */ pConst->nChng++; ExprClearProperty(pExpr, EP_Leaf); ExprSetProperty(pExpr, EP_FixedCol); assert( pExpr->pLeft==0 ); pExpr->pLeft = sqlite3ExprDup(pConst->pParse->db, pConst->apExpr[i*2+1], 0); + if( pConst->pParse->db->mallocFailed ) return WRC_Prune; break; } return WRC_Prune; } +/* +** This is a Walker expression callback. pExpr is a node from the WHERE +** clause of a SELECT statement. This function examines pExpr to see if +** any substitutions based on the contents of pWalker->u.pConst should +** be made to pExpr or its immediate children. +** +** A substitution is made if: +** +** + pExpr is a column with an affinity other than BLOB that matches +** one of the columns in pWalker->u.pConst, or +** +** + pExpr is a binary comparison operator (=, <=, >=, <, >) that +** uses an affinity other than TEXT and one of its immediate +** children is a column that matches one of the columns in +** pWalker->u.pConst. +*/ +static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ + WhereConst *pConst = pWalker->u.pConst; + assert( TK_GT==TK_EQ+1 ); + assert( TK_LE==TK_EQ+2 ); + assert( TK_LT==TK_EQ+3 ); + assert( TK_GE==TK_EQ+4 ); + if( pConst->bHasAffBlob ){ + if( (pExpr->op>=TK_EQ && pExpr->op<=TK_GE) + || pExpr->op==TK_IS + ){ + propagateConstantExprRewriteOne(pConst, pExpr->pLeft, 0); + if( pConst->pOomFault[0] ) return WRC_Prune; + if( sqlite3ExprAffinity(pExpr->pLeft)!=SQLITE_AFF_TEXT ){ + propagateConstantExprRewriteOne(pConst, pExpr->pRight, 0); + } + } + } + return propagateConstantExprRewriteOne(pConst, pExpr, pConst->bHasAffBlob); +} + /* ** The WHERE-clause constant propagation optimization. ** @@ -133649,6 +138846,21 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ ** routines know to generate the constant "123" instead of looking up the ** column value. Also, to avoid collation problems, this optimization is ** only attempted if the "a=123" term uses the default BINARY collation. +** +** 2021-05-25 forum post 6a06202608: Another troublesome case is... +** +** CREATE TABLE t1(x); +** INSERT INTO t1 VALUES(10.0); +** SELECT 1 FROM t1 WHERE x=10 AND x LIKE 10; +** +** The query should return no rows, because the t1.x value is '10.0' not '10' +** and '10.0' is not LIKE '10'. But if we are not careful, the first WHERE +** term "x=10" will cause the second WHERE term to become "10 LIKE 10", +** resulting in a false positive. To avoid this, constant propagation for +** columns with BLOB affinity is only allowed if the constant is used with +** operators ==, <=, <, >=, >, or IS in a way that will cause the correct +** type conversions to occur. See logic associated with the bHasAffBlob flag +** for details. */ static int propagateConstants( Parse *pParse, /* The parsing context */ @@ -133658,10 +138870,12 @@ static int propagateConstants( Walker w; int nChng = 0; x.pParse = pParse; + x.pOomFault = &pParse->db->mallocFailed; do{ x.nConst = 0; x.nChng = 0; x.apExpr = 0; + x.bHasAffBlob = 0; findConstInWhere(&x, p->pWhere); if( x.nConst ){ memset(&w, 0, sizeof(w)); @@ -133679,6 +138893,35 @@ static int propagateConstants( return nChng; } +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +# if !defined(SQLITE_OMIT_WINDOWFUNC) +/* +** This function is called to determine whether or not it is safe to +** push WHERE clause expression pExpr down to FROM clause sub-query +** pSubq, which contains at least one window function. Return 1 +** if it is safe and the expression should be pushed down, or 0 +** otherwise. +** +** It is only safe to push the expression down if it consists only +** of constants and copies of expressions that appear in the PARTITION +** BY clause of all window function used by the sub-query. It is safe +** to filter out entire partitions, but not rows within partitions, as +** this may change the results of the window functions. +** +** At the time this function is called it is guaranteed that +** +** * the sub-query uses only one distinct window frame, and +** * that the window frame has a PARTITION BY clase. +*/ +static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ + assert( pSubq->pWin->pPartition ); + assert( (pSubq->selFlags & SF_MultiPart)==0 ); + assert( pSubq->pPrior==0 ); + return sqlite3ExprIsConstantOrGroupBy(pParse, pExpr, pSubq->pWin->pPartition); +} +# endif /* SQLITE_OMIT_WINDOWFUNC */ +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* ** Make copies of relevant WHERE clause terms of the outer query into @@ -133726,9 +138969,24 @@ static int propagateConstants( ** But if the (b2=2) term were to be pushed down into the bb subquery, ** then the (1,1,NULL) row would be suppressed. ** -** (6) The inner query features one or more window-functions (since -** changes to the WHERE clause of the inner query could change the -** window over which window functions are calculated). +** (6) Window functions make things tricky as changes to the WHERE clause +** of the inner query could change the window over which window +** functions are calculated. Therefore, do not attempt the optimization +** if: +** +** (6a) The inner query uses multiple incompatible window partitions. +** +** (6b) The inner query is a compound and uses window-functions. +** +** (6c) The WHERE clause does not consist entirely of constants and +** copies of expressions found in the PARTITION BY clause of +** all window-functions used by the sub-query. It is safe to +** filter out entire partitions, as this does not change the +** window over which any window-function is calculated. +** +** (7) The inner query is a Common Table Expression (CTE) that should +** be materialized. (This restriction is implemented in the calling +** routine.) ** ** Return 0 if no changes are made and non-zero if one or more WHERE clause ** terms are duplicated into the subquery. @@ -133742,13 +139000,17 @@ static int pushDownWhereTerms( ){ Expr *pNew; int nChng = 0; - Select *pSel; if( pWhere==0 ) return 0; - if( pSubq->selFlags & SF_Recursive ) return 0; /* restriction (2) */ + if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0; #ifndef SQLITE_OMIT_WINDOWFUNC - for(pSel=pSubq; pSel; pSel=pSel->pPrior){ - if( pSel->pWin ) return 0; /* restriction (6) */ + if( pSubq->pPrior ){ + Select *pSel; + for(pSel=pSubq; pSel; pSel=pSel->pPrior){ + if( pSel->pWin ) return 0; /* restriction (6b) */ + } + }else{ + if( pSubq->pWin && pSubq->pWin->pPartition==0 ) return 0; } #endif @@ -133775,15 +139037,18 @@ static int pushDownWhereTerms( } 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) ){ nChng++; + pSubq->selFlags |= SF_PushDown; while( pSubq ){ SubstContext x; pNew = sqlite3ExprDup(pParse->db, pWhere, 0); @@ -133794,6 +139059,14 @@ static int pushDownWhereTerms( x.isLeftJoin = 0; x.pEList = pSubq->pEList; pNew = substExpr(&x, pNew); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){ + /* Restriction 6c has prevented push-down in this case */ + sqlite3ExprDelete(pParse->db, pNew); + nChng--; + break; + } +#endif if( pSubq->selFlags & SF_Aggregate ){ pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew); }else{ @@ -133824,7 +139097,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; @@ -133832,9 +139105,16 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ assert( *ppMinMax==0 ); assert( pFunc->op==TK_AGG_FUNCTION ); assert( !IsWindowFunc(pFunc) ); - if( pEList==0 || pEList->nExpr!=1 || ExprHasProperty(pFunc, EP_WinFunc) ){ + assert( ExprUseXList(pFunc) ); + pEList = pFunc->x.pList; + if( pEList==0 + || pEList->nExpr!=1 + || ExprHasProperty(pFunc, EP_WinFunc) + || OptimizationDisabled(db, SQLITE_MinMaxOpt) + ){ return eRet; } + assert( !ExprHasProperty(pFunc, EP_IntValue) ); zFunc = pFunc->u.zToken; if( sqlite3StrICmp(zFunc, "min")==0 ){ eRet = WHERE_ORDERBY_MIN; @@ -133862,7 +139142,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; @@ -133870,19 +139156,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; @@ -133895,24 +139188,27 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ ** SQLITE_ERROR and leave an error in pParse. Otherwise, populate ** pFrom->pIndex and return SQLITE_OK. */ -SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){ - if( pFrom->pTab && pFrom->fg.isIndexedBy ){ - Table *pTab = pFrom->pTab; - char *zIndexedBy = pFrom->u1.zIndexedBy; - Index *pIdx; - for(pIdx=pTab->pIndex; - pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); - pIdx=pIdx->pNext - ); - if( !pIdx ){ - sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0); - pParse->checkSchema = 1; - return SQLITE_ERROR; - } - pFrom->pIBIndex = pIdx; +SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ + Table *pTab = pFrom->pTab; + char *zIndexedBy = pFrom->u1.zIndexedBy; + Index *pIdx; + assert( pTab!=0 ); + assert( pFrom->fg.isIndexedBy!=0 ); + + for(pIdx=pTab->pIndex; + pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); + pIdx=pIdx->pNext + ); + if( !pIdx ){ + sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0); + pParse->checkSchema = 1; + return SQLITE_ERROR; } + assert( pFrom->fg.isCte==0 ); + pFrom->u2.pIBIndex = pIdx; return SQLITE_OK; } + /* ** Detect compound SELECT statements that use an ORDER BY clause with ** an alternative collating sequence. @@ -133999,7 +139295,7 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ ** arguments. If it does, leave an error message in pParse and return ** non-zero, since pFrom is not allowed to be a table-valued function. */ -static int cannotBeFunction(Parse *pParse, struct SrcList_item *pFrom){ +static int cannotBeFunction(Parse *pParse, SrcItem *pFrom){ if( pFrom->fg.isTabFunc ){ sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName); return 1; @@ -134020,21 +139316,22 @@ static int cannotBeFunction(Parse *pParse, struct SrcList_item *pFrom){ */ static struct Cte *searchWith( With *pWith, /* Current innermost WITH clause */ - struct SrcList_item *pItem, /* FROM clause element to resolve */ + SrcItem *pItem, /* FROM clause element to resolve */ With **ppContext /* OUT: WITH clause return value belongs to */ ){ - const char *zName; - if( pItem->zDatabase==0 && (zName = pItem->zName)!=0 ){ - With *p; - for(p=pWith; p; p=p->pOuter){ - int i; - for(i=0; inCte; i++){ - if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ - *ppContext = p; - return &p->a[i]; - } + const char *zName = pItem->zName; + With *p; + assert( pItem->zDatabase==0 ); + assert( zName!=0 ); + for(p=pWith; p; p=p->pOuter){ + int i; + for(i=0; inCte; i++){ + if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ + *ppContext = p; + return &p->a[i]; } } + if( p->bView ) break; } return 0; } @@ -134044,58 +139341,92 @@ static struct Cte *searchWith( ** ** This routine pushes the WITH clause passed as the second argument ** onto the top of the stack. If argument bFree is true, then this -** WITH clause will never be popped from the stack. In this case it -** should be freed along with the Parse object. In other cases, when +** WITH clause will never be popped from the stack but should instead +** be freed along with the Parse object. In other cases, when ** bFree==0, the With object will be freed along with the SELECT ** statement with which it is associated. +** +** This routine returns a copy of pWith. Or, if bFree is true and +** the pWith object is destroyed immediately due to an OOM condition, +** then this routine return NULL. +** +** If bFree is true, do not continue to use the pWith pointer after +** calling this routine, Instead, use only the return value. */ -SQLITE_PRIVATE void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ - assert( bFree==0 || (pParse->pWith==0 && pParse->pWithToFree==0) ); +SQLITE_PRIVATE With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ if( pWith ){ - assert( pParse->pWith!=pWith ); - pWith->pOuter = pParse->pWith; - pParse->pWith = pWith; - if( bFree ) pParse->pWithToFree = pWith; + if( bFree ){ + pWith = (With*)sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3WithDelete, + pWith); + if( pWith==0 ) return 0; + } + if( pParse->nErr==0 ){ + assert( pParse->pWith!=pWith ); + pWith->pOuter = pParse->pWith; + pParse->pWith = pWith; + } } + return pWith; } /* ** This function checks if argument pFrom refers to a CTE declared by -** a WITH clause on the stack currently maintained by the parser. And, -** if currently processing a CTE expression, if it is a recursive -** reference to the current CTE. +** a WITH clause on the stack currently maintained by the parser (on the +** pParse->pWith linked list). And if currently processing a CTE +** CTE expression, through routine checks to see if the reference is +** a recursive reference to the CTE. ** -** If pFrom falls into either of the two categories above, pFrom->pTab -** and other fields are populated accordingly. The caller should check -** (pFrom->pTab!=0) to determine whether or not a successful match -** was found. +** If pFrom matches a CTE according to either of these two above, pFrom->pTab +** and other fields are populated accordingly. ** -** Whether or not a match is found, SQLITE_OK is returned if no error -** occurs. If an error does occur, an error message is stored in the -** parser and some error code other than SQLITE_OK returned. +** Return 0 if no match is found. +** Return 1 if a match is found. +** Return 2 if an error condition is detected. */ -static int withExpand( - Walker *pWalker, - struct SrcList_item *pFrom +static int resolveFromTermToCte( + Parse *pParse, /* The parsing context */ + Walker *pWalker, /* Current tree walker */ + SrcItem *pFrom /* The FROM clause term to check */ ){ - Parse *pParse = pWalker->pParse; - sqlite3 *db = pParse->db; - struct Cte *pCte; /* Matched CTE (or NULL if no match) */ - With *pWith; /* WITH clause that pCte belongs to */ + Cte *pCte; /* Matched CTE (or NULL if no match) */ + With *pWith; /* The matching WITH */ assert( pFrom->pTab==0 ); + if( pParse->pWith==0 ){ + /* There are no WITH clauses in the stack. No match is possible */ + return 0; + } if( pParse->nErr ){ - return SQLITE_ERROR; + /* Prior errors might have left pParse->pWith in a goofy state, so + ** go no further. */ + return 0; + } + if( pFrom->zDatabase!=0 ){ + /* The FROM term contains a schema qualifier (ex: main.t1) and so + ** it cannot possibly be a CTE reference. */ + return 0; + } + if( pFrom->fg.notCte ){ + /* The FROM term is specifically excluded from matching a CTE. + ** (1) It is part of a trigger that used to have zDatabase but had + ** zDatabase removed by sqlite3FixTriggerStep(). + ** (2) This is the first term in the FROM clause of an UPDATE. + */ + return 0; } - pCte = searchWith(pParse->pWith, pFrom, &pWith); if( pCte ){ + sqlite3 *db = pParse->db; Table *pTab; ExprList *pEList; Select *pSel; Select *pLeft; /* Left-most SELECT statement */ + Select *pRecTerm; /* Left-most recursive term */ int bMayRecursive; /* True if compound joined by UNION [ALL] */ With *pSavedWith; /* Initial value of pParse->pWith */ + int iRecTab = -1; /* Cursor for recursive table */ + CteUse *pCteUse; /* If pCte->zCteErr is non-NULL at this point, then this is an illegal ** recursive reference to CTE pCte. Leave an error in pParse and return @@ -134103,63 +139434,98 @@ static int withExpand( ** In this case, proceed. */ if( pCte->zCteErr ){ sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName); - return SQLITE_ERROR; + return 2; } - if( cannotBeFunction(pParse, pFrom) ) return SQLITE_ERROR; + if( cannotBeFunction(pParse, pFrom) ) return 2; assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); - if( pTab==0 ) return WRC_Abort; + pTab = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTab==0 ) return 2; + pCteUse = pCte->pUse; + if( pCteUse==0 ){ + pCte->pUse = pCteUse = sqlite3DbMallocZero(db, sizeof(pCteUse[0])); + if( pCteUse==0 + || sqlite3ParserAddCleanup(pParse,sqlite3DbFree,pCteUse)==0 + ){ + sqlite3DbFree(db, pTab); + return 2; + } + pCteUse->eM10d = pCte->eM10d; + } + pFrom->pTab = pTab; pTab->nTabRef = 1; pTab->zName = sqlite3DbStrDup(db, pCte->zName); pTab->iPKey = -1; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); - if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; + 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++; + if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){ + pCteUse->eM10d = M10d_Yes; + } /* Check if this is a recursive CTE. */ - pSel = pFrom->pSelect; + pRecTerm = pSel = pFrom->pSelect; bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION ); - if( bMayRecursive ){ + while( bMayRecursive && pRecTerm->op==pSel->op ){ int i; - SrcList *pSrc = pFrom->pSelect->pSrc; + SrcList *pSrc = pRecTerm->pSrc; + assert( pRecTerm->pPrior!=0 ); for(i=0; inSrc; i++){ - struct SrcList_item *pItem = &pSrc->a[i]; + SrcItem *pItem = &pSrc->a[i]; if( pItem->zDatabase==0 && pItem->zName!=0 && 0==sqlite3StrICmp(pItem->zName, pCte->zName) - ){ + ){ pItem->pTab = pTab; - pItem->fg.isRecursive = 1; pTab->nTabRef++; - pSel->selFlags |= SF_Recursive; + pItem->fg.isRecursive = 1; + if( pRecTerm->selFlags & SF_Recursive ){ + sqlite3ErrorMsg(pParse, + "multiple references to recursive table: %s", pCte->zName + ); + return 2; + } + pRecTerm->selFlags |= SF_Recursive; + if( iRecTab<0 ) iRecTab = pParse->nTab++; + pItem->iCursor = iRecTab; } } + if( (pRecTerm->selFlags & SF_Recursive)==0 ) break; + pRecTerm = pRecTerm->pPrior; } - /* Only one recursive reference is permitted. */ - if( pTab->nTabRef>2 ){ - sqlite3ErrorMsg( - pParse, "multiple references to recursive table: %s", pCte->zName - ); - return SQLITE_ERROR; - } - assert( pTab->nTabRef==1 || - ((pSel->selFlags&SF_Recursive) && pTab->nTabRef==2 )); - pCte->zCteErr = "circular reference: %s"; pSavedWith = pParse->pWith; pParse->pWith = pWith; - if( bMayRecursive ){ - Select *pPrior = pSel->pPrior; - assert( pPrior->pWith==0 ); - pPrior->pWith = pSel->pWith; - sqlite3WalkSelect(pWalker, pPrior); - pPrior->pWith = 0; + if( pSel->selFlags & SF_Recursive ){ + int rc; + assert( pRecTerm!=0 ); + assert( (pRecTerm->selFlags & SF_Recursive)==0 ); + assert( pRecTerm->pNext!=0 ); + assert( (pRecTerm->pNext->selFlags & SF_Recursive)!=0 ); + assert( pRecTerm->pWith==0 ); + pRecTerm->pWith = pSel->pWith; + rc = sqlite3WalkSelect(pWalker, pRecTerm); + pRecTerm->pWith = 0; + if( rc ){ + pParse->pWith = pSavedWith; + return 2; + } }else{ - sqlite3WalkSelect(pWalker, pSel); + if( sqlite3WalkSelect(pWalker, pSel) ){ + pParse->pWith = pSavedWith; + return 2; + } } pParse->pWith = pWith; @@ -134171,7 +139537,7 @@ static int withExpand( pCte->zName, pEList->nExpr, pCte->pCols->nExpr ); pParse->pWith = pSavedWith; - return SQLITE_ERROR; + return 2; } pEList = pCte->pCols; } @@ -134187,9 +139553,9 @@ static int withExpand( } pCte->zCteErr = 0; pParse->pWith = pSavedWith; + return 1; /* Success */ } - - return SQLITE_OK; + return 0; /* No match */ } #endif @@ -134202,7 +139568,7 @@ static int withExpand( ** sqlite3SelectExpand() when walking a SELECT tree to resolve table ** names and other FROM clause elements. */ -static void selectPopWith(Walker *pWalker, Select *p){ +SQLITE_PRIVATE void sqlite3SelectPopWith(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; if( OK_IF_ALWAYS_TRUE(pParse->pWith) && p->pPrior==0 ){ With *pWith = findRightmost(p)->pWith; @@ -134212,8 +139578,6 @@ static void selectPopWith(Walker *pWalker, Select *p){ } } } -#else -#define selectPopWith 0 #endif /* @@ -134223,7 +139587,7 @@ static void selectPopWith(Walker *pWalker, Select *p){ ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, ** SQLITE_NOMEM. */ -SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){ +SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ Select *pSel = pFrom->pSelect; Table *pTab; @@ -134240,7 +139604,13 @@ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFr sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); pTab->iPKey = -1; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); - pTab->tabFlags |= TF_Ephemeral; +#ifndef SQLITE_ALLOW_ROWID_IN_VIEW + /* The usual case - do not allow ROWID on a subquery */ + pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; +#else + pTab->tabFlags |= TF_Ephemeral; /* Legacy compatibility mode */ +#endif + return pParse->nErr ? SQLITE_ERROR : SQLITE_OK; } @@ -134271,10 +139641,10 @@ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFr */ static int selectExpander(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; - int i, j, k; + int i, j, k, rc; SrcList *pTabList; ExprList *pEList; - struct SrcList_item *pFrom; + SrcItem *pFrom; sqlite3 *db = pParse->db; Expr *pE, *pRight, *pExpr; u16 selFlags = p->selFlags; @@ -134294,6 +139664,15 @@ static int selectExpander(Walker *pWalker, Select *p){ } pTabList = p->pSrc; pEList = p->pEList; + if( pParse->pWith && (p->selFlags & SF_View) ){ + if( p->pWith==0 ){ + p->pWith = (With*)sqlite3DbMallocZero(db, sizeof(With)); + if( p->pWith==0 ){ + return WRC_Abort; + } + } + p->pWith->bView = 1; + } sqlite3WithPush(pParse, p->pWith, 0); /* Make sure cursor numbers have been assigned to all entries in @@ -134310,10 +139689,6 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 ); if( pFrom->pTab ) continue; assert( pFrom->fg.isRecursive==0 ); -#ifndef SQLITE_OMIT_CTE - if( withExpand(pWalker, pFrom) ) return WRC_Abort; - if( pFrom->pTab ) {} else -#endif if( pFrom->zName==0 ){ #ifndef SQLITE_OMIT_SUBQUERY Select *pSel = pFrom->pSelect; @@ -134322,6 +139697,12 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( pFrom->pTab==0 ); if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; +#endif +#ifndef SQLITE_OMIT_CTE + }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){ + if( rc>1 ) return WRC_Abort; + pTab = pFrom->pTab; + assert( pTab!=0 ); #endif }else{ /* An ordinary table or view name in the FROM clause */ @@ -134339,26 +139720,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 ){ - 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 - 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 */ @@ -134370,14 +139756,15 @@ static int selectExpander(Walker *pWalker, Select *p){ } /* Locate the index named by the INDEXED BY clause, if any. */ - if( sqlite3IndexedByLookup(pParse, pFrom) ){ + if( pFrom->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pFrom) ){ return WRC_Abort; } } /* 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; } @@ -134458,7 +139845,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 */ @@ -134589,7 +139976,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ sqlite3WalkSelect(&w, pSelect); } w.xSelectCallback = selectExpander; - w.xSelectCallback2 = selectPopWith; + w.xSelectCallback2 = sqlite3SelectPopWith; w.eCode = 0; sqlite3WalkSelect(&w, pSelect); } @@ -134613,7 +140000,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ Parse *pParse; int i; SrcList *pTabList; - struct SrcList_item *pFrom; + SrcItem *pFrom; assert( p->selFlags & SF_Resolved ); if( p->selFlags & SF_HasTypeInfo ) return; @@ -134674,12 +140061,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); } @@ -134696,8 +140084,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 */ @@ -134715,15 +140105,17 @@ 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"); pFunc->iDistinct = -1; }else{ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0); - sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, - (char*)pKeyInfo, P4_KEYINFO); + pFunc->iDistAddr = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + pFunc->iDistinct, 0, 0, (char*)pKeyInfo, P4_KEYINFO); + ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s(DISTINCT)", + pFunc->pFunc->zName)); } } } @@ -134738,8 +140130,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); } @@ -134755,7 +140148,12 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ ** registers if register regAcc contains 0. The caller will take care ** of setting and clearing regAcc. */ -static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){ +static void updateAccumulator( + Parse *pParse, + int regAcc, + AggInfo *pAggInfo, + int eDistinctType +){ Vdbe *v = pParse->pVdbe; int i; int regHit = 0; @@ -134768,9 +140166,10 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){ 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 @@ -134801,13 +140200,12 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){ nArg = 0; regAgg = 0; } - if( pF->iDistinct>=0 ){ + if( pF->iDistinct>=0 && pList ){ if( addrNext==0 ){ addrNext = sqlite3VdbeMakeLabel(pParse); } - testcase( nArg==0 ); /* Error condition */ - testcase( nArg>1 ); /* Also an error */ - codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg); + pF->iDistinct = codeDistinct(pParse, eDistinctType, + pF->iDistinct, addrNext, pList, regAgg); } if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ CollSeq *pColl = 0; @@ -134859,7 +140257,7 @@ static void explainSimpleCount( ){ if( pParse->explain==2 ){ int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx))); - sqlite3VdbeExplain(pParse, 0, "SCAN TABLE %s%s%s", + sqlite3VdbeExplain(pParse, 0, "SCAN %s%s%s", pTab->zName, bCover ? " USING COVERING INDEX " : "", bCover ? pIdx->zName : "" @@ -134884,7 +140282,17 @@ static void explainSimpleCount( static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ if( pExpr->op!=TK_AND ){ Select *pS = pWalker->u.pSelect; - if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){ + /* 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"); if( pNew ){ @@ -134923,7 +140331,7 @@ static void havingToWhere(Parse *pParse, Select *p){ sWalker.u.pSelect = p; sqlite3WalkExpr(&sWalker, p->pHaving); #if SELECTTRACE_ENABLED - if( sWalker.eCode && (sqlite3_unsupported_selecttrace & 0x100)!=0 ){ + if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){ SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -134935,11 +140343,13 @@ static void havingToWhere(Parse *pParse, Select *p){ ** If it is, then return the SrcList_item for the prior view. If it is not, ** then return 0. */ -static struct SrcList_item *isSelfJoinView( +static SrcItem *isSelfJoinView( SrcList *pTabList, /* Search for self-joins in this FROM clause */ - struct SrcList_item *pThis /* Search for prior reference to this subquery */ + SrcItem *pThis /* Search for prior reference to this subquery */ ){ - struct SrcList_item *pItem; + SrcItem *pItem; + assert( pThis->pSelect!=0 ); + if( pThis->pSelect->selFlags & SF_PushDown ) return 0; for(pItem = pTabList->a; pItempSelect==0 ) continue; @@ -134955,9 +140365,7 @@ static struct SrcList_item *isSelfJoinView( ** names in the same FROM clause. */ continue; } - if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) - || sqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1) - ){ + if( pItem->pSelect->selFlags & SF_PushDown ){ /* The view was modified by some other optimization such as ** pushDownWhereTerms() */ continue; @@ -134967,6 +140375,15 @@ static struct SrcList_item *isSelfJoinView( return 0; } +/* +** Deallocate a single AggInfo object +*/ +static void agginfoFree(sqlite3 *db, AggInfo *p){ + sqlite3DbFree(db, p->aCol); + sqlite3DbFree(db, p->aFunc); + sqlite3DbFreeNN(db, p); +} + #ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION /* ** Attempt to transform a query of the form @@ -134998,7 +140415,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; @@ -135045,7 +140464,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ p->selFlags &= ~SF_Aggregate; #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -135091,14 +140510,16 @@ 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)); - if( sqlite3_unsupported_selecttrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ sqlite3TreeViewSelect(0, p, 0); } #endif @@ -135107,38 +140528,53 @@ SQLITE_PRIVATE int sqlite3Select( assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue ); - if( IgnorableOrderby(pDest) ){ - assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || - pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || - pDest->eDest==SRT_Queue || pDest->eDest==SRT_DistFifo || - pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_Fifo); - /* If ORDER BY makes no difference in the output then neither does - ** DISTINCT so it can be removed too. */ - sqlite3ExprListDelete(db, p->pOrderBy); - p->pOrderBy = 0; + if( IgnorableDistinct(pDest) ){ + assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || + pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || + pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo ); + /* All of these destinations are also able to ignore the ORDER BY clause */ + if( p->pOrderBy ){ +#if SELECTTRACE_ENABLED + SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n")); + if( sqlite3SelectTrace & 0x100 ){ + sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); + } +#endif + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3ExprListDelete, + p->pOrderBy); + testcase( pParse->earlyCleanup ); + p->pOrderBy = 0; + } p->selFlags &= ~SF_Distinct; 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( sqlite3_unsupported_selecttrace & 0x104 ){ + if( sqlite3SelectTrace & 0x104 ){ SELECTTRACE(0x104,pParse,p, ("after name resolution:\n")); sqlite3TreeViewSelect(0, p, 0); } #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 ){ - struct SrcList_item *p0 = &p->pSrc->a[0]; + ** 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++){ - struct SrcList_item *p1 = &p->pSrc->a[i]; + SrcItem *p1 = &p->pSrc->a[i]; if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ sqlite3ErrorMsg(pParse, "target object/alias may not appear in FROM clause: %s", @@ -135147,20 +140583,25 @@ 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 ){ - generateColumnNames(pParse, p); + sqlite3GenerateColumnNames(pParse, p); } #ifndef SQLITE_OMIT_WINDOWFUNC - rc = sqlite3WindowRewrite(pParse, p); - if( rc ){ - assert( db->mallocFailed || pParse->nErr>0 ); + if( sqlite3WindowRewrite(pParse, p) ){ + assert( pParse->nErr ); goto select_end; } #if SELECTTRACE_ENABLED - if( p->pWin && (sqlite3_unsupported_selecttrace & 0x108)!=0 ){ + if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){ SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -135176,7 +140617,7 @@ SQLITE_PRIVATE int sqlite3Select( */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && inSrc; i++){ - struct SrcList_item *pItem = &pTabList->a[i]; + SrcItem *pItem = &pTabList->a[i]; Select *pSub = pItem->pSelect; Table *pTab = pItem->pTab; @@ -135219,6 +140660,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 @@ -135267,7 +140741,7 @@ SQLITE_PRIVATE int sqlite3Select( rc = multiSelect(pParse, p, pDest); #if SELECTTRACE_ENABLED SELECTTRACE(0x1,pParse,p,("end compound-select processing\n")); - if( (sqlite3_unsupported_selecttrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif @@ -135281,12 +140755,13 @@ SQLITE_PRIVATE int sqlite3Select( ** as the equivalent optimization will be handled by query planner in ** sqlite3WhereBegin(). */ - if( pTabList->nSrc>1 + if( p->pWhere!=0 + && p->pWhere->op==TK_AND && OptimizationEnabled(db, SQLITE_PropagateConst) && propagateConstants(pParse, p) ){ #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p,("After constant propagation:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -135310,7 +140785,8 @@ SQLITE_PRIVATE int sqlite3Select( ** (2) Generate code for all sub-queries */ for(i=0; inSrc; i++){ - struct SrcList_item *pItem = &pTabList->a[i]; + SrcItem *pItem = &pTabList->a[i]; + SrcItem *pPrior; SelectDest dest; Select *pSub; #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) @@ -135343,19 +140819,8 @@ SQLITE_PRIVATE int sqlite3Select( pSub = pItem->pSelect; if( pSub==0 ) continue; - /* The code for a subquery should only be generated once, though it is - ** technically harmless for it to be generated multiple times. The - ** following assert() will detect if something changes to cause - ** the same subquery to be coded multiple times, as a signal to the - ** developers to try to optimize the situation. - ** - ** Update 2019-07-24: - ** See ticket https://sqlite.org/src/tktview/c52b09c7f38903b1311cec40. - ** The dbsqlfuzz fuzzer found a case where the same subquery gets - ** coded twice. So this assert() now becomes a testcase(). It should - ** be very rare, though. - */ - testcase( pItem->addrFillSub!=0 ); + /* The code for a subquery should only be generated once. */ + assert( pItem->addrFillSub==0 ); /* Increment Parse.nHeight by the height of the largest expression ** tree referred to by this, the parent select. The child select @@ -135370,16 +140835,19 @@ 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 && pItem->u2.pCteUse->nUse<2)) && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, (pItem->fg.jointype & JT_OUTER)!=0) ){ #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p, ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); sqlite3TreeViewSelect(0, p, 0); } #endif + assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); }else{ SELECTTRACE(0x100,pParse,p,("Push-down not possible\n")); } @@ -135389,16 +140857,18 @@ SQLITE_PRIVATE int sqlite3Select( /* Generate code to implement the subquery ** - ** The subquery is implemented as a co-routine if the subquery is - ** guaranteed to be the outer loop (so that it does not need to be - ** computed more than once) + ** The subquery is implemented as a co-routine if: + ** (1) the subquery is guaranteed to be the outer loop (so that + ** it does not need to be computed more than once), and + ** (2) the subquery is not a CTE that should be materialized ** - ** TODO: Are there other reasons beside (1) to use a co-routine + ** TODO: Are there other reasons beside (1) and (2) to use a co-routine ** implementation? */ if( i==0 && (pTabList->nSrc==1 || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */ + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */ ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. @@ -135407,10 +140877,10 @@ SQLITE_PRIVATE int sqlite3Select( pItem->regReturn = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); - VdbeComment((v, "%s", pItem->pTab->zName)); + VdbeComment((v, "%!S", pItem)); pItem->addrFillSub = addrTop; sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); - ExplainQueryPlan((pParse, 1, "CO-ROUTINE %u", pSub->selId)); + ExplainQueryPlan((pParse, 1, "CO-ROUTINE %!S", pItem)); sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowLogEst = pSub->nSelectRow; pItem->fg.viaCoroutine = 1; @@ -135418,18 +140888,34 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeEndCoroutine(v, pItem->regReturn); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); - }else{ - /* Generate a subroutine that will fill an ephemeral table with - ** the content of this subquery. pItem->addrFillSub will point - ** to the address of the generated subroutine. pItem->regReturn - ** is a register allocated to hold the subroutine return address - */ + }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ + /* This is a CTE for which materialization code has already been + ** generated. Invoke the subroutine to compute the materialization, + ** the make the pItem->iCursor be a copy of the ephemerial table that + ** holds the result of the materialization. */ + CteUse *pCteUse = pItem->u2.pCteUse; + 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 ){ + /* This view has already been materialized by a prior entry in + ** this same FROM clause. Reuse it. */ + if( pPrior->addrFillSub ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub); + } + sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); + pSub->nSelectRow = pPrior->pSelect->nSelectRow; + }else{ + /* Materialize the view. If the view is not correlated, generate a + ** subroutine to do the materialization so that subsequent uses of + ** the same view can reuse the materialization. */ int topAddr; int onceAddr = 0; int retAddr; - struct SrcList_item *pPrior; - testcase( pItem->addrFillSub==0 ); /* Ticket c52b09c7f38903b1311 */ pItem->regReturn = ++pParse->nMem; topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); pItem->addrFillSub = topAddr+1; @@ -135438,26 +140924,26 @@ SQLITE_PRIVATE int sqlite3Select( ** a trigger, then we only need to compute the value of the subquery ** once. */ onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName)); - }else{ - VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName)); - } - pPrior = isSelfJoinView(pTabList, pItem); - if( pPrior ){ - sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); - assert( pPrior->pSelect!=0 ); - pSub->nSelectRow = pPrior->pSelect->nSelectRow; + VdbeComment((v, "materialize %!S", pItem)); }else{ - sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); - ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); - sqlite3Select(pParse, pSub, &dest); + VdbeNoopComment((v, "materialize %!S", pItem)); } + sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); + ExplainQueryPlan((pParse, 1, "MATERIALIZE %!S", pItem)); + sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowLogEst = pSub->nSelectRow; if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); - VdbeComment((v, "end %s", pItem->pTab->zName)); + VdbeComment((v, "end %!S", pItem)); sqlite3VdbeChangeP1(v, topAddr, retAddr); sqlite3ClearTempRegCache(pParse); + if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ + CteUse *pCteUse = pItem->u2.pCteUse; + pCteUse->addrM9e = pItem->addrFillSub; + pCteUse->regRtn = pItem->regReturn; + pCteUse->iCur = pItem->iCursor; + pCteUse->nRowEst = pSub->nSelectRow; + } } if( db->mallocFailed ) goto select_end; pParse->nHeight -= sqlite3SelectExprHeight(p); @@ -135474,7 +140960,7 @@ SQLITE_PRIVATE int sqlite3Select( sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -135510,7 +140996,7 @@ SQLITE_PRIVATE int sqlite3Select( assert( sDistinct.isTnct ); #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -135587,7 +141073,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); @@ -135602,6 +141088,7 @@ SQLITE_PRIVATE int sqlite3Select( sSort.pOrderBy = 0; } } + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); /* If sorting index that was created by a prior OP_OpenEphemeral ** instruction ended up not being needed, then change the OP_OpenEphemeral @@ -135640,6 +141127,7 @@ SQLITE_PRIVATE int sqlite3Select( /* End the database scan loop. */ + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); } }else{ @@ -135710,11 +141198,14 @@ SQLITE_PRIVATE int sqlite3Select( ** SELECT statement. */ pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) ); - if( pAggInfo==0 ){ + if( pAggInfo ){ + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))agginfoFree, pAggInfo); + testcase( pParse->earlyCleanup ); + } + if( db->mallocFailed ){ goto select_end; } - pAggInfo->pNext = pParse->pAggList; - pParse->pAggList = pAggInfo; pAggInfo->selId = p->selId; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; @@ -135744,7 +141235,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 @@ -135758,10 +141249,14 @@ SQLITE_PRIVATE int sqlite3Select( pAggInfo->mxReg = pParse->nMem; if( db->mallocFailed ) goto select_end; #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ int ii; SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); sqlite3TreeViewSelect(0, p, 0); + if( minMaxFlag ){ + sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag); + sqlite3TreeViewExprList(0, pMinMaxOrderBy, 0, "ORDERBY"); + } for(ii=0; iinColumn; ii++){ sqlite3DebugPrintf("agg-column[%d] iMem=%d\n", ii, pAggInfo->aCol[ii].iMem); @@ -135789,6 +141284,22 @@ SQLITE_PRIVATE int sqlite3Select( int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */ int addrReset; /* Subroutine for resetting the accumulator */ int regReset; /* Return address register for reset subroutine */ + ExprList *pDistinct = 0; + u16 distFlag = 0; + int eDist = WHERE_DISTINCT_NOOP; + + if( pAggInfo->nFunc==1 + && pAggInfo->aFunc[0].iDistinct>=0 + && 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); + pDistinct = sqlite3ExprListDup(db, pGroupBy, 0); + pDistinct = sqlite3ExprListAppend(pParse, pDistinct, pExpr); + distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0; + } /* If there is a GROUP BY clause we might need a sorting index to ** implement it. Allocate that sorting index now. If it turns out @@ -135825,10 +141336,15 @@ SQLITE_PRIVATE int sqlite3Select( */ sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); SELECTTRACE(1,pParse,p,("WhereBegin\n")); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, - WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct, + 0, (WHERE_GROUPBY|(orderByGrp ? WHERE_SORTBYGROUP : 0)|distFlag), 0 ); - if( pWInfo==0 ) goto select_end; + if( pWInfo==0 ){ + sqlite3ExprListDelete(db, pDistinct); + goto select_end; + } + eDist = sqlite3WhereIsDistinct(pWInfo); + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ /* The optimizer is able to deliver rows in group by order so ** we do not have to sort. The OP_OpenEphemeral table will be @@ -135877,6 +141393,7 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempRange(pParse, regBase, nCol); + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++; sortOut = sqlite3GetTempReg(pParse); @@ -135944,19 +141461,21 @@ SQLITE_PRIVATE int sqlite3Select( ** the current row */ sqlite3VdbeJumpHere(v, addr1); - updateAccumulator(pParse, iUseFlag, pAggInfo); + updateAccumulator(pParse, iUseFlag, pAggInfo, eDist); sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); VdbeComment((v, "indicate data in accumulator")); /* End of the loop */ if( groupBySort ){ - sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx, addrTopOfLoop); + sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop); VdbeCoverage(v); }else{ + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); sqlite3VdbeChangeToNoop(v, addrSortingIdx); } + sqlite3ExprListDelete(db, pDistinct); /* Output the final row of result */ @@ -136000,6 +141519,10 @@ SQLITE_PRIVATE int sqlite3Select( VdbeComment((v, "indicate accumulator empty")); sqlite3VdbeAddOp1(v, OP_Return, regReset); + if( eDist!=WHERE_DISTINCT_NOOP ){ + struct AggInfo_func *pF = &pAggInfo->aFunc[0]; + fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); + } } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ else { Table *pTab; @@ -136063,7 +141586,9 @@ SQLITE_PRIVATE int sqlite3Select( explainSimpleCount(pParse, pTab, pBest); }else{ int regAcc = 0; /* "populate accumulators" flag */ - int addrSkip; + ExprList *pDistinct = 0; + u16 distFlag = 0; + int eDist; /* If there are accumulator registers but no min() or max() functions ** without FILTER clauses, allocate register regAcc. Register regAcc @@ -136087,6 +141612,10 @@ SQLITE_PRIVATE int sqlite3Select( regAcc = ++pParse->nMem; 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; } /* This case runs if the aggregate has no GROUP BY clause. The @@ -136106,16 +141635,23 @@ SQLITE_PRIVATE int sqlite3Select( SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, - 0, minMaxFlag, 0); + pDistinct, 0, minMaxFlag|distFlag, 0); if( pWInfo==0 ){ goto select_end; } - updateAccumulator(pParse, regAcc, pAggInfo); + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); + eDist = sqlite3WhereIsDistinct(pWInfo); + updateAccumulator(pParse, regAcc, pAggInfo, eDist); + if( eDist!=WHERE_DISTINCT_NOOP ){ + struct AggInfo_func *pF = &pAggInfo->aFunc[0]; + fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); + } + if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); - addrSkip = sqlite3WhereOrderByLimitOptLabel(pWInfo); - if( addrSkip!=sqlite3WhereContinueLabel(pWInfo) ){ - sqlite3VdbeGoto(v, addrSkip); + if( minMaxFlag ){ + sqlite3WhereMinMaxOptEarlyOut(v, pWInfo); } + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); finalizeAggFunctions(pParse, pAggInfo); } @@ -136155,20 +141691,20 @@ SQLITE_PRIVATE int sqlite3Select( ** successful coding of the SELECT. */ select_end: + assert( db->mallocFailed==0 || db->mallocFailed==1 ); + assert( db->mallocFailed==0 || pParse->nErr!=0 ); sqlite3ExprListDelete(db, pMinMaxOrderBy); #ifdef SQLITE_DEBUG if( pAggInfo && !db->mallocFailed ){ for(i=0; inColumn; i++){ Expr *pExpr = pAggInfo->aCol[i].pCExpr; - assert( pExpr!=0 || db->mallocFailed ); - if( pExpr==0 ) continue; + assert( pExpr!=0 ); assert( pExpr->pAggInfo==pAggInfo ); assert( pExpr->iAgg==i ); } for(i=0; inFunc; i++){ Expr *pExpr = pAggInfo->aFunc[i].pFExpr; - assert( pExpr!=0 || db->mallocFailed ); - if( pExpr==0 ) continue; + assert( pExpr!=0 ); assert( pExpr->pAggInfo==pAggInfo ); assert( pExpr->iAgg==i ); } @@ -136177,7 +141713,7 @@ SQLITE_PRIVATE int sqlite3Select( #if SELECTTRACE_ENABLED SELECTTRACE(0x1,pParse,p,("end processing\n")); - if( (sqlite3_unsupported_selecttrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif @@ -136438,28 +141974,51 @@ SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerS ** pTab as well as the triggers lised in pTab->pTrigger. */ SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ - Schema * const pTmpSchema = pParse->db->aDb[1].pSchema; - Trigger *pList = 0; /* List of triggers to return */ + Schema *pTmpSchema; /* Schema of the pTab table */ + Trigger *pList; /* List of triggers to return */ + HashElem *p; /* Loop variable for TEMP triggers */ if( pParse->disableTriggers ){ return 0; } - - if( pTmpSchema!=pTab->pSchema ){ - HashElem *p; - assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) ); - for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){ - Trigger *pTrig = (Trigger *)sqliteHashData(p); - if( pTrig->pTabSchema==pTab->pSchema - && 0==sqlite3StrICmp(pTrig->table, pTab->zName) - ){ - pTrig->pNext = (pList ? pList : pTab->pTrigger); - pList = pTrig; - } + pTmpSchema = pParse->db->aDb[1].pSchema; + p = sqliteHashFirst(&pTmpSchema->trigHash); + pList = pTab->pTrigger; + while( p ){ + Trigger *pTrig = (Trigger *)sqliteHashData(p); + if( pTrig->pTabSchema==pTab->pSchema + && pTrig->table + && 0==sqlite3StrICmp(pTrig->table, pTab->zName) + && pTrig->pTabSchema!=pTmpSchema + ){ + pTrig->pNext = pList; + pList = pTrig; + }else if( pTrig->op==TK_RETURNING +#ifndef SQLITE_OMIT_VIRTUALTABLE + && pParse->db->pVtabCtx==0 +#endif + ){ + assert( pParse->bReturning ); + assert( &(pParse->u1.pReturning->retTrig) == pTrig ); + pTrig->table = pTab->zName; + pTrig->pTabSchema = pTab->pSchema; + pTrig->pNext = pList; + pList = pTrig; } + p = sqliteHashNext(p); } - - return (pList ? pList : pTab->pTrigger); +#if 0 + if( pList ){ + Trigger *pX; + printf("Triggers for %s:", pTab->zName); + for(pX=pList; pX; pX=pX->pNext){ + printf(" %s", pX->zName); + } + printf("\n"); + fflush(stdout); + } +#endif + return pList; } /* @@ -136547,22 +142106,11 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( pTab = sqlite3SrcListLookup(pParse, pTableName); if( !pTab ){ /* The table does not exist. */ - if( db->init.iDb==1 ){ - /* Ticket #3810. - ** Normally, whenever a table is dropped, all associated triggers are - ** dropped too. But if a TEMP trigger is created on a non-TEMP table - ** and the table is dropped by a different database connection, the - ** trigger is not visible to the database connection that does the - ** drop so the trigger cannot be dropped. This results in an - ** "orphaned trigger" - a trigger whose associated table is missing. - */ - db->init.orphanTrigger = 1; - } - goto trigger_cleanup; + goto trigger_orphan_error; } if( IsVirtual(pTab) ){ sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); - goto trigger_cleanup; + goto trigger_orphan_error; } /* Check that the trigger name is not reserved and that no trigger of the @@ -136597,15 +142145,15 @@ 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, 0); - goto trigger_cleanup; + (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, 0); - goto trigger_cleanup; + " trigger on table: %S", pTableName->a); + goto trigger_orphan_error; } #ifndef SQLITE_OMIT_AUTHORIZATION @@ -136665,6 +142213,23 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( }else{ assert( pParse->pNewTrigger==pTrigger ); } + return; + +trigger_orphan_error: + if( db->init.iDb==1 ){ + /* Ticket #3810. + ** Normally, whenever a table is dropped, all associated triggers are + ** dropped too. But if a TEMP trigger is created on a non-TEMP table + ** and the table is dropped by a different database connection, the + ** trigger is not visible to the database connection that does the + ** drop so the trigger cannot be dropped. This results in an + ** "orphaned trigger" - a trigger whose associated table is missing. + ** + ** 2020-11-05 see also https://sqlite.org/forum/forumpost/157dc791df + */ + db->init.orphanTrigger = 1; + } + goto trigger_cleanup; } /* @@ -136722,14 +142287,14 @@ 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); sqlite3DbFree(db, z); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddParseSchemaOp(v, iDb, - sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName)); + sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName), 0); } if( db->init.busy ){ @@ -136942,7 +142507,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( ** Recursively delete a Trigger structure */ SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ - if( pTrigger==0 ) return; + if( pTrigger==0 || pTrigger->bReturning ) return; sqlite3DeleteTriggerStep(db, pTrigger->step_list); sqlite3DbFree(db, pTrigger->zName); sqlite3DbFree(db, pTrigger->table); @@ -136984,7 +142549,7 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr) } if( !pTrigger ){ if( !noErr ){ - sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); + sqlite3ErrorMsg(pParse, "no such trigger: %S", pName->a); }else{ sqlite3CodeVerifyNamedSchema(pParse, zDb); } @@ -137036,7 +142601,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); @@ -137107,15 +142672,53 @@ SQLITE_PRIVATE Trigger *sqlite3TriggersExist( Trigger *pList = 0; Trigger *p; - if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){ - pList = sqlite3TriggerList(pParse, pTab); - } - assert( pList==0 || IsVirtual(pTab)==0 ); - for(p=pList; p; p=p->pNext){ - if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ - mask |= p->tr_tm; + pList = sqlite3TriggerList(pParse, pTab); + assert( pList==0 || IsVirtual(pTab)==0 + || (pList->bReturning && pList->pNext==0) ); + if( pList!=0 ){ + p = pList; + if( (pParse->db->flags & SQLITE_EnableTrigger)==0 + && pTab->pTrigger!=0 + ){ + /* The SQLITE_DBCONFIG_ENABLE_TRIGGER setting is off. That means that + ** only TEMP triggers are allowed. Truncate the pList so that it + ** includes only TEMP triggers */ + if( pList==pTab->pTrigger ){ + pList = 0; + goto exit_triggers_exist; + } + while( ALWAYS(p->pNext) && p->pNext!=pTab->pTrigger ) p = p->pNext; + p->pNext = 0; + p = pList; } + do{ + if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ + mask |= p->tr_tm; + }else if( p->op==TK_RETURNING ){ + /* The first time a RETURNING trigger is seen, the "op" value tells + ** us what time of trigger it should be. */ + assert( sqlite3IsToplevel(pParse) ); + p->op = op; + if( IsVirtual(pTab) ){ + if( op!=TK_INSERT ){ + sqlite3ErrorMsg(pParse, + "%s RETURNING is not available on virtual tables", + op==TK_DELETE ? "DELETE" : "UPDATE"); + } + p->tr_tm = TRIGGER_BEFORE; + }else{ + p->tr_tm = TRIGGER_AFTER; + } + mask |= p->tr_tm; + }else if( p->bReturning && p->op==TK_INSERT && op==TK_UPDATE + && sqlite3IsToplevel(pParse) ){ + /* Also fire a RETURNING trigger for an UPSERT */ + mask |= p->tr_tm; + } + p = p->pNext; + }while( p ); } +exit_triggers_exist: if( pMask ){ *pMask = mask; } @@ -137158,6 +142761,146 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc( return pSrc; } +/* +** Return true if the pExpr term from the RETURNING clause argument +** list is of the form "*". Raise an error if the terms if of the +** form "table.*". +*/ +static int isAsteriskTerm( + Parse *pParse, /* Parsing context */ + Expr *pTerm /* A term in the RETURNING clause */ +){ + assert( pTerm!=0 ); + if( pTerm->op==TK_ASTERISK ) return 1; + if( pTerm->op!=TK_DOT ) return 0; + assert( pTerm->pRight!=0 ); + assert( pTerm->pLeft!=0 ); + if( pTerm->pRight->op!=TK_ASTERISK ) return 0; + sqlite3ErrorMsg(pParse, "RETURNING may not use \"TABLE.*\" wildcards"); + return 1; +} + +/* The input list pList is the list of result set terms from a RETURNING +** clause. The table that we are returning from is pTab. +** +** This routine makes a copy of the pList, and at the same time expands +** any "*" wildcards to be the complete set of columns from pTab. +*/ +static ExprList *sqlite3ExpandReturning( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* The arguments to RETURNING */ + Table *pTab /* The table being updated */ +){ + ExprList *pNew = 0; + sqlite3 *db = pParse->db; + int i; + + for(i=0; inExpr; i++){ + Expr *pOldExpr = pList->a[i].pExpr; + if( NEVER(pOldExpr==0) ) continue; + if( isAsteriskTerm(pParse, pOldExpr) ){ + int jj; + for(jj=0; jjnCol; jj++){ + Expr *pNewExpr; + if( IsHiddenColumn(pTab->aCol+jj) ) continue; + 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].zCnName); + pItem->eEName = ENAME_NAME; + } + } + }else{ + Expr *pNewExpr = sqlite3ExprDup(db, pOldExpr, 0); + pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); + if( !db->mallocFailed && ALWAYS(pList->a[i].zEName!=0) ){ + struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; + pItem->zEName = sqlite3DbStrDup(db, pList->a[i].zEName); + pItem->eEName = pList->a[i].eEName; + } + } + } + return pNew; +} + +/* +** Generate code for the RETURNING trigger. Unlike other triggers +** that invoke a subprogram in the bytecode, the code for RETURNING +** is generated in-line. +*/ +static void codeReturningTrigger( + Parse *pParse, /* Parse context */ + Trigger *pTrigger, /* The trigger step that defines the RETURNING */ + Table *pTab, /* The table to code triggers from */ + int regIn /* The first in an array of registers */ +){ + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; + ExprList *pNew; + Returning *pReturning; + Select sSelect; + SrcList sFrom; + + assert( v!=0 ); + assert( pParse->bReturning ); + assert( db->pParse==pParse ); + pReturning = pParse->u1.pReturning; + assert( pTrigger == &(pReturning->retTrig) ); + memset(&sSelect, 0, sizeof(sSelect)); + memset(&sFrom, 0, sizeof(sFrom)); + sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); + sSelect.pSrc = &sFrom; + sFrom.nSrc = 1; + sFrom.a[0].pTab = pTab; + sFrom.a[0].iCursor = -1; + sqlite3SelectPrep(pParse, &sSelect, 0); + if( pParse->nErr==0 ){ + assert( db->mallocFailed==0 ); + sqlite3GenerateColumnNames(pParse, &sSelect); + } + sqlite3ExprListDelete(db, sSelect.pEList); + pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); + if( !db->mallocFailed ){ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + if( pReturning->nRetCol==0 ){ + pReturning->nRetCol = pNew->nExpr; + pReturning->iRetCur = pParse->nTab++; + } + sNC.pParse = pParse; + sNC.uNC.iBaseReg = regIn; + sNC.ncFlags = NC_UBaseReg; + pParse->eTriggerOp = pTrigger->op; + pParse->pTriggerTab = pTab; + if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK + && ALWAYS(!db->mallocFailed) + ){ + int i; + int nCol = pNew->nExpr; + int reg = pParse->nMem+1; + pParse->nMem += nCol+2; + 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; +} + + + /* ** Generate VDBE code for the statements inside the body of a single ** trigger. @@ -137207,6 +142950,7 @@ static int codeTriggerProgram( sqlite3ExprDup(db, pStep->pWhere, 0), pParse->eOrconf, 0, 0, 0 ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } case TK_INSERT: { @@ -137217,6 +142961,7 @@ static int codeTriggerProgram( pParse->eOrconf, sqlite3UpsertDup(db, pStep->pUpsert) ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } case TK_DELETE: { @@ -137224,6 +142969,7 @@ static int codeTriggerProgram( sqlite3TriggerStepSrc(pParse, pStep), sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0 ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } default: assert( pStep->op==TK_SELECT ); { @@ -137235,9 +142981,6 @@ static int codeTriggerProgram( break; } } - if( pStep->op!=TK_SELECT ){ - sqlite3VdbeAddOp0(v, OP_ResetCount); - } } return 0; @@ -137295,8 +143038,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 ); @@ -137318,19 +143061,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; - - v = sqlite3GetVdbe(pSubParse); + 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(&sSubParse); if( v ){ VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", pTrigger->zName, onErrorText(orconf), @@ -137353,17 +143094,17 @@ static TriggerPrg *codeRowTrigger( ** OP_Halt inserted at the end of the program. */ if( pTrigger->pWhen ){ pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0); - if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) - && db->mallocFailed==0 + 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 ){ @@ -137371,24 +143112,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->pAinc && !pSubParse->pZombieTab ); - assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); - sqlite3ParserReset(pSubParse); - sqlite3StackFree(db, pSubParse); - + assert( !sSubParse.pTriggerPrg && !sSubParse.nMaxArg ); + sqlite3ParseObjectReset(&sSubParse); return pPrg; } @@ -137421,6 +143162,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; @@ -137443,7 +143185,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. */ @@ -137486,7 +143228,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( ** ... ... ** reg+N OLD.* value of right-most column of pTab ** reg+N+1 NEW.rowid -** reg+N+2 OLD.* value of left-most column of pTab +** reg+N+2 NEW.* value of left-most column of pTab ** ... ... ** reg+N+N+1 NEW.* value of right-most column of pTab ** @@ -137531,12 +143273,20 @@ SQLITE_PRIVATE void sqlite3CodeRowTrigger( assert( p->pSchema==p->pTabSchema || p->pSchema==pParse->db->aDb[1].pSchema ); - /* Determine whether we should code this trigger */ - if( p->op==op + /* Determine whether we should code this trigger. One of two choices: + ** 1. The trigger is an exact match to the current DML statement + ** 2. This is a RETURNING trigger for INSERT but we are currently + ** doing the UPDATE part of an UPSERT. + */ + if( (p->op==op || (p->bReturning && p->op==TK_INSERT && op==TK_UPDATE)) && p->tr_tm==tr_tm && checkColumnOverlap(p->pColumns, pChanges) ){ - sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); + if( !p->bReturning ){ + sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); + }else if( sqlite3IsToplevel(pParse) ){ + codeReturningTrigger(pParse, p, pTab, reg); + } } } } @@ -137581,13 +143331,18 @@ SQLITE_PRIVATE u32 sqlite3TriggerColmask( assert( isNew==1 || isNew==0 ); for(p=pTrigger; p; p=p->pNext){ - if( p->op==op && (tr_tm&p->tr_tm) + if( p->op==op + && (tr_tm&p->tr_tm) && checkColumnOverlap(p->pColumns,pChanges) ){ - TriggerPrg *pPrg; - pPrg = getRowTrigger(pParse, p, pTab, orconf); - if( pPrg ){ - mask |= pPrg->aColmask[isNew]; + if( p->bReturning ){ + mask = 0xffffffff; + }else{ + TriggerPrg *pPrg; + pPrg = getRowTrigger(pParse, p, pTab, orconf); + if( pPrg ){ + mask |= pPrg->aColmask[isNew]; + } } } } @@ -137661,13 +143416,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); @@ -137821,6 +143577,7 @@ static void updateFromSelect( assert( pTabList->nSrc>1 ); if( pSrc ){ + pSrc->a[0].fg.notCte = 1; pSrc->a[0].iCursor = -1; pSrc->a[0].pTab->nTabRef--; pSrc->a[0].pTab = 0; @@ -137835,8 +143592,8 @@ static void updateFromSelect( #endif pList = sqlite3ExprListAppend(pParse, pList, pNew); } - eDest = SRT_Upfrom; - }else if( pTab->pSelect ){ + eDest = IsVirtual(pTab) ? SRT_Table : SRT_Upfrom; + }else if( IsView(pTab) ){ for(i=0; inCol; i++){ pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i)); } @@ -137850,7 +143607,8 @@ static void updateFromSelect( } #endif } - if( ALWAYS(pChanges) ){ + assert( pChanges!=0 || pParse->db->mallocFailed ); + if( pChanges ){ for(i=0; inExpr; i++){ pList = sqlite3ExprListAppend(pParse, pList, sqlite3ExprDup(db, pChanges->a[i].pExpr, 0) @@ -137858,8 +143616,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); @@ -137944,9 +143703,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. */ @@ -137959,7 +143720,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 @@ -138048,13 +143809,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; @@ -138068,7 +143832,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 @@ -138092,7 +143856,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; @@ -138124,8 +143888,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; } @@ -138244,6 +144010,7 @@ SQLITE_PRIVATE void sqlite3Update( if( (db->flags&SQLITE_CountRows)!=0 && !pParse->pTriggerTab && !pParse->nested + && !pParse->bReturning && pUpsert==0 ){ regRowCount = ++pParse->nMem; @@ -138252,6 +144019,8 @@ SQLITE_PRIVATE void sqlite3Update( if( nChangeFrom==0 && HasRowid(pTab) ){ sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid); + iEph = pParse->nTab++; + addrOpen = sqlite3VdbeAddOp3(v, OP_OpenEphemeral, iEph, 0, regRowSet); }else{ assert( pPk!=0 || HasRowid(pTab) ); nPk = pPk ? pPk->nKeyCol : 0; @@ -138306,11 +144075,11 @@ SQLITE_PRIVATE void sqlite3Update( ** be deleted as a result of REPLACE conflict handling. Any of these ** things might disturb a cursor being used to scan through the table ** or index, causing a single-pass approach to malfunction. */ - flags = WHERE_ONEPASS_DESIRED|WHERE_SEEK_UNIQ_TABLE; + flags = WHERE_ONEPASS_DESIRED; 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 @@ -138343,9 +144112,10 @@ SQLITE_PRIVATE void sqlite3Update( ** leave it in register regOldRowid. */ sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid); if( eOnePass==ONEPASS_OFF ){ - /* We need to use regRowSet, so reallocate aRegIdx[nAllIdx] */ aRegIdx[nAllIdx] = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iEph, regRowSet, regOldRowid); + }else{ + if( ALWAYS(addrOpen) ) sqlite3VdbeChangeToNoop(v, addrOpen); } }else{ /* Read the PK of the current row into an array of registers. In @@ -138396,7 +144166,12 @@ SQLITE_PRIVATE void sqlite3Update( /* Top of the update loop */ if( eOnePass!=ONEPASS_OFF ){ - if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){ + if( aiCurOnePass[0]!=iDataCur + && aiCurOnePass[1]!=iDataCur +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + && !isView +#endif + ){ assert( pPk ); sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey); VdbeCoverage(v); @@ -138433,8 +144208,9 @@ SQLITE_PRIVATE void sqlite3Update( VdbeCoverage(v); } }else{ - labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet,labelBreak, - regOldRowid); + sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); + labelContinue = sqlite3VdbeMakeLabel(pParse); + addrTop = sqlite3VdbeAddOp2(v, OP_Rowid, iEph, regOldRowid); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); VdbeCoverage(v); @@ -138684,11 +144460,9 @@ SQLITE_PRIVATE void sqlite3Update( }else if( eOnePass==ONEPASS_MULTI ){ sqlite3VdbeResolveLabel(v, labelContinue); sqlite3WhereEnd(pWInfo); - }else if( pPk || nChangeFrom ){ + }else{ sqlite3VdbeResolveLabel(v, labelContinue); sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v); - }else{ - sqlite3VdbeGoto(v, labelContinue); } sqlite3VdbeResolveLabel(v, labelBreak); @@ -138705,9 +144479,7 @@ SQLITE_PRIVATE void sqlite3Update( ** that information. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); + sqlite3CodeChangeCount(v, regRowCount, "rows updated"); } update_cleanup: @@ -138788,12 +144560,26 @@ static void updateVirtualTable( regArg = pParse->nMem + 1; pParse->nMem += nArg; if( pSrc->nSrc>1 ){ + Index *pPk = 0; Expr *pRow; ExprList *pList; - if( pRowid ){ - pRow = sqlite3ExprDup(db, pRowid, 0); + if( HasRowid(pTab) ){ + if( pRowid ){ + pRow = sqlite3ExprDup(db, pRowid, 0); + }else{ + pRow = sqlite3PExpr(pParse, TK_ROW, 0, 0); + } }else{ - pRow = sqlite3PExpr(pParse, TK_ROW, 0, 0); + i16 iPk; /* PRIMARY KEY column */ + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + assert( pPk->nKeyCol==1 ); + iPk = pPk->aiColumn[0]; + if( aXRef[iPk]>=0 ){ + pRow = sqlite3ExprDup(db, pChanges->a[aXRef[iPk]].pExpr, 0); + }else{ + pRow = exprRowColumn(pParse, iPk); + } } pList = sqlite3ExprListAppend(pParse, 0, pRow); @@ -138807,7 +144593,7 @@ static void updateVirtualTable( } } - updateFromSelect(pParse, ephemTab, 0, pList, pSrc, pWhere, 0, 0); + updateFromSelect(pParse, ephemTab, pPk, pList, pSrc, pWhere, 0, 0); sqlite3ExprListDelete(db, pList); eOnePass = ONEPASS_OFF; }else{ @@ -138815,7 +144601,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. */ @@ -138926,16 +144714,23 @@ static void updateVirtualTable( /* ** Free a list of Upsert objects */ -SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){ - if( p ){ +static void SQLITE_NOINLINE upsertDelete(sqlite3 *db, Upsert *p){ + do{ + Upsert *pNext = p->pNextUpsert; sqlite3ExprListDelete(db, p->pUpsertTarget); sqlite3ExprDelete(db, p->pUpsertTargetWhere); sqlite3ExprListDelete(db, p->pUpsertSet); sqlite3ExprDelete(db, p->pUpsertWhere); + sqlite3DbFree(db, p->pToFree); sqlite3DbFree(db, p); - } + p = pNext; + }while( p ); +} +SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){ + if( p ) upsertDelete(db, p); } + /* ** Duplicate an Upsert object. */ @@ -138945,7 +144740,8 @@ SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){ sqlite3ExprListDup(db, p->pUpsertTarget, 0), sqlite3ExprDup(db, p->pUpsertTargetWhere, 0), sqlite3ExprListDup(db, p->pUpsertSet, 0), - sqlite3ExprDup(db, p->pUpsertWhere, 0) + sqlite3ExprDup(db, p->pUpsertWhere, 0), + sqlite3UpsertDup(db, p->pNextUpsert) ); } @@ -138957,22 +144753,25 @@ SQLITE_PRIVATE Upsert *sqlite3UpsertNew( ExprList *pTarget, /* Target argument to ON CONFLICT, or NULL */ Expr *pTargetWhere, /* Optional WHERE clause on the target */ ExprList *pSet, /* UPDATE columns, or NULL for a DO NOTHING */ - Expr *pWhere /* WHERE clause for the ON CONFLICT UPDATE */ + Expr *pWhere, /* WHERE clause for the ON CONFLICT UPDATE */ + Upsert *pNext /* Next ON CONFLICT clause in the list */ ){ Upsert *pNew; - pNew = sqlite3DbMallocRaw(db, sizeof(Upsert)); + pNew = sqlite3DbMallocZero(db, sizeof(Upsert)); if( pNew==0 ){ sqlite3ExprListDelete(db, pTarget); sqlite3ExprDelete(db, pTargetWhere); sqlite3ExprListDelete(db, pSet); sqlite3ExprDelete(db, pWhere); + sqlite3UpsertDelete(db, pNext); return 0; }else{ pNew->pUpsertTarget = pTarget; pNew->pUpsertTargetWhere = pTargetWhere; pNew->pUpsertSet = pSet; pNew->pUpsertWhere = pWhere; - pNew->pUpsertIdx = 0; + pNew->isDoUpdate = pSet!=0; + pNew->pNextUpsert = pNext; } return pNew; } @@ -138997,6 +144796,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( Expr *pTerm; /* One term of the conflict-target clause */ NameContext sNC; /* Context for resolving symbolic names */ Expr sCol[2]; /* Index column converted into an Expr */ + int nClause = 0; /* Counter of ON CONFLICT clauses */ assert( pTabList->nSrc==1 ); assert( pTabList->a[0].pTab!=0 ); @@ -139010,87 +144810,131 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; sNC.pSrcList = pTabList; - rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); - if( rc ) return rc; - rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); - if( rc ) return rc; + for(; pUpsert && pUpsert->pUpsertTarget; + pUpsert=pUpsert->pNextUpsert, nClause++){ + rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); + if( rc ) return rc; + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); + if( rc ) return rc; - /* Check to see if the conflict target matches the rowid. */ - pTab = pTabList->a[0].pTab; - pTarget = pUpsert->pUpsertTarget; - iCursor = pTabList->a[0].iCursor; - if( HasRowid(pTab) - && pTarget->nExpr==1 - && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN - && pTerm->iColumn==XN_ROWID - ){ - /* The conflict-target is the rowid of the primary table */ - assert( pUpsert->pUpsertIdx==0 ); - return SQLITE_OK; - } + /* Check to see if the conflict target matches the rowid. */ + pTab = pTabList->a[0].pTab; + pTarget = pUpsert->pUpsertTarget; + iCursor = pTabList->a[0].iCursor; + if( HasRowid(pTab) + && pTarget->nExpr==1 + && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN + && pTerm->iColumn==XN_ROWID + ){ + /* The conflict-target is the rowid of the primary table */ + assert( pUpsert->pUpsertIdx==0 ); + continue; + } - /* Initialize sCol[0..1] to be an expression parse tree for a - ** single column of an index. The sCol[0] node will be the TK_COLLATE - ** operator and sCol[1] will be the TK_COLUMN operator. Code below - ** will populate the specific collation and column number values - ** prior to comparing against the conflict-target expression. - */ - memset(sCol, 0, sizeof(sCol)); - sCol[0].op = TK_COLLATE; - sCol[0].pLeft = &sCol[1]; - sCol[1].op = TK_COLUMN; - sCol[1].iTable = pTabList->a[0].iCursor; + /* Initialize sCol[0..1] to be an expression parse tree for a + ** single column of an index. The sCol[0] node will be the TK_COLLATE + ** operator and sCol[1] will be the TK_COLUMN operator. Code below + ** will populate the specific collation and column number values + ** prior to comparing against the conflict-target expression. + */ + memset(sCol, 0, sizeof(sCol)); + sCol[0].op = TK_COLLATE; + sCol[0].pLeft = &sCol[1]; + sCol[1].op = TK_COLUMN; + sCol[1].iTable = pTabList->a[0].iCursor; - /* Check for matches against other indexes */ - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - int ii, jj, nn; - if( !IsUniqueIndex(pIdx) ) continue; - if( pTarget->nExpr!=pIdx->nKeyCol ) continue; - if( pIdx->pPartIdxWhere ){ - if( pUpsert->pUpsertTargetWhere==0 ) continue; - if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere, - pIdx->pPartIdxWhere, iCursor)!=0 ){ - continue; + /* Check for matches against other indexes */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int ii, jj, nn; + if( !IsUniqueIndex(pIdx) ) continue; + if( pTarget->nExpr!=pIdx->nKeyCol ) continue; + if( pIdx->pPartIdxWhere ){ + if( pUpsert->pUpsertTargetWhere==0 ) continue; + if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere, + pIdx->pPartIdxWhere, iCursor)!=0 ){ + continue; + } } - } - nn = pIdx->nKeyCol; - for(ii=0; iiazColl[ii]; - if( pIdx->aiColumn[ii]==XN_EXPR ){ - assert( pIdx->aColExpr!=0 ); - assert( pIdx->aColExpr->nExpr>ii ); - pExpr = pIdx->aColExpr->a[ii].pExpr; - if( pExpr->op!=TK_COLLATE ){ - sCol[0].pLeft = pExpr; + nn = pIdx->nKeyCol; + for(ii=0; iiazColl[ii]; + if( pIdx->aiColumn[ii]==XN_EXPR ){ + assert( pIdx->aColExpr!=0 ); + assert( pIdx->aColExpr->nExpr>ii ); + pExpr = pIdx->aColExpr->a[ii].pExpr; + if( pExpr->op!=TK_COLLATE ){ + sCol[0].pLeft = pExpr; + pExpr = &sCol[0]; + } + }else{ + sCol[0].pLeft = &sCol[1]; + sCol[1].iColumn = pIdx->aiColumn[ii]; pExpr = &sCol[0]; } - }else{ - sCol[0].pLeft = &sCol[1]; - sCol[1].iColumn = pIdx->aiColumn[ii]; - pExpr = &sCol[0]; - } - for(jj=0; jja[jj].pExpr, pExpr,iCursor)<2 ){ - break; /* Column ii of the index matches column jj of target */ + for(jj=0; jja[jj].pExpr,pExpr,iCursor)<2 ){ + break; /* Column ii of the index matches column jj of target */ + } + } + if( jj>=nn ){ + /* The target contains no match for column jj of the index */ + break; } } - if( jj>=nn ){ - /* The target contains no match for column jj of the index */ - break; + if( iipUpsertIdx = pIdx; + break; } - if( iipUpsertIdx==0 ){ + char zWhich[16]; + if( nClause==0 && pUpsert->pNextUpsert==0 ){ + zWhich[0] = 0; + }else{ + sqlite3_snprintf(sizeof(zWhich),zWhich,"%r ", nClause+1); + } + sqlite3ErrorMsg(pParse, "%sON CONFLICT clause does not match any " + "PRIMARY KEY or UNIQUE constraint", zWhich); + return SQLITE_ERROR; } - pUpsert->pUpsertIdx = pIdx; - return SQLITE_OK; } - sqlite3ErrorMsg(pParse, "ON CONFLICT clause does not match any " - "PRIMARY KEY or UNIQUE constraint"); - return SQLITE_ERROR; + return SQLITE_OK; +} + +/* +** Return true if pUpsert is the last ON CONFLICT clause with a +** conflict target, or if pUpsert is followed by another ON CONFLICT +** clause that targets the INTEGER PRIMARY KEY. +*/ +SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert *pUpsert){ + Upsert *pNext; + if( NEVER(pUpsert==0) ) return 0; + pNext = pUpsert->pNextUpsert; + if( pNext==0 ) return 1; + if( pNext->pUpsertTarget==0 ) return 1; + if( pNext->pUpsertIdx==0 ) return 1; + return 0; +} + +/* +** Given the list of ON CONFLICT clauses described by pUpsert, and +** a particular index pIdx, return a pointer to the particular ON CONFLICT +** clause that applies to the index. Or, if the index is not subject to +** any ON CONFLICT clause, return NULL. +*/ +SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert *pUpsert, Index *pIdx){ + while( + pUpsert + && pUpsert->pUpsertTarget!=0 + && pUpsert->pUpsertIdx!=pIdx + ){ + pUpsert = pUpsert->pNextUpsert; + } + return pUpsert; } /* @@ -139114,11 +144958,13 @@ SQLITE_PRIVATE void sqlite3UpsertDoUpdate( SrcList *pSrc; /* FROM clause for the UPDATE */ int iDataCur; int i; + Upsert *pTop = pUpsert; assert( v!=0 ); assert( pUpsert!=0 ); - VdbeNoopComment((v, "Begin DO UPDATE of UPSERT")); iDataCur = pUpsert->iDataCur; + pUpsert = sqlite3UpsertOfIndex(pTop, pIdx); + VdbeNoopComment((v, "Begin DO UPDATE of UPSERT")); if( pIdx && iCur!=iDataCur ){ if( HasRowid(pTab) ){ int regRowid = sqlite3GetTempReg(pParse); @@ -139137,7 +144983,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); @@ -139148,19 +144994,17 @@ SQLITE_PRIVATE void sqlite3UpsertDoUpdate( sqlite3VdbeJumpHere(v, i); } } - /* pUpsert does not own pUpsertSrc - the outer INSERT statement does. So - ** we have to make a copy before passing it down into sqlite3Update() */ - pSrc = sqlite3SrcListDup(db, pUpsert->pUpsertSrc, 0); + /* pUpsert does not own pTop->pUpsertSrc - the outer INSERT statement does. + ** So we have to make a copy before passing it down into sqlite3Update() */ + pSrc = sqlite3SrcListDup(db, pTop->pUpsertSrc, 0); /* excluded.* columns of type REAL need to be converted to a hard real */ for(i=0; inCol; i++){ if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ - sqlite3VdbeAddOp1(v, OP_RealAffinity, pUpsert->regData+i); + sqlite3VdbeAddOp1(v, OP_RealAffinity, pTop->regData+i); } } - sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet, - pUpsert->pUpsertWhere, OE_Abort, 0, 0, pUpsert); - pUpsert->pUpsertSet = 0; /* Will have been deleted by sqlite3Update() */ - pUpsert->pUpsertWhere = 0; /* Will have been deleted by sqlite3Update() */ + sqlite3Update(pParse, pSrc, sqlite3ExprListDup(db,pUpsert->pUpsertSet,0), + sqlite3ExprDup(db,pUpsert->pUpsertWhere,0), OE_Abort, 0, 0, pUpsert); VdbeNoopComment((v, "End DO UPDATE of UPSERT")); } @@ -139321,8 +145165,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 */ @@ -139420,7 +145264,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; } @@ -139509,8 +145355,8 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( BTREE_APPLICATION_ID, 0, /* Preserve the application id */ }; - assert( 1==sqlite3BtreeIsInTrans(pTemp) ); - assert( pOut!=0 || 1==sqlite3BtreeIsInTrans(pMain) ); + assert( SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pTemp) ); + assert( pOut!=0 || SQLITE_TXN_WRITE==sqlite3BtreeTxnState(pMain) ); /* Copy Btree meta values */ for(i=0; ipVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); + for(pVtab=pTab->u.vtab.p; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); return pVtab; } @@ -139782,7 +145628,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 ){ @@ -139797,21 +145644,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) ); @@ -139821,7 +145671,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; @@ -139849,7 +145699,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; @@ -139912,37 +145762,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; } } @@ -139965,10 +145819,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)); @@ -139985,11 +145840,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 } @@ -140017,9 +145872,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 @@ -140052,7 +145908,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, @@ -140066,24 +145922,20 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ sqlite3VdbeAddOp0(v, OP_Expire); zWhere = sqlite3MPrintf(db, "name=%Q AND sql=%Q", pTab->zName, zStmt); - sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); + sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere, 0); sqlite3DbFree(db, zStmt); 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); @@ -140134,13 +145986,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 ){ @@ -140167,7 +146022,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 ); @@ -140206,12 +146061,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], ""); @@ -140237,6 +146092,7 @@ static int vtabCallConstructor( zType[i-1] = '\0'; } pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN; + pTab->tabFlags |= TF_HasHidden; oooHidden = TF_OOOHidden; }else{ pTab->tabFlags |= oooHidden; @@ -140263,16 +146119,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{ @@ -140335,10 +146192,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, @@ -140373,8 +146230,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 ){ @@ -140391,21 +146248,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; + /* 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; - pTab->nCol = pNew->nCol; + sqlite3ExprListDelete(db, pNew->u.tab.pDfltList); + pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); pNew->nCol = 0; pNew->aCol = 0; @@ -140429,8 +146292,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; @@ -140439,7 +146303,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); @@ -140459,10 +146324,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; @@ -140476,9 +146344,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); @@ -140692,6 +146560,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; @@ -140766,8 +146635,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 @@ -140794,9 +146664,11 @@ 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)); addModuleArgument(pParse, pTab, 0); addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName)); @@ -140805,7 +146677,6 @@ SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ sqlite3ErrorMsg(pParse, "%s", zErr); sqlite3DbFree(db, zErr); sqlite3VtabEponymousTableClear(db, pMod); - return 0; } return 1; } @@ -140937,19 +146808,6 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){ #ifndef SQLITE_WHEREINT_H #define SQLITE_WHEREINT_H -/* -** Trace output macros -*/ -#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) -/***/ extern int sqlite3WhereTrace; -#endif -#if defined(SQLITE_DEBUG) \ - && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) -# define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X -# define WHERETRACE_ENABLED 1 -#else -# define WHERETRACE(K,X) -#endif /* Forward references */ @@ -140997,6 +146855,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 */ @@ -141011,7 +146870,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 */ @@ -141055,10 +146914,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 */ @@ -141181,9 +147042,11 @@ struct WhereTerm { u8 eMatchOp; /* Op for vtab MATCH/LIKE/GLOB/REGEXP terms */ int iParent; /* Disable pWC->a[iParent] when this term disabled */ int leftCursor; /* Cursor number of X in "X " */ - int iField; /* Field in (?,?,?) IN (SELECT...) vector */ union { - int leftColumn; /* Column number of X in "X " */ + struct { + int leftColumn; /* Column number of X in "X " */ + int iField; /* Field in (?,?,?) IN (SELECT...) vector */ + } x; /* Opcode other than OP_OR or OP_AND */ WhereOrInfo *pOrInfo; /* Extra information if (eOperator & WO_OR)!=0 */ WhereAndInfo *pAndInfo; /* Extra information if (eOperator& WO_AND)!=0 */ } u; @@ -141200,12 +147063,8 @@ 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 */ -#ifdef SQLITE_ENABLE_STAT4 -# define TERM_VNULL 0x0080 /* Manufactured x>NULL or x<=NULL term */ -#else -# define TERM_VNULL 0x0000 /* Disabled if not using stat4 */ -#endif +#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 */ #define TERM_LIKE 0x0400 /* The original LIKE operator */ @@ -141217,6 +147076,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 @@ -141227,11 +147087,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 aEquiv[] */ - unsigned char iEquiv; /* Next unused slot in aEquiv[] */ - 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 */ }; @@ -141255,6 +147115,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[] */ @@ -141312,11 +147173,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. @@ -141324,7 +147180,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 @@ -141392,6 +147247,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 */ @@ -141408,6 +147266,7 @@ struct WhereInfo { unsigned sorted :1; /* True if really sorted (not just grouped) */ LogEst nRowOut; /* Estimated number of output rows */ int iTop; /* The very beginning of the WHERE loop */ + int iEndWhere; /* End of the WHERE clause itself */ WhereLoop *pLoops; /* List of all WhereLoop objects */ WhereExprMod *pExprMods; /* Expression modifications */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ @@ -141444,8 +147303,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( @@ -141470,11 +147335,12 @@ 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*); SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*); -SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); +SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); @@ -141536,6 +147402,11 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereC #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */ #define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */ #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) */ @@ -141551,7 +147422,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; } /* @@ -141651,7 +147522,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( if( sqlite3ParseToplevel(pParse)->explain==2 ) #endif { - struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; + SrcItem *pItem = &pTabList->a[pLevel->iFrom]; Vdbe *v = pParse->pVdbe; /* VM being constructed */ sqlite3 *db = pParse->db; /* Database handle */ int isSearch; /* True for a SEARCH. False for SCAN. */ @@ -141670,16 +147541,8 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); - sqlite3_str_appendall(&str, isSearch ? "SEARCH" : "SCAN"); - if( pItem->pSelect ){ - sqlite3_str_appendf(&str, " SUBQUERY %u", pItem->pSelect->selId); - }else{ - sqlite3_str_appendf(&str, " TABLE %s", pItem->zName); - } - - if( pItem->zAlias ){ - sqlite3_str_appendf(&str, " AS %s", pItem->zAlias); - } + str.printfFlags = SQLITE_PRINTF_INTERNAL; + sqlite3_str_appendf(&str, "%s %S", isSearch ? "SEARCH" : "SCAN", pItem); if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ const char *zFmt = 0; Index *pIdx; @@ -141706,19 +147569,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 ){ @@ -141741,6 +147612,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 @@ -141827,6 +147748,12 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ }else{ pTerm->wtFlags |= TERM_CODED; } +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace & 0x20000 ){ + sqlite3DebugPrintf("DISABLE-"); + sqlite3WhereTermPrint(pTerm, (int)(pTerm - (pTerm->pWC->a))); + } +#endif if( pTerm->iParent<0 ) break; pTerm = &pTerm->pWC->a[pTerm->iParent]; assert( pTerm!=0 ); @@ -141940,16 +147867,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]->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; @@ -142064,7 +147998,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; @@ -142086,12 +148020,15 @@ 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); } + if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){ + pLoop->wsFlags |= WHERE_IN_EARLYOUT; + } i = pLevel->u.in.nIn; pLevel->u.in.nIn += nEq; @@ -142118,7 +148055,6 @@ static int codeEqualityTerm( if( iEq>0 ){ pIn->iBase = iReg - i; pIn->nPrefix = i; - pLoop->wsFlags |= WHERE_IN_EARLYOUT; }else{ pIn->nPrefix = 0; } @@ -142128,13 +148064,36 @@ static int codeEqualityTerm( pIn++; } } + testcase( iEq>0 + && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 + && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); + if( iEq>0 + && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 + ){ + sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); + } }else{ pLevel->u.in.nIn = 0; } sqlite3DbFree(pParse->db, aiMap); #endif } - disableTerm(pLevel, pTerm); + + /* As an optimization, try to disable the WHERE clause term that is + ** driving the index as it will always be true. The correct answer is + ** obtained regardless, but we might get the answer with fewer CPU cycles + ** by omitting the term. + ** + ** But do not disable the term unless we are certain that the term is + ** not a transitive constraint. For an example of where that does not + ** work, see https://sqlite.org/forum/forumpost/eb8613976a (2021-05-04) + */ + if( (pLevel->pWLoop->wsFlags & WHERE_TRANSCONS)==0 + || (pTerm->eOperator & WO_EQUIV)==0 + ){ + disableTerm(pLevel, pTerm); + } + return iReg; } @@ -142220,6 +148179,7 @@ static int codeAllEqualityTerms( if( nSkip ){ int iIdxCur = pLevel->iIdxCur; + sqlite3VdbeAddOp3(v, OP_Null, 0, regBase, regBase+nSkip-1); sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); @@ -142254,9 +148214,12 @@ static int codeAllEqualityTerms( sqlite3ReleaseTempReg(pParse, regBase); regBase = r1; }else{ - sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j); + 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 @@ -142271,7 +148234,8 @@ static int codeAllEqualityTerms( sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); VdbeCoverage(v); } - if( zAff ){ + if( pParse->nErr==0 ){ + assert( pParse->db->mallocFailed==0 ); if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){ zAff[j] = SQLITE_AFF_BLOB; } @@ -142434,7 +148398,7 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ ** Insert an OP_CursorHint instruction if it is appropriate to do so. */ static void codeCursorHint( - struct SrcList_item *pTabItem, /* FROM clause item */ + SrcItem *pTabItem, /* FROM clause item */ WhereInfo *pWInfo, /* The where clause */ WhereLevel *pLevel, /* Which loop to provide hints for */ WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */ @@ -142461,7 +148425,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; @@ -142491,7 +148455,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; @@ -142603,7 +148567,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 ); @@ -142613,14 +148577,16 @@ 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); } } }else{ - assert( nReg==1 ); + assert( nReg==1 || pParse->nErr ); sqlite3ExprCode(pParse, p, iReg); } } @@ -142666,10 +148632,10 @@ static int whereIndexExprTransNode(Walker *p, Expr *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; @@ -142684,7 +148650,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; @@ -142732,15 +148698,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 @@ -142789,6 +148756,64 @@ 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; + /* ,--- Because sqlite3ConstructBloomFilter() has will not have set + ** vvvvv--' pLevel->regFilter if this were true. */ + if( NEVER(pLoop->prereq & notReady) ) continue; + 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; + } +} + /* ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. @@ -142809,7 +148834,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( WhereClause *pWC; /* Decomposition of the entire WHERE clause */ WhereTerm *pTerm; /* A WHERE clause term */ sqlite3 *db; /* Database connection */ - struct SrcList_item *pTabItem; /* FROM clause term being coded */ + SrcItem *pTabItem; /* FROM clause term being coded */ int addrBrk; /* Jump here to break out of the loop */ int addrHalt; /* addrBrk for the outermost loop */ int addrCont; /* Jump here to continue with next cycle */ @@ -142900,11 +148925,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); @@ -142914,18 +148955,32 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC); VdbeCoverage(v); pLoop->u.vtab.needFree = 0; + /* An OOM inside of AddOp4(OP_VFilter) instruction above might have freed + ** the u.vtab.idxStr. NULL it out to prevent a use-after-free */ + if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0; pLevel->p1 = iCur; pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext; pLevel->p2 = sqlite3VdbeCurrentAddr(v); - iIn = pLevel->u.in.nIn; + assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); + if( pLoop->wsFlags & WHERE_IN_ABLE ){ + iIn = pLevel->u.in.nIn; + }else{ + iIn = 0; + } for(j=nConstraint-1; j>=0; j--){ + int bIn; /* True to generate byte code to loop over RHS IN values */ pTerm = pLoop->aLTerm[j]; - if( (pTerm->eOperator & WO_IN)!=0 ) iIn--; + if( (pTerm->eOperator & WO_IN)!=0 + && (SMASKBIT32(j) & pLoop->u.vtab.mHandleIn)==0 + ){ + bIn = 1; + }else{ + bIn = 0; + } + if( bIn ) 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 - ){ + }else if( bIn && sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1 ){ Expr *pCompare; /* The comparison operator */ Expr *pRight; /* RHS of the comparison */ VdbeOp *pOp; /* Opcode to access the value of the IN constraint */ @@ -142991,12 +149046,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 ){ @@ -143172,6 +149230,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */ int omitTable; /* True if we use the index only */ int regBignull = 0; /* big-null flag register */ + int addrSeekScan = 0; /* Opcode of the OP_SeekScan, if any */ pIdx = pLoop->u.btree.pIndex; iIdxCur = pLevel->iIdxCur; @@ -143243,14 +149302,18 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** a forward order scan on a descending index, interchange the ** start and end terms (pRangeStart and pRangeEnd). */ - if( (nEqnKeyCol && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) - || (bRev && pIdx->nKeyCol==nEq) - ){ + if( (nEqnColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) ){ SWAP(WhereTerm *, pRangeEnd, pRangeStart); SWAP(u8, bSeekPastNull, bStopAtNull); SWAP(u8, nBtm, nTop); } + if( iLevel>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 ){ + /* In case OP_SeekScan is used, ensure that the index cursor does not + ** point to a valid row for the first iteration of this loop. */ + sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); + } + /* Generate code to evaluate all constraint terms using == or IN ** and store the values of those terms in an array of registers ** starting at regBase. @@ -143310,16 +149373,33 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** above has already left the cursor sitting on the correct row, ** so no further seeking is needed */ }else{ - if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ - sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur); - } if( regBignull ){ 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 ); + if( (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 && op==OP_SeekGE ){ + assert( regBignull==0 ); + /* TUNING: The OP_SeekScan opcode seeks to reduce the number + ** of expensive seek operations by replacing a single seek with + ** 1 or more step operations. The question is, how many steps + ** should we try before giving up and going with a seek. The cost + ** of a seek is proportional to the logarithm of the of the number + ** of entries in the tree, so basing the number of steps to try + ** on the estimated number of rows in the btree seems like a good + ** guess. */ + addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan, + (pIdx->aiRowLogEst[0]+9)/10); + VdbeCoverage(v); + } sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); VdbeCoverage(v); VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); @@ -143351,8 +149431,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 @@ -143386,7 +149477,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 ){ @@ -143402,6 +149493,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); + if( addrSeekScan ) sqlite3VdbeJumpHere(v, addrSeekScan); } if( regBignull ){ /* During a NULL-scan, check to see if we have reached the end of @@ -143421,8 +149513,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } - if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ - sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1); + if( (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0 ){ + sqlite3VdbeAddOp3(v, OP_SeekHit, iIdxCur, nEq, nEq); } /* Seek the table cursor, if required */ @@ -143431,17 +149523,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ - if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE) - || ( (pWInfo->wctrlFlags & WHERE_SEEK_UNIQ_TABLE)!=0 - && (pWInfo->eOnePass==ONEPASS_SINGLE || pLoop->nLTerm==0) ) - ){ - iRowidReg = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); - sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg); - VdbeCoverage(v); - }else{ - codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur); - } + codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur); }else if( iCur!=iIdxCur ){ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol); @@ -143568,7 +149650,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( int iRetInit; /* Address of regReturn init */ int untestedTerms = 0; /* Some terms not completely tested */ int ii; /* Loop counter */ - u16 wctrlFlags; /* Flags for sub-WHERE clause */ Expr *pAndExpr = 0; /* An ".. AND (...)" expression */ Table *pTab = pTabItem->pTab; @@ -143586,7 +149667,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( */ if( pWInfo->nLevel>1 ){ int nNotReady; /* The number of notReady tables */ - struct SrcList_item *origSrc; /* Original list of tables */ + SrcItem *origSrc; /* Original list of tables */ nNotReady = pWInfo->nLevel - iLevel - 1; pOrTab = sqlite3StackAllocRaw(db, sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); @@ -143629,7 +149710,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. ** @@ -143641,6 +149722,12 @@ 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. */ if( pWC->nTerm>1 ){ int iTerm; @@ -143649,7 +149736,10 @@ 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 ); pExpr = sqlite3ExprDup(db, pExpr, 0); @@ -143659,7 +149749,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( /* The extra 0x10000 bit on the opcode is masked off and does not ** become part of the new Expr.op. However, it does make the ** op==TK_AND comparison inside of sqlite3PExpr() false, and this - ** prevents sqlite3PExpr() from implementing AND short-circuit + ** prevents sqlite3PExpr() from applying the AND short-circuit ** optimization, which we do not want here. */ pAndExpr = sqlite3PExpr(pParse, TK_AND|0x10000, 0, pAndExpr); } @@ -143669,17 +149759,22 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** eliminating duplicates from other WHERE clauses, the action for each ** sub-WHERE clause is to to invoke the main loop body as a subroutine. */ - wctrlFlags = WHERE_OR_SUBCLAUSE | (pWInfo->wctrlFlags & WHERE_SEEK_TABLE); ExplainQueryPlan((pParse, 1, "MULTI-INDEX OR")); for(ii=0; iinTerm; ii++){ WhereTerm *pOrTerm = &pOrWc->a[ii]; if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ WhereInfo *pSubWInfo; /* Info for single OR-term scan */ Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */ + Expr *pDelete; /* Local copy of OR clause term */ int jmp1 = 0; /* Address of jump operation */ testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0 && !ExprHasProperty(pOrExpr, EP_FromJoin) ); /* See TH3 vtab25.400 and ticket 614b25314c766238 */ + pDelete = pOrExpr = sqlite3ExprDup(db, pOrExpr, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDelete); + continue; + } if( pAndExpr ){ pAndExpr->pLeft = pOrExpr; pOrExpr = pAndExpr; @@ -143687,9 +149782,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, - wctrlFlags, iCovCur); - assert( pSubWInfo || pParse->nErr || db->mallocFailed ); + pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0, + WHERE_OR_SUBCLAUSE, iCovCur); + assert( pSubWInfo || pParse->nErr ); if( pSubWInfo ){ WhereLoop *pSubLoop; int addrExplain = sqlite3WhereExplainOneScan( @@ -143786,15 +149881,22 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( }else{ pCov = 0; } + if( sqlite3WhereUsesDeferredSeek(pSubWInfo) ){ + pWInfo->bDeferredSeek = 1; + } /* Finish the loop through table entries that match term pOrTerm. */ sqlite3WhereEnd(pSubWInfo); ExplainQueryPlanPop(pParse); } + sqlite3ExprDelete(db, pDelete); } } 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; @@ -143921,7 +150023,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; @@ -143938,12 +150040,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( #endif assert( !ExprHasProperty(pE, EP_FromJoin) ); assert( (pTerm->prereqRight & pLevel->notReady)!=0 ); - pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.leftColumn, notReady, + 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; @@ -143955,6 +150058,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( sEAlt = *pAlt->pExpr; sEAlt.pLeft = pE->pLeft; sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL); + pAlt->wtFlags |= TERM_CODED; } /* For a LEFT OUTER JOIN, generate code that will record the fact that @@ -143964,7 +150068,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; @@ -144075,6 +150179,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{ @@ -144191,6 +150296,7 @@ static int isLikeOrGlob( #ifdef SQLITE_EBCDIC if( *pnoCase ) return 0; #endif + assert( ExprUseXList(pExpr) ); pList = pExpr->x.pList; pLeft = pList->a[1].pExpr; @@ -144206,7 +150312,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 ){ @@ -144235,7 +150342,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; @@ -144287,6 +150398,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 @@ -144360,6 +150472,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; @@ -144373,9 +150486,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; @@ -144396,6 +150511,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; @@ -144405,6 +150521,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); @@ -144420,10 +150537,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++; @@ -144447,7 +150566,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; } } @@ -144507,6 +150626,7 @@ static void whereCombineDisjuncts( int op; /* Operator for the combined expression */ int idxNew; /* Index in pWC of the next virtual term */ + if( (pOne->wtFlags | pTwo->wtFlags) & TERM_VNULL ) return; if( (pOne->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; if( (pTwo->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return; if( (eOp & (WO_EQ|WO_LT|WO_LE))!=eOp @@ -144675,6 +150795,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); @@ -144717,11 +150838,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. @@ -144776,7 +150896,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. */ @@ -144794,7 +150914,8 @@ static void exprAnalyzeOrTerm( assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) ); continue; } - iColumn = pOrTerm->u.leftColumn; + assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); + iColumn = pOrTerm->u.x.leftColumn; iCursor = pOrTerm->leftCursor; pLeft = pOrTerm->pExpr->pLeft; break; @@ -144814,9 +150935,10 @@ 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; - }else if( pOrTerm->u.leftColumn!=iColumn || (iColumn==XN_EXPR + pOrTerm->wtFlags &= ~TERM_OK; + }else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1) )){ okToChngToIN = 0; @@ -144831,7 +150953,7 @@ static void exprAnalyzeOrTerm( if( affRight!=0 && affRight!=affLeft ){ okToChngToIN = 0; }else{ - pOrTerm->wtFlags |= TERM_OR_OK; + pOrTerm->wtFlags |= TERM_OK; } } } @@ -144848,10 +150970,11 @@ 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.leftColumn==iColumn ); + assert( pOrTerm->u.x.leftColumn==iColumn ); pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup); pLeft = pOrTerm->pExpr->pLeft; @@ -144862,12 +150985,12 @@ 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 ); exprAnalyze(pSrc, pWC, idxNew); - /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where used again */ + /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where reused */ markTermAsChild(pWC, idxNew, idxTerm); }else{ sqlite3ExprListDelete(db, pList); @@ -144990,7 +151113,9 @@ 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; + } if( pExpr->op==TK_COLUMN ){ @@ -145003,6 +151128,7 @@ static int exprMightBeIndexed( return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr); } + /* ** The input to this routine is an WhereTerm structure with only the ** "pExpr" field filled in. The job of this routine is to analyze the @@ -145045,30 +151171,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 */ @@ -145087,25 +151230,28 @@ static void exprAnalyze( Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; - if( pTerm->iField>0 ){ + if( pTerm->u.x.iField>0 ){ assert( op==TK_IN ); assert( pLeft->op==TK_VECTOR ); - pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr; + 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]; - pTerm->u.leftColumn = aiCurCol[1]; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + pTerm->u.x.leftColumn = aiCurCol[1]; pTerm->eOperator = operatorMask(op) & opMask; } if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; if( pRight && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op) + && !ExprHasProperty(pRight, EP_FixedCol) ){ WhereTerm *pNew; Expr *pDup; u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */ - assert( pTerm->iField==0 ); + assert( pTerm->u.x.iField==0 ); if( pTerm->leftCursor>=0 ){ int idxNew; pDup = sqlite3ExprDup(db, pExpr, 0); @@ -145131,11 +151277,23 @@ static void exprAnalyze( } pNew->wtFlags |= exprCommute(pParse, pDup); pNew->leftCursor = aiCurCol[0]; - pNew->u.leftColumn = aiCurCol[1]; + 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 + && !ExprHasProperty(pExpr,EP_FromJoin) + && 0==sqlite3ExprCanBeNull(pLeft) + ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + pExpr->op = TK_TRUEFALSE; + pExpr->u.zToken = "false"; + ExprSetProperty(pExpr, EP_IsFalse); + pTerm->prereqAll = 0; + pTerm->eOperator = 0; } } @@ -145156,9 +151314,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++){ @@ -145187,6 +151347,42 @@ static void exprAnalyze( pTerm = &pWC->a[idxTerm]; } #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ + /* The form "x IS NOT NULL" can sometimes be evaluated more efficiently + ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a + ** virtual term of that form. + ** + ** The virtual term must be tagged with TERM_VNULL. + */ + else if( pExpr->op==TK_NOTNULL ){ + if( pExpr->pLeft->op==TK_COLUMN + && pExpr->pLeft->iColumn>=0 + && !ExprHasProperty(pExpr, EP_FromJoin) + ){ + Expr *pNewExpr; + Expr *pLeft = pExpr->pLeft; + int idxNew; + WhereTerm *pNewTerm; + + pNewExpr = sqlite3PExpr(pParse, TK_GT, + sqlite3ExprDup(db, pLeft, 0), + sqlite3ExprAlloc(db, TK_NULL, 0, 0)); + + idxNew = whereClauseInsert(pWC, pNewExpr, + TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); + if( idxNew ){ + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = 0; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->u.x.leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_GT; + markTermAsChild(pWC, idxNew, idxTerm); + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; + } + } + } + #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION /* Add constraints to reduce the search space on a LIKE or GLOB @@ -145202,7 +151398,8 @@ static void exprAnalyze( ** bound is made all lowercase so that the bounds also work when comparing ** BLOBs. */ - if( pWC->op==TK_AND + else if( pExpr->op==TK_FUNCTION + && pWC->op==TK_AND && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase) ){ Expr *pLeft; /* LHS of LIKE/GLOB operator */ @@ -145214,8 +151411,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 @@ -145272,76 +151473,33 @@ static void exprAnalyze( } #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - /* Add a WO_AUX auxiliary term to the constraint set if the - ** current expression is of the form "column OP expr" where OP - ** is an operator that gets passed into virtual tables but which is - ** not normally optimized for ordinary tables. In other words, OP - ** is one of MATCH, LIKE, GLOB, REGEXP, !=, IS, IS NOT, or NOT NULL. - ** This information is used by the xBestIndex methods of - ** virtual tables. The native query optimizer does not attempt - ** to do anything with MATCH functions. - */ - if( pWC->op==TK_AND ){ - Expr *pRight = 0, *pLeft = 0; - int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight); - while( res-- > 0 ){ - int idxNew; - WhereTerm *pNewTerm; - Bitmask prereqColumn, prereqExpr; - - prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight); - prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); - if( (prereqExpr & prereqColumn)==0 ){ - Expr *pNewExpr; - pNewExpr = sqlite3PExpr(pParse, TK_MATCH, - 0, sqlite3ExprDup(db, pRight, 0)); - if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ - ExprSetProperty(pNewExpr, EP_FromJoin); - pNewExpr->iRightJoinTable = pExpr->iRightJoinTable; - } - idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); - testcase( idxNew==0 ); - pNewTerm = &pWC->a[idxNew]; - pNewTerm->prereqRight = prereqExpr; - pNewTerm->leftCursor = pLeft->iTable; - pNewTerm->u.leftColumn = pLeft->iColumn; - pNewTerm->eOperator = WO_AUX; - pNewTerm->eMatchOp = eOp2; - markTermAsChild(pWC, idxNew, idxTerm); - pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags |= TERM_COPIED; - pNewTerm->prereqAll = pTerm->prereqAll; - } - SWAP(Expr*, pLeft, pRight); - } - } -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create ** new terms for each component comparison - "a = ?" and "b = ?". The ** new terms completely replace the original vector comparison, which is ** no longer used. ** ** This is only required if at least one side of the comparison operation - ** is not a sub-select. */ - if( pWC->op==TK_AND - && (pExpr->op==TK_EQ || pExpr->op==TK_IS) - && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1 - && sqlite3ExprVectorSize(pExpr->pRight)==nLeft - && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 - || (pExpr->pRight->flags & EP_xIsSelect)==0) + ** 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 + && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 + || (pExpr->pRight->flags & EP_xIsSelect)==0) + && pWC->op==TK_AND ){ int i; 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]; @@ -145352,67 +151510,77 @@ static void exprAnalyze( /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create ** a virtual term for each vector component. The expression object ** used by each such virtual term is pExpr (the full vector IN(...) - ** expression). The WhereTerm.iField variable identifies the index within + ** expression). The WhereTerm.u.x.iField variable identifies the index within ** the vector on the LHS that the virtual term represents. ** ** This only works if the RHS is a simple SELECT (not a compound) that does ** not use window functions. */ - if( pWC->op==TK_AND && pExpr->op==TK_IN && pTerm->iField==0 + 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 #endif + && pWC->op==TK_AND ){ int i; for(i=0; ipLeft); i++){ int idxNew; - idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL); - pWC->a[idxNew].iField = i+1; + idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL|TERM_SLICE); + pWC->a[idxNew].u.x.iField = i+1; exprAnalyze(pSrc, pWC, idxNew); markTermAsChild(pWC, idxNew, idxTerm); } } -#ifdef SQLITE_ENABLE_STAT4 - /* When sqlite_stat4 histogram data is available an operator of the - ** form "x IS NOT NULL" can sometimes be evaluated more efficiently - ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a - ** virtual term of that form. - ** - ** Note that the virtual term must be tagged with TERM_VNULL. +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Add a WO_AUX auxiliary term to the constraint set if the + ** current expression is of the form "column OP expr" where OP + ** is an operator that gets passed into virtual tables but which is + ** not normally optimized for ordinary tables. In other words, OP + ** is one of MATCH, LIKE, GLOB, REGEXP, !=, IS, IS NOT, or NOT NULL. + ** This information is used by the xBestIndex methods of + ** virtual tables. The native query optimizer does not attempt + ** to do anything with MATCH functions. */ - if( pExpr->op==TK_NOTNULL - && pExpr->pLeft->op==TK_COLUMN - && pExpr->pLeft->iColumn>=0 - && !ExprHasProperty(pExpr, EP_FromJoin) - && OptimizationEnabled(db, SQLITE_Stat4) - ){ - Expr *pNewExpr; - Expr *pLeft = pExpr->pLeft; - int idxNew; - WhereTerm *pNewTerm; - - pNewExpr = sqlite3PExpr(pParse, TK_GT, - sqlite3ExprDup(db, pLeft, 0), - sqlite3ExprAlloc(db, TK_NULL, 0, 0)); - - idxNew = whereClauseInsert(pWC, pNewExpr, - TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); - if( idxNew ){ - pNewTerm = &pWC->a[idxNew]; - pNewTerm->prereqRight = 0; - pNewTerm->leftCursor = pLeft->iTable; - pNewTerm->u.leftColumn = pLeft->iColumn; - pNewTerm->eOperator = WO_GT; - markTermAsChild(pWC, idxNew, idxTerm); - pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags |= TERM_COPIED; - pNewTerm->prereqAll = pTerm->prereqAll; + else if( pWC->op==TK_AND ){ + Expr *pRight = 0, *pLeft = 0; + int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight); + while( res-- > 0 ){ + int idxNew; + WhereTerm *pNewTerm; + Bitmask prereqColumn, prereqExpr; + + prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight); + prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); + if( (prereqExpr & prereqColumn)==0 ){ + Expr *pNewExpr; + pNewExpr = sqlite3PExpr(pParse, TK_MATCH, + 0, sqlite3ExprDup(db, pRight, 0)); + if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ + ExprSetProperty(pNewExpr, EP_FromJoin); + pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable; + } + idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew==0 ); + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = prereqExpr; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->u.x.leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_AUX; + pNewTerm->eMatchOp = eOp2; + markTermAsChild(pWC, idxNew, idxTerm); + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; + } + SWAP(Expr*, pLeft, pRight); } } -#endif /* SQLITE_ENABLE_STAT4 */ +#endif /* SQLITE_OMIT_VIRTUALTABLE */ /* Prevent ON clause terms of a LEFT JOIN from being used to drive ** an index for tables to the left of the join. @@ -145447,6 +151615,7 @@ static void exprAnalyze( SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pExpr); pWC->op = op; + assert( pE2!=0 || pExpr==0 ); if( pE2==0 ) return; if( pE2->op!=op ){ whereClauseInsert(pWC, pExpr, 0); @@ -145456,6 +151625,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. */ @@ -145467,6 +151743,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; } @@ -145477,17 +151754,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 ){ @@ -145500,28 +151794,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); @@ -145529,6 +151847,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; } @@ -145571,7 +151898,7 @@ SQLITE_PRIVATE void sqlite3WhereExprAnalyze( */ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( Parse *pParse, /* Parsing context */ - struct SrcList_item *pItem, /* The FROM clause term to process */ + SrcItem *pItem, /* The FROM clause term to process */ WhereClause *pWC /* Xfer function arguments to here */ ){ Table *pTab; @@ -145596,7 +151923,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); @@ -145641,19 +151970,19 @@ 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 */ static int whereLoopResize(sqlite3*, WhereLoop*, int); -/* Test variable that can be set to enable WHERE tracing */ -#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) -/***/ int sqlite3WhereTrace = 0; -#endif - - /* ** Return the estimated number of output rows from a WHERE clause */ @@ -145716,6 +152045,32 @@ SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ return pInner->addrNxt; } +/* +** While generating code for the min/max optimization, after handling +** the aggregate-step call to min() or max(), check to see if any +** additional looping is required. If the output order is such that +** we are certain that the correct answer has already been found, then +** code an OP_Goto to by pass subsequent processing. +** +** Any extra OP_Goto that is coded here is an optimization. The +** correct answer should be obtained regardless. This OP_Goto just +** makes the answer appear faster. +*/ +SQLITE_PRIVATE void sqlite3WhereMinMaxOptEarlyOut(Vdbe *v, WhereInfo *pWInfo){ + WhereLevel *pInner; + int i; + if( !pWInfo->bOrderedInnerLoop ) return; + if( pWInfo->nOBSat==0 ) return; + for(i=pWInfo->nLevel-1; i>=0; i--){ + pInner = &pWInfo->a[i]; + if( (pInner->pWLoop->wsFlags & WHERE_COLUMN_IN)!=0 ){ + sqlite3VdbeGoto(v, pInner->addrNxt); + return; + } + } + sqlite3VdbeGoto(v, pWInfo->iBreak); +} + /* ** Return the VDBE address or label to jump to in order to continue ** immediately with the next row of a WHERE clause. @@ -145825,7 +152180,12 @@ static int whereOrInsert( 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); } @@ -145846,6 +152206,18 @@ static void createMask(WhereMaskSet *pMaskSet, int iCursor){ pMaskSet->ix[pMaskSet->n++] = iCursor; } +/* +** If the right-hand branch of the expression is a TK_COLUMN, then return +** a pointer to the right-hand branch. Otherwise, return NULL. +*/ +static Expr *whereRightSubexprIsColumn(Expr *p){ + p = sqlite3ExprSkipCollateAndLikely(p->pRight); + if( ALWAYS(p!=0) && p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){ + return p; + } + return 0; +} + /* ** Advance to the next WhereTerm that matches according to the criteria ** established when the pScan object was initialized by whereScanInit(). @@ -145865,10 +152237,12 @@ 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.leftColumn==iColumn + && pTerm->u.x.leftColumn==iColumn && (iColumn!=XN_EXPR || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft, pScan->pIdxExpr,iCur)==0) @@ -145876,8 +152250,7 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ ){ if( (pTerm->eOperator & WO_EQUIV)!=0 && pScan->nEquivaiCur) - && (pX = sqlite3ExprSkipCollateAndLikely(pTerm->pExpr->pRight))->op - ==TK_COLUMN + && (pX = whereRightSubexprIsColumn(pTerm->pExpr))!=0 ){ int j; for(j=0; jnEquiv; j++){ @@ -145909,7 +152282,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] ){ @@ -145918,6 +152292,18 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ } pScan->pWC = pWC; pScan->k = k+1; +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace & 0x20000 ){ + int ii; + sqlite3DebugPrintf("SCAN-TERM %p: nEquiv=%d", + pTerm, pScan->nEquiv); + for(ii=0; iinEquiv; ii++){ + sqlite3DebugPrintf(" {%d:%d}", + pScan->aiCur[ii], pScan->aiColumn[ii]); + } + sqlite3DebugPrintf("\n"); + } +#endif return pTerm; } } @@ -145984,16 +152370,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; @@ -146073,7 +152459,8 @@ static int findIndexCol( for(i=0; inExpr; i++){ Expr *p = sqlite3ExprSkipCollateAndLikely(pList->a[i].pExpr); - if( p->op==TK_COLUMN + if( ALWAYS(p!=0) + && (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) && p->iColumn==pIdx->aiColumn[iCol] && p->iTable==iBase ){ @@ -146137,7 +152524,9 @@ static int isDistinctRedundant( */ for(i=0; inExpr; i++){ Expr *p = sqlite3ExprSkipCollateAndLikely(pDistinct->a[i].pExpr); - if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1; + if( NEVER(p==0) ) continue; + if( p->op!=TK_COLUMN && p->op!=TK_AGG_COLUMN ) continue; + if( p->iTable==iBase && p->iColumn<0 ) return 1; } /* Loop through all indices on the table, checking each to see if it makes @@ -146155,6 +152544,7 @@ static int isDistinctRedundant( */ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( !IsUniqueIndex(pIdx) ) continue; + if( pIdx->pPartIdxWhere ) continue; for(i=0; inKeyCol; i++){ if( 0==sqlite3WhereFindTerm(pWC, iBase, i, ~(Bitmask)0, WO_EQ, pIdx) ){ if( findIndexCol(pParse, pDistinct, iBase, pIdx, i)<0 ) break; @@ -146209,14 +152599,14 @@ static void translateColumnToCopy( pOp->p2 = pOp->p3; pOp->p3 = 0; }else if( pOp->opcode==OP_Rowid ){ - if( iAutoidxCur ){ - pOp->opcode = OP_Sequence; - pOp->p1 = iAutoidxCur; - }else{ + pOp->opcode = OP_Sequence; + pOp->p1 = iAutoidxCur; +#ifdef SQLITE_ALLOW_ROWID_IN_VIEW + if( iAutoidxCur==0 ){ pOp->opcode = OP_Null; - pOp->p1 = 0; pOp->p3 = 0; } +#endif } } } @@ -146232,12 +152622,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", @@ -146273,9 +152665,9 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ ** index existed. */ static int termCanDriveIndex( - WhereTerm *pTerm, /* WHERE clause term to check */ - struct SrcList_item *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; @@ -146290,8 +152682,9 @@ static int termCanDriveIndex( return 0; } if( (pTerm->prereqRight & notReady)!=0 ) return 0; - if( pTerm->u.leftColumn<0 ) return 0; - aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity; + 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; testcase( pTerm->pExpr->op==TK_IS ); return 1; @@ -146305,11 +152698,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 */ - struct SrcList_item *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 */ @@ -146332,7 +152725,7 @@ static void constructAutomaticIndex( u8 sentWarning = 0; /* True if a warnning has been issued */ Expr *pPartial = 0; /* Partial Index Expression */ int iContinue = 0; /* Jump here to skip excluded rows */ - struct SrcList_item *pTabItem; /* FROM clause term being indexed */ + SrcItem *pTabItem; /* FROM clause term being indexed */ int addrCounter = 0; /* Address where integer counter is initialized */ int regBase; /* Array of registers where record is assembled */ @@ -146351,25 +152744,28 @@ 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 + && ((pSrc->fg.jointype&JT_LEFT)==0 || ExprHasProperty(pExpr,EP_FromJoin)) + && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) + ){ pPartial = sqlite3ExprAnd(pParse, pPartial, sqlite3ExprDup(pParse->db, pExpr, 0)); } if( termCanDriveIndex(pTerm, pSrc, notReady) ){ - int iCol = pTerm->u.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 ){ @@ -146381,7 +152777,7 @@ static void constructAutomaticIndex( } } } - assert( nKeyCol>0 ); + assert( nKeyCol>0 || pParse->db->mallocFailed ); pLoop->u.btree.nEq = pLoop->nLTerm = nKeyCol; pLoop->wsFlags = WHERE_COLUMN_EQ | WHERE_IDX_ONLY | WHERE_INDEXED | WHERE_AUTO_INDEX; @@ -146415,14 +152811,17 @@ static void constructAutomaticIndex( idxCols = 0; for(pTerm=pWC->a; pTermu.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 ){ Expr *pX = pTerm->pExpr; idxCols |= cMask; - pIdx->aiColumn[n] = pTerm->u.leftColumn; + pIdx->aiColumn[n] = pTerm->u.x.leftColumn; pColl = sqlite3ExprCompareCollSeq(pParse, pX); assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */ pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; @@ -146458,6 +152857,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]; @@ -146480,6 +152883,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); @@ -146506,22 +152913,146 @@ static void constructAutomaticIndex( } #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 + && sqlite3ExprIsTableConstant(pExpr, iCur) + ){ + 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 ){ + pLevel = &pWInfo->a[iLevel]; + 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 */ - struct SrcList_item *pSrc, /* The FROM clause term that is the vtab */ - ExprList *pOrderBy, /* The ORDER BY clause */ + SrcItem *pSrc, /* The FROM clause term that is the vtab */ 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; @@ -146530,10 +153061,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) ); @@ -146543,8 +153085,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.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 @@ -146556,11 +153111,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); + } } } @@ -146568,46 +153159,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.leftColumn>=(-1) ); - pIdxCons[j].iColumn = pTerm->u.leftColumn; + 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) ){ @@ -146640,17 +153220,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() @@ -146672,7 +153277,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 ){ @@ -147366,10 +153973,11 @@ 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.leftColumn); + pTerm->leftCursor, pTerm->u.x.leftColumn); }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){ - sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%lld", + sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx", pTerm->u.pOrInfo->indexable); }else{ sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); @@ -147383,8 +153991,8 @@ SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx", pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight); } - if( pTerm->iField ){ - sqlite3DebugPrintf(" iField=%d", pTerm->iField); + if( (pTerm->eOperator & (WO_OR|WO_AND))==0 && pTerm->u.x.iField ){ + sqlite3DebugPrintf(" iField=%d", pTerm->u.x.iField); } if( pTerm->iParent>=0 ){ sqlite3DebugPrintf(" iParent=%d", pTerm->iParent); @@ -147414,7 +154022,7 @@ SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){ SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ WhereInfo *pWInfo = pWC->pWInfo; int nb = 1+(pWInfo->pTabList->nSrc+3)/4; - struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab; + SrcItem *pItem = pWInfo->pTabList->a + p->iTab; Table *pTab = pItem->pTab; Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, @@ -147445,9 +154053,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 ){ @@ -147518,7 +154126,7 @@ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ whereLoopClearUnion(db, pTo); if( whereLoopResize(db, pTo, pFrom->nLTerm) ){ - memset(&pTo->u, 0, sizeof(pTo->u)); + memset(pTo, 0, WHERE_LOOP_XFER_SZ); return SQLITE_NOMEM_BKPT; } memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ); @@ -147547,7 +154155,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); } } @@ -147561,10 +154170,22 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ sqlite3DbFreeNN(db, pWInfo); } +/* Undo all Expr node modifications +*/ +static void whereUndoExprMods(WhereInfo *pWInfo){ + while( pWInfo->pExprMods ){ + WhereExprMod *p = pWInfo->pExprMods; + pWInfo->pExprMods = p->pNext; + memcpy(p->pExpr, &p->orig, sizeof(p->orig)); + sqlite3DbFree(pWInfo->pParse->db, p); + } +} + /* ** 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 @@ -147587,11 +154208,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--){ @@ -147607,8 +154225,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 @@ -147629,16 +154247,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); } } } @@ -147893,11 +154515,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; @@ -147905,6 +154527,13 @@ 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". */ + 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. */ @@ -147932,7 +154561,9 @@ static void whereLoopOutputAdjust( } } } - if( pLoop->nOut > nRow-iReduce ) pLoop->nOut = nRow - iReduce; + if( pLoop->nOut > nRow-iReduce ){ + pLoop->nOut = nRow - iReduce; + } } /* @@ -147969,9 +154600,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; @@ -148025,7 +154659,7 @@ static int whereRangeVectorLen( */ static int whereLoopAddBtreeIndex( WhereLoopBuilder *pBuilder, /* The WhereLoop factory */ - struct SrcList_item *pSrc, /* FROM clause term being analyzed */ + SrcItem *pSrc, /* FROM clause term being analyzed */ Index *pProbe, /* An index on pSrc */ LogEst nInMul /* log(Number of iterations due to IN) */ ){ @@ -148051,9 +154685,9 @@ static int whereLoopAddBtreeIndex( pNew = pBuilder->pNew; if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; - WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d\n", + WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d, rRun=%d\n", pProbe->pTable->zName,pProbe->zName, - pNew->u.btree.nEq, pNew->nSkip)); + pNew->u.btree.nEq, pNew->nSkip, pNew->rRun)); assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 ); assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); @@ -148066,6 +154700,8 @@ static int whereLoopAddBtreeIndex( if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); assert( pNew->u.btree.nEqnColumn ); + assert( pNew->u.btree.nEqnKeyCol + || pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY ); saved_nEq = pNew->u.btree.nEq; saved_nBtm = pNew->u.btree.nBtm; @@ -148130,7 +154766,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) ); @@ -148147,8 +154783,8 @@ static int whereLoopAddBtreeIndex( /* "x IN (value, value, ...)" */ nIn = sqlite3LogEst(pExpr->x.pList->nExpr); } - if( pProbe->hasStat1 ){ - LogEst M, logK, safetyMargin; + if( pProbe->hasStat1 && rLogSize>=10 ){ + LogEst M, logK, x; /* Let: ** N = the total number of rows in the table ** K = the number of entries on the RHS of the IN operator @@ -148166,20 +154802,30 @@ static int whereLoopAddBtreeIndex( ** a safety margin of 2 (LogEst: 10) that favors using the IN operator ** with the index, as using an index has better worst-case behavior. ** If we do not have real sqlite_stat1 data, always prefer to use - ** the index. + ** the index. Do not bother with this optimization on very small + ** tables (less than 2 rows) as it is pointless in that case. */ M = pProbe->aiRowLogEst[saved_nEq]; logK = estLog(nIn); - safetyMargin = 10; /* TUNING: extra weight for indexed IN */ - if( M + logK + safetyMargin < nIn + rLogSize ){ + /* TUNING v----- 10 to bias toward indexed IN */ + x = M + logK + 10 - (nIn + rLogSize); + if( x>=0 ){ WHERETRACE(0x40, - ("Scan preferred over IN operator on column %d of \"%s\" (%d<%d)\n", - saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize)); - continue; + ("IN operator (N=%d M=%d logK=%d nIn=%d rLogSize=%d x=%d) " + "prefers indexed lookup\n", + saved_nEq, M, logK, nIn, rLogSize, x)); + }else if( nInMul<2 && OptimizationEnabled(db, SQLITE_SeekScan) ){ + WHERETRACE(0x40, + ("IN operator (N=%d M=%d logK=%d nIn=%d rLogSize=%d x=%d" + " nInMul=%d) prefers skip-scan\n", + saved_nEq, M, logK, nIn, rLogSize, x, nInMul)); + pNew->wsFlags |= WHERE_IN_SEEKSCAN; }else{ WHERETRACE(0x40, - ("IN operator preferred on column %d of \"%s\" (%d>=%d)\n", - saved_nEq, pProbe->zName, M+logK+10, nIn+rLogSize)); + ("IN operator (N=%d M=%d logK=%d nIn=%d rLogSize=%d x=%d" + " nInMul=%d) prefers normal scan\n", + saved_nEq, M, logK, nIn, rLogSize, x, nInMul)); + continue; } } pNew->wsFlags |= WHERE_COLUMN_IN; @@ -148198,6 +154844,7 @@ static int whereLoopAddBtreeIndex( pNew->wsFlags |= WHERE_UNQ_WANTED; } } + if( scan.iEquiv>1 ) pNew->wsFlags |= WHERE_TRANSCONS; }else if( eOp & WO_ISNULL ){ pNew->wsFlags |= WHERE_COLUMN_NULL; }else if( eOp & (WO_GT|WO_GE) ){ @@ -148210,7 +154857,7 @@ static int whereLoopAddBtreeIndex( pBtm = pTerm; pTop = 0; if( pTerm->wtFlags & TERM_LIKEOPT ){ - /* Range contraints that come from the LIKE optimization are + /* Range constraints that come from the LIKE optimization are ** always used in pairs. */ pTop = &pTerm[1]; assert( (pTop-(pTerm->pWC->a))pWC->nTerm ); @@ -148259,8 +154906,8 @@ static int whereLoopAddBtreeIndex( tRowcnt nOut = 0; if( nInMul==0 && pProbe->nSample - && pNew->u.btree.nEq<=pProbe->nSampleCol - && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect)) + && ALWAYS(pNew->u.btree.nEq<=pProbe->nSampleCol) + && ((eOp & WO_IN)==0 || ExprUseXList(pTerm->pExpr)) && OptimizationEnabled(db, SQLITE_Stat4) ){ Expr *pExpr = pTerm->pExpr; @@ -148341,6 +154988,8 @@ static int whereLoopAddBtreeIndex( if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 && pNew->u.btree.nEqnColumn + && (pNew->u.btree.nEqnKeyCol || + pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY) ){ whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); } @@ -148421,6 +155070,7 @@ static int indexMightHelpWithOrderBy( if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0; for(ii=0; iinExpr; ii++){ Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr); + if( NEVER(pExpr==0) ) continue; if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){ if( pExpr->iColumn<0 ) return 1; for(jj=0; jjnKeyCol; jj++){ @@ -148458,9 +155108,10 @@ 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 ){ return 1; } @@ -148514,13 +155165,12 @@ static int whereLoopAddBtree( LogEst aiRowEstPk[2]; /* The aiRowLogEst[] value for the sPk index */ i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */ SrcList *pTabList; /* The FROM clause */ - struct SrcList_item *pSrc; /* The FROM clause btree term to add */ + SrcItem *pSrc; /* The FROM clause btree term to add */ WhereLoop *pNew; /* Template WhereLoop object */ int rc = SQLITE_OK; /* Return code */ 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 */ @@ -148532,9 +155182,10 @@ static int whereLoopAddBtree( pWC = pBuilder->pWC; assert( !IsVirtual(pSrc->pTab) ); - if( pSrc->pIBIndex ){ + if( pSrc->fg.isIndexedBy ){ + assert( pSrc->fg.isCte==0 ); /* An INDEXED BY clause specifies a particular index to use */ - pProbe = pSrc->pIBIndex; + pProbe = pSrc->u2.pIBIndex; }else if( !HasRowid(pTab) ){ pProbe = pTab->pIndex; }else{ @@ -148563,22 +155214,23 @@ static int whereLoopAddBtree( pProbe = &sPk; } rSize = pTab->nRowLogEst; - rLogSize = estLog(rSize); #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* Automatic indexes */ if( !pBuilder->pOrSet /* Not part of an OR optimization */ && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 - && pSrc->pIBIndex==0 /* Has no INDEXED BY clause */ + && !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */ && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */ && HasRowid(pTab) /* Not WITHOUT ROWID table. (FIXME: Why not?) */ && !pSrc->fg.isCorrelated /* Not a correlated subquery */ && !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) ){ @@ -148596,7 +155248,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; @@ -148620,7 +155272,7 @@ static int whereLoopAddBtree( /* Loop over all indices. If there was an INDEXED BY clause, then only ** consider index pProbe. */ for(; rc==SQLITE_OK && pProbe; - pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++ + pProbe=(pSrc->fg.isIndexedBy ? 0 : pProbe->pNext), iSortIdx++ ){ int isLeft = (pSrc->fg.jointype & JT_OUTER)!=0; if( pProbe->pPartIdxWhere!=0 @@ -148652,8 +155304,23 @@ static int whereLoopAddBtree( /* Full table scan */ pNew->iSortIdx = b ? iSortIdx : 0; - /* TUNING: Cost of full table scan is (N*3.0). */ + /* TUNING: Cost of full table scan is 3.0*N. The 3.0 factor is an + ** extra cost designed to discourage the use of full table scans, + ** since index lookups have better worst-case performance if our + ** stat guesses are wrong. Reduce the 3.0 penalty slightly + ** (to 2.75) if we have valid STAT4 information for the table. + ** At 2.75, a full table scan is preferred over using an index on + ** a column with just two distinct values where each value has about + ** an equal number of appearances. Without STAT4 data, we still want + ** to use an index in that case, since the constraint might be for + ** the scarcer of the two values, and in that case an index lookup is + ** better. + */ +#ifdef SQLITE_ENABLE_STAT4 + pNew->rRun = rSize + 16 - 2*((pTab->tabFlags & TF_HasStat4)!=0); +#else pNew->rRun = rSize + 16; +#endif ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); rc = whereLoopInsert(pBuilder, pNew); @@ -148743,6 +155410,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 @@ -148770,9 +155446,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; @@ -148780,7 +155458,7 @@ static int whereLoopAddVirtualOne( int rc = SQLITE_OK; WhereLoop *pNew = pBuilder->pNew; Parse *pParse = pBuilder->pWInfo->pParse; - struct SrcList_item *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab]; + SrcItem *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab]; int nConstraint = pIdxInfo->nConstraint; assert( (mUsable & mPrereq)==mPrereq ); @@ -148795,6 +155473,7 @@ static int whereLoopAddVirtualOne( pIdxCons->usable = 0; if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight && (pTerm->eOperator & mExclude)==0 + && (pbRetryLimit || !isLimitTerm(pTerm)) ){ pIdxCons->usable = 1; } @@ -148810,6 +155489,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); @@ -148827,8 +155507,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 @@ -148873,6 +155558,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; + } } } @@ -148917,11 +155617,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]; @@ -148938,6 +155646,73 @@ 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; +} + /* ** Add all WhereLoop objects for a table of the join identified by ** pBuilder->pNew->iTab. That table is guaranteed to be a virtual table. @@ -148972,13 +155747,14 @@ static int whereLoopAddVirtual( WhereInfo *pWInfo; /* WHERE analysis context */ Parse *pParse; /* The parsing context */ WhereClause *pWC; /* The WHERE clause */ - struct SrcList_item *pSrc; /* The FROM clause term to search */ + SrcItem *pSrc; /* The FROM clause term to search */ sqlite3_index_info *p; /* Object to pass to xBestIndex() */ int nConstraint; /* Number of constraints in p */ int bIn; /* True if plan uses IN(...) operator */ 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; @@ -148987,8 +155763,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; @@ -148996,14 +155771,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) @@ -149021,7 +155804,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 ){ @@ -149048,7 +155831,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; @@ -149061,7 +155844,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; } @@ -149071,12 +155854,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; } @@ -149100,7 +155883,7 @@ static int whereLoopAddOr( WhereClause tempWC; WhereLoopBuilder sSubBuild; WhereOrSet sSum, sCur; - struct SrcList_item *pItem; + SrcItem *pItem; pWC = pBuilder->pWC; pWCEnd = pWC->a + pWC->nTerm; @@ -149120,7 +155903,6 @@ static int whereLoopAddOr( int i, j; sSubBuild = *pBuilder; - sSubBuild.pOrderBy = 0; sSubBuild.pOrSet = &sCur; WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm)); @@ -149132,6 +155914,7 @@ static int whereLoopAddOr( tempWC.pOuter = pWC; tempWC.op = TK_AND; tempWC.nTerm = 1; + tempWC.nBase = 1; tempWC.a = pOrTerm; sSubBuild.pWC = &tempWC; }else{ @@ -149156,7 +155939,9 @@ static int whereLoopAddOr( if( rc==SQLITE_OK ){ rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable); } - assert( rc==SQLITE_OK || rc==SQLITE_DONE || sCur.n==0 ); + assert( rc==SQLITE_OK || rc==SQLITE_DONE || sCur.n==0 + || rc==SQLITE_NOMEM ); + testcase( rc==SQLITE_NOMEM && sCur.n>0 ); testcase( rc==SQLITE_DONE ); if( sCur.n==0 ){ sSum.n = 0; @@ -149216,8 +156001,8 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ Bitmask mPrior = 0; int iTab; SrcList *pTabList = pWInfo->pTabList; - struct SrcList_item *pItem; - struct SrcList_item *pEnd = &pTabList->a[pWInfo->nLevel]; + SrcItem *pItem; + SrcItem *pEnd = &pTabList->a[pWInfo->nLevel]; sqlite3 *db = pWInfo->pParse->db; int rc = SQLITE_OK; WhereLoop *pNew; @@ -149240,7 +156025,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ - struct SrcList_item *p; + SrcItem *p; for(p=&pItem[1]; pfg.jointype & (JT_LEFT|JT_CROSS)) ){ mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); @@ -149384,7 +156169,8 @@ static i8 wherePathSatisfiesOrderBy( for(i=0; ia[i].pExpr); - if( pOBExpr->op!=TK_COLUMN ) continue; + if( NEVER(pOBExpr==0) ) continue; + if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) continue; if( pOBExpr->iTable!=iCur ) continue; pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn, ~ready, eqOpMask, 0); @@ -149424,6 +156210,10 @@ static i8 wherePathSatisfiesOrderBy( assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); assert( pIndex->aiColumn[nColumn-1]==XN_ROWID || !HasRowid(pIndex->pTable)); + /* All relevant terms of the index must also be non-NULL in order + ** for isOrderDistinct to be true. So the isOrderDistint value + ** computed here might be a false positive. Corrections will be + ** made at tag-20210426-1 below */ isOrderDistinct = IsUniqueIndex(pIndex) && (pLoop->wsFlags & WHERE_SKIPSCAN)==0; } @@ -149491,14 +156281,18 @@ static i8 wherePathSatisfiesOrderBy( } /* An unconstrained column that might be NULL means that this - ** WhereLoop is not well-ordered + ** WhereLoop is not well-ordered. tag-20210426-1 */ - if( isOrderDistinct - && iColumn>=0 - && j>=pLoop->u.btree.nEq - && pIndex->pTable->aCol[iColumn].notNull==0 - ){ - isOrderDistinct = 0; + if( isOrderDistinct ){ + if( iColumn>=0 + && j>=pLoop->u.btree.nEq + && pIndex->pTable->aCol[iColumn].notNull==0 + ){ + isOrderDistinct = 0; + } + if( iColumn==XN_EXPR ){ + isOrderDistinct = 0; + } } /* Find the ORDER BY term that corresponds to the j-th column @@ -149510,9 +156304,10 @@ static i8 wherePathSatisfiesOrderBy( pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr); testcase( wctrlFlags & WHERE_GROUPBY ); testcase( wctrlFlags & WHERE_DISTINCTBY ); + if( NEVER(pOBExpr==0) ) continue; if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0; if( iColumn>=XN_ROWID ){ - if( pOBExpr->op!=TK_COLUMN ) continue; + if( pOBExpr->op!=TK_COLUMN && pOBExpr->op!=TK_AGG_COLUMN ) continue; if( pOBExpr->iTable!=iCur ) continue; if( pOBExpr->iColumn!=iColumn ) continue; }else{ @@ -149591,7 +156386,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(i0 && 66==sqlite3LogEst(100) ); rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; rSortCost = nRow + rScale + 16; /* Multiple by log(M) where M is the number of output rows. - ** Use the LIMIT for M if it is smaller */ + ** Use the LIMIT for M if it is smaller. Or if this sort is for + ** a DISTINCT operator, M will be the number of distinct output + ** rows, so fudge it downwards a bit. + */ if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimitiLimit; + }else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){ + /* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT + ** reduces the number of output rows by a factor of 2 */ + if( nRow>10 ){ nRow -= 10; assert( 10==sqlite3LogEst(2) ); } } rSortCost += estLog(nRow); return rSortCost; @@ -150085,7 +156888,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ */ static int whereShortCut(WhereLoopBuilder *pBuilder){ WhereInfo *pWInfo; - struct SrcList_item *pItem; + SrcItem *pItem; WhereClause *pWC; WhereTerm *pTerm; WhereLoop *pLoop; @@ -150093,6 +156896,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ int j; Table *pTab; Index *pIdx; + WhereScan scan; pWInfo = pBuilder->pWInfo; if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; @@ -150106,7 +156910,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; @@ -150125,7 +156930,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; @@ -150154,8 +156960,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; } @@ -150210,6 +157022,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 @@ -150304,6 +157260,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 */ @@ -150338,13 +157295,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 @@ -150387,11 +157337,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); @@ -150404,7 +157361,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); @@ -150412,7 +157368,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")); @@ -150450,6 +157408,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 @@ -150463,7 +157422,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)) ){ @@ -150473,7 +157432,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 ){ @@ -150544,9 +157508,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ pWInfo->revMask = ALLBITS; } - if( pParse->nErr || NEVER(db->mallocFailed) ){ + if( pParse->nErr ){ goto whereBeginError; } + assert( db->mallocFailed==0 ); #ifdef WHERETRACE_ENABLED if( sqlite3WhereTrace ){ sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut); @@ -150574,83 +157539,36 @@ 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: - ** - ** 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); + /* Attempt to omit tables from a join that do not affect the result. + ** See the comment on whereOmitNoopJoin() for further information. ** - ** 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 - && pResultSet!=0 /* guarantees condition (1) above */ + && pResultSet!=0 /* these two combine to guarantee */ + && 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; - struct SrcList_item *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"); @@ -150705,13 +157623,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( for(ii=0, pLevel=pWInfo->a; iia[pLevel->iFrom]; 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 @@ -150737,6 +157655,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 @@ -150800,6 +157719,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0 && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0 && (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0 + && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED ){ @@ -150835,15 +157755,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 ); @@ -150857,11 +157782,14 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( /* Done. */ VdbeModuleComment((v, "Begin WHERE-core")); + pWInfo->iEndWhere = sqlite3VdbeCurrentAddr(v); return pWInfo; /* Jump here if malloc fails */ whereBeginError: if( pWInfo ){ + testcase( pWInfo->pExprMods!=0 ); + whereUndoExprMods(pWInfo); pParse->nQueryLoop = pWInfo->savedNQueryLoop; whereInfoFree(db, pWInfo); } @@ -150900,6 +157828,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ WhereLoop *pLoop; SrcList *pTabList = pWInfo->pTabList; sqlite3 *db = pParse->db; + int iEnd = sqlite3VdbeCurrentAddr(v); /* Generate loop termination code. */ @@ -150952,15 +157881,19 @@ 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); for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ + assert( sqlite3VdbeGetOp(v, pIn->addrInTop+1)->opcode==OP_IsNull + || pParse->db->mallocFailed ); sqlite3VdbeJumpHere(v, pIn->addrInTop+1); if( pIn->eEndLoopOp!=OP_Noop ){ if( pIn->nPrefix ){ - assert( pLoop->wsFlags & WHERE_IN_EARLYOUT ); + int bEarlyOut = + (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 + && (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0; if( pLevel->iLeftJoin ){ /* For LEFT JOIN queries, cursor pIn->iCur may not have been ** opened yet. This occurs for WHERE clauses such as @@ -150971,16 +157904,19 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ ** jump over the OP_Next or OP_Prev instruction about to ** be coded. */ sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur, - sqlite3VdbeCurrentAddr(v) + 2 + - ((pLoop->wsFlags & WHERE_VIRTUALTABLE)==0) - ); + sqlite3VdbeCurrentAddr(v) + 2 + bEarlyOut); VdbeCoverage(v); } - if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ + if( bEarlyOut ){ sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, sqlite3VdbeCurrentAddr(v)+2, pIn->iBase, pIn->nPrefix); VdbeCoverage(v); + /* Retarget the OP_IsNull against the left operand of IN so + ** it jumps past the OP_IfNoHope. This is because the + ** OP_IsNull also bypasses the OP_Affinity opcode that is + ** required by OP_IfNoHope. */ + sqlite3VdbeJumpHere(v, pIn->addrInTop+1); } } sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); @@ -151014,8 +157950,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 ){ @@ -151037,9 +157979,9 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ assert( pWInfo->nLevel<=pTabList->nSrc ); for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){ int k, last; - VdbeOp *pOp; + VdbeOp *pOp, *pLastOp; Index *pIdx = 0; - struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; + SrcItem *pTabItem = &pTabList->a[pLevel->iFrom]; Table *pTab = pTabItem->pTab; assert( pTab!=0 ); pLoop = pLevel->pWLoop; @@ -151062,7 +158004,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; @@ -151092,23 +158034,34 @@ 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 - && (pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable)) && !db->mallocFailed ){ - last = sqlite3VdbeCurrentAddr(v); - k = pLevel->addrBody; + if( pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable) ){ + last = iEnd; + }else{ + last = pWInfo->iEndWhere; + } + k = pLevel->addrBody + 1; #ifdef SQLITE_DEBUG if( db->flags & SQLITE_VdbeAddopTrace ){ printf("TRANSLATE opcodes in range %d..%d\n", k, last-1); } + /* Proof that the "+1" on the k value above is safe */ + pOp = sqlite3VdbeGetOp(v, k - 1); + assert( pOp->opcode!=OP_Column || pOp->p1!=pLevel->iTabCur ); + assert( pOp->opcode!=OP_Rowid || pOp->p1!=pLevel->iTabCur ); + assert( pOp->opcode!=OP_IfNullRow || pOp->p1!=pLevel->iTabCur ); #endif pOp = sqlite3VdbeGetOp(v, k); - for(; kp1!=pLevel->iTabCur ) continue; - if( pOp->opcode==OP_Column + pLastOp = pOp + (last - k); + assert( pOp<=pLastOp ); + do{ + if( pOp->p1!=pLevel->iTabCur ){ + /* no-op */ + }else if( pOp->opcode==OP_Column #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC || pOp->opcode==OP_Offset #endif @@ -151139,23 +158092,19 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); } - } +#ifdef SQLITE_DEBUG + k++; +#endif + }while( (++pOp)flags & SQLITE_VdbeAddopTrace ) printf("TRANSLATE complete\n"); #endif } } - /* Undo all Expr node modifications */ - while( pWInfo->pExprMods ){ - WhereExprMod *p = pWInfo->pExprMods; - pWInfo->pExprMods = p->pNext; - memcpy(p->pExpr, &p->orig, sizeof(p->orig)); - sqlite3DbFree(db, p); - } - /* Final cleanup */ + if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo); pParse->nQueryLoop = pWInfo->savedNQueryLoop; whereInfoFree(db, pWInfo); return; @@ -151746,7 +158695,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} \ } @@ -151754,7 +158703,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} \ } @@ -151763,7 +158712,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} \ } @@ -151953,6 +158902,7 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ case TK_AGG_FUNCTION: case TK_COLUMN: { int iCol = -1; + if( pParse->db->mallocFailed ) return WRC_Abort; if( p->pSub ){ int i; for(i=0; ipSub->nExpr; i++){ @@ -152062,14 +159012,17 @@ static ExprList *exprListAppendList( int i; int nInit = pList ? pList->nExpr : 0; for(i=0; inExpr; i++){ - Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0); + sqlite3 *db = pParse->db; + Expr *pDup = sqlite3ExprDup(db, pAppend->a[i].pExpr, 0); assert( pDup==0 || !ExprHasProperty(pDup, EP_MemToken) ); - if( bIntToNull && pDup ){ + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + break; + } + 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); @@ -152100,6 +159053,15 @@ static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){ return WRC_Continue; } +static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_AGG_FUNCTION && pExpr->pAggInfo==0 ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3ErrorMsg(pWalker->pParse, + "misuse of aggregate: %s()", pExpr->u.zToken); + } + return WRC_Continue; +} + /* ** If the SELECT statement passed as the second argument does not invoke ** any SQL window functions, this function is a no-op. Otherwise, it @@ -152109,7 +159071,7 @@ static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){ */ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ int rc = SQLITE_OK; - if( p->pWin && p->pPrior==0 && (p->selFlags & SF_WinRewrite)==0 ){ + if( p->pWin && p->pPrior==0 && ALWAYS((p->selFlags & SF_WinRewrite)==0) ){ Vdbe *v = sqlite3GetVdbe(pParse); sqlite3 *db = pParse->db; Select *pSub = 0; /* The subquery */ @@ -152133,6 +159095,11 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ } sqlite3AggInfoPersistWalkerInit(&w, pParse); sqlite3WalkSelect(&w, p); + if( (p->selFlags & SF_Aggregate)==0 ){ + w.xExprCallback = disallowAggregatesInOrderByCb; + w.xSelectCallback = 0; + sqlite3WalkExprList(&w, p->pOrderBy); + } p->pSrc = 0; p->pWhere = 0; @@ -152177,7 +159144,9 @@ 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) ); + 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); @@ -152214,11 +159183,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 ){ @@ -152241,15 +159213,14 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ sqlite3SelectDelete(db, pSub); } if( db->mallocFailed ) rc = SQLITE_NOMEM; - sqlite3DbFree(db, pTab); - } - if( rc ){ - if( pParse->nErr==0 ){ - assert( pParse->db->mallocFailed ); - sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM); - } + /* 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); } + + assert( rc==SQLITE_OK || pParse->nErr!=0 ); return rc; } @@ -152469,15 +159440,19 @@ SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ ** SELECT, or (b) the windows already linked use a compatible window frame. */ SQLITE_PRIVATE void sqlite3WindowLink(Select *pSel, Window *pWin){ - if( pSel!=0 - && (0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0)) - ){ - pWin->pNextWin = pSel->pWin; - if( pSel->pWin ){ - pSel->pWin->ppThis = &pWin->pNextWin; + if( pSel ){ + if( 0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0) ){ + pWin->pNextWin = pSel->pWin; + if( pSel->pWin ){ + pSel->pWin->ppThis = &pWin->pNextWin; + } + pSel->pWin = pWin; + pWin->ppThis = &pSel->pWin; + }else{ + if( sqlite3ExprListCompare(pWin->pPartition, pSel->pWin->pPartition,-1) ){ + pSel->selFlags |= SF_MultiPart; + } } - pSel->pWin = pWin; - pWin->ppThis = &pSel->pWin; } } @@ -152486,7 +159461,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; @@ -152558,8 +159538,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; @@ -152630,6 +159613,7 @@ static void windowCheckValue(Parse *pParse, int reg, int eCond){ VdbeCoverageIf(v, eCond==2); } sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg); + sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC); VdbeCoverageNeverNullIf(v, eCond==0); /* NULL case captured by */ VdbeCoverageNeverNullIf(v, eCond==1); /* the OP_MustBeInt */ VdbeCoverageNeverNullIf(v, eCond==2); @@ -152646,7 +159630,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); } @@ -152724,6 +159710,7 @@ struct WindowCodeArg { int regGosub; /* Register used with OP_Gosub(addrGosub) */ int regArg; /* First in array of accumulator registers */ int eDelete; /* See above */ + int regRowid; WindowCsrAndReg start; WindowCsrAndReg current; @@ -152830,6 +159817,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); @@ -152840,15 +159828,16 @@ static void windowAggStep( } if( pWin->bExprArgs ){ - int iStart = sqlite3VdbeCurrentAddr(v); - VdbeOp *pOp, *pEnd; + 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); - pEnd = sqlite3VdbeGetOp(v, -1); - for(pOp=sqlite3VdbeGetOp(v, iStart); pOp<=pEnd; pOp++){ + for(iEnd=sqlite3VdbeCurrentAddr(v); iOpopcode==OP_Column && pOp->p1==pWin->iEphCsr ){ pOp->p1 = csr; } @@ -152857,6 +159846,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); } @@ -153042,6 +160032,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 ){ @@ -153207,7 +160198,7 @@ static void windowIfNewPeer( ** if( csr1.peerVal - regVal <= csr2.peerVal ) goto lbl; ** ** A special type of arithmetic is used such that if csr1.peerVal is not -** a numeric type (real or integer), then the result of the addition addition +** a numeric type (real or integer), then the result of the addition ** or subtraction is a a copy of csr1.peerVal. */ static void windowCodeRangeTest( @@ -153226,6 +160217,12 @@ static void windowCodeRangeTest( int regString = ++pParse->nMem; /* Reg. for constant value '' */ int arith = OP_Add; /* OP_Add or OP_Subtract */ int addrGe; /* Jump destination */ + int addrDone = sqlite3VdbeMakeLabel(pParse); /* Address past OP_Ge */ + CollSeq *pColl; + + /* Read the peer-value from each cursor into a register */ + windowReadPeerValues(p, csr1, reg1); + windowReadPeerValues(p, csr2, reg2); assert( op==OP_Ge || op==OP_Gt || op==OP_Le ); assert( pOrderBy && pOrderBy->nExpr==1 ); @@ -153238,34 +160235,11 @@ static void windowCodeRangeTest( arith = OP_Subtract; } - /* Read the peer-value from each cursor into a register */ - windowReadPeerValues(p, csr1, reg1); - windowReadPeerValues(p, csr2, reg2); - VdbeModuleComment((v, "CodeRangeTest: if( R%d %s R%d %s R%d ) goto lbl", reg1, (arith==OP_Add ? "+" : "-"), regVal, ((op==OP_Ge) ? ">=" : (op==OP_Le) ? "<=" : (op==OP_Gt) ? ">" : "<"), reg2 )); - /* Register reg1 currently contains csr1.peerVal (the peer-value from csr1). - ** This block adds (or subtracts for DESC) the numeric value in regVal - ** from it. Or, if reg1 is not numeric (it is a NULL, a text value or a blob), - ** then leave reg1 as it is. In pseudo-code, this is implemented as: - ** - ** if( reg1>='' ) goto addrGe; - ** reg1 = reg1 +/- regVal - ** addrGe: - ** - ** Since all strings and blobs are greater-than-or-equal-to an empty string, - ** the add/subtract is skipped for these, as required. If reg1 is a NULL, - ** then the arithmetic is performed, but since adding or subtracting from - ** NULL is always NULL anyway, this case is handled as required too. */ - sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC); - addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1); - VdbeCoverage(v); - sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1); - sqlite3VdbeJumpHere(v, addrGe); - /* If the BIGNULL flag is set for the ORDER BY, then it is required to ** consider NULL values to be larger than all other values, instead of ** the usual smaller. The VDBE opcodes OP_Ge and so on do not handle this @@ -153302,21 +160276,46 @@ static void windowCodeRangeTest( break; default: assert( op==OP_Lt ); /* no-op */ break; } - sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrDone); /* This block runs if reg1 is not NULL, but reg2 is. */ sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); if( op==OP_Gt || op==OP_Ge ){ - sqlite3VdbeChangeP2(v, -1, sqlite3VdbeCurrentAddr(v)+1); + sqlite3VdbeChangeP2(v, -1, addrDone); } } + /* Register reg1 currently contains csr1.peerVal (the peer-value from csr1). + ** This block adds (or subtracts for DESC) the numeric value in regVal + ** from it. Or, if reg1 is not numeric (it is a NULL, a text value or a blob), + ** then leave reg1 as it is. In pseudo-code, this is implemented as: + ** + ** if( reg1>='' ) goto addrGe; + ** reg1 = reg1 +/- regVal + ** addrGe: + ** + ** Since all strings and blobs are greater-than-or-equal-to an empty string, + ** the add/subtract is skipped for these, as required. If reg1 is a NULL, + ** then the arithmetic is performed, but since adding or subtracting from + ** NULL is always NULL anyway, this case is handled as required too. */ + sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC); + addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1); + VdbeCoverage(v); + if( (op==OP_Ge && arith==OP_Add) || (op==OP_Le && arith==OP_Subtract) ){ + sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v); + } + sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1); + sqlite3VdbeJumpHere(v, addrGe); + /* Compare registers reg2 and reg1, taking the jump if required. Note that ** control skips over this test if the BIGNULL flag is set and either ** reg1 or reg2 contain a NULL value. */ sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v); + pColl = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[0].pExpr); + sqlite3VdbeAppendP4(v, (void*)pColl, P4_COLLSEQ); sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + sqlite3VdbeResolveLabel(v, addrDone); assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le ); testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge); @@ -153392,16 +160391,24 @@ static int windowCodeOp( /* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or ** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the ** start cursor does not advance past the end cursor within the - ** temporary table. It otherwise might, if (a>b). */ + ** temporary table. It otherwise might, if (a>b). Also ensure that, + ** if the input cursor is still finding new rows, that the end + ** cursor does not go past it to EOF. */ if( pMWin->eStart==pMWin->eEnd && regCountdown - && pMWin->eFrmType==TK_RANGE && op==WINDOW_AGGINVERSE + && pMWin->eFrmType==TK_RANGE ){ int regRowid1 = sqlite3GetTempReg(pParse); int regRowid2 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1); - sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2); - sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1); - VdbeCoverage(v); + if( op==WINDOW_AGGINVERSE ){ + sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1); + sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2); + sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1); + VdbeCoverage(v); + }else if( p->regRowid ){ + sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid1); + sqlite3VdbeAddOp3(v, OP_Ge, p->regRowid, lblDone, regRowid1); + VdbeCoverageNeverNull(v); + } sqlite3ReleaseTempReg(pParse, regRowid1); sqlite3ReleaseTempReg(pParse, regRowid2); assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ); @@ -153898,7 +160905,6 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( int addrEmpty; /* Address of OP_Rewind in flush: */ int regNew; /* Array of registers holding new input row */ int regRecord; /* regNew array in record form */ - int regRowid; /* Rowid for regRecord in eph table */ int regNewPeer = 0; /* Peer values for new row (part of regNew) */ int regPeer = 0; /* Peer values for current row */ int regFlushPart = 0; /* Register for "Gosub flush_partition" */ @@ -153970,7 +160976,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( regNew = pParse->nMem+1; pParse->nMem += nInput; regRecord = ++pParse->nMem; - regRowid = ++pParse->nMem; + s.regRowid = ++pParse->nMem; /* If the window frame contains an " PRECEDING" or " FOLLOWING" ** clause, allocate registers to store the results of evaluating each @@ -154026,9 +161032,9 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( } /* Insert the new row into the ephemeral table */ - sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid); - sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid); - addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, regRowid); + sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, s.regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, s.regRowid); + addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, s.regRowid); VdbeCoverageNeverNull(v); /* This block is run for the first row of each partition */ @@ -154146,6 +161152,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( sqlite3VdbeJumpHere(v, addrGosubFlush); } + s.regRowid = 0; addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite); VdbeCoverage(v); if( pMWin->eEnd==TK_PRECEDING ){ @@ -154208,8 +161215,10 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( /************** End of window.c **********************************************/ /************** Begin file parse.c *******************************************/ +/* This file is automatically generated by Lemon from input grammar +** source file "parse.y". */ /* -** 2000-05-29 +** 2001-09-15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: @@ -154219,22 +161228,15 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep( ** May you share freely, never taking more than you give. ** ************************************************************************* -** Driver template for the LEMON parser generator. -** -** The "lemon" program processes an LALR(1) input grammar file, then uses -** this template to construct a parser. The "lemon" program inserts text -** at each "%%" line. Also, any "P-a-r-s-e" identifer prefix (without the -** interstitial "-" characters) contained in this template is changed into -** the value of the %name directive from the grammar. Otherwise, the content -** of this template is copied straight through into the generate parser -** source file. +** This file contains SQLite's SQL parser. ** -** The following is the concatenation of all %include directives from the -** input grammar file: +** The canonical source code to this file ("parse.y") is a Lemon grammar +** file that specifies the input grammar and actions to take while parsing. +** That input file is processed by Lemon to generate a C-language +** implementation of a parser for the given grammer. You might be reading +** this comment as part of the translated C-code. Edits should be made +** to the original parse.y sources. */ -/* #include */ -/* #include */ -/************ Begin %include sections from the grammar ************************/ /* #include "sqliteInt.h" */ @@ -154327,11 +161329,21 @@ static void updateDeleteLimitError( static void parserDoubleLinkSelect(Parse *pParse, Select *p){ assert( p!=0 ); if( p->pPrior ){ - Select *pNext = 0, *pLoop; - int mxSelect, cnt = 0; - for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){ + Select *pNext = 0, *pLoop = p; + int mxSelect, cnt = 1; + while(1){ pLoop->pNext = pNext; pLoop->selFlags |= SF_Compound; + pNext = pLoop; + pLoop = pLoop->pPrior; + if( pLoop==0 ) break; + cnt++; + if( pLoop->pOrderBy || pLoop->pLimit ){ + sqlite3ErrorMsg(pParse,"%s clause should come after %s not before", + pLoop->pOrderBy!=0 ? "ORDER BY" : "LIMIT", + sqlite3SelectOpName(pNext->op)); + break; + } } if( (p->selFlags & SF_MultiValue)==0 && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && @@ -154342,11 +161354,21 @@ 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. + /* Attach a With object describing the WITH clause to a Select + ** object describing the query for which the WITH clause is a prefix. */ + static Select *attachWithToSelect(Parse *pParse, Select *pSelect, With *pWith){ + if( pSelect ){ + pSelect->pWith = pWith; + parserDoubleLinkSelect(pParse, pSelect); + }else{ + sqlite3WithDelete(pParse->db, pWith); + } + return pSelect; + } + + + /* 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 ){ @@ -154357,15 +161379,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); } @@ -154418,11 +161441,195 @@ static void updateDeleteLimitError( # error too many tokens in the grammar #endif /**************** End of %include directives **********************************/ -/* These constants specify the various numeric values for terminal symbols -** in a format understandable to "makeheaders". This section is blank unless -** "lemon" is run with the "-m" command-line option. -***************** Begin makeheaders token definitions *************************/ -/**************** End makeheaders token definitions ***************************/ +/* These constants specify the various numeric values for terminal symbols. +***************** Begin token definitions *************************************/ +#ifndef TK_SEMI +#define TK_SEMI 1 +#define TK_EXPLAIN 2 +#define TK_QUERY 3 +#define TK_PLAN 4 +#define TK_BEGIN 5 +#define TK_TRANSACTION 6 +#define TK_DEFERRED 7 +#define TK_IMMEDIATE 8 +#define TK_EXCLUSIVE 9 +#define TK_COMMIT 10 +#define TK_END 11 +#define TK_ROLLBACK 12 +#define TK_SAVEPOINT 13 +#define TK_RELEASE 14 +#define TK_TO 15 +#define TK_TABLE 16 +#define TK_CREATE 17 +#define TK_IF 18 +#define TK_NOT 19 +#define TK_EXISTS 20 +#define TK_TEMP 21 +#define TK_LP 22 +#define TK_RP 23 +#define TK_AS 24 +#define TK_COMMA 25 +#define TK_WITHOUT 26 +#define TK_ABORT 27 +#define TK_ACTION 28 +#define TK_AFTER 29 +#define TK_ANALYZE 30 +#define TK_ASC 31 +#define TK_ATTACH 32 +#define TK_BEFORE 33 +#define TK_BY 34 +#define TK_CASCADE 35 +#define TK_CAST 36 +#define TK_CONFLICT 37 +#define TK_DATABASE 38 +#define TK_DESC 39 +#define TK_DETACH 40 +#define TK_EACH 41 +#define TK_FAIL 42 +#define TK_OR 43 +#define TK_AND 44 +#define TK_IS 45 +#define TK_MATCH 46 +#define TK_LIKE_KW 47 +#define TK_BETWEEN 48 +#define TK_IN 49 +#define TK_ISNULL 50 +#define TK_NOTNULL 51 +#define TK_NE 52 +#define TK_EQ 53 +#define TK_GT 54 +#define TK_LE 55 +#define TK_LT 56 +#define TK_GE 57 +#define TK_ESCAPE 58 +#define TK_ID 59 +#define TK_COLUMNKW 60 +#define TK_DO 61 +#define TK_FOR 62 +#define TK_IGNORE 63 +#define TK_INITIALLY 64 +#define TK_INSTEAD 65 +#define TK_NO 66 +#define TK_KEY 67 +#define TK_OF 68 +#define TK_OFFSET 69 +#define TK_PRAGMA 70 +#define TK_RAISE 71 +#define TK_RECURSIVE 72 +#define TK_REPLACE 73 +#define TK_RESTRICT 74 +#define TK_ROW 75 +#define TK_ROWS 76 +#define TK_TRIGGER 77 +#define TK_VACUUM 78 +#define TK_VIEW 79 +#define TK_VIRTUAL 80 +#define TK_WITH 81 +#define TK_NULLS 82 +#define TK_FIRST 83 +#define TK_LAST 84 +#define TK_CURRENT 85 +#define TK_FOLLOWING 86 +#define TK_PARTITION 87 +#define TK_PRECEDING 88 +#define TK_RANGE 89 +#define TK_UNBOUNDED 90 +#define TK_EXCLUDE 91 +#define TK_GROUPS 92 +#define TK_OTHERS 93 +#define TK_TIES 94 +#define TK_GENERATED 95 +#define TK_ALWAYS 96 +#define TK_MATERIALIZED 97 +#define TK_REINDEX 98 +#define TK_RENAME 99 +#define TK_CTIME_KW 100 +#define TK_ANY 101 +#define TK_BITAND 102 +#define TK_BITOR 103 +#define TK_LSHIFT 104 +#define TK_RSHIFT 105 +#define TK_PLUS 106 +#define TK_MINUS 107 +#define TK_STAR 108 +#define TK_SLASH 109 +#define TK_REM 110 +#define TK_CONCAT 111 +#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 ***************************************/ /* The next sections is a series of control #defines. ** various aspects of the generated parser. @@ -154480,28 +161687,30 @@ static void updateDeleteLimitError( #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 310 +#define YYNOCODE 319 #define YYACTIONTYPE unsigned short int -#define YYWILDCARD 100 +#define YYWILDCARD 101 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; - SrcList* yy47; - u8 yy58; - struct FrameBound yy77; - With* yy131; - int yy192; - Expr* yy202; - struct {int value; int mask;} yy207; - struct TrigEvent yy230; - ExprList* yy242; - Window* yy303; - Upsert* yy318; - const char* yy436; - TriggerStep* yy447; - Select* yy539; - IdList* yy600; + 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 @@ -154517,18 +161726,18 @@ typedef union { #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 -#define YYNSTATE 553 -#define YYNRULE 385 -#define YYNRULE_WITH_ACTION 325 -#define YYNTOKEN 181 -#define YY_MAX_SHIFT 552 -#define YY_MIN_SHIFTREDUCE 803 -#define YY_MAX_SHIFTREDUCE 1187 -#define YY_ERROR_ACTION 1188 -#define YY_ACCEPT_ACTION 1189 -#define YY_NO_ACTION 1190 -#define YY_MIN_REDUCE 1191 -#define YY_MAX_REDUCE 1575 +#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]))) @@ -154595,586 +161804,612 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (1962) +#define YY_ACTTAB_COUNT (2070) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 546, 1222, 546, 451, 1260, 546, 1239, 546, 114, 111, - /* 10 */ 211, 546, 1537, 546, 1260, 523, 114, 111, 211, 392, - /* 20 */ 1232, 344, 42, 42, 42, 42, 1225, 42, 42, 71, - /* 30 */ 71, 937, 1224, 71, 71, 71, 71, 1462, 1493, 938, - /* 40 */ 820, 453, 6, 121, 122, 112, 1165, 1165, 1006, 1009, - /* 50 */ 999, 999, 119, 119, 120, 120, 120, 120, 1543, 392, - /* 60 */ 1358, 1517, 552, 2, 1193, 194, 528, 436, 143, 291, - /* 70 */ 528, 136, 528, 371, 261, 504, 272, 385, 1273, 527, - /* 80 */ 503, 493, 164, 121, 122, 112, 1165, 1165, 1006, 1009, - /* 90 */ 999, 999, 119, 119, 120, 120, 120, 120, 1358, 442, - /* 100 */ 1514, 118, 118, 118, 118, 117, 117, 116, 116, 116, - /* 110 */ 115, 424, 266, 266, 266, 266, 1498, 358, 1500, 435, - /* 120 */ 357, 1498, 517, 524, 1485, 543, 1114, 543, 1114, 392, - /* 130 */ 405, 241, 208, 114, 111, 211, 98, 290, 537, 221, - /* 140 */ 1029, 118, 118, 118, 118, 117, 117, 116, 116, 116, - /* 150 */ 115, 424, 1142, 121, 122, 112, 1165, 1165, 1006, 1009, - /* 160 */ 999, 999, 119, 119, 120, 120, 120, 120, 406, 428, - /* 170 */ 117, 117, 116, 116, 116, 115, 424, 1418, 468, 123, - /* 180 */ 118, 118, 118, 118, 117, 117, 116, 116, 116, 115, - /* 190 */ 424, 116, 116, 116, 115, 424, 540, 540, 540, 392, - /* 200 */ 505, 120, 120, 120, 120, 113, 1051, 1142, 1143, 1144, - /* 210 */ 1051, 118, 118, 118, 118, 117, 117, 116, 116, 116, - /* 220 */ 115, 424, 1461, 121, 122, 112, 1165, 1165, 1006, 1009, - /* 230 */ 999, 999, 119, 119, 120, 120, 120, 120, 392, 444, - /* 240 */ 316, 83, 463, 81, 359, 382, 1142, 80, 118, 118, - /* 250 */ 118, 118, 117, 117, 116, 116, 116, 115, 424, 179, - /* 260 */ 434, 424, 121, 122, 112, 1165, 1165, 1006, 1009, 999, - /* 270 */ 999, 119, 119, 120, 120, 120, 120, 434, 433, 266, - /* 280 */ 266, 118, 118, 118, 118, 117, 117, 116, 116, 116, - /* 290 */ 115, 424, 543, 1109, 903, 506, 1142, 114, 111, 211, - /* 300 */ 1431, 1142, 1143, 1144, 206, 491, 1109, 392, 449, 1109, - /* 310 */ 545, 330, 120, 120, 120, 120, 298, 1431, 1433, 17, - /* 320 */ 118, 118, 118, 118, 117, 117, 116, 116, 116, 115, - /* 330 */ 424, 121, 122, 112, 1165, 1165, 1006, 1009, 999, 999, - /* 340 */ 119, 119, 120, 120, 120, 120, 392, 1358, 434, 1142, - /* 350 */ 482, 1142, 1143, 1144, 996, 996, 1007, 1010, 445, 118, - /* 360 */ 118, 118, 118, 117, 117, 116, 116, 116, 115, 424, - /* 370 */ 121, 122, 112, 1165, 1165, 1006, 1009, 999, 999, 119, - /* 380 */ 119, 120, 120, 120, 120, 1054, 1054, 465, 1431, 118, - /* 390 */ 118, 118, 118, 117, 117, 116, 116, 116, 115, 424, - /* 400 */ 1142, 451, 546, 1426, 1142, 1143, 1144, 233, 966, 1142, - /* 410 */ 481, 478, 477, 171, 360, 392, 164, 407, 414, 842, - /* 420 */ 476, 164, 185, 334, 71, 71, 1243, 1000, 118, 118, - /* 430 */ 118, 118, 117, 117, 116, 116, 116, 115, 424, 121, - /* 440 */ 122, 112, 1165, 1165, 1006, 1009, 999, 999, 119, 119, - /* 450 */ 120, 120, 120, 120, 392, 1142, 1143, 1144, 835, 12, - /* 460 */ 314, 509, 163, 356, 1142, 1143, 1144, 114, 111, 211, - /* 470 */ 508, 290, 537, 546, 276, 180, 290, 537, 121, 122, - /* 480 */ 112, 1165, 1165, 1006, 1009, 999, 999, 119, 119, 120, - /* 490 */ 120, 120, 120, 345, 484, 71, 71, 118, 118, 118, - /* 500 */ 118, 117, 117, 116, 116, 116, 115, 424, 1142, 209, - /* 510 */ 411, 523, 1142, 1109, 1571, 378, 252, 269, 342, 487, - /* 520 */ 337, 486, 238, 392, 513, 364, 1109, 1127, 333, 1109, - /* 530 */ 191, 409, 286, 32, 457, 443, 118, 118, 118, 118, - /* 540 */ 117, 117, 116, 116, 116, 115, 424, 121, 122, 112, - /* 550 */ 1165, 1165, 1006, 1009, 999, 999, 119, 119, 120, 120, - /* 560 */ 120, 120, 392, 1142, 1143, 1144, 987, 1142, 1143, 1144, - /* 570 */ 1142, 233, 492, 1492, 481, 478, 477, 6, 163, 546, - /* 580 */ 512, 546, 115, 424, 476, 5, 121, 122, 112, 1165, - /* 590 */ 1165, 1006, 1009, 999, 999, 119, 119, 120, 120, 120, - /* 600 */ 120, 13, 13, 13, 13, 118, 118, 118, 118, 117, - /* 610 */ 117, 116, 116, 116, 115, 424, 403, 502, 408, 546, - /* 620 */ 1486, 544, 1142, 892, 892, 1142, 1143, 1144, 1473, 1142, - /* 630 */ 275, 392, 808, 809, 810, 971, 422, 422, 422, 16, - /* 640 */ 16, 55, 55, 1242, 118, 118, 118, 118, 117, 117, - /* 650 */ 116, 116, 116, 115, 424, 121, 122, 112, 1165, 1165, - /* 660 */ 1006, 1009, 999, 999, 119, 119, 120, 120, 120, 120, - /* 670 */ 392, 1189, 1, 1, 552, 2, 1193, 1142, 1143, 1144, - /* 680 */ 194, 291, 898, 136, 1142, 1143, 1144, 897, 521, 1492, - /* 690 */ 1273, 3, 380, 6, 121, 122, 112, 1165, 1165, 1006, - /* 700 */ 1009, 999, 999, 119, 119, 120, 120, 120, 120, 858, - /* 710 */ 546, 924, 546, 118, 118, 118, 118, 117, 117, 116, - /* 720 */ 116, 116, 115, 424, 266, 266, 1092, 1569, 1142, 551, - /* 730 */ 1569, 1193, 13, 13, 13, 13, 291, 543, 136, 392, - /* 740 */ 485, 421, 420, 966, 344, 1273, 468, 410, 859, 279, - /* 750 */ 140, 221, 118, 118, 118, 118, 117, 117, 116, 116, - /* 760 */ 116, 115, 424, 121, 122, 112, 1165, 1165, 1006, 1009, - /* 770 */ 999, 999, 119, 119, 120, 120, 120, 120, 546, 266, - /* 780 */ 266, 428, 392, 1142, 1143, 1144, 1172, 830, 1172, 468, - /* 790 */ 431, 145, 543, 1146, 401, 314, 439, 302, 838, 1490, - /* 800 */ 71, 71, 412, 6, 1090, 473, 221, 100, 112, 1165, - /* 810 */ 1165, 1006, 1009, 999, 999, 119, 119, 120, 120, 120, - /* 820 */ 120, 118, 118, 118, 118, 117, 117, 116, 116, 116, - /* 830 */ 115, 424, 237, 1425, 546, 451, 428, 287, 986, 546, - /* 840 */ 236, 235, 234, 830, 97, 529, 429, 1265, 1265, 1146, - /* 850 */ 494, 307, 430, 838, 977, 546, 71, 71, 976, 1241, - /* 860 */ 546, 51, 51, 300, 118, 118, 118, 118, 117, 117, - /* 870 */ 116, 116, 116, 115, 424, 194, 103, 70, 70, 266, - /* 880 */ 266, 546, 71, 71, 266, 266, 30, 391, 344, 976, - /* 890 */ 976, 978, 543, 528, 1109, 328, 392, 543, 495, 397, - /* 900 */ 1470, 195, 530, 13, 13, 1358, 240, 1109, 277, 280, - /* 910 */ 1109, 280, 304, 457, 306, 333, 392, 31, 188, 419, - /* 920 */ 121, 122, 112, 1165, 1165, 1006, 1009, 999, 999, 119, - /* 930 */ 119, 120, 120, 120, 120, 142, 392, 365, 457, 986, - /* 940 */ 121, 122, 112, 1165, 1165, 1006, 1009, 999, 999, 119, - /* 950 */ 119, 120, 120, 120, 120, 977, 323, 1142, 326, 976, - /* 960 */ 121, 110, 112, 1165, 1165, 1006, 1009, 999, 999, 119, - /* 970 */ 119, 120, 120, 120, 120, 464, 377, 1185, 118, 118, - /* 980 */ 118, 118, 117, 117, 116, 116, 116, 115, 424, 1142, - /* 990 */ 976, 976, 978, 305, 9, 366, 244, 362, 118, 118, - /* 1000 */ 118, 118, 117, 117, 116, 116, 116, 115, 424, 313, - /* 1010 */ 546, 344, 1142, 1143, 1144, 299, 290, 537, 118, 118, - /* 1020 */ 118, 118, 117, 117, 116, 116, 116, 115, 424, 1263, - /* 1030 */ 1263, 1163, 13, 13, 278, 421, 420, 468, 392, 923, - /* 1040 */ 260, 260, 289, 1169, 1142, 1143, 1144, 189, 1171, 266, - /* 1050 */ 266, 468, 390, 543, 1186, 546, 1170, 263, 144, 489, - /* 1060 */ 922, 546, 543, 122, 112, 1165, 1165, 1006, 1009, 999, - /* 1070 */ 999, 119, 119, 120, 120, 120, 120, 71, 71, 1142, - /* 1080 */ 1172, 1272, 1172, 13, 13, 898, 1070, 1163, 546, 468, - /* 1090 */ 897, 107, 538, 1491, 4, 1268, 1109, 6, 525, 1049, - /* 1100 */ 12, 1071, 1092, 1570, 312, 455, 1570, 520, 541, 1109, - /* 1110 */ 56, 56, 1109, 1489, 423, 1358, 1072, 6, 345, 285, - /* 1120 */ 118, 118, 118, 118, 117, 117, 116, 116, 116, 115, - /* 1130 */ 424, 425, 1271, 321, 1142, 1143, 1144, 878, 266, 266, - /* 1140 */ 1277, 107, 538, 535, 4, 1488, 293, 879, 1211, 6, - /* 1150 */ 210, 543, 543, 164, 294, 496, 416, 204, 541, 267, - /* 1160 */ 267, 1214, 398, 511, 499, 204, 266, 266, 396, 531, - /* 1170 */ 8, 986, 543, 519, 546, 922, 458, 105, 105, 543, - /* 1180 */ 1090, 425, 266, 266, 106, 417, 425, 548, 547, 266, - /* 1190 */ 266, 976, 518, 535, 1373, 543, 15, 15, 266, 266, - /* 1200 */ 456, 1120, 543, 266, 266, 1070, 1372, 515, 290, 537, - /* 1210 */ 546, 543, 514, 97, 444, 316, 543, 546, 922, 125, - /* 1220 */ 1071, 986, 976, 976, 978, 979, 27, 105, 105, 401, - /* 1230 */ 343, 1511, 44, 44, 106, 1072, 425, 548, 547, 57, - /* 1240 */ 57, 976, 343, 1511, 107, 538, 546, 4, 462, 401, - /* 1250 */ 214, 1120, 459, 297, 377, 1091, 534, 1309, 546, 539, - /* 1260 */ 398, 541, 290, 537, 104, 244, 102, 526, 58, 58, - /* 1270 */ 546, 199, 976, 976, 978, 979, 27, 1516, 1131, 427, - /* 1280 */ 59, 59, 270, 237, 425, 138, 95, 375, 375, 374, - /* 1290 */ 255, 372, 60, 60, 817, 1180, 535, 546, 273, 546, - /* 1300 */ 1163, 1308, 389, 388, 546, 438, 546, 215, 210, 296, - /* 1310 */ 515, 849, 546, 265, 208, 516, 1476, 295, 274, 61, - /* 1320 */ 61, 62, 62, 308, 986, 109, 45, 45, 46, 46, - /* 1330 */ 105, 105, 1186, 922, 47, 47, 341, 106, 546, 425, - /* 1340 */ 548, 547, 1542, 546, 976, 867, 340, 217, 546, 937, - /* 1350 */ 397, 107, 538, 218, 4, 156, 1163, 938, 158, 546, - /* 1360 */ 49, 49, 1162, 546, 268, 50, 50, 546, 541, 1450, - /* 1370 */ 63, 63, 546, 1449, 216, 976, 976, 978, 979, 27, - /* 1380 */ 446, 64, 64, 546, 460, 65, 65, 546, 318, 14, - /* 1390 */ 14, 425, 1305, 546, 66, 66, 1087, 546, 141, 379, - /* 1400 */ 38, 546, 963, 535, 322, 127, 127, 546, 393, 67, - /* 1410 */ 67, 546, 325, 290, 537, 52, 52, 515, 546, 68, - /* 1420 */ 68, 845, 514, 69, 69, 399, 165, 857, 856, 53, - /* 1430 */ 53, 986, 311, 151, 151, 97, 432, 105, 105, 327, - /* 1440 */ 152, 152, 526, 1048, 106, 1048, 425, 548, 547, 1131, - /* 1450 */ 427, 976, 1032, 270, 968, 239, 329, 243, 375, 375, - /* 1460 */ 374, 255, 372, 940, 941, 817, 1296, 546, 220, 546, - /* 1470 */ 107, 538, 546, 4, 546, 1256, 199, 845, 215, 1036, - /* 1480 */ 296, 1530, 976, 976, 978, 979, 27, 541, 295, 76, - /* 1490 */ 76, 54, 54, 980, 72, 72, 128, 128, 864, 865, - /* 1500 */ 107, 538, 546, 4, 1047, 546, 1047, 533, 469, 546, - /* 1510 */ 425, 546, 450, 1240, 546, 243, 546, 541, 217, 546, - /* 1520 */ 452, 197, 535, 243, 73, 73, 156, 129, 129, 158, - /* 1530 */ 336, 130, 130, 126, 126, 1036, 150, 150, 149, 149, - /* 1540 */ 425, 134, 134, 317, 474, 216, 97, 239, 331, 980, - /* 1550 */ 986, 97, 535, 346, 347, 546, 105, 105, 902, 931, - /* 1560 */ 546, 895, 243, 106, 109, 425, 548, 547, 546, 1505, - /* 1570 */ 976, 828, 99, 538, 139, 4, 546, 133, 133, 393, - /* 1580 */ 986, 1317, 131, 131, 290, 537, 105, 105, 1357, 541, - /* 1590 */ 132, 132, 1292, 106, 1303, 425, 548, 547, 75, 75, - /* 1600 */ 976, 976, 976, 978, 979, 27, 546, 432, 896, 1289, - /* 1610 */ 532, 109, 425, 1363, 546, 1221, 1213, 1202, 258, 546, - /* 1620 */ 349, 546, 1201, 11, 535, 1203, 1524, 351, 77, 77, - /* 1630 */ 376, 976, 976, 978, 979, 27, 74, 74, 353, 213, - /* 1640 */ 301, 43, 43, 48, 48, 437, 310, 201, 303, 1350, - /* 1650 */ 315, 355, 986, 454, 479, 1239, 339, 192, 105, 105, - /* 1660 */ 1422, 1421, 193, 536, 205, 106, 1527, 425, 548, 547, - /* 1670 */ 1180, 167, 976, 270, 247, 1469, 1467, 1177, 375, 375, - /* 1680 */ 374, 255, 372, 200, 369, 817, 400, 83, 79, 82, - /* 1690 */ 1427, 448, 177, 95, 1342, 161, 169, 1339, 215, 440, - /* 1700 */ 296, 172, 173, 976, 976, 978, 979, 27, 295, 174, - /* 1710 */ 175, 441, 472, 223, 1347, 383, 35, 381, 36, 461, - /* 1720 */ 88, 1353, 181, 447, 384, 1416, 227, 467, 259, 229, - /* 1730 */ 186, 488, 470, 324, 1250, 230, 231, 320, 217, 1204, - /* 1740 */ 1438, 1259, 386, 1258, 413, 90, 156, 849, 1541, 158, - /* 1750 */ 206, 415, 1540, 507, 1300, 1257, 94, 348, 1229, 1301, - /* 1760 */ 387, 1510, 1228, 338, 1227, 216, 350, 1539, 498, 283, - /* 1770 */ 284, 1249, 501, 1299, 352, 245, 246, 418, 1298, 354, - /* 1780 */ 1496, 1495, 124, 10, 526, 363, 101, 1324, 253, 96, - /* 1790 */ 510, 1210, 34, 549, 1137, 254, 256, 257, 166, 393, - /* 1800 */ 550, 1199, 1282, 361, 290, 537, 1281, 196, 367, 368, - /* 1810 */ 1194, 153, 1454, 137, 281, 1323, 1455, 804, 154, 426, - /* 1820 */ 198, 155, 1453, 1452, 292, 212, 202, 432, 1402, 203, - /* 1830 */ 271, 135, 288, 78, 1046, 1044, 960, 168, 157, 881, - /* 1840 */ 170, 219, 309, 222, 1060, 176, 964, 159, 402, 84, - /* 1850 */ 178, 404, 85, 86, 87, 160, 1063, 224, 394, 395, - /* 1860 */ 225, 1059, 146, 18, 226, 319, 243, 1174, 466, 228, - /* 1870 */ 1052, 182, 183, 37, 819, 471, 340, 232, 332, 483, - /* 1880 */ 184, 89, 162, 19, 20, 475, 91, 480, 847, 335, - /* 1890 */ 147, 860, 282, 92, 490, 93, 1125, 148, 1012, 1095, - /* 1900 */ 39, 497, 1096, 40, 500, 262, 207, 264, 930, 187, - /* 1910 */ 925, 109, 1111, 1115, 1113, 7, 1099, 242, 33, 1119, - /* 1920 */ 21, 522, 22, 23, 24, 1118, 25, 190, 97, 26, - /* 1930 */ 1027, 1013, 1011, 1015, 1069, 1016, 1068, 249, 248, 28, - /* 1940 */ 41, 891, 981, 829, 108, 29, 250, 542, 251, 370, - /* 1950 */ 373, 1133, 1132, 1190, 1190, 1190, 1190, 1190, 1190, 1190, - /* 1960 */ 1532, 1531, + /* 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 */ 189, 211, 189, 189, 218, 189, 220, 189, 267, 268, - /* 10 */ 269, 189, 210, 189, 228, 189, 267, 268, 269, 19, - /* 20 */ 218, 189, 211, 212, 211, 212, 211, 211, 212, 211, - /* 30 */ 212, 31, 211, 211, 212, 211, 212, 288, 300, 39, - /* 40 */ 21, 189, 304, 43, 44, 45, 46, 47, 48, 49, - /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 225, 19, - /* 60 */ 189, 183, 184, 185, 186, 189, 248, 263, 236, 191, - /* 70 */ 248, 193, 248, 197, 208, 257, 262, 201, 200, 257, - /* 80 */ 200, 257, 81, 43, 44, 45, 46, 47, 48, 49, - /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 189, 80, - /* 100 */ 189, 101, 102, 103, 104, 105, 106, 107, 108, 109, - /* 110 */ 110, 111, 234, 235, 234, 235, 305, 306, 305, 118, - /* 120 */ 307, 305, 306, 297, 298, 247, 86, 247, 88, 19, - /* 130 */ 259, 251, 252, 267, 268, 269, 26, 136, 137, 261, - /* 140 */ 121, 101, 102, 103, 104, 105, 106, 107, 108, 109, - /* 150 */ 110, 111, 59, 43, 44, 45, 46, 47, 48, 49, - /* 160 */ 50, 51, 52, 53, 54, 55, 56, 57, 259, 291, - /* 170 */ 105, 106, 107, 108, 109, 110, 111, 158, 189, 69, - /* 180 */ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 190 */ 111, 107, 108, 109, 110, 111, 205, 206, 207, 19, - /* 200 */ 19, 54, 55, 56, 57, 58, 29, 114, 115, 116, - /* 210 */ 33, 101, 102, 103, 104, 105, 106, 107, 108, 109, - /* 220 */ 110, 111, 233, 43, 44, 45, 46, 47, 48, 49, - /* 230 */ 50, 51, 52, 53, 54, 55, 56, 57, 19, 126, - /* 240 */ 127, 148, 65, 24, 214, 200, 59, 67, 101, 102, - /* 250 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 22, - /* 260 */ 189, 111, 43, 44, 45, 46, 47, 48, 49, 50, - /* 270 */ 51, 52, 53, 54, 55, 56, 57, 206, 207, 234, - /* 280 */ 235, 101, 102, 103, 104, 105, 106, 107, 108, 109, - /* 290 */ 110, 111, 247, 76, 107, 114, 59, 267, 268, 269, - /* 300 */ 189, 114, 115, 116, 162, 163, 89, 19, 263, 92, - /* 310 */ 189, 23, 54, 55, 56, 57, 189, 206, 207, 22, - /* 320 */ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 330 */ 111, 43, 44, 45, 46, 47, 48, 49, 50, 51, - /* 340 */ 52, 53, 54, 55, 56, 57, 19, 189, 277, 59, - /* 350 */ 23, 114, 115, 116, 46, 47, 48, 49, 61, 101, + /* 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 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 380 */ 53, 54, 55, 56, 57, 125, 126, 127, 277, 101, - /* 390 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 400 */ 59, 189, 189, 276, 114, 115, 116, 117, 73, 59, - /* 410 */ 120, 121, 122, 72, 214, 19, 81, 259, 19, 23, - /* 420 */ 130, 81, 72, 24, 211, 212, 221, 119, 101, 102, - /* 430 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 43, - /* 440 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 450 */ 54, 55, 56, 57, 19, 114, 115, 116, 23, 208, - /* 460 */ 125, 248, 189, 189, 114, 115, 116, 267, 268, 269, - /* 470 */ 189, 136, 137, 189, 262, 22, 136, 137, 43, 44, - /* 480 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 490 */ 55, 56, 57, 189, 95, 211, 212, 101, 102, 103, - /* 500 */ 104, 105, 106, 107, 108, 109, 110, 111, 59, 189, - /* 510 */ 111, 189, 59, 76, 294, 295, 117, 118, 119, 120, - /* 520 */ 121, 122, 123, 19, 87, 189, 89, 23, 129, 92, - /* 530 */ 279, 227, 248, 22, 189, 284, 101, 102, 103, 104, - /* 540 */ 105, 106, 107, 108, 109, 110, 111, 43, 44, 45, - /* 550 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - /* 560 */ 56, 57, 19, 114, 115, 116, 23, 114, 115, 116, - /* 570 */ 59, 117, 299, 300, 120, 121, 122, 304, 189, 189, - /* 580 */ 143, 189, 110, 111, 130, 22, 43, 44, 45, 46, - /* 590 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 600 */ 57, 211, 212, 211, 212, 101, 102, 103, 104, 105, - /* 610 */ 106, 107, 108, 109, 110, 111, 226, 189, 226, 189, - /* 620 */ 298, 132, 59, 134, 135, 114, 115, 116, 189, 59, - /* 630 */ 285, 19, 7, 8, 9, 23, 205, 206, 207, 211, - /* 640 */ 212, 211, 212, 221, 101, 102, 103, 104, 105, 106, - /* 650 */ 107, 108, 109, 110, 111, 43, 44, 45, 46, 47, - /* 660 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 670 */ 19, 181, 182, 183, 184, 185, 186, 114, 115, 116, - /* 680 */ 189, 191, 133, 193, 114, 115, 116, 138, 299, 300, - /* 690 */ 200, 22, 201, 304, 43, 44, 45, 46, 47, 48, - /* 700 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 35, - /* 710 */ 189, 141, 189, 101, 102, 103, 104, 105, 106, 107, - /* 720 */ 108, 109, 110, 111, 234, 235, 22, 23, 59, 184, - /* 730 */ 26, 186, 211, 212, 211, 212, 191, 247, 193, 19, - /* 740 */ 66, 105, 106, 73, 189, 200, 189, 226, 74, 226, - /* 750 */ 22, 261, 101, 102, 103, 104, 105, 106, 107, 108, - /* 760 */ 109, 110, 111, 43, 44, 45, 46, 47, 48, 49, - /* 770 */ 50, 51, 52, 53, 54, 55, 56, 57, 189, 234, - /* 780 */ 235, 291, 19, 114, 115, 116, 150, 59, 152, 189, - /* 790 */ 233, 236, 247, 59, 189, 125, 126, 127, 59, 300, - /* 800 */ 211, 212, 128, 304, 100, 19, 261, 156, 45, 46, - /* 810 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 820 */ 57, 101, 102, 103, 104, 105, 106, 107, 108, 109, - /* 830 */ 110, 111, 46, 233, 189, 189, 291, 248, 99, 189, - /* 840 */ 125, 126, 127, 115, 26, 200, 289, 230, 231, 115, - /* 850 */ 200, 16, 189, 114, 115, 189, 211, 212, 119, 221, - /* 860 */ 189, 211, 212, 258, 101, 102, 103, 104, 105, 106, - /* 870 */ 107, 108, 109, 110, 111, 189, 156, 211, 212, 234, - /* 880 */ 235, 189, 211, 212, 234, 235, 22, 201, 189, 150, - /* 890 */ 151, 152, 247, 248, 76, 16, 19, 247, 248, 113, - /* 900 */ 189, 24, 257, 211, 212, 189, 26, 89, 262, 223, - /* 910 */ 92, 225, 77, 189, 79, 129, 19, 53, 226, 248, - /* 920 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 930 */ 53, 54, 55, 56, 57, 236, 19, 271, 189, 99, - /* 940 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 950 */ 53, 54, 55, 56, 57, 115, 77, 59, 79, 119, - /* 960 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 970 */ 53, 54, 55, 56, 57, 259, 22, 23, 101, 102, - /* 980 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 59, - /* 990 */ 150, 151, 152, 158, 22, 244, 24, 246, 101, 102, - /* 1000 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 285, - /* 1010 */ 189, 189, 114, 115, 116, 200, 136, 137, 101, 102, - /* 1020 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 230, - /* 1030 */ 231, 59, 211, 212, 285, 105, 106, 189, 19, 141, - /* 1040 */ 234, 235, 239, 113, 114, 115, 116, 226, 118, 234, - /* 1050 */ 235, 189, 249, 247, 100, 189, 126, 23, 236, 107, - /* 1060 */ 26, 189, 247, 44, 45, 46, 47, 48, 49, 50, - /* 1070 */ 51, 52, 53, 54, 55, 56, 57, 211, 212, 59, - /* 1080 */ 150, 233, 152, 211, 212, 133, 12, 115, 189, 189, - /* 1090 */ 138, 19, 20, 300, 22, 233, 76, 304, 226, 11, - /* 1100 */ 208, 27, 22, 23, 200, 19, 26, 87, 36, 89, - /* 1110 */ 211, 212, 92, 300, 248, 189, 42, 304, 189, 250, - /* 1120 */ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 1130 */ 111, 59, 200, 233, 114, 115, 116, 63, 234, 235, - /* 1140 */ 235, 19, 20, 71, 22, 300, 189, 73, 200, 304, - /* 1150 */ 116, 247, 247, 81, 189, 200, 227, 26, 36, 234, - /* 1160 */ 235, 203, 204, 143, 200, 26, 234, 235, 194, 200, - /* 1170 */ 48, 99, 247, 66, 189, 141, 284, 105, 106, 247, - /* 1180 */ 100, 59, 234, 235, 112, 259, 114, 115, 116, 234, - /* 1190 */ 235, 119, 85, 71, 266, 247, 211, 212, 234, 235, - /* 1200 */ 114, 94, 247, 234, 235, 12, 266, 85, 136, 137, - /* 1210 */ 189, 247, 90, 26, 126, 127, 247, 189, 26, 22, - /* 1220 */ 27, 99, 150, 151, 152, 153, 154, 105, 106, 189, - /* 1230 */ 302, 303, 211, 212, 112, 42, 114, 115, 116, 211, - /* 1240 */ 212, 119, 302, 303, 19, 20, 189, 22, 274, 189, - /* 1250 */ 15, 144, 278, 189, 22, 23, 63, 189, 189, 203, - /* 1260 */ 204, 36, 136, 137, 155, 24, 157, 143, 211, 212, - /* 1270 */ 189, 140, 150, 151, 152, 153, 154, 0, 1, 2, - /* 1280 */ 211, 212, 5, 46, 59, 161, 147, 10, 11, 12, - /* 1290 */ 13, 14, 211, 212, 17, 60, 71, 189, 258, 189, - /* 1300 */ 59, 189, 105, 106, 189, 189, 189, 30, 116, 32, - /* 1310 */ 85, 124, 189, 251, 252, 90, 189, 40, 258, 211, - /* 1320 */ 212, 211, 212, 189, 99, 26, 211, 212, 211, 212, - /* 1330 */ 105, 106, 100, 141, 211, 212, 119, 112, 189, 114, - /* 1340 */ 115, 116, 23, 189, 119, 26, 129, 70, 189, 31, - /* 1350 */ 113, 19, 20, 24, 22, 78, 115, 39, 81, 189, - /* 1360 */ 211, 212, 26, 189, 22, 211, 212, 189, 36, 189, - /* 1370 */ 211, 212, 189, 189, 97, 150, 151, 152, 153, 154, - /* 1380 */ 127, 211, 212, 189, 189, 211, 212, 189, 189, 211, - /* 1390 */ 212, 59, 189, 189, 211, 212, 23, 189, 22, 26, - /* 1400 */ 24, 189, 149, 71, 189, 211, 212, 189, 131, 211, - /* 1410 */ 212, 189, 189, 136, 137, 211, 212, 85, 189, 211, - /* 1420 */ 212, 59, 90, 211, 212, 292, 293, 118, 119, 211, - /* 1430 */ 212, 99, 23, 211, 212, 26, 159, 105, 106, 189, - /* 1440 */ 211, 212, 143, 150, 112, 152, 114, 115, 116, 1, - /* 1450 */ 2, 119, 23, 5, 23, 26, 189, 26, 10, 11, - /* 1460 */ 12, 13, 14, 83, 84, 17, 253, 189, 139, 189, - /* 1470 */ 19, 20, 189, 22, 189, 189, 140, 115, 30, 59, - /* 1480 */ 32, 139, 150, 151, 152, 153, 154, 36, 40, 211, - /* 1490 */ 212, 211, 212, 59, 211, 212, 211, 212, 7, 8, - /* 1500 */ 19, 20, 189, 22, 150, 189, 152, 231, 281, 189, - /* 1510 */ 59, 189, 23, 189, 189, 26, 189, 36, 70, 189, - /* 1520 */ 23, 237, 71, 26, 211, 212, 78, 211, 212, 81, - /* 1530 */ 189, 211, 212, 211, 212, 115, 211, 212, 211, 212, - /* 1540 */ 59, 211, 212, 23, 23, 97, 26, 26, 23, 115, - /* 1550 */ 99, 26, 71, 189, 189, 189, 105, 106, 107, 23, - /* 1560 */ 189, 23, 26, 112, 26, 114, 115, 116, 189, 309, - /* 1570 */ 119, 23, 19, 20, 26, 22, 189, 211, 212, 131, - /* 1580 */ 99, 189, 211, 212, 136, 137, 105, 106, 189, 36, - /* 1590 */ 211, 212, 189, 112, 189, 114, 115, 116, 211, 212, - /* 1600 */ 119, 150, 151, 152, 153, 154, 189, 159, 23, 250, - /* 1610 */ 189, 26, 59, 189, 189, 189, 189, 189, 280, 189, - /* 1620 */ 250, 189, 189, 238, 71, 189, 189, 250, 211, 212, - /* 1630 */ 187, 150, 151, 152, 153, 154, 211, 212, 250, 290, - /* 1640 */ 240, 211, 212, 211, 212, 254, 286, 209, 254, 241, - /* 1650 */ 240, 254, 99, 286, 215, 220, 214, 244, 105, 106, - /* 1660 */ 214, 214, 244, 273, 224, 112, 192, 114, 115, 116, - /* 1670 */ 60, 290, 119, 5, 139, 196, 196, 38, 10, 11, - /* 1680 */ 12, 13, 14, 238, 240, 17, 196, 148, 287, 287, - /* 1690 */ 276, 113, 22, 147, 241, 43, 229, 241, 30, 18, - /* 1700 */ 32, 232, 232, 150, 151, 152, 153, 154, 40, 232, - /* 1710 */ 232, 196, 18, 195, 265, 265, 264, 241, 264, 196, - /* 1720 */ 155, 229, 229, 241, 241, 241, 195, 62, 196, 195, - /* 1730 */ 22, 113, 216, 196, 222, 195, 195, 282, 70, 196, - /* 1740 */ 283, 213, 216, 213, 64, 22, 78, 124, 219, 81, - /* 1750 */ 162, 111, 219, 142, 256, 213, 113, 255, 213, 256, - /* 1760 */ 216, 303, 215, 213, 213, 97, 255, 213, 216, 275, - /* 1770 */ 275, 222, 216, 256, 255, 196, 91, 82, 256, 255, - /* 1780 */ 308, 308, 146, 22, 143, 196, 155, 260, 25, 145, - /* 1790 */ 144, 199, 26, 198, 13, 190, 190, 6, 293, 131, - /* 1800 */ 188, 188, 245, 244, 136, 137, 245, 243, 242, 241, - /* 1810 */ 188, 202, 208, 217, 217, 260, 208, 4, 202, 3, - /* 1820 */ 22, 202, 208, 208, 160, 15, 209, 159, 270, 209, - /* 1830 */ 98, 16, 272, 208, 23, 23, 137, 148, 128, 20, - /* 1840 */ 140, 24, 16, 142, 1, 140, 149, 128, 61, 53, - /* 1850 */ 148, 37, 53, 53, 53, 128, 114, 34, 296, 296, - /* 1860 */ 139, 1, 5, 22, 113, 158, 26, 75, 41, 139, - /* 1870 */ 68, 68, 113, 24, 20, 19, 129, 123, 23, 96, - /* 1880 */ 22, 22, 37, 22, 22, 67, 22, 67, 59, 24, - /* 1890 */ 23, 28, 67, 147, 22, 26, 23, 23, 23, 23, - /* 1900 */ 22, 24, 23, 22, 24, 23, 139, 23, 114, 22, - /* 1910 */ 141, 26, 88, 75, 86, 44, 23, 34, 22, 75, - /* 1920 */ 34, 24, 34, 34, 34, 93, 34, 26, 26, 34, - /* 1930 */ 23, 23, 23, 23, 23, 11, 23, 22, 26, 22, - /* 1940 */ 22, 133, 23, 23, 22, 22, 139, 26, 139, 23, - /* 1950 */ 15, 1, 1, 310, 310, 310, 310, 310, 310, 310, - /* 1960 */ 139, 139, 310, 310, 310, 310, 310, 310, 310, 310, - /* 1970 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 1980 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 1990 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2000 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2010 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2020 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2030 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2040 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2050 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2060 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2070 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2080 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2090 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2100 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2110 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2120 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2130 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2140 */ 310, 310, 310, + /* 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 (552) +#define YY_SHIFT_COUNT (573) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (1951) +#define YY_SHIFT_MAX (2045) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 1448, 1277, 1668, 1072, 1072, 340, 1122, 1225, 1332, 1481, - /* 10 */ 1481, 1481, 335, 0, 0, 180, 897, 1481, 1481, 1481, - /* 20 */ 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, - /* 30 */ 930, 930, 1020, 1020, 290, 1, 340, 340, 340, 340, - /* 40 */ 340, 340, 40, 110, 219, 288, 327, 396, 435, 504, - /* 50 */ 543, 612, 651, 720, 877, 897, 897, 897, 897, 897, - /* 60 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 70 */ 897, 897, 897, 917, 897, 1019, 763, 763, 1451, 1481, - /* 80 */ 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, - /* 90 */ 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, - /* 100 */ 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, - /* 110 */ 1481, 1481, 1553, 1481, 1481, 1481, 1481, 1481, 1481, 1481, - /* 120 */ 1481, 1481, 1481, 1481, 1481, 1481, 147, 258, 258, 258, - /* 130 */ 258, 258, 79, 65, 84, 449, 19, 786, 449, 636, - /* 140 */ 636, 449, 880, 880, 880, 880, 113, 142, 142, 472, - /* 150 */ 150, 1962, 1962, 399, 399, 399, 93, 237, 341, 237, - /* 160 */ 237, 1074, 1074, 437, 350, 704, 1080, 449, 449, 449, - /* 170 */ 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - /* 180 */ 449, 449, 449, 449, 449, 449, 449, 449, 818, 818, - /* 190 */ 449, 1088, 217, 217, 734, 734, 1124, 1126, 1962, 1962, - /* 200 */ 1962, 739, 840, 840, 453, 454, 511, 187, 563, 570, - /* 210 */ 898, 669, 449, 449, 449, 449, 449, 449, 449, 449, - /* 220 */ 449, 670, 449, 449, 449, 449, 449, 449, 449, 449, - /* 230 */ 449, 449, 449, 449, 674, 674, 674, 449, 449, 449, - /* 240 */ 449, 1034, 449, 449, 449, 972, 1107, 449, 449, 1193, - /* 250 */ 449, 449, 449, 449, 449, 449, 449, 449, 260, 177, - /* 260 */ 489, 1241, 1241, 1241, 1241, 1192, 489, 489, 952, 1197, - /* 270 */ 625, 1235, 1131, 181, 181, 1086, 1139, 1131, 1086, 1187, - /* 280 */ 1319, 1237, 1318, 1318, 1318, 181, 1299, 1299, 1109, 1336, - /* 290 */ 549, 1376, 1610, 1535, 1535, 1639, 1639, 1535, 1539, 1578, - /* 300 */ 1670, 1546, 1652, 1546, 1681, 1681, 1681, 1681, 1535, 1694, - /* 310 */ 1546, 1546, 1578, 1670, 1652, 1546, 1652, 1546, 1535, 1694, - /* 320 */ 1565, 1665, 1535, 1694, 1708, 1535, 1694, 1535, 1694, 1708, - /* 330 */ 1618, 1618, 1618, 1680, 1723, 1723, 1708, 1618, 1623, 1618, - /* 340 */ 1680, 1618, 1618, 1588, 1708, 1640, 1640, 1708, 1611, 1643, - /* 350 */ 1611, 1643, 1611, 1643, 1611, 1643, 1535, 1685, 1685, 1695, - /* 360 */ 1695, 1636, 1641, 1761, 1535, 1631, 1636, 1644, 1646, 1546, - /* 370 */ 1763, 1766, 1781, 1781, 1791, 1791, 1791, 1962, 1962, 1962, - /* 380 */ 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, - /* 390 */ 1962, 1962, 308, 835, 954, 1232, 879, 715, 728, 1373, - /* 400 */ 864, 1329, 1253, 1409, 297, 1431, 1489, 1497, 1520, 1521, - /* 410 */ 1525, 1362, 1309, 1491, 1217, 1420, 1429, 1536, 1380, 1538, - /* 420 */ 1293, 1354, 1548, 1585, 1434, 1342, 1813, 1816, 1798, 1664, - /* 430 */ 1810, 1732, 1815, 1811, 1812, 1699, 1689, 1710, 1817, 1700, - /* 440 */ 1819, 1701, 1826, 1843, 1705, 1697, 1719, 1787, 1814, 1702, - /* 450 */ 1796, 1799, 1800, 1801, 1727, 1742, 1823, 1721, 1860, 1857, - /* 460 */ 1841, 1751, 1707, 1802, 1840, 1803, 1792, 1827, 1730, 1759, - /* 470 */ 1849, 1854, 1856, 1747, 1754, 1858, 1818, 1859, 1861, 1855, - /* 480 */ 1862, 1820, 1829, 1865, 1783, 1863, 1864, 1825, 1845, 1867, - /* 490 */ 1746, 1872, 1873, 1874, 1875, 1869, 1876, 1878, 1877, 1879, - /* 500 */ 1881, 1880, 1767, 1882, 1884, 1794, 1883, 1887, 1769, 1885, - /* 510 */ 1886, 1888, 1889, 1890, 1824, 1838, 1828, 1871, 1844, 1832, - /* 520 */ 1892, 1893, 1896, 1897, 1901, 1902, 1895, 1907, 1885, 1908, - /* 530 */ 1909, 1910, 1911, 1912, 1913, 1915, 1924, 1917, 1918, 1919, - /* 540 */ 1920, 1922, 1923, 1921, 1808, 1807, 1809, 1821, 1822, 1926, - /* 550 */ 1935, 1950, 1951, + /* 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 (391) -#define YY_REDUCE_MIN (-262) -#define YY_REDUCE_MAX (1625) +#define YY_REDUCE_COUNT (408) +#define YY_REDUCE_MIN (-267) +#define YY_REDUCE_MAX (1715) static const short yy_reduce_ofst[] = { - /* 0 */ 490, -122, 545, 645, 650, -120, -189, -187, -184, -182, - /* 10 */ -178, -176, 45, 30, 200, -251, -134, 390, 392, 521, - /* 20 */ 523, 213, 692, 821, 284, 589, 872, 666, 671, 866, - /* 30 */ 71, 111, 273, 389, 686, 815, 904, 932, 948, 955, - /* 40 */ 964, 969, -259, -259, -259, -259, -259, -259, -259, -259, - /* 50 */ -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, - /* 60 */ -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, - /* 70 */ -259, -259, -259, -259, -259, -259, -259, -259, 428, 430, - /* 80 */ 899, 985, 1021, 1028, 1057, 1069, 1081, 1108, 1110, 1115, - /* 90 */ 1117, 1123, 1149, 1154, 1159, 1170, 1174, 1178, 1183, 1194, - /* 100 */ 1198, 1204, 1208, 1212, 1218, 1222, 1229, 1278, 1280, 1283, - /* 110 */ 1285, 1313, 1316, 1320, 1322, 1325, 1327, 1330, 1366, 1371, - /* 120 */ 1379, 1387, 1417, 1425, 1430, 1432, -259, -259, -259, -259, - /* 130 */ -259, -259, -259, -259, -259, 557, 974, -214, -174, -9, - /* 140 */ 431, -124, 806, 925, 806, 925, 251, 928, 940, -259, - /* 150 */ -259, -259, -259, -198, -198, -198, 127, -186, -168, 212, - /* 160 */ 646, 617, 799, -262, 555, 220, 220, 491, 605, 1040, - /* 170 */ 1060, 699, -11, 600, 848, 862, 345, -129, 724, -91, - /* 180 */ 158, 749, 716, 900, 304, 822, 929, 926, 499, 793, - /* 190 */ 322, 892, 813, 845, 958, 1056, 751, 905, 1133, 1062, - /* 200 */ 803, -210, -185, -179, -148, -167, -89, 121, 274, 281, - /* 210 */ 320, 336, 439, 663, 711, 957, 965, 1064, 1068, 1112, - /* 220 */ 1116, -196, 1127, 1134, 1180, 1184, 1195, 1199, 1203, 1215, - /* 230 */ 1223, 1250, 1267, 1286, 205, 422, 638, 1324, 1341, 1364, - /* 240 */ 1365, 1213, 1392, 1399, 1403, 869, 1260, 1405, 1421, 1276, - /* 250 */ 1424, 121, 1426, 1427, 1428, 1433, 1436, 1437, 1227, 1338, - /* 260 */ 1284, 1359, 1370, 1377, 1388, 1213, 1284, 1284, 1385, 1438, - /* 270 */ 1443, 1349, 1400, 1391, 1394, 1360, 1408, 1410, 1367, 1439, - /* 280 */ 1440, 1435, 1442, 1446, 1447, 1397, 1413, 1418, 1390, 1444, - /* 290 */ 1445, 1474, 1381, 1479, 1480, 1401, 1402, 1490, 1414, 1449, - /* 300 */ 1452, 1453, 1467, 1456, 1469, 1470, 1477, 1478, 1515, 1518, - /* 310 */ 1476, 1482, 1450, 1454, 1492, 1483, 1493, 1484, 1523, 1531, - /* 320 */ 1457, 1455, 1532, 1534, 1516, 1537, 1540, 1543, 1541, 1526, - /* 330 */ 1528, 1530, 1542, 1512, 1529, 1533, 1544, 1545, 1547, 1550, - /* 340 */ 1549, 1551, 1554, 1458, 1552, 1494, 1495, 1556, 1498, 1502, - /* 350 */ 1503, 1511, 1517, 1519, 1522, 1524, 1579, 1472, 1473, 1527, - /* 360 */ 1555, 1557, 1559, 1558, 1589, 1560, 1561, 1564, 1566, 1568, - /* 370 */ 1592, 1595, 1605, 1606, 1612, 1613, 1622, 1562, 1563, 1505, - /* 380 */ 1609, 1604, 1608, 1614, 1615, 1616, 1596, 1597, 1617, 1620, - /* 390 */ 1625, 1619, + /* 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 */ 1575, 1575, 1575, 1411, 1188, 1297, 1188, 1188, 1188, 1411, - /* 10 */ 1411, 1411, 1188, 1327, 1327, 1464, 1219, 1188, 1188, 1188, - /* 20 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1410, 1188, 1188, - /* 30 */ 1188, 1188, 1494, 1494, 1188, 1188, 1188, 1188, 1188, 1188, - /* 40 */ 1188, 1188, 1188, 1336, 1188, 1188, 1188, 1188, 1188, 1188, - /* 50 */ 1412, 1413, 1188, 1188, 1188, 1463, 1465, 1428, 1346, 1345, - /* 60 */ 1344, 1343, 1446, 1314, 1341, 1334, 1338, 1406, 1407, 1405, - /* 70 */ 1409, 1413, 1412, 1188, 1337, 1377, 1391, 1376, 1188, 1188, - /* 80 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 90 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 100 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 110 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 120 */ 1188, 1188, 1188, 1188, 1188, 1188, 1385, 1390, 1396, 1389, - /* 130 */ 1386, 1379, 1378, 1380, 1381, 1188, 1209, 1261, 1188, 1188, - /* 140 */ 1188, 1188, 1482, 1481, 1188, 1188, 1219, 1371, 1370, 1382, - /* 150 */ 1383, 1393, 1392, 1471, 1529, 1528, 1429, 1188, 1188, 1188, - /* 160 */ 1188, 1188, 1188, 1494, 1188, 1188, 1188, 1188, 1188, 1188, - /* 170 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 180 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1494, 1494, - /* 190 */ 1188, 1219, 1494, 1494, 1215, 1215, 1321, 1188, 1477, 1297, - /* 200 */ 1288, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 210 */ 1188, 1188, 1188, 1188, 1188, 1468, 1466, 1188, 1188, 1188, - /* 220 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 230 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 240 */ 1188, 1188, 1188, 1188, 1188, 1293, 1188, 1188, 1188, 1188, - /* 250 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1523, 1188, 1441, - /* 260 */ 1275, 1293, 1293, 1293, 1293, 1295, 1276, 1274, 1287, 1220, - /* 270 */ 1195, 1567, 1294, 1316, 1316, 1564, 1340, 1294, 1564, 1236, - /* 280 */ 1545, 1231, 1327, 1327, 1327, 1316, 1321, 1321, 1408, 1294, - /* 290 */ 1287, 1188, 1567, 1302, 1302, 1566, 1566, 1302, 1429, 1349, - /* 300 */ 1355, 1340, 1264, 1340, 1270, 1270, 1270, 1270, 1302, 1206, - /* 310 */ 1340, 1340, 1349, 1355, 1264, 1340, 1264, 1340, 1302, 1206, - /* 320 */ 1445, 1561, 1302, 1206, 1419, 1302, 1206, 1302, 1206, 1419, - /* 330 */ 1262, 1262, 1262, 1251, 1188, 1188, 1419, 1262, 1236, 1262, - /* 340 */ 1251, 1262, 1262, 1512, 1419, 1423, 1423, 1419, 1320, 1315, - /* 350 */ 1320, 1315, 1320, 1315, 1320, 1315, 1302, 1504, 1504, 1330, - /* 360 */ 1330, 1335, 1321, 1414, 1302, 1188, 1335, 1333, 1331, 1340, - /* 370 */ 1212, 1254, 1526, 1526, 1522, 1522, 1522, 1572, 1572, 1477, - /* 380 */ 1538, 1219, 1219, 1219, 1219, 1538, 1238, 1238, 1220, 1220, - /* 390 */ 1219, 1538, 1188, 1188, 1188, 1188, 1188, 1188, 1533, 1188, - /* 400 */ 1430, 1306, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 410 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 420 */ 1188, 1188, 1188, 1188, 1188, 1360, 1188, 1191, 1474, 1188, - /* 430 */ 1188, 1472, 1188, 1188, 1188, 1188, 1188, 1188, 1307, 1188, - /* 440 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 450 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1563, 1188, 1188, - /* 460 */ 1188, 1188, 1188, 1188, 1444, 1443, 1188, 1188, 1304, 1188, - /* 470 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 480 */ 1188, 1188, 1234, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 490 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 500 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1332, - /* 510 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 520 */ 1188, 1188, 1188, 1188, 1509, 1322, 1188, 1188, 1554, 1188, - /* 530 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 540 */ 1188, 1188, 1188, 1549, 1278, 1362, 1188, 1361, 1365, 1188, - /* 550 */ 1200, 1188, 1188, + /* 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 *****************************/ @@ -155219,8 +162454,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 */ @@ -155291,6 +162526,7 @@ static const YYCODETYPE yyFallback[] = { 59, /* TIES => ID */ 59, /* GENERATED => ID */ 59, /* ALWAYS => ID */ + 59, /* MATERIALIZED => ID */ 59, /* REINDEX => ID */ 59, /* RENAME => ID */ 59, /* CTIME_KW => ID */ @@ -155305,6 +162541,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 */ @@ -155342,6 +162579,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* HAVING => nothing */ 0, /* LIMIT => nothing */ 0, /* WHERE => nothing */ + 0, /* RETURNING => nothing */ 0, /* INTO => nothing */ 0, /* NOTHING => nothing */ 0, /* FLOAT => nothing */ @@ -155373,6 +162611,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* IF_NULL_ROW => nothing */ 0, /* ASTERISK => nothing */ 0, /* SPAN => nothing */ + 0, /* ERROR => nothing */ 0, /* SPACE => nothing */ 0, /* ILLEGAL => nothing */ }; @@ -155426,6 +162665,7 @@ struct yyParser { }; typedef struct yyParser yyParser; +/* #include */ #ifndef NDEBUG /* #include */ static FILE *yyTraceFILE = 0; @@ -155487,8 +162727,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", @@ -155559,219 +162799,228 @@ static const char *const yyTokenName[] = { /* 94 */ "TIES", /* 95 */ "GENERATED", /* 96 */ "ALWAYS", - /* 97 */ "REINDEX", - /* 98 */ "RENAME", - /* 99 */ "CTIME_KW", - /* 100 */ "ANY", - /* 101 */ "BITAND", - /* 102 */ "BITOR", - /* 103 */ "LSHIFT", - /* 104 */ "RSHIFT", - /* 105 */ "PLUS", - /* 106 */ "MINUS", - /* 107 */ "STAR", - /* 108 */ "SLASH", - /* 109 */ "REM", - /* 110 */ "CONCAT", - /* 111 */ "COLLATE", - /* 112 */ "BITNOT", - /* 113 */ "ON", - /* 114 */ "INDEXED", - /* 115 */ "STRING", - /* 116 */ "JOIN_KW", - /* 117 */ "CONSTRAINT", - /* 118 */ "DEFAULT", - /* 119 */ "NULL", - /* 120 */ "PRIMARY", - /* 121 */ "UNIQUE", - /* 122 */ "CHECK", - /* 123 */ "REFERENCES", - /* 124 */ "AUTOINCR", - /* 125 */ "INSERT", - /* 126 */ "DELETE", - /* 127 */ "UPDATE", - /* 128 */ "SET", - /* 129 */ "DEFERRABLE", - /* 130 */ "FOREIGN", - /* 131 */ "DROP", - /* 132 */ "UNION", - /* 133 */ "ALL", - /* 134 */ "EXCEPT", - /* 135 */ "INTERSECT", - /* 136 */ "SELECT", - /* 137 */ "VALUES", - /* 138 */ "DISTINCT", - /* 139 */ "DOT", - /* 140 */ "FROM", - /* 141 */ "JOIN", - /* 142 */ "USING", - /* 143 */ "ORDER", - /* 144 */ "GROUP", - /* 145 */ "HAVING", - /* 146 */ "LIMIT", - /* 147 */ "WHERE", - /* 148 */ "INTO", - /* 149 */ "NOTHING", - /* 150 */ "FLOAT", - /* 151 */ "BLOB", - /* 152 */ "INTEGER", - /* 153 */ "VARIABLE", - /* 154 */ "CASE", - /* 155 */ "WHEN", - /* 156 */ "THEN", - /* 157 */ "ELSE", - /* 158 */ "INDEX", - /* 159 */ "ALTER", - /* 160 */ "ADD", - /* 161 */ "WINDOW", - /* 162 */ "OVER", - /* 163 */ "FILTER", - /* 164 */ "COLUMN", - /* 165 */ "AGG_FUNCTION", - /* 166 */ "AGG_COLUMN", - /* 167 */ "TRUEFALSE", - /* 168 */ "ISNOT", - /* 169 */ "FUNCTION", - /* 170 */ "UMINUS", - /* 171 */ "UPLUS", - /* 172 */ "TRUTH", - /* 173 */ "REGISTER", - /* 174 */ "VECTOR", - /* 175 */ "SELECT_COLUMN", - /* 176 */ "IF_NULL_ROW", - /* 177 */ "ASTERISK", - /* 178 */ "SPAN", - /* 179 */ "SPACE", - /* 180 */ "ILLEGAL", - /* 181 */ "input", - /* 182 */ "cmdlist", - /* 183 */ "ecmd", - /* 184 */ "cmdx", - /* 185 */ "explain", - /* 186 */ "cmd", - /* 187 */ "transtype", - /* 188 */ "trans_opt", - /* 189 */ "nm", - /* 190 */ "savepoint_opt", - /* 191 */ "create_table", - /* 192 */ "create_table_args", - /* 193 */ "createkw", - /* 194 */ "temp", - /* 195 */ "ifnotexists", - /* 196 */ "dbnm", - /* 197 */ "columnlist", - /* 198 */ "conslist_opt", - /* 199 */ "table_options", - /* 200 */ "select", - /* 201 */ "columnname", - /* 202 */ "carglist", - /* 203 */ "typetoken", - /* 204 */ "typename", - /* 205 */ "signed", - /* 206 */ "plus_num", - /* 207 */ "minus_num", - /* 208 */ "scanpt", - /* 209 */ "scantok", - /* 210 */ "ccons", - /* 211 */ "term", - /* 212 */ "expr", - /* 213 */ "onconf", - /* 214 */ "sortorder", - /* 215 */ "autoinc", - /* 216 */ "eidlist_opt", - /* 217 */ "refargs", - /* 218 */ "defer_subclause", - /* 219 */ "generated", - /* 220 */ "refarg", - /* 221 */ "refact", - /* 222 */ "init_deferred_pred_opt", - /* 223 */ "conslist", - /* 224 */ "tconscomma", - /* 225 */ "tcons", - /* 226 */ "sortlist", - /* 227 */ "eidlist", - /* 228 */ "defer_subclause_opt", - /* 229 */ "orconf", - /* 230 */ "resolvetype", - /* 231 */ "raisetype", - /* 232 */ "ifexists", - /* 233 */ "fullname", - /* 234 */ "selectnowith", - /* 235 */ "oneselect", - /* 236 */ "wqlist", - /* 237 */ "multiselect_op", - /* 238 */ "distinct", - /* 239 */ "selcollist", - /* 240 */ "from", - /* 241 */ "where_opt", - /* 242 */ "groupby_opt", - /* 243 */ "having_opt", - /* 244 */ "orderby_opt", - /* 245 */ "limit_opt", - /* 246 */ "window_clause", - /* 247 */ "values", - /* 248 */ "nexprlist", - /* 249 */ "sclp", - /* 250 */ "as", - /* 251 */ "seltablist", - /* 252 */ "stl_prefix", - /* 253 */ "joinop", - /* 254 */ "indexed_opt", - /* 255 */ "on_opt", - /* 256 */ "using_opt", - /* 257 */ "exprlist", - /* 258 */ "xfullname", - /* 259 */ "idlist", - /* 260 */ "nulls", - /* 261 */ "with", - /* 262 */ "setlist", - /* 263 */ "insert_cmd", - /* 264 */ "idlist_opt", - /* 265 */ "upsert", - /* 266 */ "filter_over", - /* 267 */ "likeop", - /* 268 */ "between_op", - /* 269 */ "in_op", - /* 270 */ "paren_exprlist", - /* 271 */ "case_operand", - /* 272 */ "case_exprlist", - /* 273 */ "case_else", - /* 274 */ "uniqueflag", - /* 275 */ "collate", - /* 276 */ "vinto", - /* 277 */ "nmnum", - /* 278 */ "trigger_decl", - /* 279 */ "trigger_cmd_list", - /* 280 */ "trigger_time", - /* 281 */ "trigger_event", - /* 282 */ "foreach_clause", - /* 283 */ "when_clause", - /* 284 */ "trigger_cmd", - /* 285 */ "trnm", - /* 286 */ "tridxby", - /* 287 */ "database_kw_opt", - /* 288 */ "key_opt", - /* 289 */ "add_column_fullname", - /* 290 */ "kwcolumn_opt", - /* 291 */ "create_vtab", - /* 292 */ "vtabarglist", - /* 293 */ "vtabarg", - /* 294 */ "vtabargtoken", - /* 295 */ "lp", - /* 296 */ "anylist", - /* 297 */ "windowdefn_list", - /* 298 */ "windowdefn", - /* 299 */ "window", - /* 300 */ "frame_opt", - /* 301 */ "part_opt", - /* 302 */ "filter_clause", - /* 303 */ "over_clause", - /* 304 */ "range_or_rows", - /* 305 */ "frame_bound", - /* 306 */ "frame_bound_s", - /* 307 */ "frame_bound_e", - /* 308 */ "frame_exclude_opt", - /* 309 */ "frame_exclude", + /* 97 */ "MATERIALIZED", + /* 98 */ "REINDEX", + /* 99 */ "RENAME", + /* 100 */ "CTIME_KW", + /* 101 */ "ANY", + /* 102 */ "BITAND", + /* 103 */ "BITOR", + /* 104 */ "LSHIFT", + /* 105 */ "RSHIFT", + /* 106 */ "PLUS", + /* 107 */ "MINUS", + /* 108 */ "STAR", + /* 109 */ "SLASH", + /* 110 */ "REM", + /* 111 */ "CONCAT", + /* 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) */ @@ -155798,372 +163047,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", - /* 149 */ "where_opt ::=", - /* 150 */ "where_opt ::= WHERE expr", - /* 151 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt", - /* 152 */ "setlist ::= setlist COMMA nm EQ expr", - /* 153 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", - /* 154 */ "setlist ::= nm EQ expr", - /* 155 */ "setlist ::= LP idlist RP EQ expr", - /* 156 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", - /* 157 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES", - /* 158 */ "upsert ::=", - /* 159 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt", - /* 160 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING", - /* 161 */ "upsert ::= ON CONFLICT DO NOTHING", - /* 162 */ "insert_cmd ::= INSERT orconf", - /* 163 */ "insert_cmd ::= REPLACE", - /* 164 */ "idlist_opt ::=", - /* 165 */ "idlist_opt ::= LP idlist RP", - /* 166 */ "idlist ::= idlist COMMA nm", - /* 167 */ "idlist ::= nm", - /* 168 */ "expr ::= LP expr RP", - /* 169 */ "expr ::= ID|INDEXED", - /* 170 */ "expr ::= JOIN_KW", - /* 171 */ "expr ::= nm DOT nm", - /* 172 */ "expr ::= nm DOT nm DOT nm", - /* 173 */ "term ::= NULL|FLOAT|BLOB", - /* 174 */ "term ::= STRING", - /* 175 */ "term ::= INTEGER", - /* 176 */ "expr ::= VARIABLE", - /* 177 */ "expr ::= expr COLLATE ID|STRING", - /* 178 */ "expr ::= CAST LP expr AS typetoken RP", - /* 179 */ "expr ::= ID|INDEXED LP distinct exprlist RP", - /* 180 */ "expr ::= ID|INDEXED LP STAR RP", - /* 181 */ "expr ::= ID|INDEXED LP distinct exprlist RP filter_over", - /* 182 */ "expr ::= ID|INDEXED LP STAR RP filter_over", - /* 183 */ "term ::= CTIME_KW", - /* 184 */ "expr ::= LP nexprlist COMMA expr RP", - /* 185 */ "expr ::= expr AND expr", - /* 186 */ "expr ::= expr OR expr", - /* 187 */ "expr ::= expr LT|GT|GE|LE expr", - /* 188 */ "expr ::= expr EQ|NE expr", - /* 189 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", - /* 190 */ "expr ::= expr PLUS|MINUS expr", - /* 191 */ "expr ::= expr STAR|SLASH|REM expr", - /* 192 */ "expr ::= expr CONCAT expr", - /* 193 */ "likeop ::= NOT LIKE_KW|MATCH", - /* 194 */ "expr ::= expr likeop expr", - /* 195 */ "expr ::= expr likeop expr ESCAPE expr", - /* 196 */ "expr ::= expr ISNULL|NOTNULL", - /* 197 */ "expr ::= expr NOT NULL", - /* 198 */ "expr ::= expr IS expr", - /* 199 */ "expr ::= expr IS NOT expr", - /* 200 */ "expr ::= NOT expr", - /* 201 */ "expr ::= BITNOT expr", - /* 202 */ "expr ::= PLUS|MINUS expr", - /* 203 */ "between_op ::= BETWEEN", - /* 204 */ "between_op ::= NOT BETWEEN", - /* 205 */ "expr ::= expr between_op expr AND expr", - /* 206 */ "in_op ::= IN", - /* 207 */ "in_op ::= NOT IN", - /* 208 */ "expr ::= expr in_op LP exprlist RP", - /* 209 */ "expr ::= LP select RP", - /* 210 */ "expr ::= expr in_op LP select RP", - /* 211 */ "expr ::= expr in_op nm dbnm paren_exprlist", - /* 212 */ "expr ::= EXISTS LP select RP", - /* 213 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 214 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 215 */ "case_exprlist ::= WHEN expr THEN expr", - /* 216 */ "case_else ::= ELSE expr", - /* 217 */ "case_else ::=", - /* 218 */ "case_operand ::= expr", - /* 219 */ "case_operand ::=", - /* 220 */ "exprlist ::=", - /* 221 */ "nexprlist ::= nexprlist COMMA expr", - /* 222 */ "nexprlist ::= expr", - /* 223 */ "paren_exprlist ::=", - /* 224 */ "paren_exprlist ::= LP exprlist RP", - /* 225 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", - /* 226 */ "uniqueflag ::= UNIQUE", - /* 227 */ "uniqueflag ::=", - /* 228 */ "eidlist_opt ::=", - /* 229 */ "eidlist_opt ::= LP eidlist RP", - /* 230 */ "eidlist ::= eidlist COMMA nm collate sortorder", - /* 231 */ "eidlist ::= nm collate sortorder", - /* 232 */ "collate ::=", - /* 233 */ "collate ::= COLLATE ID|STRING", - /* 234 */ "cmd ::= DROP INDEX ifexists fullname", - /* 235 */ "cmd ::= VACUUM vinto", - /* 236 */ "cmd ::= VACUUM nm vinto", - /* 237 */ "vinto ::= INTO expr", - /* 238 */ "vinto ::=", - /* 239 */ "cmd ::= PRAGMA nm dbnm", - /* 240 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 241 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 242 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 243 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 244 */ "plus_num ::= PLUS INTEGER|FLOAT", - /* 245 */ "minus_num ::= MINUS INTEGER|FLOAT", - /* 246 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 247 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 248 */ "trigger_time ::= BEFORE|AFTER", - /* 249 */ "trigger_time ::= INSTEAD OF", - /* 250 */ "trigger_time ::=", - /* 251 */ "trigger_event ::= DELETE|INSERT", - /* 252 */ "trigger_event ::= UPDATE", - /* 253 */ "trigger_event ::= UPDATE OF idlist", - /* 254 */ "when_clause ::=", - /* 255 */ "when_clause ::= WHEN expr", - /* 256 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 257 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 258 */ "trnm ::= nm DOT nm", - /* 259 */ "tridxby ::= INDEXED BY nm", - /* 260 */ "tridxby ::= NOT INDEXED", - /* 261 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", - /* 262 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", - /* 263 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", - /* 264 */ "trigger_cmd ::= scanpt select scanpt", - /* 265 */ "expr ::= RAISE LP IGNORE RP", - /* 266 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 267 */ "raisetype ::= ROLLBACK", - /* 268 */ "raisetype ::= ABORT", - /* 269 */ "raisetype ::= FAIL", - /* 270 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 271 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 272 */ "cmd ::= DETACH database_kw_opt expr", - /* 273 */ "key_opt ::=", - /* 274 */ "key_opt ::= KEY expr", - /* 275 */ "cmd ::= REINDEX", - /* 276 */ "cmd ::= REINDEX nm dbnm", - /* 277 */ "cmd ::= ANALYZE", - /* 278 */ "cmd ::= ANALYZE nm dbnm", - /* 279 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 280 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", - /* 281 */ "add_column_fullname ::= fullname", - /* 282 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", - /* 283 */ "cmd ::= create_vtab", - /* 284 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 285 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", - /* 286 */ "vtabarg ::=", - /* 287 */ "vtabargtoken ::= ANY", - /* 288 */ "vtabargtoken ::= lp anylist RP", - /* 289 */ "lp ::= LP", - /* 290 */ "with ::= WITH wqlist", - /* 291 */ "with ::= WITH RECURSIVE wqlist", - /* 292 */ "wqlist ::= nm eidlist_opt AS LP select RP", - /* 293 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP", - /* 294 */ "windowdefn_list ::= windowdefn", - /* 295 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", - /* 296 */ "windowdefn ::= nm AS LP window RP", - /* 297 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", - /* 298 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", - /* 299 */ "window ::= ORDER BY sortlist frame_opt", - /* 300 */ "window ::= nm ORDER BY sortlist frame_opt", - /* 301 */ "window ::= frame_opt", - /* 302 */ "window ::= nm frame_opt", - /* 303 */ "frame_opt ::=", - /* 304 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", - /* 305 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", - /* 306 */ "range_or_rows ::= RANGE|ROWS|GROUPS", - /* 307 */ "frame_bound_s ::= frame_bound", - /* 308 */ "frame_bound_s ::= UNBOUNDED PRECEDING", - /* 309 */ "frame_bound_e ::= frame_bound", - /* 310 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", - /* 311 */ "frame_bound ::= expr PRECEDING|FOLLOWING", - /* 312 */ "frame_bound ::= CURRENT ROW", - /* 313 */ "frame_exclude_opt ::=", - /* 314 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", - /* 315 */ "frame_exclude ::= NO OTHERS", - /* 316 */ "frame_exclude ::= CURRENT ROW", - /* 317 */ "frame_exclude ::= GROUP|TIES", - /* 318 */ "window_clause ::= WINDOW windowdefn_list", - /* 319 */ "filter_over ::= filter_clause over_clause", - /* 320 */ "filter_over ::= over_clause", - /* 321 */ "filter_over ::= filter_clause", - /* 322 */ "over_clause ::= OVER LP window RP", - /* 323 */ "over_clause ::= OVER nm", - /* 324 */ "filter_clause ::= FILTER LP WHERE expr RP", - /* 325 */ "input ::= cmdlist", - /* 326 */ "cmdlist ::= cmdlist ecmd", - /* 327 */ "cmdlist ::= ecmd", - /* 328 */ "ecmd ::= SEMI", - /* 329 */ "ecmd ::= cmdx SEMI", - /* 330 */ "ecmd ::= explain cmdx SEMI", - /* 331 */ "trans_opt ::=", - /* 332 */ "trans_opt ::= TRANSACTION", - /* 333 */ "trans_opt ::= TRANSACTION nm", - /* 334 */ "savepoint_opt ::= SAVEPOINT", - /* 335 */ "savepoint_opt ::=", - /* 336 */ "cmd ::= create_table create_table_args", - /* 337 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 338 */ "columnlist ::= columnname carglist", - /* 339 */ "nm ::= ID|INDEXED", - /* 340 */ "nm ::= STRING", - /* 341 */ "nm ::= JOIN_KW", - /* 342 */ "typetoken ::= typename", - /* 343 */ "typename ::= ID|STRING", - /* 344 */ "signed ::= plus_num", - /* 345 */ "signed ::= minus_num", - /* 346 */ "carglist ::= carglist ccons", - /* 347 */ "carglist ::=", - /* 348 */ "ccons ::= NULL onconf", - /* 349 */ "ccons ::= GENERATED ALWAYS AS generated", - /* 350 */ "ccons ::= AS generated", - /* 351 */ "conslist_opt ::= COMMA conslist", - /* 352 */ "conslist ::= conslist tconscomma tcons", - /* 353 */ "conslist ::= tcons", - /* 354 */ "tconscomma ::=", - /* 355 */ "defer_subclause_opt ::= defer_subclause", - /* 356 */ "resolvetype ::= raisetype", - /* 357 */ "selectnowith ::= oneselect", - /* 358 */ "oneselect ::= values", - /* 359 */ "sclp ::= selcollist COMMA", - /* 360 */ "as ::= ID|STRING", - /* 361 */ "expr ::= term", - /* 362 */ "likeop ::= LIKE_KW|MATCH", - /* 363 */ "exprlist ::= nexprlist", - /* 364 */ "nmnum ::= plus_num", - /* 365 */ "nmnum ::= nm", - /* 366 */ "nmnum ::= ON", - /* 367 */ "nmnum ::= DELETE", - /* 368 */ "nmnum ::= DEFAULT", - /* 369 */ "plus_num ::= INTEGER|FLOAT", - /* 370 */ "foreach_clause ::=", - /* 371 */ "foreach_clause ::= FOR EACH ROW", - /* 372 */ "trnm ::= nm", - /* 373 */ "tridxby ::=", - /* 374 */ "database_kw_opt ::= DATABASE", - /* 375 */ "database_kw_opt ::=", - /* 376 */ "kwcolumn_opt ::=", - /* 377 */ "kwcolumn_opt ::= COLUMNKW", - /* 378 */ "vtabarglist ::= vtabarg", - /* 379 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 380 */ "vtabarg ::= vtabarg vtabargtoken", - /* 381 */ "anylist ::=", - /* 382 */ "anylist ::= anylist LP anylist RP", - /* 383 */ "anylist ::= anylist ANY", - /* 384 */ "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 */ @@ -156289,98 +163555,99 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 200: /* select */ - case 234: /* selectnowith */ - case 235: /* oneselect */ - case 247: /* values */ + case 204: /* select */ + case 239: /* selectnowith */ + case 240: /* oneselect */ + case 252: /* values */ { -sqlite3SelectDelete(pParse->db, (yypminor->yy539)); -} - break; - case 211: /* term */ - case 212: /* expr */ - case 241: /* where_opt */ - case 243: /* having_opt */ - case 255: /* on_opt */ - case 271: /* case_operand */ - case 273: /* case_else */ - case 276: /* vinto */ - case 283: /* when_clause */ - case 288: /* key_opt */ - case 302: /* filter_clause */ +sqlite3SelectDelete(pParse->db, (yypminor->yy47)); +} + break; + 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->yy202)); -} - break; - case 216: /* eidlist_opt */ - case 226: /* sortlist */ - case 227: /* eidlist */ - case 239: /* selcollist */ - case 242: /* groupby_opt */ - case 244: /* orderby_opt */ - case 248: /* nexprlist */ - case 249: /* sclp */ - case 257: /* exprlist */ - case 262: /* setlist */ - case 270: /* paren_exprlist */ - case 272: /* case_exprlist */ - case 301: /* part_opt */ +sqlite3ExprDelete(pParse->db, (yypminor->yy528)); +} + break; + 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->yy242)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy322)); } break; - case 233: /* fullname */ - case 240: /* from */ - case 251: /* seltablist */ - case 252: /* stl_prefix */ - case 258: /* xfullname */ + case 238: /* fullname */ + case 245: /* from */ + case 256: /* seltablist */ + case 257: /* stl_prefix */ + case 263: /* xfullname */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy47)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy131)); } break; - case 236: /* wqlist */ + case 241: /* wqlist */ { -sqlite3WithDelete(pParse->db, (yypminor->yy131)); +sqlite3WithDelete(pParse->db, (yypminor->yy521)); } break; - case 246: /* window_clause */ - case 297: /* windowdefn_list */ + case 251: /* window_clause */ + case 306: /* windowdefn_list */ { -sqlite3WindowListDelete(pParse->db, (yypminor->yy303)); +sqlite3WindowListDelete(pParse->db, (yypminor->yy41)); } break; - case 256: /* using_opt */ - case 259: /* idlist */ - case 264: /* idlist_opt */ + case 261: /* using_opt */ + case 264: /* idlist */ + case 270: /* idlist_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy600)); +sqlite3IdListDelete(pParse->db, (yypminor->yy254)); } break; - case 266: /* filter_over */ - case 298: /* windowdefn */ - case 299: /* window */ - case 300: /* frame_opt */ - case 303: /* over_clause */ + case 273: /* filter_over */ + case 307: /* windowdefn */ + case 308: /* window */ + case 309: /* frame_opt */ + case 312: /* over_clause */ { -sqlite3WindowDelete(pParse->db, (yypminor->yy303)); +sqlite3WindowDelete(pParse->db, (yypminor->yy41)); } break; - case 279: /* trigger_cmd_list */ - case 284: /* trigger_cmd */ + case 286: /* trigger_cmd_list */ + case 291: /* trigger_cmd */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy447)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy33)); } break; - case 281: /* trigger_event */ + case 288: /* trigger_event */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy230).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy180).b); } break; - case 305: /* frame_bound */ - case 306: /* frame_bound_s */ - case 307: /* frame_bound_e */ + case 314: /* frame_bound */ + case 315: /* frame_bound_s */ + case 316: /* frame_bound_e */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy77).pExpr); +sqlite3ExprDelete(pParse->db, (yypminor->yy595).pExpr); } break; /********* End destructor definitions *****************************************/ @@ -156547,7 +163814,7 @@ static YYACTIONTYPE yy_find_shift_action( #endif /* YYWILDCARD */ return yy_default[stateno]; }else{ - assert( i>=0 && i=0 && i<(int)(sizeof(yy_action)/sizeof(yy_action[0])) ); return yy_action[i]; } }while(1); @@ -156671,391 +163938,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[] = { - 185, /* (0) explain ::= EXPLAIN */ - 185, /* (1) explain ::= EXPLAIN QUERY PLAN */ - 184, /* (2) cmdx ::= cmd */ - 186, /* (3) cmd ::= BEGIN transtype trans_opt */ - 187, /* (4) transtype ::= */ - 187, /* (5) transtype ::= DEFERRED */ - 187, /* (6) transtype ::= IMMEDIATE */ - 187, /* (7) transtype ::= EXCLUSIVE */ - 186, /* (8) cmd ::= COMMIT|END trans_opt */ - 186, /* (9) cmd ::= ROLLBACK trans_opt */ - 186, /* (10) cmd ::= SAVEPOINT nm */ - 186, /* (11) cmd ::= RELEASE savepoint_opt nm */ - 186, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ - 191, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ - 193, /* (14) createkw ::= CREATE */ - 195, /* (15) ifnotexists ::= */ - 195, /* (16) ifnotexists ::= IF NOT EXISTS */ - 194, /* (17) temp ::= TEMP */ - 194, /* (18) temp ::= */ - 192, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */ - 192, /* (20) create_table_args ::= AS select */ - 199, /* (21) table_options ::= */ - 199, /* (22) table_options ::= WITHOUT nm */ - 201, /* (23) columnname ::= nm typetoken */ - 203, /* (24) typetoken ::= */ - 203, /* (25) typetoken ::= typename LP signed RP */ - 203, /* (26) typetoken ::= typename LP signed COMMA signed RP */ - 204, /* (27) typename ::= typename ID|STRING */ - 208, /* (28) scanpt ::= */ - 209, /* (29) scantok ::= */ - 210, /* (30) ccons ::= CONSTRAINT nm */ - 210, /* (31) ccons ::= DEFAULT scantok term */ - 210, /* (32) ccons ::= DEFAULT LP expr RP */ - 210, /* (33) ccons ::= DEFAULT PLUS scantok term */ - 210, /* (34) ccons ::= DEFAULT MINUS scantok term */ - 210, /* (35) ccons ::= DEFAULT scantok ID|INDEXED */ - 210, /* (36) ccons ::= NOT NULL onconf */ - 210, /* (37) ccons ::= PRIMARY KEY sortorder onconf autoinc */ - 210, /* (38) ccons ::= UNIQUE onconf */ - 210, /* (39) ccons ::= CHECK LP expr RP */ - 210, /* (40) ccons ::= REFERENCES nm eidlist_opt refargs */ - 210, /* (41) ccons ::= defer_subclause */ - 210, /* (42) ccons ::= COLLATE ID|STRING */ - 219, /* (43) generated ::= LP expr RP */ - 219, /* (44) generated ::= LP expr RP ID */ - 215, /* (45) autoinc ::= */ - 215, /* (46) autoinc ::= AUTOINCR */ - 217, /* (47) refargs ::= */ - 217, /* (48) refargs ::= refargs refarg */ - 220, /* (49) refarg ::= MATCH nm */ - 220, /* (50) refarg ::= ON INSERT refact */ - 220, /* (51) refarg ::= ON DELETE refact */ - 220, /* (52) refarg ::= ON UPDATE refact */ - 221, /* (53) refact ::= SET NULL */ - 221, /* (54) refact ::= SET DEFAULT */ - 221, /* (55) refact ::= CASCADE */ - 221, /* (56) refact ::= RESTRICT */ - 221, /* (57) refact ::= NO ACTION */ - 218, /* (58) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ - 218, /* (59) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - 222, /* (60) init_deferred_pred_opt ::= */ - 222, /* (61) init_deferred_pred_opt ::= INITIALLY DEFERRED */ - 222, /* (62) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ - 198, /* (63) conslist_opt ::= */ - 224, /* (64) tconscomma ::= COMMA */ - 225, /* (65) tcons ::= CONSTRAINT nm */ - 225, /* (66) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ - 225, /* (67) tcons ::= UNIQUE LP sortlist RP onconf */ - 225, /* (68) tcons ::= CHECK LP expr RP onconf */ - 225, /* (69) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ - 228, /* (70) defer_subclause_opt ::= */ - 213, /* (71) onconf ::= */ - 213, /* (72) onconf ::= ON CONFLICT resolvetype */ - 229, /* (73) orconf ::= */ - 229, /* (74) orconf ::= OR resolvetype */ - 230, /* (75) resolvetype ::= IGNORE */ - 230, /* (76) resolvetype ::= REPLACE */ - 186, /* (77) cmd ::= DROP TABLE ifexists fullname */ - 232, /* (78) ifexists ::= IF EXISTS */ - 232, /* (79) ifexists ::= */ - 186, /* (80) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ - 186, /* (81) cmd ::= DROP VIEW ifexists fullname */ - 186, /* (82) cmd ::= select */ - 200, /* (83) select ::= WITH wqlist selectnowith */ - 200, /* (84) select ::= WITH RECURSIVE wqlist selectnowith */ - 200, /* (85) select ::= selectnowith */ - 234, /* (86) selectnowith ::= selectnowith multiselect_op oneselect */ - 237, /* (87) multiselect_op ::= UNION */ - 237, /* (88) multiselect_op ::= UNION ALL */ - 237, /* (89) multiselect_op ::= EXCEPT|INTERSECT */ - 235, /* (90) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ - 235, /* (91) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ - 247, /* (92) values ::= VALUES LP nexprlist RP */ - 247, /* (93) values ::= values COMMA LP nexprlist RP */ - 238, /* (94) distinct ::= DISTINCT */ - 238, /* (95) distinct ::= ALL */ - 238, /* (96) distinct ::= */ - 249, /* (97) sclp ::= */ - 239, /* (98) selcollist ::= sclp scanpt expr scanpt as */ - 239, /* (99) selcollist ::= sclp scanpt STAR */ - 239, /* (100) selcollist ::= sclp scanpt nm DOT STAR */ - 250, /* (101) as ::= AS nm */ - 250, /* (102) as ::= */ - 240, /* (103) from ::= */ - 240, /* (104) from ::= FROM seltablist */ - 252, /* (105) stl_prefix ::= seltablist joinop */ - 252, /* (106) stl_prefix ::= */ - 251, /* (107) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ - 251, /* (108) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ - 251, /* (109) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ - 251, /* (110) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ - 196, /* (111) dbnm ::= */ - 196, /* (112) dbnm ::= DOT nm */ - 233, /* (113) fullname ::= nm */ - 233, /* (114) fullname ::= nm DOT nm */ - 258, /* (115) xfullname ::= nm */ - 258, /* (116) xfullname ::= nm DOT nm */ - 258, /* (117) xfullname ::= nm DOT nm AS nm */ - 258, /* (118) xfullname ::= nm AS nm */ - 253, /* (119) joinop ::= COMMA|JOIN */ - 253, /* (120) joinop ::= JOIN_KW JOIN */ - 253, /* (121) joinop ::= JOIN_KW nm JOIN */ - 253, /* (122) joinop ::= JOIN_KW nm nm JOIN */ - 255, /* (123) on_opt ::= ON expr */ - 255, /* (124) on_opt ::= */ - 254, /* (125) indexed_opt ::= */ - 254, /* (126) indexed_opt ::= INDEXED BY nm */ - 254, /* (127) indexed_opt ::= NOT INDEXED */ - 256, /* (128) using_opt ::= USING LP idlist RP */ - 256, /* (129) using_opt ::= */ - 244, /* (130) orderby_opt ::= */ - 244, /* (131) orderby_opt ::= ORDER BY sortlist */ - 226, /* (132) sortlist ::= sortlist COMMA expr sortorder nulls */ - 226, /* (133) sortlist ::= expr sortorder nulls */ - 214, /* (134) sortorder ::= ASC */ - 214, /* (135) sortorder ::= DESC */ - 214, /* (136) sortorder ::= */ - 260, /* (137) nulls ::= NULLS FIRST */ - 260, /* (138) nulls ::= NULLS LAST */ - 260, /* (139) nulls ::= */ - 242, /* (140) groupby_opt ::= */ - 242, /* (141) groupby_opt ::= GROUP BY nexprlist */ - 243, /* (142) having_opt ::= */ - 243, /* (143) having_opt ::= HAVING expr */ - 245, /* (144) limit_opt ::= */ - 245, /* (145) limit_opt ::= LIMIT expr */ - 245, /* (146) limit_opt ::= LIMIT expr OFFSET expr */ - 245, /* (147) limit_opt ::= LIMIT expr COMMA expr */ - 186, /* (148) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ - 241, /* (149) where_opt ::= */ - 241, /* (150) where_opt ::= WHERE expr */ - 186, /* (151) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt */ - 262, /* (152) setlist ::= setlist COMMA nm EQ expr */ - 262, /* (153) setlist ::= setlist COMMA LP idlist RP EQ expr */ - 262, /* (154) setlist ::= nm EQ expr */ - 262, /* (155) setlist ::= LP idlist RP EQ expr */ - 186, /* (156) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - 186, /* (157) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ - 265, /* (158) upsert ::= */ - 265, /* (159) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ - 265, /* (160) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ - 265, /* (161) upsert ::= ON CONFLICT DO NOTHING */ - 263, /* (162) insert_cmd ::= INSERT orconf */ - 263, /* (163) insert_cmd ::= REPLACE */ - 264, /* (164) idlist_opt ::= */ - 264, /* (165) idlist_opt ::= LP idlist RP */ - 259, /* (166) idlist ::= idlist COMMA nm */ - 259, /* (167) idlist ::= nm */ - 212, /* (168) expr ::= LP expr RP */ - 212, /* (169) expr ::= ID|INDEXED */ - 212, /* (170) expr ::= JOIN_KW */ - 212, /* (171) expr ::= nm DOT nm */ - 212, /* (172) expr ::= nm DOT nm DOT nm */ - 211, /* (173) term ::= NULL|FLOAT|BLOB */ - 211, /* (174) term ::= STRING */ - 211, /* (175) term ::= INTEGER */ - 212, /* (176) expr ::= VARIABLE */ - 212, /* (177) expr ::= expr COLLATE ID|STRING */ - 212, /* (178) expr ::= CAST LP expr AS typetoken RP */ - 212, /* (179) expr ::= ID|INDEXED LP distinct exprlist RP */ - 212, /* (180) expr ::= ID|INDEXED LP STAR RP */ - 212, /* (181) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ - 212, /* (182) expr ::= ID|INDEXED LP STAR RP filter_over */ - 211, /* (183) term ::= CTIME_KW */ - 212, /* (184) expr ::= LP nexprlist COMMA expr RP */ - 212, /* (185) expr ::= expr AND expr */ - 212, /* (186) expr ::= expr OR expr */ - 212, /* (187) expr ::= expr LT|GT|GE|LE expr */ - 212, /* (188) expr ::= expr EQ|NE expr */ - 212, /* (189) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - 212, /* (190) expr ::= expr PLUS|MINUS expr */ - 212, /* (191) expr ::= expr STAR|SLASH|REM expr */ - 212, /* (192) expr ::= expr CONCAT expr */ - 267, /* (193) likeop ::= NOT LIKE_KW|MATCH */ - 212, /* (194) expr ::= expr likeop expr */ - 212, /* (195) expr ::= expr likeop expr ESCAPE expr */ - 212, /* (196) expr ::= expr ISNULL|NOTNULL */ - 212, /* (197) expr ::= expr NOT NULL */ - 212, /* (198) expr ::= expr IS expr */ - 212, /* (199) expr ::= expr IS NOT expr */ - 212, /* (200) expr ::= NOT expr */ - 212, /* (201) expr ::= BITNOT expr */ - 212, /* (202) expr ::= PLUS|MINUS expr */ - 268, /* (203) between_op ::= BETWEEN */ - 268, /* (204) between_op ::= NOT BETWEEN */ - 212, /* (205) expr ::= expr between_op expr AND expr */ - 269, /* (206) in_op ::= IN */ - 269, /* (207) in_op ::= NOT IN */ - 212, /* (208) expr ::= expr in_op LP exprlist RP */ - 212, /* (209) expr ::= LP select RP */ - 212, /* (210) expr ::= expr in_op LP select RP */ - 212, /* (211) expr ::= expr in_op nm dbnm paren_exprlist */ - 212, /* (212) expr ::= EXISTS LP select RP */ - 212, /* (213) expr ::= CASE case_operand case_exprlist case_else END */ - 272, /* (214) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - 272, /* (215) case_exprlist ::= WHEN expr THEN expr */ - 273, /* (216) case_else ::= ELSE expr */ - 273, /* (217) case_else ::= */ - 271, /* (218) case_operand ::= expr */ - 271, /* (219) case_operand ::= */ - 257, /* (220) exprlist ::= */ - 248, /* (221) nexprlist ::= nexprlist COMMA expr */ - 248, /* (222) nexprlist ::= expr */ - 270, /* (223) paren_exprlist ::= */ - 270, /* (224) paren_exprlist ::= LP exprlist RP */ - 186, /* (225) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - 274, /* (226) uniqueflag ::= UNIQUE */ - 274, /* (227) uniqueflag ::= */ - 216, /* (228) eidlist_opt ::= */ - 216, /* (229) eidlist_opt ::= LP eidlist RP */ - 227, /* (230) eidlist ::= eidlist COMMA nm collate sortorder */ - 227, /* (231) eidlist ::= nm collate sortorder */ - 275, /* (232) collate ::= */ - 275, /* (233) collate ::= COLLATE ID|STRING */ - 186, /* (234) cmd ::= DROP INDEX ifexists fullname */ - 186, /* (235) cmd ::= VACUUM vinto */ - 186, /* (236) cmd ::= VACUUM nm vinto */ - 276, /* (237) vinto ::= INTO expr */ - 276, /* (238) vinto ::= */ - 186, /* (239) cmd ::= PRAGMA nm dbnm */ - 186, /* (240) cmd ::= PRAGMA nm dbnm EQ nmnum */ - 186, /* (241) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - 186, /* (242) cmd ::= PRAGMA nm dbnm EQ minus_num */ - 186, /* (243) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - 206, /* (244) plus_num ::= PLUS INTEGER|FLOAT */ - 207, /* (245) minus_num ::= MINUS INTEGER|FLOAT */ - 186, /* (246) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - 278, /* (247) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - 280, /* (248) trigger_time ::= BEFORE|AFTER */ - 280, /* (249) trigger_time ::= INSTEAD OF */ - 280, /* (250) trigger_time ::= */ - 281, /* (251) trigger_event ::= DELETE|INSERT */ - 281, /* (252) trigger_event ::= UPDATE */ - 281, /* (253) trigger_event ::= UPDATE OF idlist */ - 283, /* (254) when_clause ::= */ - 283, /* (255) when_clause ::= WHEN expr */ - 279, /* (256) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - 279, /* (257) trigger_cmd_list ::= trigger_cmd SEMI */ - 285, /* (258) trnm ::= nm DOT nm */ - 286, /* (259) tridxby ::= INDEXED BY nm */ - 286, /* (260) tridxby ::= NOT INDEXED */ - 284, /* (261) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - 284, /* (262) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - 284, /* (263) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - 284, /* (264) trigger_cmd ::= scanpt select scanpt */ - 212, /* (265) expr ::= RAISE LP IGNORE RP */ - 212, /* (266) expr ::= RAISE LP raisetype COMMA nm RP */ - 231, /* (267) raisetype ::= ROLLBACK */ - 231, /* (268) raisetype ::= ABORT */ - 231, /* (269) raisetype ::= FAIL */ - 186, /* (270) cmd ::= DROP TRIGGER ifexists fullname */ - 186, /* (271) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - 186, /* (272) cmd ::= DETACH database_kw_opt expr */ - 288, /* (273) key_opt ::= */ - 288, /* (274) key_opt ::= KEY expr */ - 186, /* (275) cmd ::= REINDEX */ - 186, /* (276) cmd ::= REINDEX nm dbnm */ - 186, /* (277) cmd ::= ANALYZE */ - 186, /* (278) cmd ::= ANALYZE nm dbnm */ - 186, /* (279) cmd ::= ALTER TABLE fullname RENAME TO nm */ - 186, /* (280) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - 289, /* (281) add_column_fullname ::= fullname */ - 186, /* (282) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - 186, /* (283) cmd ::= create_vtab */ - 186, /* (284) cmd ::= create_vtab LP vtabarglist RP */ - 291, /* (285) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 293, /* (286) vtabarg ::= */ - 294, /* (287) vtabargtoken ::= ANY */ - 294, /* (288) vtabargtoken ::= lp anylist RP */ - 295, /* (289) lp ::= LP */ - 261, /* (290) with ::= WITH wqlist */ - 261, /* (291) with ::= WITH RECURSIVE wqlist */ - 236, /* (292) wqlist ::= nm eidlist_opt AS LP select RP */ - 236, /* (293) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ - 297, /* (294) windowdefn_list ::= windowdefn */ - 297, /* (295) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - 298, /* (296) windowdefn ::= nm AS LP window RP */ - 299, /* (297) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - 299, /* (298) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - 299, /* (299) window ::= ORDER BY sortlist frame_opt */ - 299, /* (300) window ::= nm ORDER BY sortlist frame_opt */ - 299, /* (301) window ::= frame_opt */ - 299, /* (302) window ::= nm frame_opt */ - 300, /* (303) frame_opt ::= */ - 300, /* (304) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - 300, /* (305) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - 304, /* (306) range_or_rows ::= RANGE|ROWS|GROUPS */ - 306, /* (307) frame_bound_s ::= frame_bound */ - 306, /* (308) frame_bound_s ::= UNBOUNDED PRECEDING */ - 307, /* (309) frame_bound_e ::= frame_bound */ - 307, /* (310) frame_bound_e ::= UNBOUNDED FOLLOWING */ - 305, /* (311) frame_bound ::= expr PRECEDING|FOLLOWING */ - 305, /* (312) frame_bound ::= CURRENT ROW */ - 308, /* (313) frame_exclude_opt ::= */ - 308, /* (314) frame_exclude_opt ::= EXCLUDE frame_exclude */ - 309, /* (315) frame_exclude ::= NO OTHERS */ - 309, /* (316) frame_exclude ::= CURRENT ROW */ - 309, /* (317) frame_exclude ::= GROUP|TIES */ - 246, /* (318) window_clause ::= WINDOW windowdefn_list */ - 266, /* (319) filter_over ::= filter_clause over_clause */ - 266, /* (320) filter_over ::= over_clause */ - 266, /* (321) filter_over ::= filter_clause */ - 303, /* (322) over_clause ::= OVER LP window RP */ - 303, /* (323) over_clause ::= OVER nm */ - 302, /* (324) filter_clause ::= FILTER LP WHERE expr RP */ - 181, /* (325) input ::= cmdlist */ - 182, /* (326) cmdlist ::= cmdlist ecmd */ - 182, /* (327) cmdlist ::= ecmd */ - 183, /* (328) ecmd ::= SEMI */ - 183, /* (329) ecmd ::= cmdx SEMI */ - 183, /* (330) ecmd ::= explain cmdx SEMI */ - 188, /* (331) trans_opt ::= */ - 188, /* (332) trans_opt ::= TRANSACTION */ - 188, /* (333) trans_opt ::= TRANSACTION nm */ - 190, /* (334) savepoint_opt ::= SAVEPOINT */ - 190, /* (335) savepoint_opt ::= */ - 186, /* (336) cmd ::= create_table create_table_args */ - 197, /* (337) columnlist ::= columnlist COMMA columnname carglist */ - 197, /* (338) columnlist ::= columnname carglist */ - 189, /* (339) nm ::= ID|INDEXED */ - 189, /* (340) nm ::= STRING */ - 189, /* (341) nm ::= JOIN_KW */ - 203, /* (342) typetoken ::= typename */ - 204, /* (343) typename ::= ID|STRING */ - 205, /* (344) signed ::= plus_num */ - 205, /* (345) signed ::= minus_num */ - 202, /* (346) carglist ::= carglist ccons */ - 202, /* (347) carglist ::= */ - 210, /* (348) ccons ::= NULL onconf */ - 210, /* (349) ccons ::= GENERATED ALWAYS AS generated */ - 210, /* (350) ccons ::= AS generated */ - 198, /* (351) conslist_opt ::= COMMA conslist */ - 223, /* (352) conslist ::= conslist tconscomma tcons */ - 223, /* (353) conslist ::= tcons */ - 224, /* (354) tconscomma ::= */ - 228, /* (355) defer_subclause_opt ::= defer_subclause */ - 230, /* (356) resolvetype ::= raisetype */ - 234, /* (357) selectnowith ::= oneselect */ - 235, /* (358) oneselect ::= values */ - 249, /* (359) sclp ::= selcollist COMMA */ - 250, /* (360) as ::= ID|STRING */ - 212, /* (361) expr ::= term */ - 267, /* (362) likeop ::= LIKE_KW|MATCH */ - 257, /* (363) exprlist ::= nexprlist */ - 277, /* (364) nmnum ::= plus_num */ - 277, /* (365) nmnum ::= nm */ - 277, /* (366) nmnum ::= ON */ - 277, /* (367) nmnum ::= DELETE */ - 277, /* (368) nmnum ::= DEFAULT */ - 206, /* (369) plus_num ::= INTEGER|FLOAT */ - 282, /* (370) foreach_clause ::= */ - 282, /* (371) foreach_clause ::= FOR EACH ROW */ - 285, /* (372) trnm ::= nm */ - 286, /* (373) tridxby ::= */ - 287, /* (374) database_kw_opt ::= DATABASE */ - 287, /* (375) database_kw_opt ::= */ - 290, /* (376) kwcolumn_opt ::= */ - 290, /* (377) kwcolumn_opt ::= COLUMNKW */ - 292, /* (378) vtabarglist ::= vtabarg */ - 292, /* (379) vtabarglist ::= vtabarglist COMMA vtabarg */ - 293, /* (380) vtabarg ::= vtabarg vtabargtoken */ - 296, /* (381) anylist ::= */ - 296, /* (382) anylist ::= anylist LP anylist RP */ - 296, /* (383) anylist ::= anylist ANY */ - 261, /* (384) 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 @@ -157080,372 +164364,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 */ - 0, /* (149) where_opt ::= */ - -2, /* (150) where_opt ::= WHERE expr */ - -9, /* (151) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt */ - -5, /* (152) setlist ::= setlist COMMA nm EQ expr */ - -7, /* (153) setlist ::= setlist COMMA LP idlist RP EQ expr */ - -3, /* (154) setlist ::= nm EQ expr */ - -5, /* (155) setlist ::= LP idlist RP EQ expr */ - -7, /* (156) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - -7, /* (157) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ - 0, /* (158) upsert ::= */ - -11, /* (159) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ - -8, /* (160) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ - -4, /* (161) upsert ::= ON CONFLICT DO NOTHING */ - -2, /* (162) insert_cmd ::= INSERT orconf */ - -1, /* (163) insert_cmd ::= REPLACE */ - 0, /* (164) idlist_opt ::= */ - -3, /* (165) idlist_opt ::= LP idlist RP */ - -3, /* (166) idlist ::= idlist COMMA nm */ - -1, /* (167) idlist ::= nm */ - -3, /* (168) expr ::= LP expr RP */ - -1, /* (169) expr ::= ID|INDEXED */ - -1, /* (170) expr ::= JOIN_KW */ - -3, /* (171) expr ::= nm DOT nm */ - -5, /* (172) expr ::= nm DOT nm DOT nm */ - -1, /* (173) term ::= NULL|FLOAT|BLOB */ - -1, /* (174) term ::= STRING */ - -1, /* (175) term ::= INTEGER */ - -1, /* (176) expr ::= VARIABLE */ - -3, /* (177) expr ::= expr COLLATE ID|STRING */ - -6, /* (178) expr ::= CAST LP expr AS typetoken RP */ - -5, /* (179) expr ::= ID|INDEXED LP distinct exprlist RP */ - -4, /* (180) expr ::= ID|INDEXED LP STAR RP */ - -6, /* (181) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ - -5, /* (182) expr ::= ID|INDEXED LP STAR RP filter_over */ - -1, /* (183) term ::= CTIME_KW */ - -5, /* (184) expr ::= LP nexprlist COMMA expr RP */ - -3, /* (185) expr ::= expr AND expr */ - -3, /* (186) expr ::= expr OR expr */ - -3, /* (187) expr ::= expr LT|GT|GE|LE expr */ - -3, /* (188) expr ::= expr EQ|NE expr */ - -3, /* (189) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - -3, /* (190) expr ::= expr PLUS|MINUS expr */ - -3, /* (191) expr ::= expr STAR|SLASH|REM expr */ - -3, /* (192) expr ::= expr CONCAT expr */ - -2, /* (193) likeop ::= NOT LIKE_KW|MATCH */ - -3, /* (194) expr ::= expr likeop expr */ - -5, /* (195) expr ::= expr likeop expr ESCAPE expr */ - -2, /* (196) expr ::= expr ISNULL|NOTNULL */ - -3, /* (197) expr ::= expr NOT NULL */ - -3, /* (198) expr ::= expr IS expr */ - -4, /* (199) expr ::= expr IS NOT expr */ - -2, /* (200) expr ::= NOT expr */ - -2, /* (201) expr ::= BITNOT expr */ - -2, /* (202) expr ::= PLUS|MINUS expr */ - -1, /* (203) between_op ::= BETWEEN */ - -2, /* (204) between_op ::= NOT BETWEEN */ - -5, /* (205) expr ::= expr between_op expr AND expr */ - -1, /* (206) in_op ::= IN */ - -2, /* (207) in_op ::= NOT IN */ - -5, /* (208) expr ::= expr in_op LP exprlist RP */ - -3, /* (209) expr ::= LP select RP */ - -5, /* (210) expr ::= expr in_op LP select RP */ - -5, /* (211) expr ::= expr in_op nm dbnm paren_exprlist */ - -4, /* (212) expr ::= EXISTS LP select RP */ - -5, /* (213) expr ::= CASE case_operand case_exprlist case_else END */ - -5, /* (214) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - -4, /* (215) case_exprlist ::= WHEN expr THEN expr */ - -2, /* (216) case_else ::= ELSE expr */ - 0, /* (217) case_else ::= */ - -1, /* (218) case_operand ::= expr */ - 0, /* (219) case_operand ::= */ - 0, /* (220) exprlist ::= */ - -3, /* (221) nexprlist ::= nexprlist COMMA expr */ - -1, /* (222) nexprlist ::= expr */ - 0, /* (223) paren_exprlist ::= */ - -3, /* (224) paren_exprlist ::= LP exprlist RP */ - -12, /* (225) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - -1, /* (226) uniqueflag ::= UNIQUE */ - 0, /* (227) uniqueflag ::= */ - 0, /* (228) eidlist_opt ::= */ - -3, /* (229) eidlist_opt ::= LP eidlist RP */ - -5, /* (230) eidlist ::= eidlist COMMA nm collate sortorder */ - -3, /* (231) eidlist ::= nm collate sortorder */ - 0, /* (232) collate ::= */ - -2, /* (233) collate ::= COLLATE ID|STRING */ - -4, /* (234) cmd ::= DROP INDEX ifexists fullname */ - -2, /* (235) cmd ::= VACUUM vinto */ - -3, /* (236) cmd ::= VACUUM nm vinto */ - -2, /* (237) vinto ::= INTO expr */ - 0, /* (238) vinto ::= */ - -3, /* (239) cmd ::= PRAGMA nm dbnm */ - -5, /* (240) cmd ::= PRAGMA nm dbnm EQ nmnum */ - -6, /* (241) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - -5, /* (242) cmd ::= PRAGMA nm dbnm EQ minus_num */ - -6, /* (243) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - -2, /* (244) plus_num ::= PLUS INTEGER|FLOAT */ - -2, /* (245) minus_num ::= MINUS INTEGER|FLOAT */ - -5, /* (246) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - -11, /* (247) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - -1, /* (248) trigger_time ::= BEFORE|AFTER */ - -2, /* (249) trigger_time ::= INSTEAD OF */ - 0, /* (250) trigger_time ::= */ - -1, /* (251) trigger_event ::= DELETE|INSERT */ - -1, /* (252) trigger_event ::= UPDATE */ - -3, /* (253) trigger_event ::= UPDATE OF idlist */ - 0, /* (254) when_clause ::= */ - -2, /* (255) when_clause ::= WHEN expr */ - -3, /* (256) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - -2, /* (257) trigger_cmd_list ::= trigger_cmd SEMI */ - -3, /* (258) trnm ::= nm DOT nm */ - -3, /* (259) tridxby ::= INDEXED BY nm */ - -2, /* (260) tridxby ::= NOT INDEXED */ - -9, /* (261) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - -8, /* (262) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - -6, /* (263) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - -3, /* (264) trigger_cmd ::= scanpt select scanpt */ - -4, /* (265) expr ::= RAISE LP IGNORE RP */ - -6, /* (266) expr ::= RAISE LP raisetype COMMA nm RP */ - -1, /* (267) raisetype ::= ROLLBACK */ - -1, /* (268) raisetype ::= ABORT */ - -1, /* (269) raisetype ::= FAIL */ - -4, /* (270) cmd ::= DROP TRIGGER ifexists fullname */ - -6, /* (271) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - -3, /* (272) cmd ::= DETACH database_kw_opt expr */ - 0, /* (273) key_opt ::= */ - -2, /* (274) key_opt ::= KEY expr */ - -1, /* (275) cmd ::= REINDEX */ - -3, /* (276) cmd ::= REINDEX nm dbnm */ - -1, /* (277) cmd ::= ANALYZE */ - -3, /* (278) cmd ::= ANALYZE nm dbnm */ - -6, /* (279) cmd ::= ALTER TABLE fullname RENAME TO nm */ - -7, /* (280) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - -1, /* (281) add_column_fullname ::= fullname */ - -8, /* (282) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - -1, /* (283) cmd ::= create_vtab */ - -4, /* (284) cmd ::= create_vtab LP vtabarglist RP */ - -8, /* (285) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 0, /* (286) vtabarg ::= */ - -1, /* (287) vtabargtoken ::= ANY */ - -3, /* (288) vtabargtoken ::= lp anylist RP */ - -1, /* (289) lp ::= LP */ - -2, /* (290) with ::= WITH wqlist */ - -3, /* (291) with ::= WITH RECURSIVE wqlist */ - -6, /* (292) wqlist ::= nm eidlist_opt AS LP select RP */ - -8, /* (293) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ - -1, /* (294) windowdefn_list ::= windowdefn */ - -3, /* (295) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - -5, /* (296) windowdefn ::= nm AS LP window RP */ - -5, /* (297) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - -6, /* (298) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - -4, /* (299) window ::= ORDER BY sortlist frame_opt */ - -5, /* (300) window ::= nm ORDER BY sortlist frame_opt */ - -1, /* (301) window ::= frame_opt */ - -2, /* (302) window ::= nm frame_opt */ - 0, /* (303) frame_opt ::= */ - -3, /* (304) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - -6, /* (305) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - -1, /* (306) range_or_rows ::= RANGE|ROWS|GROUPS */ - -1, /* (307) frame_bound_s ::= frame_bound */ - -2, /* (308) frame_bound_s ::= UNBOUNDED PRECEDING */ - -1, /* (309) frame_bound_e ::= frame_bound */ - -2, /* (310) frame_bound_e ::= UNBOUNDED FOLLOWING */ - -2, /* (311) frame_bound ::= expr PRECEDING|FOLLOWING */ - -2, /* (312) frame_bound ::= CURRENT ROW */ - 0, /* (313) frame_exclude_opt ::= */ - -2, /* (314) frame_exclude_opt ::= EXCLUDE frame_exclude */ - -2, /* (315) frame_exclude ::= NO OTHERS */ - -2, /* (316) frame_exclude ::= CURRENT ROW */ - -1, /* (317) frame_exclude ::= GROUP|TIES */ - -2, /* (318) window_clause ::= WINDOW windowdefn_list */ - -2, /* (319) filter_over ::= filter_clause over_clause */ - -1, /* (320) filter_over ::= over_clause */ - -1, /* (321) filter_over ::= filter_clause */ - -4, /* (322) over_clause ::= OVER LP window RP */ - -2, /* (323) over_clause ::= OVER nm */ - -5, /* (324) filter_clause ::= FILTER LP WHERE expr RP */ - -1, /* (325) input ::= cmdlist */ - -2, /* (326) cmdlist ::= cmdlist ecmd */ - -1, /* (327) cmdlist ::= ecmd */ - -1, /* (328) ecmd ::= SEMI */ - -2, /* (329) ecmd ::= cmdx SEMI */ - -3, /* (330) ecmd ::= explain cmdx SEMI */ - 0, /* (331) trans_opt ::= */ - -1, /* (332) trans_opt ::= TRANSACTION */ - -2, /* (333) trans_opt ::= TRANSACTION nm */ - -1, /* (334) savepoint_opt ::= SAVEPOINT */ - 0, /* (335) savepoint_opt ::= */ - -2, /* (336) cmd ::= create_table create_table_args */ - -4, /* (337) columnlist ::= columnlist COMMA columnname carglist */ - -2, /* (338) columnlist ::= columnname carglist */ - -1, /* (339) nm ::= ID|INDEXED */ - -1, /* (340) nm ::= STRING */ - -1, /* (341) nm ::= JOIN_KW */ - -1, /* (342) typetoken ::= typename */ - -1, /* (343) typename ::= ID|STRING */ - -1, /* (344) signed ::= plus_num */ - -1, /* (345) signed ::= minus_num */ - -2, /* (346) carglist ::= carglist ccons */ - 0, /* (347) carglist ::= */ - -2, /* (348) ccons ::= NULL onconf */ - -4, /* (349) ccons ::= GENERATED ALWAYS AS generated */ - -2, /* (350) ccons ::= AS generated */ - -2, /* (351) conslist_opt ::= COMMA conslist */ - -3, /* (352) conslist ::= conslist tconscomma tcons */ - -1, /* (353) conslist ::= tcons */ - 0, /* (354) tconscomma ::= */ - -1, /* (355) defer_subclause_opt ::= defer_subclause */ - -1, /* (356) resolvetype ::= raisetype */ - -1, /* (357) selectnowith ::= oneselect */ - -1, /* (358) oneselect ::= values */ - -2, /* (359) sclp ::= selcollist COMMA */ - -1, /* (360) as ::= ID|STRING */ - -1, /* (361) expr ::= term */ - -1, /* (362) likeop ::= LIKE_KW|MATCH */ - -1, /* (363) exprlist ::= nexprlist */ - -1, /* (364) nmnum ::= plus_num */ - -1, /* (365) nmnum ::= nm */ - -1, /* (366) nmnum ::= ON */ - -1, /* (367) nmnum ::= DELETE */ - -1, /* (368) nmnum ::= DEFAULT */ - -1, /* (369) plus_num ::= INTEGER|FLOAT */ - 0, /* (370) foreach_clause ::= */ - -3, /* (371) foreach_clause ::= FOR EACH ROW */ - -1, /* (372) trnm ::= nm */ - 0, /* (373) tridxby ::= */ - -1, /* (374) database_kw_opt ::= DATABASE */ - 0, /* (375) database_kw_opt ::= */ - 0, /* (376) kwcolumn_opt ::= */ - -1, /* (377) kwcolumn_opt ::= COLUMNKW */ - -1, /* (378) vtabarglist ::= vtabarg */ - -3, /* (379) vtabarglist ::= vtabarglist COMMA vtabarg */ - -2, /* (380) vtabarg ::= vtabarg vtabargtoken */ - 0, /* (381) anylist ::= */ - -4, /* (382) anylist ::= anylist LP anylist RP */ - -2, /* (383) anylist ::= anylist ANY */ - 0, /* (384) 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 */ @@ -157475,54 +164776,6 @@ static YYACTIONTYPE yy_reduce( (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; -#ifndef NDEBUG - if( yyTraceFILE && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ - yysize = yyRuleInfoNRhs[yyruleno]; - if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", - yyTracePrompt, - yyruleno, yyRuleName[yyruleno], - yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ - yypParser->yyhwm++; - assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack)); - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yytos>=yypParser->yystackEnd ){ - yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } -#else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ - if( yyGrowStack(yypParser) ){ - yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } - yymsp = yypParser->yytos; - } -#endif - } switch( yyruleno ){ /* Beginning here are the reduction cases. A typical example @@ -157545,16 +164798,16 @@ static YYACTIONTYPE yy_reduce( { sqlite3FinishCoding(pParse); } break; case 3: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy192);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy394);} break; case 4: /* transtype ::= */ -{yymsp[1].minor.yy192 = 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 306: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==306); -{yymsp[0].minor.yy192 = 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); @@ -157577,7 +164830,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.yy192,0,0,yymsp[-2].minor.yy192); + 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 */ @@ -157585,96 +164838,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 232: /* collate ::= */ yytestcase(yyruleno==232); -{yymsp[1].minor.yy192 = 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.yy192 = 1;} +{yymsp[-2].minor.yy394 = 1;} break; case 17: /* temp ::= TEMP */ - case 46: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==46); -{yymsp[0].minor.yy192 = 1;} +{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.yy192,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.yy539); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy539); + 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.yy192 = TF_WithoutRowid | TF_NoVisibleRowid; + yymsp[-1].minor.yy285 = TF_WithoutRowid | TF_NoVisibleRowid; }else{ - yymsp[-1].minor.yy192 = 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 25: /* columnname ::= nm typetoken */ +{sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);} break; - case 24: /* typetoken ::= */ - case 63: /* conslist_opt ::= */ yytestcase(yyruleno==63); - case 102: /* as ::= */ yytestcase(yyruleno==102); + 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.yy436 = 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.yy202,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.yy202,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.yy202,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.yy202, 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 ){ @@ -157684,177 +164953,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.yy192);} + 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.yy192,yymsp[0].minor.yy192,yymsp[-2].minor.yy192);} + 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.yy192,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.yy202);} + 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.yy242,yymsp[0].minor.yy192);} + 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.yy192);} + 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.yy202,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.yy202,&yymsp[0].minor.yy0);} + case 46: /* generated ::= LP expr RP ID */ +{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy528,&yymsp[0].minor.yy0);} break; - case 47: /* refargs ::= */ -{ yymsp[1].minor.yy192 = OE_None*0x0101; /* EV: R-19803-45884 */} + case 48: /* autoinc ::= AUTOINCR */ +{yymsp[0].minor.yy394 = 1;} break; - case 48: /* refargs ::= refargs refarg */ -{ yymsp[-1].minor.yy192 = (yymsp[-1].minor.yy192 & ~yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; } + case 49: /* refargs ::= */ +{ yymsp[1].minor.yy394 = OE_None*0x0101; /* EV: R-19803-45884 */} break; - case 49: /* refarg ::= MATCH nm */ -{ yymsp[-1].minor.yy207.value = 0; yymsp[-1].minor.yy207.mask = 0x000000; } + 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 50: /* refarg ::= ON INSERT refact */ -{ yymsp[-2].minor.yy207.value = 0; yymsp[-2].minor.yy207.mask = 0x000000; } + case 51: /* refarg ::= MATCH nm */ +{ yymsp[-1].minor.yy231.value = 0; yymsp[-1].minor.yy231.mask = 0x000000; } break; - case 51: /* refarg ::= ON DELETE refact */ -{ yymsp[-2].minor.yy207.value = yymsp[0].minor.yy192; yymsp[-2].minor.yy207.mask = 0x0000ff; } + case 52: /* refarg ::= ON INSERT refact */ +{ yymsp[-2].minor.yy231.value = 0; yymsp[-2].minor.yy231.mask = 0x000000; } break; - case 52: /* refarg ::= ON UPDATE refact */ -{ yymsp[-2].minor.yy207.value = yymsp[0].minor.yy192<<8; yymsp[-2].minor.yy207.mask = 0x00ff00; } + case 53: /* refarg ::= ON DELETE refact */ +{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394; yymsp[-2].minor.yy231.mask = 0x0000ff; } break; - case 53: /* refact ::= SET NULL */ -{ yymsp[-1].minor.yy192 = OE_SetNull; /* EV: R-33326-45252 */} + case 54: /* refarg ::= ON UPDATE refact */ +{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394<<8; yymsp[-2].minor.yy231.mask = 0x00ff00; } break; - case 54: /* refact ::= SET DEFAULT */ -{ yymsp[-1].minor.yy192 = OE_SetDflt; /* EV: R-33326-45252 */} + case 55: /* refact ::= SET NULL */ +{ yymsp[-1].minor.yy394 = OE_SetNull; /* EV: R-33326-45252 */} break; - case 55: /* refact ::= CASCADE */ -{ yymsp[0].minor.yy192 = OE_Cascade; /* EV: R-33326-45252 */} + case 56: /* refact ::= SET DEFAULT */ +{ yymsp[-1].minor.yy394 = OE_SetDflt; /* EV: R-33326-45252 */} break; - case 56: /* refact ::= RESTRICT */ -{ yymsp[0].minor.yy192 = OE_Restrict; /* EV: R-33326-45252 */} + case 57: /* refact ::= CASCADE */ +{ yymsp[0].minor.yy394 = OE_Cascade; /* EV: R-33326-45252 */} break; - case 57: /* refact ::= NO ACTION */ -{ yymsp[-1].minor.yy192 = OE_None; /* EV: R-33326-45252 */} + case 58: /* refact ::= RESTRICT */ +{ yymsp[0].minor.yy394 = OE_Restrict; /* EV: R-33326-45252 */} break; - case 58: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -{yymsp[-2].minor.yy192 = 0;} + case 59: /* refact ::= NO ACTION */ +{ yymsp[-1].minor.yy394 = OE_None; /* EV: R-33326-45252 */} break; - case 59: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - case 74: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==74); - case 162: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==162); -{yymsp[-1].minor.yy192 = yymsp[0].minor.yy192;} + case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ +{yymsp[-2].minor.yy394 = 0;} break; - case 61: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ - case 78: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==78); - case 204: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==204); - case 207: /* in_op ::= NOT IN */ yytestcase(yyruleno==207); - case 233: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==233); -{yymsp[-1].minor.yy192 = 1;} + 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 62: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -{yymsp[-1].minor.yy192 = 0;} + 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 64: /* tconscomma ::= COMMA */ + case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ +{yymsp[-1].minor.yy394 = 0;} + break; + case 66: /* tconscomma ::= COMMA */ {pParse->constraintName.n = 0;} break; - case 66: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy242,yymsp[0].minor.yy192,yymsp[-2].minor.yy192,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.yy242,yymsp[0].minor.yy192,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.yy202);} + 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.yy242, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy242, yymsp[-1].minor.yy192); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy192); + 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.yy192 = 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.yy192 = yymsp[0].minor.yy192;} + case 74: /* onconf ::= ON CONFLICT resolvetype */ +{yymsp[-2].minor.yy394 = yymsp[0].minor.yy394;} break; - case 75: /* resolvetype ::= IGNORE */ -{yymsp[0].minor.yy192 = OE_Ignore;} + case 77: /* resolvetype ::= IGNORE */ +{yymsp[0].minor.yy394 = OE_Ignore;} break; - case 76: /* resolvetype ::= REPLACE */ - case 163: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==163); -{yymsp[0].minor.yy192 = 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.yy47, 0, yymsp[-1].minor.yy192); + 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.yy242, yymsp[0].minor.yy539, yymsp[-7].minor.yy192, yymsp[-5].minor.yy192); + 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.yy47, 1, yymsp[-1].minor.yy192); + 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.yy539, &dest); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy539); + sqlite3Select(pParse, yymsp[0].minor.yy47, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47); } break; - case 83: /* select ::= WITH wqlist selectnowith */ -{ - Select *p = yymsp[0].minor.yy539; - if( p ){ - p->pWith = yymsp[-1].minor.yy131; - parserDoubleLinkSelect(pParse, p); - }else{ - sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy131); - } - yymsp[-2].minor.yy539 = p; -} + 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 */ -{ - Select *p = yymsp[0].minor.yy539; - if( p ){ - p->pWith = yymsp[-1].minor.yy131; - parserDoubleLinkSelect(pParse, p); - }else{ - sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy131); - } - yymsp[-3].minor.yy539 = p; -} + 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.yy539; + Select *p = yymsp[0].minor.yy47; if( p ){ parserDoubleLinkSelect(pParse, p); } - yymsp[0].minor.yy539 = 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.yy539; - Select *pLhs = yymsp[-2].minor.yy539; + Select *pRhs = yymsp[0].minor.yy47; + Select *pLhs = yymsp[-2].minor.yy47; if( pRhs && pRhs->pPrior ){ SrcList *pFrom; Token x; @@ -157864,140 +165118,140 @@ static YYACTIONTYPE yy_reduce( pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ - pRhs->op = (u8)yymsp[-1].minor.yy192; + 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.yy192!=TK_ALL ) pParse->hasCompound = 1; + if( yymsp[-1].minor.yy394!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); } - yymsp[-2].minor.yy539 = pRhs; + yymsp[-2].minor.yy47 = pRhs; } break; - case 87: /* multiselect_op ::= UNION */ - case 89: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==89); -{yymsp[0].minor.yy192 = 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.yy192 = 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.yy539 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy242,yymsp[-5].minor.yy47,yymsp[-4].minor.yy202,yymsp[-3].minor.yy242,yymsp[-2].minor.yy202,yymsp[-1].minor.yy242,yymsp[-7].minor.yy192,yymsp[0].minor.yy202); + 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.yy539 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy242,yymsp[-6].minor.yy47,yymsp[-5].minor.yy202,yymsp[-4].minor.yy242,yymsp[-3].minor.yy202,yymsp[-1].minor.yy242,yymsp[-8].minor.yy192,yymsp[0].minor.yy202); - if( yymsp[-9].minor.yy539 ){ - yymsp[-9].minor.yy539->pWinDefn = yymsp[-2].minor.yy303; + 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.yy303); + 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.yy539 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy242,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.yy539; - pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy242,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.yy539 = pRight; + yymsp[-4].minor.yy47 = pRight; }else{ - yymsp[-4].minor.yy539 = pLeft; + yymsp[-4].minor.yy47 = pLeft; } } break; - case 94: /* distinct ::= DISTINCT */ -{yymsp[0].minor.yy192 = SF_Distinct;} + case 96: /* distinct ::= DISTINCT */ +{yymsp[0].minor.yy394 = SF_Distinct;} break; - case 95: /* distinct ::= ALL */ -{yymsp[0].minor.yy192 = 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 220: /* exprlist ::= */ yytestcase(yyruleno==220); - case 223: /* paren_exprlist ::= */ yytestcase(yyruleno==223); - case 228: /* eidlist_opt ::= */ yytestcase(yyruleno==228); -{yymsp[1].minor.yy242 = 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.yy242 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy242, yymsp[-2].minor.yy202); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy242, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy242,yymsp[-3].minor.yy436,yymsp[-1].minor.yy436); + 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.yy242 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy242, 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.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, 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 244: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==244); - case 245: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==245); + 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.yy47 = 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.yy47 = yymsp[0].minor.yy47; - sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy47); + 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.yy47 && yymsp[-1].minor.yy47->nSrc>0) ) yymsp[-1].minor.yy47->a[yymsp[-1].minor.yy47->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy192; + 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.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); - sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy47, &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.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy47,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); - sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy47, yymsp[-4].minor.yy242); + 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.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy539,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); + 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.yy47==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy202==0 && yymsp[0].minor.yy600==0 ){ - yymsp[-6].minor.yy47 = yymsp[-4].minor.yy47; - }else if( yymsp[-4].minor.yy47->nSrc==1 ){ - yymsp[-6].minor.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); - if( yymsp[-6].minor.yy47 ){ - struct SrcList_item *pNew = &yymsp[-6].minor.yy47->a[yymsp[-6].minor.yy47->nSrc-1]; - struct SrcList_item *pOld = yymsp[-4].minor.yy47->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; @@ -158010,250 +165264,263 @@ static YYACTIONTYPE yy_reduce( pOld->zName = pOld->zDatabase = 0; pOld->pSelect = 0; } - sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy47); + sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy131); }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy47); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy47,0,0,0,0,SF_NestedFrom,0); - yymsp[-6].minor.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); + 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.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); - if( IN_RENAME_OBJECT && yylhsminor.yy47 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy47->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.yy47 = yylhsminor.yy47; + yymsp[0].minor.yy131 = yylhsminor.yy131; break; - case 114: /* fullname ::= nm DOT nm */ + case 116: /* fullname ::= nm DOT nm */ { - yylhsminor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); - if( IN_RENAME_OBJECT && yylhsminor.yy47 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy47->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.yy47 = yylhsminor.yy47; + yymsp[-2].minor.yy131 = yylhsminor.yy131; break; - case 115: /* xfullname ::= nm */ -{yymsp[0].minor.yy47 = 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.yy47 = 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.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ - if( yymsp[-4].minor.yy47 ) yymsp[-4].minor.yy47->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.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ - if( yymsp[-2].minor.yy47 ) yymsp[-2].minor.yy47->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.yy192 = JT_INNER; } + case 121: /* joinop ::= COMMA|JOIN */ +{ yymsp[0].minor.yy394 = JT_INNER; } break; - case 120: /* joinop ::= JOIN_KW JOIN */ -{yymsp[-1].minor.yy192 = 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.yy192 = 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.yy192 = 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 216: /* case_else ::= ELSE expr */ yytestcase(yyruleno==216); - case 237: /* vinto ::= INTO expr */ yytestcase(yyruleno==237); -{yymsp[-1].minor.yy202 = yymsp[0].minor.yy202;} + 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 217: /* case_else ::= */ yytestcase(yyruleno==217); - case 219: /* case_operand ::= */ yytestcase(yyruleno==219); - case 238: /* vinto ::= */ yytestcase(yyruleno==238); -{yymsp[1].minor.yy202 = 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.yy600 = yymsp[-1].minor.yy600;} + case 130: /* using_opt ::= USING LP idlist RP */ +{yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;} break; - case 129: /* using_opt ::= */ - case 164: /* idlist_opt ::= */ yytestcase(yyruleno==164); -{yymsp[1].minor.yy600 = 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.yy242 = yymsp[0].minor.yy242;} + 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.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242,yymsp[-2].minor.yy202); - sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy242,yymsp[-1].minor.yy192,yymsp[0].minor.yy192); + 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.yy242 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy202); /*A-overwrites-Y*/ - sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy242,yymsp[-1].minor.yy192,yymsp[0].minor.yy192); + 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.yy192 = SQLITE_SO_ASC;} + case 136: /* sortorder ::= ASC */ +{yymsp[0].minor.yy394 = SQLITE_SO_ASC;} break; - case 135: /* sortorder ::= DESC */ -{yymsp[0].minor.yy192 = 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.yy192 = 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.yy192 = SQLITE_SO_ASC;} + case 139: /* nulls ::= NULLS FIRST */ +{yymsp[-1].minor.yy394 = SQLITE_SO_ASC;} break; - case 138: /* nulls ::= NULLS LAST */ -{yymsp[-1].minor.yy192 = 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.yy202 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy202,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.yy202 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy202,yymsp[0].minor.yy202);} + 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.yy202 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy202,yymsp[-2].minor.yy202);} + 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 */ + case 150: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy47, &yymsp[-1].minor.yy0); - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy47,yymsp[0].minor.yy202,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 151: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt */ + case 155: /* where_opt_ret ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-1].minor.yy528 = 0;} + break; + 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 157: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy47, &yymsp[-4].minor.yy0); - sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy242,"set list"); - yymsp[-5].minor.yy47 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy47, yymsp[-1].minor.yy47); - sqlite3Update(pParse,yymsp[-5].minor.yy47,yymsp[-2].minor.yy242,yymsp[0].minor.yy202,yymsp[-6].minor.yy192,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 152: /* setlist ::= setlist COMMA nm EQ expr */ + case 158: /* setlist ::= setlist COMMA nm EQ expr */ { - yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy242, yymsp[0].minor.yy202); - sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy242, &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 153: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ + case 159: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ { - yymsp[-6].minor.yy242 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy242, yymsp[-3].minor.yy600, yymsp[0].minor.yy202); + yymsp[-6].minor.yy322 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy322, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); } break; - case 154: /* setlist ::= nm EQ expr */ + case 160: /* setlist ::= nm EQ expr */ { - yylhsminor.yy242 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy202); - sqlite3ExprListSetName(pParse, yylhsminor.yy242, &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.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy322 = yylhsminor.yy322; break; - case 155: /* setlist ::= LP idlist RP EQ expr */ + case 161: /* setlist ::= LP idlist RP EQ expr */ { - yymsp[-4].minor.yy242 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy600, yymsp[0].minor.yy202); + yymsp[-4].minor.yy322 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); } break; - case 156: /* 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.yy47, yymsp[-1].minor.yy539, yymsp[-2].minor.yy600, yymsp[-5].minor.yy192, yymsp[0].minor.yy318); + sqlite3Insert(pParse, yymsp[-3].minor.yy131, yymsp[-1].minor.yy47, yymsp[-2].minor.yy254, yymsp[-5].minor.yy394, yymsp[0].minor.yy444); } break; - case 157: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ + case 163: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy47, 0, yymsp[-2].minor.yy600, yymsp[-5].minor.yy192, 0); + sqlite3Insert(pParse, yymsp[-4].minor.yy131, 0, yymsp[-3].minor.yy254, yymsp[-6].minor.yy394, 0); } break; - case 158: /* upsert ::= */ -{ yymsp[1].minor.yy318 = 0; } + case 164: /* upsert ::= */ +{ yymsp[1].minor.yy444 = 0; } + break; + case 165: /* upsert ::= RETURNING selcollist */ +{ yymsp[-1].minor.yy444 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy322); } + break; + 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 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 159: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ -{ yymsp[-10].minor.yy318 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy242,yymsp[-5].minor.yy202,yymsp[-1].minor.yy242,yymsp[0].minor.yy202);} + case 168: /* upsert ::= ON CONFLICT DO NOTHING returning */ +{ yymsp[-4].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } break; - case 160: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ -{ yymsp[-7].minor.yy318 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy242,yymsp[-2].minor.yy202,0,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 161: /* upsert ::= ON CONFLICT DO NOTHING */ -{ yymsp[-3].minor.yy318 = sqlite3UpsertNew(pParse->db,0,0,0,0); } + case 170: /* returning ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy322);} break; - case 165: /* idlist_opt ::= LP idlist RP */ -{yymsp[-2].minor.yy600 = yymsp[-1].minor.yy600;} + case 174: /* idlist_opt ::= LP idlist RP */ +{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;} break; - case 166: /* idlist ::= idlist COMMA nm */ -{yymsp[-2].minor.yy600 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy600,&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 167: /* idlist ::= nm */ -{yymsp[0].minor.yy600 = 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 168: /* expr ::= LP expr RP */ -{yymsp[-2].minor.yy202 = yymsp[-1].minor.yy202;} + case 177: /* expr ::= LP expr RP */ +{yymsp[-2].minor.yy528 = yymsp[-1].minor.yy528;} break; - case 169: /* expr ::= ID|INDEXED */ - case 170: /* expr ::= JOIN_KW */ yytestcase(yyruleno==170); -{yymsp[0].minor.yy202=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 171: /* 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.yy202 = 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.yy202 = yylhsminor.yy202; + yymsp[-2].minor.yy528 = yylhsminor.yy528; break; - case 172: /* 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.yy202 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); + yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } - yymsp[-4].minor.yy202 = yylhsminor.yy202; + yymsp[-4].minor.yy528 = yylhsminor.yy528; break; - case 173: /* term ::= NULL|FLOAT|BLOB */ - case 174: /* term ::= STRING */ yytestcase(yyruleno==174); -{yymsp[0].minor.yy202=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 175: /* term ::= INTEGER */ + case 184: /* term ::= INTEGER */ { - yylhsminor.yy202 = 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.yy202 = yylhsminor.yy202; + yymsp[0].minor.yy528 = yylhsminor.yy528; break; - case 176: /* 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.yy202 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy202, 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 @@ -158262,159 +165529,167 @@ static YYACTIONTYPE yy_reduce( assert( t.n>=2 ); if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); - yymsp[0].minor.yy202 = 0; + yymsp[0].minor.yy528 = 0; }else{ - yymsp[0].minor.yy202 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); - if( yymsp[0].minor.yy202 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy202->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 177: /* expr ::= expr COLLATE ID|STRING */ + case 186: /* expr ::= expr COLLATE ID|STRING */ { - yymsp[-2].minor.yy202 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy202, &yymsp[0].minor.yy0, 1); + yymsp[-2].minor.yy528 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy528, &yymsp[0].minor.yy0, 1); } break; - case 178: /* expr ::= CAST LP expr AS typetoken RP */ + case 187: /* expr ::= CAST LP expr AS typetoken RP */ { - yymsp[-5].minor.yy202 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); - sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy202, yymsp[-3].minor.yy202, 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 179: /* expr ::= ID|INDEXED LP distinct exprlist RP */ + case 188: /* expr ::= ID|INDEXED LP distinct exprlist RP */ { - yylhsminor.yy202 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy242, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy192); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy394); } - yymsp[-4].minor.yy202 = yylhsminor.yy202; + yymsp[-4].minor.yy528 = yylhsminor.yy528; break; - case 180: /* expr ::= ID|INDEXED LP STAR RP */ + case 189: /* expr ::= ID|INDEXED LP STAR RP */ { - yylhsminor.yy202 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } - yymsp[-3].minor.yy202 = yylhsminor.yy202; + yymsp[-3].minor.yy528 = yylhsminor.yy528; break; - case 181: /* expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + case 190: /* expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ { - yylhsminor.yy202 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy242, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy192); - sqlite3WindowAttach(pParse, yylhsminor.yy202, yymsp[0].minor.yy303); + 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.yy202 = yylhsminor.yy202; + yymsp[-5].minor.yy528 = yylhsminor.yy528; break; - case 182: /* expr ::= ID|INDEXED LP STAR RP filter_over */ + case 191: /* expr ::= ID|INDEXED LP STAR RP filter_over */ { - yylhsminor.yy202 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); - sqlite3WindowAttach(pParse, yylhsminor.yy202, yymsp[0].minor.yy303); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); + sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); } - yymsp[-4].minor.yy202 = yylhsminor.yy202; + yymsp[-4].minor.yy528 = yylhsminor.yy528; break; - case 183: /* term ::= CTIME_KW */ + case 192: /* term ::= CTIME_KW */ { - yylhsminor.yy202 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } - yymsp[0].minor.yy202 = yylhsminor.yy202; + yymsp[0].minor.yy528 = yylhsminor.yy528; break; - case 184: /* expr ::= LP nexprlist COMMA expr RP */ + case 193: /* expr ::= LP nexprlist COMMA expr RP */ { - ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy242, yymsp[-1].minor.yy202); - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); - if( yymsp[-4].minor.yy202 ){ - yymsp[-4].minor.yy202->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.yy202->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 185: /* expr ::= expr AND expr */ -{yymsp[-2].minor.yy202=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy202,yymsp[0].minor.yy202);} + case 194: /* expr ::= expr AND expr */ +{yymsp[-2].minor.yy528=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} break; - case 186: /* expr ::= expr OR expr */ - case 187: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==187); - case 188: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==188); - case 189: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==189); - case 190: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==190); - case 191: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==191); - case 192: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==192); -{yymsp[-2].minor.yy202=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy202,yymsp[0].minor.yy202);} + 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 193: /* 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 194: /* 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.yy202); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy202); - yymsp[-2].minor.yy202 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); - if( bNot ) yymsp[-2].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy202, 0); - if( yymsp[-2].minor.yy202 ) yymsp[-2].minor.yy202->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 195: /* 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.yy202); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy202); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy202); - yymsp[-4].minor.yy202 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); - if( bNot ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); - if( yymsp[-4].minor.yy202 ) yymsp[-4].minor.yy202->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 196: /* expr ::= expr ISNULL|NOTNULL */ -{yymsp[-1].minor.yy202 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy202,0);} + case 205: /* expr ::= expr ISNULL|NOTNULL */ +{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy528,0);} break; - case 197: /* expr ::= expr NOT NULL */ -{yymsp[-2].minor.yy202 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy202,0);} + case 206: /* expr ::= expr NOT NULL */ +{yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy528,0);} break; - case 198: /* expr ::= expr IS expr */ + case 207: /* expr ::= expr IS expr */ { - yymsp[-2].minor.yy202 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy202,yymsp[0].minor.yy202); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy202, yymsp[-2].minor.yy202, 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 199: /* expr ::= expr IS NOT expr */ + case 208: /* expr ::= expr IS NOT expr */ { - yymsp[-3].minor.yy202 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy202,yymsp[0].minor.yy202); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy202, yymsp[-3].minor.yy202, 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 200: /* expr ::= NOT expr */ - case 201: /* expr ::= BITNOT expr */ yytestcase(yyruleno==201); -{yymsp[-1].minor.yy202 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy202, 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 202: /* expr ::= PLUS|MINUS expr */ + case 211: /* expr ::= PLUS|MINUS expr */ { - yymsp[-1].minor.yy202 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy202, 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 203: /* between_op ::= BETWEEN */ - case 206: /* in_op ::= IN */ yytestcase(yyruleno==206); -{yymsp[0].minor.yy192 = 0;} + case 212: /* expr ::= expr PTR expr */ +{ + 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 205: /* expr ::= expr between_op expr AND expr */ + case 215: /* expr ::= expr between_op expr AND expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy202); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy202); - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy202, 0); - if( yymsp[-4].minor.yy202 ){ - yymsp[-4].minor.yy202->x.pList = pList; + 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.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } break; - case 208: /* expr ::= expr in_op LP exprlist RP */ + case 218: /* expr ::= expr in_op LP exprlist RP */ { - if( yymsp[-1].minor.yy242==0 ){ + if( yymsp[-1].minor.yy322==0 ){ /* Expressions of the form ** ** expr1 IN () @@ -158423,197 +165698,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.yy202); - yymsp[-4].minor.yy202 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy192 ? "1" : "0"); - }else if( yymsp[-1].minor.yy242->nExpr==1 && sqlite3ExprIsConstant(yymsp[-1].minor.yy242->a[0].pExpr) ){ - Expr *pRHS = yymsp[-1].minor.yy242->a[0].pExpr; - yymsp[-1].minor.yy242->a[0].pExpr = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy242); - pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy202, pRHS); - if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); - }else{ - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy202, 0); - if( yymsp[-4].minor.yy202 ){ - yymsp[-4].minor.yy202->x.pList = yymsp[-1].minor.yy242; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy202); + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy394 ? "1" : "0"); + }else{ + 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.yy242); + 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.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } } break; - case 209: /* expr ::= LP select RP */ + case 219: /* expr ::= LP select RP */ { - yymsp[-2].minor.yy202 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); - sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy202, yymsp[-1].minor.yy539); + yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47); } break; - case 210: /* expr ::= expr in_op LP select RP */ + case 220: /* expr ::= expr in_op LP select RP */ { - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy202, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy202, yymsp[-1].minor.yy539); - if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 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 211: /* 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.yy242 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy242); - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy202, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy202, pSelect); - if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 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 212: /* expr ::= EXISTS LP select RP */ + case 222: /* expr ::= EXISTS LP select RP */ { Expr *p; - p = yymsp[-3].minor.yy202 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); - sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy539); + p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47); } break; - case 213: /* expr ::= CASE case_operand case_exprlist case_else END */ + case 223: /* expr ::= CASE case_operand case_exprlist case_else END */ { - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy202, 0); - if( yymsp[-4].minor.yy202 ){ - yymsp[-4].minor.yy202->x.pList = yymsp[-1].minor.yy202 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy242,yymsp[-1].minor.yy202) : yymsp[-2].minor.yy242; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy202); + 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.yy242); - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy202); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); } } break; - case 214: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + case 224: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { - yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, yymsp[-2].minor.yy202); - yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, yymsp[0].minor.yy202); + 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 215: /* case_exprlist ::= WHEN expr THEN expr */ + case 225: /* case_exprlist ::= WHEN expr THEN expr */ { - yymsp[-3].minor.yy242 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy202); - yymsp[-3].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy242, yymsp[0].minor.yy202); + 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 218: /* case_operand ::= expr */ -{yymsp[0].minor.yy202 = yymsp[0].minor.yy202; /*A-overwrites-X*/} + case 228: /* case_operand ::= expr */ +{yymsp[0].minor.yy528 = yymsp[0].minor.yy528; /*A-overwrites-X*/} break; - case 221: /* nexprlist ::= nexprlist COMMA expr */ -{yymsp[-2].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy242,yymsp[0].minor.yy202);} + case 231: /* nexprlist ::= nexprlist COMMA expr */ +{yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);} break; - case 222: /* nexprlist ::= expr */ -{yymsp[0].minor.yy242 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy202); /*A-overwrites-Y*/} + case 232: /* nexprlist ::= expr */ +{yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/} break; - case 224: /* paren_exprlist ::= LP exprlist RP */ - case 229: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==229); -{yymsp[-2].minor.yy242 = yymsp[-1].minor.yy242;} + 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 225: /* 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.yy242, yymsp[-10].minor.yy192, - &yymsp[-11].minor.yy0, yymsp[0].minor.yy202, SQLITE_SO_ASC, yymsp[-8].minor.yy192, 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 226: /* uniqueflag ::= UNIQUE */ - case 268: /* raisetype ::= ABORT */ yytestcase(yyruleno==268); -{yymsp[0].minor.yy192 = OE_Abort;} + case 236: /* uniqueflag ::= UNIQUE */ + case 278: /* raisetype ::= ABORT */ yytestcase(yyruleno==278); +{yymsp[0].minor.yy394 = OE_Abort;} break; - case 227: /* uniqueflag ::= */ -{yymsp[1].minor.yy192 = OE_None;} + case 237: /* uniqueflag ::= */ +{yymsp[1].minor.yy394 = OE_None;} break; - case 230: /* eidlist ::= eidlist COMMA nm collate sortorder */ + case 240: /* eidlist ::= eidlist COMMA nm collate sortorder */ { - yymsp[-4].minor.yy242 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy242, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy192, yymsp[0].minor.yy192); + yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); } break; - case 231: /* eidlist ::= nm collate sortorder */ + case 241: /* eidlist ::= nm collate sortorder */ { - yymsp[-2].minor.yy242 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy192, yymsp[0].minor.yy192); /*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 234: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy47, yymsp[-1].minor.yy192);} + case 244: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);} break; - case 235: /* cmd ::= VACUUM vinto */ -{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy202);} + case 245: /* cmd ::= VACUUM vinto */ +{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);} break; - case 236: /* cmd ::= VACUUM nm vinto */ -{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy202);} + case 246: /* cmd ::= VACUUM nm vinto */ +{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);} break; - case 239: /* cmd ::= PRAGMA nm dbnm */ + case 249: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 240: /* 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 241: /* 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 242: /* 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 243: /* 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 246: /* 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.yy447, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all); } break; - case 247: /* 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.yy192, yymsp[-4].minor.yy230.a, yymsp[-4].minor.yy230.b, yymsp[-2].minor.yy47, yymsp[0].minor.yy202, yymsp[-10].minor.yy192, yymsp[-8].minor.yy192); + 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 248: /* trigger_time ::= BEFORE|AFTER */ -{ yymsp[0].minor.yy192 = yymsp[0].major; /*A-overwrites-X*/ } + case 258: /* trigger_time ::= BEFORE|AFTER */ +{ yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ } break; - case 249: /* trigger_time ::= INSTEAD OF */ -{ yymsp[-1].minor.yy192 = TK_INSTEAD;} + case 259: /* trigger_time ::= INSTEAD OF */ +{ yymsp[-1].minor.yy394 = TK_INSTEAD;} break; - case 250: /* trigger_time ::= */ -{ yymsp[1].minor.yy192 = TK_BEFORE; } + case 260: /* trigger_time ::= */ +{ yymsp[1].minor.yy394 = TK_BEFORE; } break; - case 251: /* trigger_event ::= DELETE|INSERT */ - case 252: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==252); -{yymsp[0].minor.yy230.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy230.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 253: /* trigger_event ::= UPDATE OF idlist */ -{yymsp[-2].minor.yy230.a = TK_UPDATE; yymsp[-2].minor.yy230.b = yymsp[0].minor.yy600;} + 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 254: /* when_clause ::= */ - case 273: /* key_opt ::= */ yytestcase(yyruleno==273); -{ yymsp[1].minor.yy202 = 0; } + case 264: /* when_clause ::= */ + case 283: /* key_opt ::= */ yytestcase(yyruleno==283); +{ yymsp[1].minor.yy528 = 0; } break; - case 255: /* when_clause ::= WHEN expr */ - case 274: /* key_opt ::= KEY expr */ yytestcase(yyruleno==274); -{ yymsp[-1].minor.yy202 = yymsp[0].minor.yy202; } + 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 256: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 266: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { - assert( yymsp[-2].minor.yy447!=0 ); - yymsp[-2].minor.yy447->pLast->pNext = yymsp[-1].minor.yy447; - yymsp[-2].minor.yy447->pLast = yymsp[-1].minor.yy447; + 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 257: /* trigger_cmd_list ::= trigger_cmd SEMI */ + case 267: /* trigger_cmd_list ::= trigger_cmd SEMI */ { - assert( yymsp[-1].minor.yy447!=0 ); - yymsp[-1].minor.yy447->pLast = yymsp[-1].minor.yy447; + assert( yymsp[-1].minor.yy33!=0 ); + yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33; } break; - case 258: /* trnm ::= nm DOT nm */ + case 268: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, @@ -158621,344 +165904,369 @@ static YYACTIONTYPE yy_reduce( "statements within triggers"); } break; - case 259: /* 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 260: /* 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 261: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ -{yylhsminor.yy447 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy47, yymsp[-3].minor.yy242, yymsp[-1].minor.yy202, yymsp[-7].minor.yy192, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy436);} - yymsp[-8].minor.yy447 = yylhsminor.yy447; + 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 262: /* 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.yy447 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy600,yymsp[-2].minor.yy539,yymsp[-6].minor.yy192,yymsp[-1].minor.yy318,yymsp[-7].minor.yy436,yymsp[0].minor.yy436);/*yylhsminor.yy447-overwrites-yymsp[-6].minor.yy192*/ + 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.yy447 = yylhsminor.yy447; + yymsp[-7].minor.yy33 = yylhsminor.yy33; break; - case 263: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -{yylhsminor.yy447 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy202, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy436);} - yymsp[-5].minor.yy447 = yylhsminor.yy447; + 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 264: /* trigger_cmd ::= scanpt select scanpt */ -{yylhsminor.yy447 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy539, yymsp[-2].minor.yy436, yymsp[0].minor.yy436); /*yylhsminor.yy447-overwrites-yymsp[-1].minor.yy539*/} - yymsp[-2].minor.yy447 = yylhsminor.yy447; + 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 265: /* expr ::= RAISE LP IGNORE RP */ + case 275: /* expr ::= RAISE LP IGNORE RP */ { - yymsp[-3].minor.yy202 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); - if( yymsp[-3].minor.yy202 ){ - yymsp[-3].minor.yy202->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 266: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 276: /* expr ::= RAISE LP raisetype COMMA nm RP */ { - yymsp[-5].minor.yy202 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); - if( yymsp[-5].minor.yy202 ) { - yymsp[-5].minor.yy202->affExpr = (char)yymsp[-3].minor.yy192; + 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 267: /* raisetype ::= ROLLBACK */ -{yymsp[0].minor.yy192 = OE_Rollback;} + case 277: /* raisetype ::= ROLLBACK */ +{yymsp[0].minor.yy394 = OE_Rollback;} break; - case 269: /* raisetype ::= FAIL */ -{yymsp[0].minor.yy192 = OE_Fail;} + case 279: /* raisetype ::= FAIL */ +{yymsp[0].minor.yy394 = OE_Fail;} break; - case 270: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 280: /* cmd ::= DROP TRIGGER ifexists fullname */ { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy192); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394); } break; - case 271: /* 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.yy202, yymsp[-1].minor.yy202, yymsp[0].minor.yy202); + sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528); } break; - case 272: /* cmd ::= DETACH database_kw_opt expr */ + case 282: /* cmd ::= DETACH database_kw_opt expr */ { - sqlite3Detach(pParse, yymsp[0].minor.yy202); + sqlite3Detach(pParse, yymsp[0].minor.yy528); } break; - case 275: /* cmd ::= REINDEX */ + case 285: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 276: /* cmd ::= REINDEX nm dbnm */ + case 286: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 277: /* cmd ::= ANALYZE */ + case 287: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 278: /* cmd ::= ANALYZE nm dbnm */ + case 288: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 279: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 289: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy47,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0); } break; - case 280: /* 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 281: /* add_column_fullname ::= fullname */ + case 291: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ +{ + sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0); +} + break; + case 292: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy47); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131); } break; - case 282: /* 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.yy47, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 283: /* cmd ::= create_vtab */ + case 294: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 284: /* cmd ::= create_vtab LP vtabarglist RP */ + case 295: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 285: /* 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.yy192); + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394); } break; - case 286: /* vtabarg ::= */ + case 297: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 287: /* vtabargtoken ::= ANY */ - case 288: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==288); - case 289: /* lp ::= LP */ yytestcase(yyruleno==289); + 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 290: /* with ::= WITH wqlist */ - case 291: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==291); -{ sqlite3WithPush(pParse, yymsp[0].minor.yy131, 1); } + case 301: /* with ::= WITH wqlist */ + case 302: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==302); +{ sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); } + break; + case 303: /* wqas ::= AS */ +{yymsp[0].minor.yy516 = M10d_Any;} + break; + case 304: /* wqas ::= AS MATERIALIZED */ +{yymsp[-1].minor.yy516 = M10d_Yes;} + break; + case 305: /* wqas ::= AS NOT MATERIALIZED */ +{yymsp[-2].minor.yy516 = M10d_No;} + break; + case 306: /* wqitem ::= nm eidlist_opt wqas LP select RP */ +{ + 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 292: /* wqlist ::= nm eidlist_opt AS LP select RP */ + case 307: /* wqlist ::= wqitem */ { - yymsp[-5].minor.yy131 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy242, yymsp[-1].minor.yy539); /*A-overwrites-X*/ + yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/ } break; - case 293: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ + case 308: /* wqlist ::= wqlist COMMA wqitem */ { - yymsp[-7].minor.yy131 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy131, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy242, yymsp[-1].minor.yy539); + yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385); } break; - case 294: /* windowdefn_list ::= windowdefn */ -{ yylhsminor.yy303 = yymsp[0].minor.yy303; } - yymsp[0].minor.yy303 = yylhsminor.yy303; + case 309: /* windowdefn_list ::= windowdefn */ +{ yylhsminor.yy41 = yymsp[0].minor.yy41; } + yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 295: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ + case 310: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ { - assert( yymsp[0].minor.yy303!=0 ); - sqlite3WindowChain(pParse, yymsp[0].minor.yy303, yymsp[-2].minor.yy303); - yymsp[0].minor.yy303->pNextWin = yymsp[-2].minor.yy303; - yylhsminor.yy303 = yymsp[0].minor.yy303; + 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.yy303 = yylhsminor.yy303; + yymsp[-2].minor.yy41 = yylhsminor.yy41; break; - case 296: /* windowdefn ::= nm AS LP window RP */ + case 311: /* windowdefn ::= nm AS LP window RP */ { - if( ALWAYS(yymsp[-1].minor.yy303) ){ - yymsp[-1].minor.yy303->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.yy303 = yymsp[-1].minor.yy303; + yylhsminor.yy41 = yymsp[-1].minor.yy41; } - yymsp[-4].minor.yy303 = yylhsminor.yy303; + yymsp[-4].minor.yy41 = yylhsminor.yy41; break; - case 297: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + case 312: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ { - yymsp[-4].minor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, yymsp[-2].minor.yy242, yymsp[-1].minor.yy242, 0); + yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0); } break; - case 298: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + case 313: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ { - yylhsminor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, yymsp[-2].minor.yy242, yymsp[-1].minor.yy242, &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.yy303 = yylhsminor.yy303; + yymsp[-5].minor.yy41 = yylhsminor.yy41; break; - case 299: /* window ::= ORDER BY sortlist frame_opt */ + case 314: /* window ::= ORDER BY sortlist frame_opt */ { - yymsp[-3].minor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, 0, yymsp[-1].minor.yy242, 0); + yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0); } break; - case 300: /* window ::= nm ORDER BY sortlist frame_opt */ + case 315: /* window ::= nm ORDER BY sortlist frame_opt */ { - yylhsminor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, 0, yymsp[-1].minor.yy242, &yymsp[-4].minor.yy0); + yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); } - yymsp[-4].minor.yy303 = yylhsminor.yy303; + yymsp[-4].minor.yy41 = yylhsminor.yy41; break; - case 301: /* window ::= frame_opt */ - case 320: /* filter_over ::= over_clause */ yytestcase(yyruleno==320); + case 316: /* window ::= frame_opt */ + case 335: /* filter_over ::= over_clause */ yytestcase(yyruleno==335); { - yylhsminor.yy303 = yymsp[0].minor.yy303; + yylhsminor.yy41 = yymsp[0].minor.yy41; } - yymsp[0].minor.yy303 = yylhsminor.yy303; + yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 302: /* window ::= nm frame_opt */ + case 317: /* window ::= nm frame_opt */ { - yylhsminor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, 0, 0, &yymsp[-1].minor.yy0); + yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy303 = yylhsminor.yy303; + yymsp[-1].minor.yy41 = yylhsminor.yy41; break; - case 303: /* frame_opt ::= */ + case 318: /* frame_opt ::= */ { - yymsp[1].minor.yy303 = 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 304: /* 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.yy303 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy192, yymsp[-1].minor.yy77.eType, yymsp[-1].minor.yy77.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy58); + 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.yy303 = yylhsminor.yy303; + yymsp[-2].minor.yy41 = yylhsminor.yy41; break; - case 305: /* 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.yy303 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy192, yymsp[-3].minor.yy77.eType, yymsp[-3].minor.yy77.pExpr, yymsp[-1].minor.yy77.eType, yymsp[-1].minor.yy77.pExpr, yymsp[0].minor.yy58); + 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.yy303 = yylhsminor.yy303; + yymsp[-5].minor.yy41 = yylhsminor.yy41; break; - case 307: /* frame_bound_s ::= frame_bound */ - case 309: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==309); -{yylhsminor.yy77 = yymsp[0].minor.yy77;} - yymsp[0].minor.yy77 = yylhsminor.yy77; + 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 308: /* frame_bound_s ::= UNBOUNDED PRECEDING */ - case 310: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==310); - case 312: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==312); -{yylhsminor.yy77.eType = yymsp[-1].major; yylhsminor.yy77.pExpr = 0;} - yymsp[-1].minor.yy77 = yylhsminor.yy77; + 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 311: /* frame_bound ::= expr PRECEDING|FOLLOWING */ -{yylhsminor.yy77.eType = yymsp[0].major; yylhsminor.yy77.pExpr = yymsp[-1].minor.yy202;} - yymsp[-1].minor.yy77 = yylhsminor.yy77; + 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 313: /* frame_exclude_opt ::= */ -{yymsp[1].minor.yy58 = 0;} + case 328: /* frame_exclude_opt ::= */ +{yymsp[1].minor.yy516 = 0;} break; - case 314: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ -{yymsp[-1].minor.yy58 = yymsp[0].minor.yy58;} + case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ +{yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;} break; - case 315: /* frame_exclude ::= NO OTHERS */ - case 316: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==316); -{yymsp[-1].minor.yy58 = 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 317: /* frame_exclude ::= GROUP|TIES */ -{yymsp[0].minor.yy58 = yymsp[0].major; /*A-overwrites-X*/} + case 332: /* frame_exclude ::= GROUP|TIES */ +{yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/} break; - case 318: /* window_clause ::= WINDOW windowdefn_list */ -{ yymsp[-1].minor.yy303 = yymsp[0].minor.yy303; } + case 333: /* window_clause ::= WINDOW windowdefn_list */ +{ yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; } break; - case 319: /* filter_over ::= filter_clause over_clause */ + case 334: /* filter_over ::= filter_clause over_clause */ { - yymsp[0].minor.yy303->pFilter = yymsp[-1].minor.yy202; - yylhsminor.yy303 = yymsp[0].minor.yy303; + if( yymsp[0].minor.yy41 ){ + yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528; + }else{ + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); + } + yylhsminor.yy41 = yymsp[0].minor.yy41; } - yymsp[-1].minor.yy303 = yylhsminor.yy303; + yymsp[-1].minor.yy41 = yylhsminor.yy41; break; - case 321: /* filter_over ::= filter_clause */ + case 336: /* filter_over ::= filter_clause */ { - yylhsminor.yy303 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yylhsminor.yy303 ){ - yylhsminor.yy303->eFrmType = TK_FILTER; - yylhsminor.yy303->pFilter = yymsp[0].minor.yy202; + 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.yy202); + sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy528); } } - yymsp[0].minor.yy303 = yylhsminor.yy303; + yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 322: /* over_clause ::= OVER LP window RP */ + case 337: /* over_clause ::= OVER LP window RP */ { - yymsp[-3].minor.yy303 = yymsp[-1].minor.yy303; - assert( yymsp[-3].minor.yy303!=0 ); + yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41; + assert( yymsp[-3].minor.yy41!=0 ); } break; - case 323: /* over_clause ::= OVER nm */ + case 338: /* over_clause ::= OVER nm */ { - yymsp[-1].minor.yy303 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yymsp[-1].minor.yy303 ){ - yymsp[-1].minor.yy303->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 324: /* filter_clause ::= FILTER LP WHERE expr RP */ -{ yymsp[-4].minor.yy202 = yymsp[-1].minor.yy202; } + case 339: /* filter_clause ::= FILTER LP WHERE expr RP */ +{ yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; } break; default: - /* (325) input ::= cmdlist */ yytestcase(yyruleno==325); - /* (326) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==326); - /* (327) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=327); - /* (328) ecmd ::= SEMI */ yytestcase(yyruleno==328); - /* (329) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==329); - /* (330) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=330); - /* (331) trans_opt ::= */ yytestcase(yyruleno==331); - /* (332) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==332); - /* (333) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==333); - /* (334) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==334); - /* (335) savepoint_opt ::= */ yytestcase(yyruleno==335); - /* (336) cmd ::= create_table create_table_args */ yytestcase(yyruleno==336); - /* (337) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==337); - /* (338) columnlist ::= columnname carglist */ yytestcase(yyruleno==338); - /* (339) nm ::= ID|INDEXED */ yytestcase(yyruleno==339); - /* (340) nm ::= STRING */ yytestcase(yyruleno==340); - /* (341) nm ::= JOIN_KW */ yytestcase(yyruleno==341); - /* (342) typetoken ::= typename */ yytestcase(yyruleno==342); - /* (343) typename ::= ID|STRING */ yytestcase(yyruleno==343); - /* (344) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=344); - /* (345) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=345); - /* (346) carglist ::= carglist ccons */ yytestcase(yyruleno==346); - /* (347) carglist ::= */ yytestcase(yyruleno==347); - /* (348) ccons ::= NULL onconf */ yytestcase(yyruleno==348); - /* (349) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==349); - /* (350) ccons ::= AS generated */ yytestcase(yyruleno==350); - /* (351) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==351); - /* (352) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==352); - /* (353) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=353); - /* (354) tconscomma ::= */ yytestcase(yyruleno==354); - /* (355) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=355); - /* (356) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=356); - /* (357) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=357); - /* (358) oneselect ::= values */ yytestcase(yyruleno==358); - /* (359) sclp ::= selcollist COMMA */ yytestcase(yyruleno==359); - /* (360) as ::= ID|STRING */ yytestcase(yyruleno==360); - /* (361) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=361); - /* (362) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==362); - /* (363) exprlist ::= nexprlist */ yytestcase(yyruleno==363); - /* (364) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=364); - /* (365) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=365); - /* (366) nmnum ::= ON */ yytestcase(yyruleno==366); - /* (367) nmnum ::= DELETE */ yytestcase(yyruleno==367); - /* (368) nmnum ::= DEFAULT */ yytestcase(yyruleno==368); - /* (369) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==369); - /* (370) foreach_clause ::= */ yytestcase(yyruleno==370); - /* (371) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==371); - /* (372) trnm ::= nm */ yytestcase(yyruleno==372); - /* (373) tridxby ::= */ yytestcase(yyruleno==373); - /* (374) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==374); - /* (375) database_kw_opt ::= */ yytestcase(yyruleno==375); - /* (376) kwcolumn_opt ::= */ yytestcase(yyruleno==376); - /* (377) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==377); - /* (378) vtabarglist ::= vtabarg */ yytestcase(yyruleno==378); - /* (379) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==379); - /* (380) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==380); - /* (381) anylist ::= */ yytestcase(yyruleno==381); - /* (382) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==382); - /* (383) anylist ::= anylist ANY */ yytestcase(yyruleno==383); - /* (384) with ::= */ yytestcase(yyruleno==384); + /* (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 ************************************************/ }; @@ -159110,12 +166418,56 @@ SQLITE_PRIVATE void sqlite3Parser( } #endif - do{ + while(1){ /* Exit by "break" */ + assert( yypParser->yytos>=yypParser->yystack ); assert( yyact==yypParser->yytos->stateno ); yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); if( yyact >= YY_MIN_REDUCE ){ - yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, - yyminor sqlite3ParserCTX_PARAM); + unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */ +#ifndef NDEBUG + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); + if( yyTraceFILE ){ + int yysize = yyRuleInfoNRhs[yyruleno]; + if( yysize ){ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + yyTracePrompt, + yyruleno, yyRuleName[yyruleno], + yyrulenoyytos[yysize].stateno); + }else{ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", + yyTracePrompt, yyruleno, yyRuleName[yyruleno], + yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == + (int)(yypParser->yytos - yypParser->yystack)); + } +#endif +#if YYSTACKDEPTH>0 + if( yypParser->yytos>=yypParser->yystackEnd ){ + yyStackOverflow(yypParser); + break; + } +#else + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ + if( yyGrowStack(yypParser) ){ + yyStackOverflow(yypParser); + break; + } + } +#endif + } + yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor sqlite3ParserCTX_PARAM); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); #ifndef YYNOERRORRECOVERY @@ -159171,14 +166523,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 @@ -159228,7 +166579,7 @@ SQLITE_PRIVATE void sqlite3Parser( break; #endif } - }while( yypParser->yytos>yypParser->yystack ); + } #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; @@ -159289,8 +166640,8 @@ SQLITE_PRIVATE int sqlite3ParserFallback(int iToken){ ** all of them need to be used within the switch. */ #define CC_X 0 /* The letter 'x', or start of BLOB literal */ -#define CC_KYWD 1 /* Alphabetics or '_'. Usable in a keyword */ -#define CC_ID 2 /* unicode characters usable in IDs */ +#define CC_KYWD0 1 /* First letter of a keyword */ +#define CC_KYWD 2 /* Alphabetics or '_'. Usable in a keyword */ #define CC_DIGIT 3 /* Digits */ #define CC_DOLLAR 4 /* '$' */ #define CC_VARALPHA 5 /* '@', '#', ':'. Alphabetic SQL variables */ @@ -159315,47 +166666,49 @@ SQLITE_PRIVATE int sqlite3ParserFallback(int iToken){ #define CC_AND 24 /* '&' */ #define CC_TILDA 25 /* '~' */ #define CC_DOT 26 /* '.' */ -#define CC_ILLEGAL 27 /* Illegal character */ -#define CC_NUL 28 /* 0x00 */ +#define CC_ID 27 /* unicode characters usable in IDs */ +#define CC_ILLEGAL 28 /* Illegal character */ +#define CC_NUL 29 /* 0x00 */ +#define CC_BOM 30 /* First byte of UTF8 BOM: 0xEF 0xBB 0xBF */ static const unsigned char aiClass[] = { #ifdef SQLITE_ASCII /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ -/* 0x */ 28, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27, -/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* 0x */ 29, 28, 28, 28, 28, 28, 28, 28, 28, 7, 7, 28, 7, 7, 28, 28, +/* 1x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, /* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16, /* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6, /* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 9, 27, 27, 27, 1, +/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 9, 28, 28, 28, 2, /* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 10, 27, 25, 27, -/* 8x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* 9x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Ax */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Bx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Cx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Dx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Ex */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Fx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 +/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 28, 10, 28, 25, 28, +/* 8x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* 9x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Ax */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Cx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Dx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Ex */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 30, +/* Fx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27 #endif #ifdef SQLITE_EBCDIC /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ -/* 0x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 7, 7, 27, 27, -/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 2x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 3x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 4x */ 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 12, 17, 20, 10, -/* 5x */ 24, 27, 27, 27, 27, 27, 27, 27, 27, 27, 15, 4, 21, 18, 19, 27, -/* 6x */ 11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22, 1, 13, 6, -/* 7x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 8, 5, 5, 5, 8, 14, 8, -/* 8x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* 9x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* Ax */ 27, 25, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, -/* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 9, 27, 27, 27, 27, 27, -/* Cx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* Dx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* Ex */ 27, 27, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, -/* Fx */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 27, 27, 27, 27, 27, 27, +/* 0x */ 29, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 7, 7, 28, 28, +/* 1x */ 28, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 2x */ 28, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 3x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 4x */ 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 26, 12, 17, 20, 10, +/* 5x */ 24, 28, 28, 28, 28, 28, 28, 28, 28, 28, 15, 4, 21, 18, 19, 28, +/* 6x */ 11, 16, 28, 28, 28, 28, 28, 28, 28, 28, 28, 23, 22, 2, 13, 6, +/* 7x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 8, 5, 5, 5, 8, 14, 8, +/* 8x */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* 9x */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Ax */ 28, 25, 1, 1, 1, 1, 1, 0, 2, 2, 28, 28, 28, 28, 28, 28, +/* Bx */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 9, 28, 28, 28, 28, 28, +/* Cx */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Dx */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Ex */ 28, 28, 1, 1, 1, 1, 1, 0, 2, 2, 28, 28, 28, 28, 28, 28, +/* Fx */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 28, 28, 28, 28, 28, 28, #endif }; @@ -159420,20 +166773,21 @@ const unsigned char ebcdicToAscii[] = { ** is substantially reduced. This is important for embedded applications ** on platforms with limited memory. */ -/* Hash score: 227 */ -/* zKWText[] encodes 984 bytes of keyword text in 648 bytes */ +/* Hash score: 231 */ +/* zKWText[] encodes 1007 bytes of keyword text in 667 bytes */ /* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */ /* ABLEFTHENDEFERRABLELSEXCLUDELETEMPORARYISNULLSAVEPOINTERSECT */ /* IESNOTNULLIKEXCEPTRANSACTIONATURALTERAISEXCLUSIVEXISTS */ /* CONSTRAINTOFFSETRIGGERANGENERATEDETACHAVINGLOBEGINNEREFERENCES */ /* UNIQUERYWITHOUTERELEASEATTACHBETWEENOTHINGROUPSCASCADEFAULT */ /* CASECOLLATECREATECURRENT_DATEIMMEDIATEJOINSERTMATCHPLANALYZE */ -/* PRAGMABORTUPDATEVALUESVIRTUALWAYSWHENWHERECURSIVEAFTERENAMEAND */ -/* EFERREDISTINCTAUTOINCREMENTCASTCOLUMNCOMMITCONFLICTCROSS */ -/* CURRENT_TIMESTAMPARTITIONDROPRECEDINGFAILASTFILTEREPLACEFIRST */ -/* FOLLOWINGFROMFULLIMITIFORDERESTRICTOTHERSOVERIGHTROLLBACKROWS */ -/* UNBOUNDEDUNIONUSINGVACUUMVIEWINDOWBYINITIALLYPRIMARY */ -static const char zKWText[647] = { +/* PRAGMATERIALIZEDEFERREDISTINCTUPDATEVALUESVIRTUALWAYSWHENWHERE */ +/* CURSIVEABORTAFTERENAMEANDROPARTITIONAUTOINCREMENTCASTCOLUMN */ +/* COMMITCONFLICTCROSSCURRENT_TIMESTAMPRECEDINGFAILASTFILTER */ +/* EPLACEFIRSTFOLLOWINGFROMFULLIMITIFORDERESTRICTOTHERSOVER */ +/* ETURNINGRIGHTROLLBACKROWSUNBOUNDEDUNIONUSINGVACUUMVIEWINDOWBY */ +/* INITIALLYPRIMARY */ +static const char zKWText[666] = { 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H', 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G', 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A', @@ -159454,86 +166808,87 @@ static const char zKWText[647] = { 'C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A','T','E', 'I','M','M','E','D','I','A','T','E','J','O','I','N','S','E','R','T','M', 'A','T','C','H','P','L','A','N','A','L','Y','Z','E','P','R','A','G','M', - 'A','B','O','R','T','U','P','D','A','T','E','V','A','L','U','E','S','V', - 'I','R','T','U','A','L','W','A','Y','S','W','H','E','N','W','H','E','R', - 'E','C','U','R','S','I','V','E','A','F','T','E','R','E','N','A','M','E', - 'A','N','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','A', - 'U','T','O','I','N','C','R','E','M','E','N','T','C','A','S','T','C','O', - 'L','U','M','N','C','O','M','M','I','T','C','O','N','F','L','I','C','T', - 'C','R','O','S','S','C','U','R','R','E','N','T','_','T','I','M','E','S', - 'T','A','M','P','A','R','T','I','T','I','O','N','D','R','O','P','R','E', - 'C','E','D','I','N','G','F','A','I','L','A','S','T','F','I','L','T','E', - 'R','E','P','L','A','C','E','F','I','R','S','T','F','O','L','L','O','W', - 'I','N','G','F','R','O','M','F','U','L','L','I','M','I','T','I','F','O', - 'R','D','E','R','E','S','T','R','I','C','T','O','T','H','E','R','S','O', - 'V','E','R','I','G','H','T','R','O','L','L','B','A','C','K','R','O','W', - 'S','U','N','B','O','U','N','D','E','D','U','N','I','O','N','U','S','I', - 'N','G','V','A','C','U','U','M','V','I','E','W','I','N','D','O','W','B', - 'Y','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R','Y', + 'A','T','E','R','I','A','L','I','Z','E','D','E','F','E','R','R','E','D', + 'I','S','T','I','N','C','T','U','P','D','A','T','E','V','A','L','U','E', + 'S','V','I','R','T','U','A','L','W','A','Y','S','W','H','E','N','W','H', + 'E','R','E','C','U','R','S','I','V','E','A','B','O','R','T','A','F','T', + 'E','R','E','N','A','M','E','A','N','D','R','O','P','A','R','T','I','T', + 'I','O','N','A','U','T','O','I','N','C','R','E','M','E','N','T','C','A', + 'S','T','C','O','L','U','M','N','C','O','M','M','I','T','C','O','N','F', + 'L','I','C','T','C','R','O','S','S','C','U','R','R','E','N','T','_','T', + 'I','M','E','S','T','A','M','P','R','E','C','E','D','I','N','G','F','A', + 'I','L','A','S','T','F','I','L','T','E','R','E','P','L','A','C','E','F', + 'I','R','S','T','F','O','L','L','O','W','I','N','G','F','R','O','M','F', + 'U','L','L','I','M','I','T','I','F','O','R','D','E','R','E','S','T','R', + 'I','C','T','O','T','H','E','R','S','O','V','E','R','E','T','U','R','N', + 'I','N','G','R','I','G','H','T','R','O','L','L','B','A','C','K','R','O', + 'W','S','U','N','B','O','U','N','D','E','D','U','N','I','O','N','U','S', + 'I','N','G','V','A','C','U','U','M','V','I','E','W','I','N','D','O','W', + 'B','Y','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R','Y', }; /* aKWHash[i] is the hash value for the i-th keyword */ static const unsigned char aKWHash[127] = { - 84, 102, 132, 82, 114, 29, 0, 0, 91, 0, 85, 72, 0, - 53, 35, 86, 15, 0, 42, 94, 54, 126, 133, 19, 0, 0, - 138, 0, 40, 128, 0, 22, 104, 0, 9, 0, 0, 122, 80, - 0, 78, 6, 0, 65, 99, 145, 0, 134, 112, 0, 0, 48, - 0, 100, 24, 0, 17, 0, 27, 70, 23, 26, 5, 60, 140, - 107, 121, 0, 73, 101, 71, 143, 61, 119, 74, 0, 49, 0, - 11, 41, 0, 110, 0, 0, 0, 106, 10, 108, 113, 124, 14, - 50, 123, 0, 89, 0, 18, 120, 142, 56, 129, 137, 88, 83, - 37, 30, 125, 0, 0, 105, 51, 130, 127, 0, 34, 0, 0, - 44, 0, 95, 38, 39, 0, 20, 45, 116, 90, + 84, 92, 134, 82, 105, 29, 0, 0, 94, 0, 85, 72, 0, + 53, 35, 86, 15, 0, 42, 97, 54, 89, 135, 19, 0, 0, + 140, 0, 40, 129, 0, 22, 107, 0, 9, 0, 0, 123, 80, + 0, 78, 6, 0, 65, 103, 147, 0, 136, 115, 0, 0, 48, + 0, 90, 24, 0, 17, 0, 27, 70, 23, 26, 5, 60, 142, + 110, 122, 0, 73, 91, 71, 145, 61, 120, 74, 0, 49, 0, + 11, 41, 0, 113, 0, 0, 0, 109, 10, 111, 116, 125, 14, + 50, 124, 0, 100, 0, 18, 121, 144, 56, 130, 139, 88, 83, + 37, 30, 126, 0, 0, 108, 51, 131, 128, 0, 34, 0, 0, + 132, 0, 98, 38, 39, 0, 20, 45, 117, 93, }; /* aKWNext[] forms the hash collision chain. If aKWHash[i]==0 ** then the i-th keyword has no more hash collisions. Otherwise, ** the next keyword with the same hash is aKWHash[i]-1. */ -static const unsigned char aKWNext[145] = { - 0, 0, 0, 0, 4, 0, 43, 0, 0, 103, 111, 0, 0, - 0, 2, 0, 0, 141, 0, 0, 0, 13, 0, 0, 0, 0, - 139, 0, 0, 118, 52, 0, 0, 135, 12, 0, 0, 62, 0, - 136, 0, 131, 0, 0, 36, 0, 0, 28, 77, 0, 0, 0, +static const unsigned char aKWNext[147] = { + 0, 0, 0, 0, 4, 0, 43, 0, 0, 106, 114, 0, 0, + 0, 2, 0, 0, 143, 0, 0, 0, 13, 0, 0, 0, 0, + 141, 0, 0, 119, 52, 0, 0, 137, 12, 0, 0, 62, 0, + 138, 0, 133, 0, 0, 36, 0, 0, 28, 77, 0, 0, 0, 0, 59, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 69, 0, 0, 0, 0, 0, 144, 3, 0, 58, 0, 1, - 75, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 64, 66, - 63, 0, 0, 0, 0, 46, 0, 16, 0, 115, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 81, 97, 0, 8, 0, 109, - 21, 7, 67, 0, 79, 93, 117, 0, 0, 68, 0, 0, 96, - 0, 55, 0, 76, 0, 92, 32, 33, 57, 25, 0, 98, 0, - 0, 87, + 0, 69, 0, 0, 0, 0, 0, 146, 3, 0, 58, 0, 1, + 75, 0, 0, 0, 31, 0, 0, 0, 0, 0, 127, 0, 104, + 0, 64, 66, 63, 0, 0, 0, 0, 0, 46, 0, 16, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 101, 0, + 112, 21, 7, 67, 0, 79, 96, 118, 0, 0, 68, 0, 0, + 99, 44, 0, 55, 0, 76, 0, 95, 32, 33, 57, 25, 0, + 102, 0, 0, 87, }; /* aKWLen[i] is the length (in bytes) of the i-th keyword */ -static const unsigned char aKWLen[145] = { +static const unsigned char aKWLen[147] = { 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6, 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 7, 6, 9, 4, 2, 6, 5, 9, 9, 4, 7, 3, 2, 4, 4, 6, 11, 6, 2, 7, 5, 5, 9, 6, 10, 4, 6, 2, 3, 7, 5, 9, 6, 6, 4, 5, 5, 10, 6, 5, 7, 4, 5, 7, 6, 7, 7, 6, 5, 7, 3, 7, 4, - 7, 6, 12, 9, 4, 6, 5, 4, 7, 6, 5, 6, 6, - 7, 6, 4, 5, 9, 5, 6, 3, 8, 8, 2, 13, 2, - 2, 4, 6, 6, 8, 5, 17, 12, 7, 9, 4, 9, 4, - 4, 6, 7, 5, 9, 4, 4, 5, 2, 5, 8, 6, 4, - 5, 8, 4, 3, 9, 5, 5, 6, 4, 6, 2, 2, 9, - 3, 7, + 7, 6, 12, 9, 4, 6, 5, 4, 7, 6, 12, 8, 8, + 2, 6, 6, 7, 6, 4, 5, 9, 5, 5, 6, 3, 4, + 9, 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 9, + 4, 4, 6, 7, 5, 9, 4, 4, 5, 2, 5, 8, 6, + 4, 9, 5, 8, 4, 3, 9, 5, 5, 6, 4, 6, 2, + 2, 9, 3, 7, }; /* aKWOffset[i] is the index into zKWText[] of the start of ** the text for the i-th keyword. */ -static const unsigned short int aKWOffset[145] = { +static const unsigned short int aKWOffset[147] = { 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33, 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81, 86, 90, 90, 94, 99, 101, 105, 111, 119, 123, 123, 123, 126, 129, 132, 137, 142, 146, 147, 152, 156, 160, 168, 174, 181, 184, 184, 187, 189, 195, 198, 206, 211, 216, 219, 222, 226, 236, 239, 244, 244, 248, 252, 259, 265, 271, 277, 277, 283, 284, 288, 295, - 299, 306, 312, 324, 333, 335, 341, 346, 348, 355, 360, 365, 371, - 377, 382, 388, 392, 395, 404, 408, 414, 416, 423, 424, 431, 433, - 435, 444, 448, 454, 460, 468, 473, 473, 473, 489, 498, 501, 510, - 513, 517, 522, 529, 534, 543, 547, 550, 555, 557, 561, 569, 575, - 578, 583, 591, 591, 595, 604, 609, 614, 620, 623, 626, 629, 631, - 636, 640, + 299, 306, 312, 324, 333, 335, 341, 346, 348, 355, 359, 370, 377, + 378, 385, 391, 397, 402, 408, 412, 415, 424, 429, 433, 439, 441, + 444, 453, 455, 457, 466, 470, 476, 482, 490, 495, 495, 495, 511, + 520, 523, 527, 532, 539, 544, 553, 557, 560, 565, 567, 571, 579, + 585, 588, 597, 602, 610, 610, 614, 623, 628, 633, 639, 642, 645, + 648, 650, 655, 659, }; /* aKWCode[i] is the parser symbol code for the i-th keyword */ -static const unsigned char aKWCode[145] = { +static const unsigned char aKWCode[147] = { TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, @@ -159551,18 +166906,19 @@ static const unsigned char aKWCode[145] = { TK_BETWEEN, TK_NOTHING, TK_GROUPS, TK_GROUP, TK_CASCADE, TK_ASC, TK_DEFAULT, TK_CASE, TK_COLLATE, TK_CREATE, TK_CTIME_KW, TK_IMMEDIATE, TK_JOIN, TK_INSERT, TK_MATCH, - TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_ABORT, TK_UPDATE, - TK_VALUES, TK_VIRTUAL, TK_ALWAYS, TK_WHEN, TK_WHERE, - TK_RECURSIVE, TK_AFTER, TK_RENAME, TK_AND, TK_DEFERRED, - TK_DISTINCT, TK_IS, TK_AUTOINCR, TK_TO, TK_IN, - TK_CAST, TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, - TK_CTIME_KW, TK_CTIME_KW, TK_CURRENT, TK_PARTITION, TK_DROP, - TK_PRECEDING, TK_FAIL, TK_LAST, TK_FILTER, TK_REPLACE, - TK_FIRST, TK_FOLLOWING, TK_FROM, TK_JOIN_KW, TK_LIMIT, - TK_IF, TK_ORDER, TK_RESTRICT, TK_OTHERS, TK_OVER, - TK_JOIN_KW, TK_ROLLBACK, TK_ROWS, TK_ROW, TK_UNBOUNDED, - TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_WINDOW, - TK_DO, TK_BY, TK_INITIALLY, TK_ALL, TK_PRIMARY, + TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_MATERIALIZED, TK_DEFERRED, + TK_DISTINCT, TK_IS, TK_UPDATE, TK_VALUES, TK_VIRTUAL, + TK_ALWAYS, TK_WHEN, TK_WHERE, TK_RECURSIVE, TK_ABORT, + TK_AFTER, TK_RENAME, TK_AND, TK_DROP, TK_PARTITION, + TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, + TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, + TK_CURRENT, TK_PRECEDING, TK_FAIL, TK_LAST, TK_FILTER, + TK_REPLACE, TK_FIRST, TK_FOLLOWING, TK_FROM, TK_JOIN_KW, + TK_LIMIT, TK_IF, TK_ORDER, TK_RESTRICT, TK_OTHERS, + TK_OVER, TK_RETURNING, TK_JOIN_KW, TK_ROLLBACK, TK_ROWS, + TK_ROW, TK_UNBOUNDED, TK_UNION, TK_USING, TK_VACUUM, + TK_VIEW, TK_WINDOW, TK_DO, TK_BY, TK_INITIALLY, + TK_ALL, TK_PRIMARY, }; /* Hash table decoded: ** 0: INSERT @@ -159586,7 +166942,7 @@ static const unsigned char aKWCode[145] = { ** 18: TRANSACTION RIGHT ** 19: WHEN ** 20: SET HAVING -** 21: IF +** 21: MATERIALIZED IF ** 22: ROWS ** 23: SELECT ** 24: @@ -159682,7 +167038,7 @@ static const unsigned char aKWCode[145] = { ** 114: INTERSECT UNBOUNDED ** 115: ** 116: -** 117: ON +** 117: RETURNING ON ** 118: ** 119: WHERE ** 120: NO INNER @@ -159700,7 +167056,7 @@ static int keywordCode(const char *z, int n, int *pType){ int i, j; const char *zKW; if( n>=2 ){ - i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) % 127; + i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n*1) % 127; for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){ if( aKWLen[i]!=n ) continue; zKW = &zKWText[aKWOffset[i]]; @@ -159805,63 +167161,65 @@ static int keywordCode(const char *z, int n, int *pType){ testcase( i==85 ); /* PLAN */ testcase( i==86 ); /* ANALYZE */ testcase( i==87 ); /* PRAGMA */ - testcase( i==88 ); /* ABORT */ - testcase( i==89 ); /* UPDATE */ - testcase( i==90 ); /* VALUES */ - testcase( i==91 ); /* VIRTUAL */ - testcase( i==92 ); /* ALWAYS */ - testcase( i==93 ); /* WHEN */ - testcase( i==94 ); /* WHERE */ - testcase( i==95 ); /* RECURSIVE */ - testcase( i==96 ); /* AFTER */ - testcase( i==97 ); /* RENAME */ - testcase( i==98 ); /* AND */ - testcase( i==99 ); /* DEFERRED */ - testcase( i==100 ); /* DISTINCT */ - testcase( i==101 ); /* IS */ - testcase( i==102 ); /* AUTOINCREMENT */ - testcase( i==103 ); /* TO */ - testcase( i==104 ); /* IN */ - testcase( i==105 ); /* CAST */ - testcase( i==106 ); /* COLUMN */ - testcase( i==107 ); /* COMMIT */ - testcase( i==108 ); /* CONFLICT */ - testcase( i==109 ); /* CROSS */ - testcase( i==110 ); /* CURRENT_TIMESTAMP */ - testcase( i==111 ); /* CURRENT_TIME */ - testcase( i==112 ); /* CURRENT */ - testcase( i==113 ); /* PARTITION */ - testcase( i==114 ); /* DROP */ - testcase( i==115 ); /* PRECEDING */ - testcase( i==116 ); /* FAIL */ - testcase( i==117 ); /* LAST */ - testcase( i==118 ); /* FILTER */ - testcase( i==119 ); /* REPLACE */ - testcase( i==120 ); /* FIRST */ - testcase( i==121 ); /* FOLLOWING */ - testcase( i==122 ); /* FROM */ - testcase( i==123 ); /* FULL */ - testcase( i==124 ); /* LIMIT */ - testcase( i==125 ); /* IF */ - testcase( i==126 ); /* ORDER */ - testcase( i==127 ); /* RESTRICT */ - testcase( i==128 ); /* OTHERS */ - testcase( i==129 ); /* OVER */ - testcase( i==130 ); /* RIGHT */ - testcase( i==131 ); /* ROLLBACK */ - testcase( i==132 ); /* ROWS */ - testcase( i==133 ); /* ROW */ - testcase( i==134 ); /* UNBOUNDED */ - testcase( i==135 ); /* UNION */ - testcase( i==136 ); /* USING */ - testcase( i==137 ); /* VACUUM */ - testcase( i==138 ); /* VIEW */ - testcase( i==139 ); /* WINDOW */ - testcase( i==140 ); /* DO */ - testcase( i==141 ); /* BY */ - testcase( i==142 ); /* INITIALLY */ - testcase( i==143 ); /* ALL */ - testcase( i==144 ); /* PRIMARY */ + testcase( i==88 ); /* MATERIALIZED */ + testcase( i==89 ); /* DEFERRED */ + testcase( i==90 ); /* DISTINCT */ + testcase( i==91 ); /* IS */ + testcase( i==92 ); /* UPDATE */ + testcase( i==93 ); /* VALUES */ + testcase( i==94 ); /* VIRTUAL */ + testcase( i==95 ); /* ALWAYS */ + testcase( i==96 ); /* WHEN */ + testcase( i==97 ); /* WHERE */ + testcase( i==98 ); /* RECURSIVE */ + testcase( i==99 ); /* ABORT */ + testcase( i==100 ); /* AFTER */ + testcase( i==101 ); /* RENAME */ + testcase( i==102 ); /* AND */ + testcase( i==103 ); /* DROP */ + testcase( i==104 ); /* PARTITION */ + testcase( i==105 ); /* AUTOINCREMENT */ + testcase( i==106 ); /* TO */ + testcase( i==107 ); /* IN */ + testcase( i==108 ); /* CAST */ + testcase( i==109 ); /* COLUMN */ + testcase( i==110 ); /* COMMIT */ + testcase( i==111 ); /* CONFLICT */ + testcase( i==112 ); /* CROSS */ + testcase( i==113 ); /* CURRENT_TIMESTAMP */ + testcase( i==114 ); /* CURRENT_TIME */ + testcase( i==115 ); /* CURRENT */ + testcase( i==116 ); /* PRECEDING */ + testcase( i==117 ); /* FAIL */ + testcase( i==118 ); /* LAST */ + testcase( i==119 ); /* FILTER */ + testcase( i==120 ); /* REPLACE */ + testcase( i==121 ); /* FIRST */ + testcase( i==122 ); /* FOLLOWING */ + testcase( i==123 ); /* FROM */ + testcase( i==124 ); /* FULL */ + testcase( i==125 ); /* LIMIT */ + testcase( i==126 ); /* IF */ + testcase( i==127 ); /* ORDER */ + testcase( i==128 ); /* RESTRICT */ + testcase( i==129 ); /* OTHERS */ + testcase( i==130 ); /* OVER */ + testcase( i==131 ); /* RETURNING */ + testcase( i==132 ); /* RIGHT */ + testcase( i==133 ); /* ROLLBACK */ + testcase( i==134 ); /* ROWS */ + testcase( i==135 ); /* ROW */ + testcase( i==136 ); /* UNBOUNDED */ + testcase( i==137 ); /* UNION */ + testcase( i==138 ); /* USING */ + testcase( i==139 ); /* VACUUM */ + testcase( i==140 ); /* VIEW */ + testcase( i==141 ); /* WINDOW */ + testcase( i==142 ); /* DO */ + testcase( i==143 ); /* BY */ + testcase( i==144 ); /* INITIALLY */ + testcase( i==145 ); /* ALL */ + testcase( i==146 ); /* PRIMARY */ *pType = aKWCode[i]; break; } @@ -159873,7 +167231,7 @@ SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){ keywordCode((char*)z, n, &id); return id; } -#define SQLITE_N_KEYWORD 145 +#define SQLITE_N_KEYWORD 147 SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){ if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR; *pzName = zKWText + aKWOffset[i]; @@ -160031,6 +167389,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; @@ -160242,7 +167603,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ if( n==0 ) *tokenType = TK_ILLEGAL; return i; } - case CC_KYWD: { + case CC_KYWD0: { for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} if( IdChar(z[i]) ){ /* This token started out using characters that can appear in keywords, @@ -160272,10 +167633,19 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ ** SQL keywords start with the letter 'x'. Fall through */ /* no break */ deliberate_fall_through } + case CC_KYWD: case CC_ID: { i = 1; break; } + case CC_BOM: { + if( z[1]==0xbb && z[2]==0xbf ){ + *tokenType = TK_SPACE; + return 3; + } + i = 1; + break; + } case CC_NUL: { *tokenType = TK_ILLEGAL; return 0; @@ -160291,13 +167661,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 */ @@ -160305,6 +167671,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 @@ -160317,7 +167684,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); @@ -160340,7 +167706,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); @@ -160360,6 +167726,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 ){ @@ -160389,7 +167756,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; } } @@ -160417,58 +167787,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); } - - if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree); sqlite3DbFree(db, pParse->pVList); - while( pParse->pAinc ){ - AutoincInfo *p = pParse->pAinc; - pParse->pAinc = p->pNext; - sqlite3DbFreeNN(db, p); - } - while( pParse->pZombieTab ){ - Table *p = pParse->pZombieTab; - pParse->pZombieTab = p->pNextZombie; - sqlite3DeleteTable(db, p); - } - db->pParse = pParse->pParentParse; - pParse->pParentParse = 0; + db->pParse = pParentParse; assert( nErr==0 || pParse->rc!=SQLITE_OK ); return nErr; } @@ -161049,9 +168391,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 @@ -161086,8 +168425,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, @@ -161304,7 +168643,7 @@ SQLITE_API int sqlite3_initialize(void){ sqlite3GlobalConfig.isPCacheInit = 1; rc = sqlite3OsInit(); } -#ifdef SQLITE_ENABLE_DESERIALIZE +#ifndef SQLITE_OMIT_DESERIALIZE if( rc==SQLITE_OK ){ rc = sqlite3MemdbInit(); } @@ -161719,12 +169058,12 @@ SQLITE_API int sqlite3_config(int op, ...){ } #endif /* SQLITE_ENABLE_SORTER_REFERENCES */ -#ifdef SQLITE_ENABLE_DESERIALIZE +#ifndef SQLITE_OMIT_DESERIALIZE case SQLITE_CONFIG_MEMDB_MAXSIZE: { sqlite3GlobalConfig.mxMemdbSize = va_arg(ap, sqlite3_int64); break; } -#endif /* SQLITE_ENABLE_DESERIALIZE */ +#endif /* SQLITE_OMIT_DESERIALIZE */ default: { rc = SQLITE_ERROR; @@ -161896,7 +169235,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3 *db){ sqlite3BtreeEnterAll(db); for(i=0; rc==SQLITE_OK && inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( pBt && sqlite3BtreeIsInTrans(pBt) ){ + if( pBt && sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){ Pager *pPager = sqlite3BtreePager(pBt); rc = sqlite3PagerFlush(pPager); if( rc==SQLITE_BUSY ){ @@ -162085,7 +169424,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; @@ -162094,11 +169433,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; @@ -162107,6 +169449,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 @@ -162131,7 +169476,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 ){ @@ -162235,15 +169582,45 @@ 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; } +/* +** Return the transaction state for a single databse, or the maximum +** transaction state over all attached databases if zSchema is null. +*/ +SQLITE_API int sqlite3_txn_state(sqlite3 *db, const char *zSchema){ + int iDb, nDb; + int iTxn = -1; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + (void)SQLITE_MISUSE_BKPT; + return -1; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( zSchema ){ + nDb = iDb = sqlite3FindDbName(db, zSchema); + if( iDb<0 ) nDb--; + }else{ + iDb = 0; + nDb = db->nDb-1; + } + for(; iDb<=nDb; iDb++){ + Btree *pBt = db->aDb[iDb].pBt; + int x = pBt!=0 ? sqlite3BtreeTxnState(pBt) : SQLITE_TXN_NONE; + if( x>iTxn ) iTxn = x; + } + sqlite3_mutex_leave(db->mutex); + return iTxn; +} + /* ** Two variations on the public interface for closing a database ** connection. The sqlite3_close() version returns SQLITE_BUSY and -** leaves the connection option if there are unfinalized prepared +** leaves the connection open if there are unfinalized prepared ** statements or unfinished sqlite3_backups. The sqlite3_close_v2() ** version forces the connection to become a zombie if there are ** unclosed resources, and arranges for deallocation when the last @@ -162269,7 +169646,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; } @@ -162355,7 +169732,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()). @@ -162364,8 +169741,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 ){ @@ -162400,7 +169780,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ for(i=0; inDb; i++){ Btree *p = db->aDb[i].pBt; if( p ){ - if( sqlite3BtreeIsInTrans(p) ){ + if( sqlite3BtreeTxnState(p)==SQLITE_TXN_WRITE ){ inTrans = 1; } sqlite3BtreeRollback(p, tripCode, !schemaChange); @@ -162418,7 +169798,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) ){ @@ -162753,7 +170133,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; } @@ -162782,7 +170162,6 @@ SQLITE_PRIVATE int sqlite3CreateFunc( FuncDestructor *pDestructor ){ FuncDef *p; - int nName; int extraFlags; assert( sqlite3_mutex_held(db->mutex) ); @@ -162792,7 +170171,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); } @@ -163251,6 +170645,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(). @@ -163343,7 +170765,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( return SQLITE_OK; #else int rc; /* Return code */ - int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */ + int iDb; /* Schema to checkpoint */ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; @@ -163366,6 +170788,8 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( sqlite3_mutex_enter(db->mutex); if( zDb && zDb[0] ){ iDb = sqlite3FindDbName(db, zDb); + }else{ + iDb = SQLITE_MAX_DB; /* This means process all schemas */ } if( iDb<0 ){ rc = SQLITE_ERROR; @@ -163414,7 +170838,7 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ ** associated with the specific b-tree being checkpointed is taken by ** this function while the checkpoint is running. ** -** If iDb is passed SQLITE_MAX_ATTACHED, then all attached databases are +** If iDb is passed SQLITE_MAX_DB then all attached databases are ** checkpointed. If an error is encountered it is returned immediately - ** no attempt is made to checkpoint any remaining databases. ** @@ -163429,9 +170853,11 @@ SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog assert( sqlite3_mutex_held(db->mutex) ); assert( !pnLog || *pnLog==-1 ); assert( !pnCkpt || *pnCkpt==-1 ); + testcase( iDb==SQLITE_MAX_ATTACHED ); /* See forum post a006d86f72 */ + testcase( iDb==SQLITE_MAX_DB ); for(i=0; inDb && rc==SQLITE_OK; i++){ - if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){ + if( i==iDb || iDb==SQLITE_MAX_DB ){ rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt); pnLog = 0; pnCkpt = 0; @@ -163509,6 +170935,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 @@ -163769,6 +171208,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; } @@ -164040,7 +171481,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; @@ -164100,8 +171541,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 | @@ -164136,9 +171577,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; @@ -164150,7 +171591,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 @@ -164298,7 +171747,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; } @@ -164360,12 +171809,12 @@ static int openDatabase( 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 @@ -164376,7 +171825,7 @@ static int openDatabase( } #endif sqlite3_free_filename(zOpen); - return rc & 0xff; + return rc; } @@ -164676,7 +172125,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; } @@ -164687,7 +172136,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; } } @@ -164714,7 +172163,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; @@ -164821,7 +172270,9 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo } rc = SQLITE_OK; }else{ + int nSave = db->busyHandler.nBusy; rc = sqlite3OsFileControl(fd, op, pArg); + db->busyHandler.nBusy = nSave; } sqlite3BtreeLeave(pBtree); } @@ -164919,12 +172370,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; } @@ -165047,17 +172502,31 @@ SQLITE_API int sqlite3_test_control(int op, ...){ */ case SQLITE_TESTCTRL_OPTIMIZATIONS: { sqlite3 *db = va_arg(ap, sqlite3*); - db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff); + db->dbOptFlags = va_arg(ap, u32); break; } - /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt); + ** + ** 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*); ** - ** If parameter onoff is non-zero, subsequent calls to localtime() - ** and its variants fail. If onoff is zero, undo this setting. + ** 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; } @@ -165162,12 +172631,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; @@ -165204,6 +172677,94 @@ SQLITE_API int sqlite3_test_control(int op, ...){ sqlite3ResultIntReal(pCtx); break; } + + /* sqlite3_test_control(SQLITE_TESTCTRL_SEEK_COUNT, + ** sqlite3 *db, // Database connection + ** u64 *pnSeek // Write seek count here + ** ); + ** + ** This test-control queries the seek-counter on the "main" database + ** file. The seek-counter is written into *pnSeek and is then reset. + ** The seek-count is only available if compiled with SQLITE_DEBUG. + */ + case SQLITE_TESTCTRL_SEEK_COUNT: { + sqlite3 *db = va_arg(ap, sqlite3*); + u64 *pn = va_arg(ap, sqlite3_uint64*); + *pn = sqlite3BtreeSeekCount(db->aDb->pBt); + (void)db; /* Silence harmless unused variable warning */ + break; + } + + /* sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, op, ptr) + ** + ** "ptr" is a pointer to a u32. + ** + ** op==0 Store the current sqlite3SelectTrace in *ptr + ** op==1 Set sqlite3SelectTrace to the value *ptr + ** op==3 Store the current sqlite3WhereTrace in *ptr + ** op==3 Set sqlite3WhereTrace to the value *ptr + */ + case SQLITE_TESTCTRL_TRACEFLAGS: { + int opTrace = va_arg(ap, int); + u32 *ptr = va_arg(ap, u32*); + switch( opTrace ){ + case 0: *ptr = sqlite3SelectTrace; break; + case 1: sqlite3SelectTrace = *ptr; break; + case 2: *ptr = sqlite3WhereTrace; break; + case 3: sqlite3WhereTrace = *ptr; break; + } + 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) + ** + ** If "id" is an integer between 1 and SQLITE_NTUNE then set the value + ** of the id-th tuning parameter to *piValue. If "id" is between -1 + ** and -SQLITE_NTUNE, then write the current value of the (-id)-th + ** tuning parameter into *piValue. + ** + ** Tuning parameters are for use during transient development builds, + ** to help find the best values for constants in the query planner. + ** Access tuning parameters using the Tuning(ID) macro. Set the + ** parameters in the CLI using ".testctrl tune ID VALUE". + ** + ** Transient use only. Tuning parameters should not be used in + ** checked-in code. + */ + case SQLITE_TESTCTRL_TUNE: { + int id = va_arg(ap, int); + int *piValue = va_arg(ap, int*); + if( id>0 && id<=SQLITE_NTUNE ){ + Tuning(id) = *piValue; + }else if( id<0 && id>=-SQLITE_NTUNE ){ + *piValue = Tuning(-id); + }else{ + rc = SQLITE_NOTFOUND; + } + break; + } +#endif } va_end(ap); #endif /* SQLITE_UNTESTABLE */ @@ -165311,7 +172872,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; } @@ -165354,12 +172915,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; } @@ -165370,7 +172933,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 } @@ -165439,7 +173002,7 @@ SQLITE_API int sqlite3_snapshot_get( int iDb = sqlite3FindDbName(db, zDb); if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; - if( 0==sqlite3BtreeIsInTrans(pBt) ){ + if( SQLITE_TXN_WRITE!=sqlite3BtreeTxnState(pBt) ){ rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); @@ -165475,10 +173038,10 @@ SQLITE_API int sqlite3_snapshot_open( iDb = sqlite3FindDbName(db, zDb); if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; - if( sqlite3BtreeIsInTrans(pBt)==0 ){ + if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_WRITE ){ Pager *pPager = sqlite3BtreePager(pBt); int bUnlock = 0; - if( sqlite3BtreeIsInReadTrans(pBt) ){ + if( sqlite3BtreeTxnState(pBt)!=SQLITE_TXN_NONE ){ if( db->nVdbeActive==0 ){ rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot); if( rc==SQLITE_OK ){ @@ -165527,7 +173090,7 @@ SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ iDb = sqlite3FindDbName(db, zDb); if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; - if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ + if( SQLITE_TXN_NONE==sqlite3BtreeTxnState(pBt) ){ rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt)); @@ -166646,7 +174209,7 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi ** is used for assert() conditions that are true only if it can be ** guranteed that the database is not corrupt. */ -#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) +#ifdef SQLITE_DEBUG SQLITE_API extern int sqlite3_fts3_may_be_corrupt; # define assert_fts3_nc(x) assert(sqlite3_fts3_may_be_corrupt || (x)) #else @@ -166663,17 +174226,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 /* @@ -167132,6 +174696,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 ** @@ -167151,7 +174716,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 @@ -167184,25 +174749,26 @@ 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 ** assert() conditions in the fts3 code are activated - conditions that are ** only true if it is guaranteed that the fts3 database is not corrupt. */ +#ifdef SQLITE_DEBUG SQLITE_API int sqlite3_fts3_may_be_corrupt = 1; +#endif /* ** Write a 64-bit variable-length integer to memory starting at p[0]. @@ -168053,7 +175619,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 */ @@ -168773,7 +176339,7 @@ static int fts3ScanInteriorNode( char *zBuffer = 0; /* Buffer to load terms into */ i64 nAlloc = 0; /* Size of allocated buffer */ int isFirstTerm = 1; /* True when processing first term on page */ - sqlite3_int64 iChild; /* Block id of child node to descend to */ + u64 iChild; /* Block id of child node to descend to */ int nBuffer = 0; /* Total term size */ /* Skip over the 'height' varint that occurs at the start of every @@ -168789,8 +176355,8 @@ static int fts3ScanInteriorNode( ** table, then there are always 20 bytes of zeroed padding following the ** nNode bytes of content (see sqlite3Fts3ReadBlock() for details). */ - zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); - zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); + zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild); + zCsr += sqlite3Fts3GetVarintU(zCsr, &iChild); if( zCsr>zEnd ){ return FTS_CORRUPT_VTAB; } @@ -168843,20 +176409,20 @@ static int fts3ScanInteriorNode( */ cmp = memcmp(zTerm, zBuffer, (nBuffer>nTerm ? nTerm : nBuffer)); if( piFirst && (cmp<0 || (cmp==0 && nBuffer>nTerm)) ){ - *piFirst = iChild; + *piFirst = (i64)iChild; piFirst = 0; } if( piLast && cmp<0 ){ - *piLast = iChild; + *piLast = (i64)iChild; piLast = 0; } iChild++; }; - if( piFirst ) *piFirst = iChild; - if( piLast ) *piLast = iChild; + if( piFirst ) *piFirst = (i64)iChild; + if( piLast ) *piLast = (i64)iChild; finish_scan: sqlite3_free(zBuffer); @@ -170462,14 +178028,20 @@ static int fts3SetHasStat(Fts3Table *p){ */ static int fts3BeginMethod(sqlite3_vtab *pVtab){ Fts3Table *p = (Fts3Table*)pVtab; + int rc; UNUSED_PARAMETER(pVtab); assert( p->pSegments==0 ); assert( p->nPendingData==0 ); assert( p->inTransaction!=1 ); - TESTONLY( p->inTransaction = 1 ); - TESTONLY( p->mxSavepoint = -1; ); p->nLeafAdd = 0; - return fts3SetHasStat(p); + rc = fts3SetHasStat(p); +#ifdef SQLITE_DEBUG + if( rc==SQLITE_OK ){ + p->inTransaction = 1; + p->mxSavepoint = -1; + } +#endif + return rc; } /* @@ -170882,9 +178454,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); + } } /* @@ -170914,7 +178489,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 @@ -170942,23 +178517,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; @@ -170967,7 +178543,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ #ifdef SQLITE_TEST if( rc==SQLITE_OK ){ - rc = sqlite3Fts3ExprInitTestInterface(db, pHash); + rc = sqlite3Fts3ExprInitTestInterface(db, &pHash->hash); } #endif @@ -170976,23 +178552,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; } @@ -171001,7 +178580,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; @@ -171348,7 +178927,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 ){ @@ -171998,16 +179577,15 @@ static int fts3EvalStart(Fts3Cursor *pCsr){ #ifndef SQLITE_DISABLE_FTS4_DEFERRED if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){ Fts3TokenAndCost *aTC; - Fts3Expr **apOr; aTC = (Fts3TokenAndCost *)sqlite3_malloc64( sizeof(Fts3TokenAndCost) * nToken + sizeof(Fts3Expr *) * nOr * 2 ); - apOr = (Fts3Expr **)&aTC[nToken]; if( !aTC ){ rc = SQLITE_NOMEM; }else{ + Fts3Expr **apOr = (Fts3Expr **)&aTC[nToken]; int ii; Fts3TokenAndCost *pTC = aTC; Fts3Expr **ppOr = apOr; @@ -172088,9 +179666,9 @@ static int fts3EvalNearTrim( ); if( res ){ nNew = (int)(pOut - pPhrase->doclist.pList) - 1; - if( nNew>=0 ){ + assert_fts3_nc( nNew<=pPhrase->doclist.nList && nNew>0 ); + if( nNew>=0 && nNew<=pPhrase->doclist.nList ){ assert( pPhrase->doclist.pList[nNew]=='\0' ); - assert( nNew<=pPhrase->doclist.nList && nNew>0 ); memset(&pPhrase->doclist.pList[nNew], 0, pPhrase->doclist.nList - nNew); pPhrase->doclist.nList = nNew; } @@ -172213,8 +179791,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); @@ -172852,6 +180430,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 ){ @@ -173274,6 +180855,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; @@ -173325,7 +180911,6 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){ } pCsr->iCol = 0; - rc = SQLITE_OK; }else{ pCsr->isEof = 1; } @@ -173383,6 +180968,7 @@ static int fts3auxFilterMethod( sqlite3Fts3SegReaderFinish(&pCsr->csr); sqlite3_free((void *)pCsr->filter.zTerm); sqlite3_free(pCsr->aStat); + sqlite3_free(pCsr->zStop); memset(&pCsr->csr, 0, ((u8*)&pCsr[1]) - (u8*)&pCsr->csr); pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; @@ -173653,7 +181239,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; @@ -173734,7 +181320,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{ @@ -173989,7 +181575,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; } @@ -174024,6 +181610,11 @@ static int getNextNode( if( *zInput=='(' ){ int nConsumed = 0; pParse->nNest++; +#if !defined(SQLITE_MAX_EXPR_DEPTH) + if( pParse->nNest>1000 ) return SQLITE_ERROR; +#elif SQLITE_MAX_EXPR_DEPTH>0 + if( pParse->nNest>SQLITE_MAX_EXPR_DEPTH ) return SQLITE_ERROR; +#endif rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed); *pnConsumed = (int)(zInput - z) + 1 + nConsumed; return rc; @@ -174163,7 +181754,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; @@ -174197,7 +181788,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; @@ -177053,7 +184644,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 */ @@ -177082,7 +184673,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; } @@ -178427,8 +186020,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); @@ -178681,9 +186284,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); } @@ -178899,7 +186500,7 @@ static int fts3SegReaderCmp(Fts3SegReader *pLhs, Fts3SegReader *pRhs){ if( rc==0 ){ rc = pRhs->iIdx - pLhs->iIdx; } - assert( rc!=0 ); + assert_fts3_nc( rc!=0 ); return rc; } @@ -179095,8 +186696,8 @@ static int fts3PrefixCompress( int nNext /* Size of buffer zNext in bytes */ ){ int n; - UNUSED_PARAMETER(nNext); - for(n=0; nterm, 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; @@ -181269,7 +188870,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; @@ -181427,17 +189032,20 @@ static int fts3IncrmergeLoad( while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader); blobGrowBuffer(&pNode->key, reader.term.n, &rc); if( rc==SQLITE_OK ){ - memcpy(pNode->key.a, reader.term.a, reader.term.n); + assert_fts3_nc( reader.term.n>0 || reader.aNode==0 ); + if( reader.term.n>0 ){ + memcpy(pNode->key.a, reader.term.a, reader.term.n); + } pNode->key.n = reader.term.n; if( i>0 ){ char *aBlock = 0; int nBlock = 0; pNode = &pWriter->aNodeWriter[i-1]; pNode->iBlock = reader.iChild; - rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0); + rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock,0); blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc - ); + ); if( rc==SQLITE_OK ){ memcpy(pNode->block.a, aBlock, nBlock); pNode->block.n = nBlock; @@ -181910,7 +189518,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; } } @@ -182906,6 +190514,10 @@ SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){ /* #include */ /* #include */ +#ifndef SQLITE_AMALGAMATION +typedef sqlite3_int64 i64; +#endif + /* ** Characters that may appear in the second argument to matchinfo(). */ @@ -182956,9 +190568,9 @@ struct SnippetIter { struct SnippetPhrase { int nToken; /* Number of tokens in phrase */ char *pList; /* Pointer to start of phrase position list */ - int iHead; /* Next value in position list */ + i64 iHead; /* Next value in position list */ char *pHead; /* Position list data following iHead */ - int iTail; /* Next value in trailing position list */ + i64 iTail; /* Next value in trailing position list */ char *pTail; /* Position list data following iTail */ }; @@ -183023,9 +190635,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); @@ -183123,7 +190734,7 @@ SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p){ ** After it returns, *piPos contains the value of the next element of the ** list and *pp is advanced to the following varint. */ -static void fts3GetDeltaPosition(char **pp, int *piPos){ +static void fts3GetDeltaPosition(char **pp, i64 *piPos){ int iVal; *pp += fts3GetVarint32(*pp, &iVal); *piPos += (iVal-2); @@ -183232,10 +190843,10 @@ static int fts3ExprPhraseCount(Fts3Expr *pExpr){ ** arguments so that it points to the first element with a value greater ** than or equal to parameter iNext. */ -static void fts3SnippetAdvance(char **ppIter, int *piIter, int iNext){ +static void fts3SnippetAdvance(char **ppIter, i64 *piIter, int iNext){ char *pIter = *ppIter; if( pIter ){ - int iIter = *piIter; + i64 iIter = *piIter; while( iIteraPhrase[i]; if( pPhrase->pTail ){ char *pCsr = pPhrase->pTail; - int iCsr = pPhrase->iTail; + i64 iCsr = pPhrase->iTail; while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){ int j; @@ -183364,7 +190975,7 @@ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){ rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pCsr); assert( rc==SQLITE_OK || pCsr==0 ); if( pCsr ){ - int iFirst = 0; + i64 iFirst = 0; pPhrase->pList = pCsr; fts3GetDeltaPosition(&pCsr, &iFirst); if( iFirst<0 ){ @@ -183429,11 +191040,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. @@ -183997,10 +191607,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; @@ -184034,9 +191646,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++){ @@ -184428,8 +192039,8 @@ typedef struct TermOffsetCtx TermOffsetCtx; struct TermOffset { char *pList; /* Position-list */ - int iPos; /* Position just read from pList */ - int iOff; /* Offset of this term from read positions */ + i64 iPos; /* Position just read from pList */ + i64 iOff; /* Offset of this term from read positions */ }; struct TermOffsetCtx { @@ -184448,7 +192059,7 @@ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){ int nTerm; /* Number of tokens in phrase */ int iTerm; /* For looping through nTerm phrase terms */ char *pList; /* Pointer to position list for phrase */ - int iPos = 0; /* First position in position-list */ + i64 iPos = 0; /* First position in position-list */ int rc; UNUSED_PARAMETER(iPhrase); @@ -184497,7 +192108,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; @@ -184518,13 +192129,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. @@ -184925,6 +192536,7 @@ static int unicodeOpen( pCsr->aInput = (const unsigned char *)aInput; if( aInput==0 ){ pCsr->nInput = 0; + pCsr->aInput = (const unsigned char*)""; }else if( nInput<0 ){ pCsr->nInput = (int)strlen(aInput); }else{ @@ -185422,7 +193034,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 ** @@ -185435,10 +193047,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 @@ -185446,48 +193058,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 @@ -185512,15 +193084,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 */ @@ -185579,13 +193148,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; }; @@ -185724,7 +193294,7 @@ static void jsonAppendSeparator(JsonString *p){ */ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ u32 i; - if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return; + if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return; p->zBuf[p->nUsed++] = '"'; for(i=0; ijnFlags & (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 ){ @@ -185886,6 +193459,7 @@ static void jsonRenderNode( } case JSON_STRING: { if( pNode->jnFlags & JNODE_RAW ){ + assert( pNode->eU==1 ); jsonAppendString(pOut, pNode->u.zJContent, pNode->n); break; } @@ -185893,6 +193467,7 @@ static void jsonRenderNode( } case JSON_REAL: case JSON_INT: { + assert( pNode->eU==1 ); jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); break; } @@ -185908,6 +193483,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; } @@ -185928,6 +193504,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; } @@ -185972,10 +193549,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) @@ -186007,7 +193584,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'; @@ -186030,14 +193609,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); @@ -186048,6 +193630,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 @@ -186055,15 +193638,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); @@ -186184,12 +193770,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++; @@ -186200,7 +193787,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; } @@ -186219,13 +193806,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 ){ @@ -186238,14 +193825,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; @@ -186257,8 +193844,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--; @@ -186267,7 +193855,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; @@ -186304,17 +193892,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') ){ @@ -186385,7 +193973,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 ){ @@ -186521,6 +194109,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; @@ -186586,6 +194175,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; @@ -186600,8 +194190,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; @@ -186609,7 +194201,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++; } @@ -186624,18 +194216,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; } @@ -186657,6 +194250,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; @@ -186672,8 +194266,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; } @@ -186827,9 +194423,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); } @@ -186847,7 +194447,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 */ @@ -186868,7 +194468,7 @@ static void jsonQuoteFunc( sqlite3_value **argv ){ JsonString jx; - UNUSED_PARAM(argc); + UNUSED_PARAMETER(argc); jsonInit(&jx, ctx); jsonAppendValue(&jx, argv[0]); @@ -186939,13 +194539,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 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. ** -** 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. +** 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, @@ -186955,35 +194576,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. @@ -187012,6 +194675,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 ); @@ -187028,6 +194692,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; } @@ -187043,9 +194713,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]; } @@ -187067,7 +194742,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); @@ -187187,11 +194862,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); @@ -187200,6 +194879,7 @@ static void jsonReplaceFunc( jsonParseReset(&x); } + /* ** json_set(JSON, PATH, VALUE, ...) ** @@ -187222,7 +194902,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 ) { @@ -187241,11 +194921,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); @@ -187258,8 +194942,8 @@ static void jsonSetFunc( ** 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, @@ -187295,7 +194979,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); } @@ -187315,7 +194999,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 ){ @@ -187323,8 +195007,8 @@ static void jsonArrayStep( jsonAppendChar(pStr, '['); }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); - pStr->pCtx = ctx; } + pStr->pCtx = ctx; jsonAppendValue(pStr, argv[0]); } } @@ -187375,8 +195059,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 @@ -187384,11 +195068,7 @@ static void jsonGroupInverse( if( NEVER(!pStr) ) return; #endif z = pStr->zBuf; - for(i=1; (c = z[i])!=',' || inStr || nNest; i++){ - if( i>=pStr->nUsed ){ - pStr->nUsed = 1; - return; - } + for(i=1; inUsed && ((c = z[i])!=',' || inStr || nNest); i++){ if( c=='"' ){ inStr = !inStr; }else if( c=='\\' ){ @@ -187398,8 +195078,13 @@ static void jsonGroupInverse( if( c=='}' || c==']' ) nNest--; } } - pStr->nUsed -= i; - memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1); + if( inUsed ){ + pStr->nUsed -= i; + memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1); + z[pStr->nUsed] = 0; + }else{ + pStr->nUsed = 1; + } } #else # define jsonGroupInverse 0 @@ -187419,7 +195104,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 ){ @@ -187427,8 +195112,8 @@ static void jsonObjectStep( jsonAppendChar(pStr, '{'); }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); - pStr->pCtx = ctx; } + pStr->pCtx = ctx; z = (const char*)sqlite3_value_text(argv[0]); n = (u32)sqlite3_value_bytes(argv[0]); jsonAppendString(pStr, z, n); @@ -187510,10 +195195,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)"); @@ -187536,7 +195221,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)); @@ -187595,6 +195280,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{ @@ -187641,12 +195329,15 @@ static void jsonEachComputePath( pNode = &p->sParse.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 ); + assert( pNode->eU==1 ); jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1); } } @@ -187668,6 +195359,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; @@ -187717,6 +195409,7 @@ static int jsonEachColumn( if( p->eType==JSON_ARRAY ){ jsonPrintf(30, &x, "[%d]", p->iRowid); }else if( p->eType==JSON_OBJECT ){ + assert( pThis->eU==1 ); jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); } } @@ -187775,7 +195468,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++){ @@ -187784,6 +195477,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; @@ -187830,8 +195524,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]); @@ -187881,6 +195575,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 ){ @@ -187954,108 +195650,68 @@ static sqlite3_module jsonTreeModule = { 0 /* xShadowName */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ - -/**************************************************************************** -** 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 }, - +#endif /* !defined(SQLITE_OMIT_JSON) */ + +/* +** 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 }, -#endif + 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 */ @@ -188194,7 +195867,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 @@ -188476,7 +196151,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 /* @@ -188725,18 +196405,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. */ @@ -188753,14 +196421,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; } @@ -188818,7 +196479,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 && iNode==1 ){ + if( rc==SQLITE_OK && pNode && iNode==1 ){ pRtree->iDepth = readInt16(pNode->zData); if( pRtree->iDepth>RTREE_MAX_DEPTH ){ rc = SQLITE_CORRUPT_VTAB; @@ -189341,20 +197002,29 @@ static void rtreeNonleafConstraint( switch( p->op ){ case RTREE_TRUE: return; /* Always satisfied */ case RTREE_FALSE: break; /* Never satisfied */ + 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: - case RTREE_EQ: 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; } @@ -189424,11 +197094,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; } /* @@ -189551,7 +197222,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{ @@ -189612,7 +197284,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]; @@ -189753,7 +197425,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; @@ -189771,7 +197443,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 ){ @@ -189970,8 +197642,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; @@ -190048,7 +197723,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; @@ -190254,7 +197929,7 @@ static int ChooseLeaf( int nCell = NCELL(pNode); RtreeCell cell; - RtreeNode *pChild; + RtreeNode *pChild = 0; RtreeCell *aCell = 0; @@ -190301,12 +197976,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; } @@ -190595,12 +198277,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); } @@ -190690,11 +198377,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; } } @@ -190769,7 +198457,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); } } @@ -190800,6 +198488,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 ){ @@ -191022,7 +198711,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{ @@ -191128,7 +198817,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); } @@ -191463,7 +199152,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 @@ -191480,20 +199169,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; } @@ -191643,9 +199322,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); } } @@ -191910,6 +199592,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]; } @@ -192734,11 +200421,16 @@ 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 ){ + if( pCtx ) sqlite3_result_error_nomem(pCtx); + return 0; + } nVertex = (a[1]<<16) + (a[2]<<8) + a[3]; if( (a[0]==0 || a[0]==1) && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte @@ -193112,7 +200804,7 @@ static GeoPoly *geopolyBBox( aCoord[2].f = mnY; aCoord[3].f = mxY; } - }else{ + }else if( aCoord ){ memset(aCoord, 0, sizeof(RtreeCoord)*4); } return pOut; @@ -193504,7 +201196,7 @@ static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){ geopolyAddSegments(p, p1, 1); geopolyAddSegments(p, p2, 2); pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent); - rX = pThisEvent->x==0.0 ? -1.0 : 0.0; + rX = pThisEvent && pThisEvent->x==0.0 ? -1.0 : 0.0; memset(aOverlap, 0, sizeof(aOverlap)); while( pThisEvent ){ if( pThisEvent->x!=rX ){ @@ -193563,11 +201255,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; } } @@ -193811,6 +201503,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; @@ -194038,6 +201731,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 ){ @@ -194391,7 +202085,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; @@ -195962,6 +203659,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 @@ -197046,7 +204750,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 )); @@ -197406,7 +205112,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 */ ){ @@ -197472,7 +205178,9 @@ char *rbuVacuumIndexStart( zSep = ""; for(iCol=0; iColnCol; iCol++){ const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol); - if( zQuoted[0]=='N' ){ + if( zQuoted==0 ){ + p->rc = SQLITE_NOMEM; + }else if( zQuoted[0]=='N' ){ bFailed = 1; break; } @@ -198577,7 +206285,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: @@ -198604,13 +206312,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); @@ -198976,15 +206690,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) @@ -199042,18 +206772,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); - if( p->rc==SQLITE_OK ){ - rbuFileSuffix3(zBase, zWal); - rbuFileSuffix3(zBase, zOal); + 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; + /* 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 ){ #if defined(_WIN32_WCE) { LPWSTR zWideOal; @@ -199080,11 +206816,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); } } @@ -199835,9 +207579,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); } } @@ -199932,6 +207676,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; @@ -199969,7 +207721,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); } @@ -200680,22 +208431,24 @@ static int rbuVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ #endif assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) ); - if( pRbu && (pRbu->eStage==RBU_STAGE_OAL || pRbu->eStage==RBU_STAGE_MOVE) ){ - /* Magic number 1 is the WAL_CKPT_LOCK lock. Preventing SQLite from - ** taking this lock also prevents any checkpoints from occurring. - ** todo: really, it's not clear why this might occur, as - ** wal_autocheckpoint ought to be turned off. */ + if( pRbu && ( + pRbu->eStage==RBU_STAGE_OAL + || pRbu->eStage==RBU_STAGE_MOVE + || pRbu->eStage==RBU_STAGE_DONE + )){ + /* Prevent SQLite from taking a shm-lock on the target file when it + ** is supplying heap memory to the upper layer in place of *-shm + ** segments. */ if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY; }else{ int bCapture = 0; if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){ bCapture = 1; } - if( bCapture==0 || 0==(flags & SQLITE_SHM_UNLOCK) ){ rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags); if( bCapture && rc==SQLITE_OK ){ - pRbu->mLock |= (1 << ofst); + pRbu->mLock |= ((1<pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ - /* This call is to open a *-wal file. Intead, open the *-oal. This - ** code ensures that the string passed to xOpen() is terminated by a - ** pair of '\0' bytes in case the VFS attempts to extract a URI - ** parameter from it. */ - const char *zBase = zName; - size_t nCopy; - char *zCopy; + /* This call is to open a *-wal file. Intead, open the *-oal. */ + size_t nOpen; if( rbuIsVacuum(pDb->pRbu) ){ - zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main"); - zBase = sqlite3_filename_wal(zBase); - } - nCopy = strlen(zBase); - zCopy = sqlite3_malloc64(nCopy+2); - if( zCopy ){ - memcpy(zCopy, zBase, nCopy); - zCopy[nCopy-3] = 'o'; - zCopy[nCopy] = '\0'; - zCopy[nCopy+1] = '\0'; - zOpen = (const char*)(pFd->zDel = zCopy); - }else{ - rc = SQLITE_NOMEM; + zOpen = sqlite3_db_filename(pDb->pRbu->dbRbu, "main"); + zOpen = sqlite3_filename_wal(zOpen); } + nOpen = strlen(zOpen); + ((char*)zOpen)[nOpen-3] = 'o'; pFd->pRbu = pDb->pRbu; } pDb->pWalFd = pFd; @@ -201184,6 +208923,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: ** @@ -201251,9 +208999,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(): */ @@ -201465,18 +209212,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; @@ -201541,7 +209295,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]; @@ -201612,7 +209366,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); @@ -201671,6 +209425,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), @@ -201689,7 +209475,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); @@ -201701,7 +209487,7 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ 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 ){ @@ -201752,9 +209538,8 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ 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; @@ -201773,7 +209558,7 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ }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 ){ @@ -201903,6 +209688,7 @@ static int statFilter( } if( rc==SQLITE_OK ){ + pCsr->iPage = -1; rc = statNext(pCursor); } return rc; @@ -202476,12 +210262,15 @@ struct SessionHook { struct sqlite3_session { sqlite3 *db; /* Database handle session is attached to */ char *zDb; /* Name of database session is attached to */ + int bEnableSize; /* True if changeset_size() enabled */ int bEnable; /* True if currently recording */ int bIndirect; /* True if all changes are indirect */ int bAutoAttach; /* True to auto-attach tables */ int rc; /* Non-zero if an error has occurred */ void *pFilterCtx; /* First argument to pass to xTableFilter */ int (*xTableFilter)(void *pCtx, const char *zTab); + i64 nMalloc; /* Number of bytes of data allocated */ + i64 nMaxChangesetSize; sqlite3_value *pZeroBlob; /* Value containing X'' */ sqlite3_session *pNext; /* Next session object on same db. */ SessionTable *pTable; /* List of attached tables */ @@ -202524,6 +210313,7 @@ struct sqlite3_changeset_iter { SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */ int bPatchset; /* True if this is a patchset */ int bInvert; /* True to invert changeset */ + int bSkipEmpty; /* Skip noop UPDATE changes */ int rc; /* Iterator error code */ sqlite3_stmt *pConflict; /* Points to conflicting row, if any */ char *zTab; /* Current table */ @@ -202723,8 +210513,9 @@ struct SessionTable { ** this structure stored in a SessionTable.aChange[] hash table. */ struct SessionChange { - int op; /* One of UPDATE, DELETE, INSERT */ - int bIndirect; /* True if this change is "indirect" */ + u8 op; /* One of UPDATE, DELETE, INSERT */ + u8 bIndirect; /* True if this change is "indirect" */ + int nMaxSize; /* Max size of eventual changeset record */ int nRecord; /* Number of bytes in buffer aRecord[] */ u8 *aRecord; /* Buffer containing old.* record */ SessionChange *pNext; /* For hash-table collisions */ @@ -202849,7 +210640,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; @@ -202865,6 +210656,26 @@ static int sessionSerializeValue( return SQLITE_OK; } +/* +** Allocate and return a pointer to a buffer nByte bytes in size. If +** pSession is not NULL, increase the sqlite3_session.nMalloc variable +** by the number of bytes allocated. +*/ +static void *sessionMalloc64(sqlite3_session *pSession, i64 nByte){ + void *pRet = sqlite3_malloc64(nByte); + if( pSession ) pSession->nMalloc += sqlite3_msize(pRet); + return pRet; +} + +/* +** Free buffer pFree, which must have been allocated by an earlier +** call to sessionMalloc64(). If pSession is not NULL, decrease the +** sqlite3_session.nMalloc counter by the number of bytes freed. +*/ +static void sessionFree(sqlite3_session *pSession, void *pFree){ + if( pSession ) pSession->nMalloc -= sqlite3_msize(pFree); + sqlite3_free(pFree); +} /* ** This macro is used to calculate hash key values for data structures. In @@ -203332,13 +211143,19 @@ static int sessionPreupdateEqual( ** Growing the hash table in this case is a performance optimization only, ** it is not required for correct operation. */ -static int sessionGrowHash(int bPatchset, SessionTable *pTab){ +static int sessionGrowHash( + sqlite3_session *pSession, /* For memory accounting. May be NULL */ + int bPatchset, + SessionTable *pTab +){ if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){ int i; SessionChange **apNew; sqlite3_int64 nNew = 2*(sqlite3_int64)(pTab->nChange ? pTab->nChange : 128); - apNew = (SessionChange **)sqlite3_malloc64(sizeof(SessionChange *) * nNew); + apNew = (SessionChange**)sessionMalloc64( + pSession, sizeof(SessionChange*) * nNew + ); if( apNew==0 ){ if( pTab->nChange==0 ){ return SQLITE_ERROR; @@ -203359,7 +211176,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ } } - sqlite3_free(pTab->apChange); + sessionFree(pSession, pTab->apChange); pTab->nChange = nNew; pTab->apChange = apNew; } @@ -203393,6 +211210,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ ** be freed using sqlite3_free() by the caller */ static int sessionTableInfo( + sqlite3_session *pSession, /* For memory accounting. May be NULL */ sqlite3 *db, /* Database connection */ const char *zDb, /* Name of attached database (e.g. "main") */ const char *zThis, /* Table name */ @@ -203427,16 +211245,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) ){ @@ -203447,7 +211281,7 @@ static int sessionTableInfo( if( rc==SQLITE_OK ){ nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1); - pAlloc = sqlite3_malloc64(nByte); + pAlloc = sessionMalloc64(pSession, nByte); if( pAlloc==0 ){ rc = SQLITE_NOMEM; } @@ -203490,7 +211324,7 @@ static int sessionTableInfo( *pabPK = 0; *pnCol = 0; if( pzTab ) *pzTab = 0; - sqlite3_free(azCol); + sessionFree(pSession, azCol); } sqlite3_finalize(pStmt); return rc; @@ -203512,7 +211346,7 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ if( pTab->nCol==0 ){ u8 *abPK; assert( pTab->azCol==0 || pTab->abPK==0 ); - pSession->rc = sessionTableInfo(pSession->db, pSession->zDb, + pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK ); if( pSession->rc==SQLITE_OK ){ @@ -203526,6 +211360,12 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){ pTab->bStat1 = 1; } + + if( pSession->bEnableSize ){ + pSession->nMaxChangesetSize += ( + 1 + sessionVarintLen(pTab->nCol) + pTab->nCol + strlen(pTab->zName)+1 + ); + } } } return (pSession->rc || pTab->abPK==0); @@ -203571,6 +211411,103 @@ static int sessionStat1Depth(void *pCtx){ return p->hook.xDepth(p->hook.pCtx); } +static int sessionUpdateMaxSize( + int op, + sqlite3_session *pSession, /* Session object pTab is attached to */ + SessionTable *pTab, /* Table that change applies to */ + SessionChange *pC /* Update pC->nMaxSize */ +){ + i64 nNew = 2; + if( pC->op==SQLITE_INSERT ){ + if( op!=SQLITE_DELETE ){ + int ii; + for(ii=0; iinCol; ii++){ + sqlite3_value *p = 0; + pSession->hook.xNew(pSession->hook.pCtx, ii, &p); + sessionSerializeValue(0, p, &nNew); + } + } + }else if( op==SQLITE_DELETE ){ + nNew += pC->nRecord; + if( sqlite3_preupdate_blobwrite(pSession->db)>=0 ){ + nNew += pC->nRecord; + } + }else{ + int ii; + u8 *pCsr = pC->aRecord; + for(ii=0; iinCol; ii++){ + int bChanged = 1; + int nOld = 0; + int eType; + sqlite3_value *p = 0; + pSession->hook.xNew(pSession->hook.pCtx, ii, &p); + if( p==0 ){ + return SQLITE_NOMEM; + } + + eType = *pCsr++; + switch( eType ){ + case SQLITE_NULL: + bChanged = sqlite3_value_type(p)!=SQLITE_NULL; + break; + + case SQLITE_FLOAT: + case SQLITE_INTEGER: { + if( eType==sqlite3_value_type(p) ){ + sqlite3_int64 iVal = sessionGetI64(pCsr); + if( eType==SQLITE_INTEGER ){ + bChanged = (iVal!=sqlite3_value_int64(p)); + }else{ + double dVal; + memcpy(&dVal, &iVal, 8); + bChanged = (dVal!=sqlite3_value_double(p)); + } + } + nOld = 8; + pCsr += 8; + break; + } + + default: { + int nByte; + nOld = sessionVarintGet(pCsr, &nByte); + pCsr += nOld; + nOld += nByte; + assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); + if( eType==sqlite3_value_type(p) + && nByte==sqlite3_value_bytes(p) + && (nByte==0 || 0==memcmp(pCsr, sqlite3_value_blob(p), nByte)) + ){ + bChanged = 0; + } + pCsr += nByte; + break; + } + } + + if( bChanged && pTab->abPK[ii] ){ + nNew = pC->nRecord + 2; + break; + } + + if( bChanged ){ + nNew += 1 + nOld; + sessionSerializeValue(0, p, &nNew); + }else if( pTab->abPK[ii] ){ + nNew += 2 + nOld; + }else{ + nNew += 2; + } + } + } + + if( nNew>pC->nMaxSize ){ + int nIncr = nNew - pC->nMaxSize; + pC->nMaxSize = nNew; + pSession->nMaxChangesetSize += nIncr; + } + return SQLITE_OK; +} /* ** This function is only called from with a pre-update-hook reporting a @@ -203603,7 +211540,7 @@ static void sessionPreupdateOneChange( } /* Grow the hash table if required */ - if( sessionGrowHash(0, pTab) ){ + if( sessionGrowHash(pSession, 0, pTab) ){ pSession->rc = SQLITE_NOMEM; return; } @@ -203644,7 +211581,6 @@ static void sessionPreupdateOneChange( /* Create a new change object containing all the old values (if ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK ** values (if this is an INSERT). */ - SessionChange *pChange; /* New change object */ sqlite3_int64 nByte; /* Number of bytes to allocate */ int i; /* Used to iterate through columns */ @@ -203670,13 +211606,13 @@ static void sessionPreupdateOneChange( } /* Allocate the change object */ - pChange = (SessionChange *)sqlite3_malloc64(nByte); - if( !pChange ){ + pC = (SessionChange *)sessionMalloc64(pSession, nByte); + if( !pC ){ rc = SQLITE_NOMEM; goto error_out; }else{ - memset(pChange, 0, sizeof(SessionChange)); - pChange->aRecord = (u8 *)&pChange[1]; + memset(pC, 0, sizeof(SessionChange)); + pC->aRecord = (u8 *)&pC[1]; } /* Populate the change object. None of the preupdate_old(), @@ -203691,17 +211627,17 @@ static void sessionPreupdateOneChange( }else if( pTab->abPK[i] ){ pSession->hook.xNew(pSession->hook.pCtx, i, &p); } - sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte); + sessionSerializeValue(&pC->aRecord[nByte], p, &nByte); } /* Add the change to the hash-table */ if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){ - pChange->bIndirect = 1; + pC->bIndirect = 1; } - pChange->nRecord = nByte; - pChange->op = op; - pChange->pNext = pTab->apChange[iHash]; - pTab->apChange[iHash] = pChange; + pC->nRecord = nByte; + pC->op = op; + pC->pNext = pTab->apChange[iHash]; + pTab->apChange[iHash] = pC; }else if( pC->bIndirect ){ /* If the existing change is considered "indirect", but this current @@ -203712,8 +211648,14 @@ static void sessionPreupdateOneChange( pC->bIndirect = 0; } } + + assert( rc==SQLITE_OK ); + if( pSession->bEnableSize ){ + rc = sessionUpdateMaxSize(op, pSession, pTab, pC); + } } + /* If an error has occurred, mark the session object as failed. */ error_out: if( pTab->bStat1 ){ @@ -203746,7 +211688,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) ); } } @@ -204043,7 +211989,7 @@ SQLITE_API int sqlite3session_diff( int nCol; /* Columns in zFrom.zTbl */ u8 *abPK; const char **azCol = 0; - rc = sessionTableInfo(db, zFrom, zTbl, &nCol, 0, &azCol, &abPK); + rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK); if( rc==SQLITE_OK ){ if( pTo->nCol!=nCol ){ bMismatch = 1; @@ -204141,7 +212087,7 @@ SQLITE_API int sqlite3session_create( ** Free the list of table objects passed as the first argument. The contents ** of the changed-rows hash tables are also deleted. */ -static void sessionDeleteTable(SessionTable *pList){ +static void sessionDeleteTable(sqlite3_session *pSession, SessionTable *pList){ SessionTable *pNext; SessionTable *pTab; @@ -204153,12 +212099,12 @@ static void sessionDeleteTable(SessionTable *pList){ SessionChange *pNextChange; for(p=pTab->apChange[i]; p; p=pNextChange){ pNextChange = p->pNext; - sqlite3_free(p); + sessionFree(pSession, p); } } - sqlite3_free((char*)pTab->azCol); /* cast works around VC++ bug */ - sqlite3_free(pTab->apChange); - sqlite3_free(pTab); + sessionFree(pSession, (char*)pTab->azCol); /* cast works around VC++ bug */ + sessionFree(pSession, pTab->apChange); + sessionFree(pSession, pTab); } } @@ -204186,9 +212132,11 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){ /* Delete all attached table objects. And the contents of their ** associated hash-tables. */ - sessionDeleteTable(pSession->pTable); + sessionDeleteTable(pSession, pSession->pTable); - /* Free the session object itself. */ + /* Assert that all allocations have been freed and then free the + ** session object itself. */ + assert( pSession->nMalloc==0 ); sqlite3_free(pSession); } @@ -204235,7 +212183,8 @@ SQLITE_API int sqlite3session_attach( if( !pTab ){ /* Allocate new SessionTable object. */ - pTab = (SessionTable *)sqlite3_malloc64(sizeof(SessionTable) + nName + 1); + int nByte = sizeof(SessionTable) + nName + 1; + pTab = (SessionTable*)sessionMalloc64(pSession, nByte); if( !pTab ){ rc = SQLITE_NOMEM; }else{ @@ -204265,13 +212214,29 @@ SQLITE_API int sqlite3session_attach( ** If successful, return zero. Otherwise, if an OOM condition is encountered, ** set *pRc to SQLITE_NOMEM and return non-zero. */ -static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){ - if( *pRc==SQLITE_OK && (size_t)(p->nAlloc-p->nBuf)nBuf + nByte; + if( *pRc==SQLITE_OK && nReq>p->nAlloc ){ u8 *aNew; i64 nNew = p->nAlloc ? p->nAlloc : 128; + do { nNew = nNew*2; - }while( (size_t)(nNew-p->nBuf)SESSION_MAX_BUFFER_SZ ){ + nNew = SESSION_MAX_BUFFER_SZ; + if( nNewaBuf, nNew); if( 0==aNew ){ @@ -204500,6 +212465,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 */ @@ -204832,7 +212800,7 @@ static int sessionGenerateChangeset( int nNoop; /* Size of buffer after writing tbl header */ /* Check the table schema is still Ok. */ - rc = sessionTableInfo(db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK); + rc = sessionTableInfo(0, db, pSession->zDb, zName, &nCol, 0,&azCol,&abPK); if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){ rc = SQLITE_SCHEMA; } @@ -204862,6 +212830,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 ){ @@ -204922,7 +212891,14 @@ SQLITE_API int sqlite3session_changeset( int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ){ - return 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 + ); + return rc; } /* @@ -204933,6 +212909,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); } @@ -204944,6 +212921,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); } @@ -204959,6 +212937,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); } @@ -205007,6 +212986,46 @@ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession){ return (ret==0); } +/* +** Return the amount of heap memory in use. +*/ +SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession){ + return pSession->nMalloc; +} + +/* +** Configure the session object passed as the first argument. +*/ +SQLITE_API int sqlite3session_object_config(sqlite3_session *pSession, int op, void *pArg){ + int rc = SQLITE_OK; + switch( op ){ + case SQLITE_SESSION_OBJCONFIG_SIZE: { + int iArg = *(int*)pArg; + if( iArg>=0 ){ + if( pSession->pTable ){ + rc = SQLITE_MISUSE; + }else{ + pSession->bEnableSize = (iArg!=0); + } + } + *(int*)pArg = pSession->bEnableSize; + break; + } + + default: + rc = SQLITE_MISUSE; + } + + return rc; +} + +/* +** Return the maximum size of sqlite3session_changeset() output. +*/ +SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession){ + return pSession->nMaxChangesetSize; +} + /* ** Do the work for either sqlite3changeset_start() or start_strm(). */ @@ -205016,7 +213035,8 @@ static int sessionChangesetStart( void *pIn, int nChangeset, /* Size of buffer pChangeset in bytes */ void *pChangeset, /* Pointer to buffer containing changeset */ - int bInvert /* True to invert changeset */ + int bInvert, /* True to invert changeset */ + int bSkipEmpty /* True to skip empty UPDATE changes */ ){ sqlite3_changeset_iter *pRet; /* Iterator to return */ int nByte; /* Number of bytes to allocate for iterator */ @@ -205037,6 +213057,7 @@ static int sessionChangesetStart( pRet->in.pIn = pIn; pRet->in.bEof = (xInput ? 0 : 1); pRet->bInvert = bInvert; + pRet->bSkipEmpty = bSkipEmpty; /* Populate the output variable and return success. */ *pp = pRet; @@ -205051,7 +213072,7 @@ SQLITE_API int sqlite3changeset_start( int nChangeset, /* Size of buffer pChangeset in bytes */ void *pChangeset /* Pointer to buffer containing changeset */ ){ - return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0); + return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0, 0); } SQLITE_API int sqlite3changeset_start_v2( sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ @@ -205060,7 +213081,7 @@ SQLITE_API int sqlite3changeset_start_v2( int flags ){ int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT); - return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert); + return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert, 0); } /* @@ -205071,7 +213092,7 @@ SQLITE_API int sqlite3changeset_start_strm( int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn ){ - return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0); + return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0, 0); } SQLITE_API int sqlite3changeset_start_v2_strm( sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ @@ -205080,7 +213101,7 @@ SQLITE_API int sqlite3changeset_start_v2_strm( int flags ){ int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT); - return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert); + return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert, 0); } /* @@ -205206,11 +213227,14 @@ static int sessionReadRecord( SessionInput *pIn, /* Input data */ int nCol, /* Number of values in record */ u8 *abPK, /* Array of primary key flags, or NULL */ - sqlite3_value **apOut /* Write values to this array */ + sqlite3_value **apOut, /* Write values to this array */ + int *pbEmpty ){ int i; /* Used to iterate through columns */ int rc = SQLITE_OK; + assert( pbEmpty==0 || *pbEmpty==0 ); + if( pbEmpty ) *pbEmpty = 1; for(i=0; iaData[pIn->iNext++]; assert( apOut[i]==0 ); if( eType ){ + if( pbEmpty ) *pbEmpty = 0; apOut[i] = sqlite3ValueNew(0); if( !apOut[i] ) rc = SQLITE_NOMEM; } @@ -205401,31 +213426,27 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ } /* -** Advance the changeset iterator to the next change. -** -** If both paRec and pnRec are NULL, then this function works like the public -** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the -** sqlite3changeset_new() and old() APIs may be used to query for values. +** Advance the changeset iterator to the next change. The differences between +** this function and sessionChangesetNext() are that ** -** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change -** record is written to *paRec before returning and the number of bytes in -** the record to *pnRec. +** * If pbEmpty is not NULL and the change is a no-op UPDATE (an UPDATE +** that modifies no columns), this function sets (*pbEmpty) to 1. ** -** Either way, this function returns SQLITE_ROW if the iterator is -** successfully advanced to the next change in the changeset, an SQLite -** error code if an error occurs, or SQLITE_DONE if there are no further -** changes in the changeset. +** * If the iterator is configured to skip no-op UPDATEs, +** sessionChangesetNext() does that. This function does not. */ -static int sessionChangesetNext( +static int sessionChangesetNextOne( sqlite3_changeset_iter *p, /* Changeset iterator */ u8 **paRec, /* If non-NULL, store record pointer here */ int *pnRec, /* If non-NULL, store size of record here */ - int *pbNew /* If non-NULL, true if new table */ + int *pbNew, /* If non-NULL, true if new table */ + int *pbEmpty ){ int i; u8 op; assert( (paRec==0 && pnRec==0) || (paRec && pnRec) ); + assert( pbEmpty==0 || *pbEmpty==0 ); /* If the iterator is in the error-state, return immediately. */ if( p->rc!=SQLITE_OK ) return p->rc; @@ -205498,13 +213519,13 @@ static int sessionChangesetNext( /* If this is an UPDATE or DELETE, read the old.* record. */ if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){ u8 *abPK = p->bPatchset ? p->abPK : 0; - p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld); + p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld, 0); if( p->rc!=SQLITE_OK ) return p->rc; } /* If this is an INSERT or UPDATE, read the new.* record. */ if( p->op!=SQLITE_DELETE ){ - p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew); + p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew, pbEmpty); if( p->rc!=SQLITE_OK ) return p->rc; } @@ -205531,6 +213552,37 @@ static int sessionChangesetNext( return SQLITE_ROW; } +/* +** Advance the changeset iterator to the next change. +** +** If both paRec and pnRec are NULL, then this function works like the public +** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the +** sqlite3changeset_new() and old() APIs may be used to query for values. +** +** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change +** record is written to *paRec before returning and the number of bytes in +** the record to *pnRec. +** +** Either way, this function returns SQLITE_ROW if the iterator is +** successfully advanced to the next change in the changeset, an SQLite +** error code if an error occurs, or SQLITE_DONE if there are no further +** changes in the changeset. +*/ +static int sessionChangesetNext( + sqlite3_changeset_iter *p, /* Changeset iterator */ + u8 **paRec, /* If non-NULL, store record pointer here */ + int *pnRec, /* If non-NULL, store size of record here */ + int *pbNew /* If non-NULL, true if new table */ +){ + int bEmpty; + int rc; + do { + bEmpty = 0; + rc = sessionChangesetNextOne(p, paRec, pnRec, pbNew, &bEmpty); + }while( rc==SQLITE_ROW && p->bSkipEmpty && bEmpty); + return rc; +} + /* ** Advance an iterator created by sqlite3changeset_start() to the next ** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE @@ -205803,9 +213855,9 @@ static int sessionChangesetInvert( /* Read the old.* and new.* records for the update change. */ pInput->iNext += 2; - rc = sessionReadRecord(pInput, nCol, 0, &apVal[0]); + rc = sessionReadRecord(pInput, nCol, 0, &apVal[0], 0); if( rc==SQLITE_OK ){ - rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol]); + rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol], 0); } /* Write the new old.* record. Consists of the PK columns from the @@ -205849,11 +213901,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); } @@ -205906,16 +213958,25 @@ SQLITE_API int sqlite3changeset_invert_strm( return rc; } + +typedef struct SessionUpdate SessionUpdate; +struct SessionUpdate { + sqlite3_stmt *pStmt; + u32 *aMask; + SessionUpdate *pNext; +}; + typedef struct SessionApplyCtx SessionApplyCtx; struct SessionApplyCtx { sqlite3 *db; sqlite3_stmt *pDelete; /* DELETE statement */ - sqlite3_stmt *pUpdate; /* UPDATE statement */ sqlite3_stmt *pInsert; /* INSERT statement */ sqlite3_stmt *pSelect; /* SELECT statement */ int nCol; /* Size of azCol[] and abPK[] arrays */ const char **azCol; /* Array of column names */ u8 *abPK; /* Boolean array - true if column is in PK */ + u32 *aUpdateMask; /* Used by sessionUpdateFind */ + SessionUpdate *pUp; int bStat1; /* True if table is sqlite_stat1 */ int bDeferConstraints; /* True to defer constraints */ int bInvertConstraints; /* Invert when iterating constraints buffer */ @@ -205925,6 +213986,167 @@ struct SessionApplyCtx { u8 bRebase; /* True to collect rebase information */ }; +/* Number of prepared UPDATE statements to cache. */ +#define SESSION_UPDATE_CACHE_SZ 12 + +/* +** Find a prepared UPDATE statement suitable for the UPDATE step currently +** being visited by the iterator. The UPDATE is of the form: +** +** UPDATE tbl SET col = ?, col2 = ? WHERE pk1 IS ? AND pk2 IS ? +*/ +static int sessionUpdateFind( + sqlite3_changeset_iter *pIter, + SessionApplyCtx *p, + int bPatchset, + sqlite3_stmt **ppStmt +){ + int rc = SQLITE_OK; + SessionUpdate *pUp = 0; + int nCol = pIter->nCol; + int nU32 = (pIter->nCol+33)/32; + int ii; + + if( p->aUpdateMask==0 ){ + p->aUpdateMask = sqlite3_malloc(nU32*sizeof(u32)); + if( p->aUpdateMask==0 ){ + rc = SQLITE_NOMEM; + } + } + + if( rc==SQLITE_OK ){ + memset(p->aUpdateMask, 0, nU32*sizeof(u32)); + rc = SQLITE_CORRUPT; + for(ii=0; iinCol; ii++){ + if( sessionChangesetNew(pIter, ii) ){ + p->aUpdateMask[ii/32] |= (1<<(ii%32)); + rc = SQLITE_OK; + } + } + } + + if( rc==SQLITE_OK ){ + if( bPatchset ) p->aUpdateMask[nCol/32] |= (1<<(nCol%32)); + + if( p->pUp ){ + int nUp = 0; + SessionUpdate **pp = &p->pUp; + while( 1 ){ + nUp++; + if( 0==memcmp(p->aUpdateMask, (*pp)->aMask, nU32*sizeof(u32)) ){ + pUp = *pp; + *pp = pUp->pNext; + pUp->pNext = p->pUp; + p->pUp = pUp; + break; + } + + if( (*pp)->pNext ){ + pp = &(*pp)->pNext; + }else{ + if( nUp>=SESSION_UPDATE_CACHE_SZ ){ + sqlite3_finalize((*pp)->pStmt); + sqlite3_free(*pp); + *pp = 0; + } + break; + } + } + } + + if( pUp==0 ){ + int nByte = sizeof(SessionUpdate) * nU32*sizeof(u32); + int bStat1 = (sqlite3_stricmp(pIter->zTab, "sqlite_stat1")==0); + pUp = (SessionUpdate*)sqlite3_malloc(nByte); + if( pUp==0 ){ + rc = SQLITE_NOMEM; + }else{ + const char *zSep = ""; + SessionBuffer buf; + + memset(&buf, 0, sizeof(buf)); + pUp->aMask = (u32*)&pUp[1]; + memcpy(pUp->aMask, p->aUpdateMask, nU32*sizeof(u32)); + + sessionAppendStr(&buf, "UPDATE main.", &rc); + sessionAppendIdent(&buf, pIter->zTab, &rc); + sessionAppendStr(&buf, " SET ", &rc); + + /* Create the assignments part of the UPDATE */ + for(ii=0; iinCol; ii++){ + if( p->abPK[ii]==0 && sessionChangesetNew(pIter, ii) ){ + sessionAppendStr(&buf, zSep, &rc); + sessionAppendIdent(&buf, p->azCol[ii], &rc); + sessionAppendStr(&buf, " = ?", &rc); + sessionAppendInteger(&buf, ii*2+1, &rc); + zSep = ", "; + } + } + + /* Create the WHERE clause part of the UPDATE */ + zSep = ""; + sessionAppendStr(&buf, " WHERE ", &rc); + for(ii=0; iinCol; ii++){ + if( p->abPK[ii] || (bPatchset==0 && sessionChangesetOld(pIter, ii)) ){ + sessionAppendStr(&buf, zSep, &rc); + if( bStat1 && ii==1 ){ + assert( sqlite3_stricmp(p->azCol[ii], "idx")==0 ); + sessionAppendStr(&buf, + "idx IS CASE " + "WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL " + "ELSE ?4 END ", &rc + ); + }else{ + sessionAppendIdent(&buf, p->azCol[ii], &rc); + sessionAppendStr(&buf, " IS ?", &rc); + sessionAppendInteger(&buf, ii*2+2, &rc); + } + zSep = " AND "; + } + } + + if( rc==SQLITE_OK ){ + char *zSql = (char*)buf.aBuf; + rc = sqlite3_prepare_v2(p->db, zSql, buf.nBuf, &pUp->pStmt, 0); + } + + if( rc!=SQLITE_OK ){ + sqlite3_free(pUp); + pUp = 0; + }else{ + pUp->pNext = p->pUp; + p->pUp = pUp; + } + sqlite3_free(buf.aBuf); + } + } + } + + assert( (rc==SQLITE_OK)==(pUp!=0) ); + if( pUp ){ + *ppStmt = pUp->pStmt; + }else{ + *ppStmt = 0; + } + return rc; +} + +/* +** Free all cached UPDATE statements. +*/ +static void sessionUpdateFree(SessionApplyCtx *p){ + SessionUpdate *pUp; + SessionUpdate *pNext; + for(pUp=p->pUp; pUp; pUp=pNext){ + pNext = pUp->pNext; + sqlite3_finalize(pUp->pStmt); + sqlite3_free(pUp); + } + p->pUp = 0; + sqlite3_free(p->aUpdateMask); + p->aUpdateMask = 0; +} + /* ** Formulate a statement to DELETE a row from database db. Assuming a table ** structure like this: @@ -205994,103 +214216,6 @@ static int sessionDeleteRow( return rc; } -/* -** Formulate and prepare a statement to UPDATE a row from database db. -** Assuming a table structure like this: -** -** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c)); -** -** The UPDATE statement looks like this: -** -** UPDATE x SET -** a = CASE WHEN ?2 THEN ?3 ELSE a END, -** b = CASE WHEN ?5 THEN ?6 ELSE b END, -** c = CASE WHEN ?8 THEN ?9 ELSE c END, -** d = CASE WHEN ?11 THEN ?12 ELSE d END -** WHERE a = ?1 AND c = ?7 AND (?13 OR -** (?5==0 OR b IS ?4) AND (?11==0 OR d IS ?10) AND -** ) -** -** For each column in the table, there are three variables to bind: -** -** ?(i*3+1) The old.* value of the column, if any. -** ?(i*3+2) A boolean flag indicating that the value is being modified. -** ?(i*3+3) The new.* value of the column, if any. -** -** Also, a boolean flag that, if set to true, causes the statement to update -** a row even if the non-PK values do not match. This is required if the -** conflict-handler is invoked with CHANGESET_DATA and returns -** CHANGESET_REPLACE. This is variable "?(nCol*3+1)". -** -** If successful, SQLITE_OK is returned and SessionApplyCtx.pUpdate is left -** pointing to the prepared version of the SQL statement. -*/ -static int sessionUpdateRow( - sqlite3 *db, /* Database handle */ - const char *zTab, /* Table name */ - SessionApplyCtx *p /* Session changeset-apply context */ -){ - int rc = SQLITE_OK; - int i; - const char *zSep = ""; - SessionBuffer buf = {0, 0, 0}; - - /* Append "UPDATE tbl SET " */ - sessionAppendStr(&buf, "UPDATE main.", &rc); - sessionAppendIdent(&buf, zTab, &rc); - sessionAppendStr(&buf, " SET ", &rc); - - /* Append the assignments */ - for(i=0; inCol; i++){ - sessionAppendStr(&buf, zSep, &rc); - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " = CASE WHEN ?", &rc); - sessionAppendInteger(&buf, i*3+2, &rc); - sessionAppendStr(&buf, " THEN ?", &rc); - sessionAppendInteger(&buf, i*3+3, &rc); - sessionAppendStr(&buf, " ELSE ", &rc); - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " END", &rc); - zSep = ", "; - } - - /* Append the PK part of the WHERE clause */ - sessionAppendStr(&buf, " WHERE ", &rc); - for(i=0; inCol; i++){ - if( p->abPK[i] ){ - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " = ?", &rc); - sessionAppendInteger(&buf, i*3+1, &rc); - sessionAppendStr(&buf, " AND ", &rc); - } - } - - /* Append the non-PK part of the WHERE clause */ - sessionAppendStr(&buf, " (?", &rc); - sessionAppendInteger(&buf, p->nCol*3+1, &rc); - sessionAppendStr(&buf, " OR 1", &rc); - for(i=0; inCol; i++){ - if( !p->abPK[i] ){ - sessionAppendStr(&buf, " AND (?", &rc); - sessionAppendInteger(&buf, i*3+2, &rc); - sessionAppendStr(&buf, "=0 OR ", &rc); - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " IS ?", &rc); - sessionAppendInteger(&buf, i*3+1, &rc); - sessionAppendStr(&buf, ")", &rc); - } - } - sessionAppendStr(&buf, ")", &rc); - - if( rc==SQLITE_OK ){ - rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pUpdate, 0); - } - sqlite3_free(buf.aBuf); - - return rc; -} - - /* ** Formulate and prepare an SQL statement to query table zTab by primary ** key. Assuming the following table structure: @@ -206171,17 +214296,6 @@ static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){ "?3)" ); } - if( rc==SQLITE_OK ){ - rc = sessionPrepare(db, &p->pUpdate, - "UPDATE main.sqlite_stat1 SET " - "tbl = CASE WHEN ?2 THEN ?3 ELSE tbl END, " - "idx = CASE WHEN ?5 THEN ?6 ELSE idx END, " - "stat = CASE WHEN ?8 THEN ?9 ELSE stat END " - "WHERE tbl=?1 AND idx IS " - "CASE WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL ELSE ?4 END " - "AND (?10 OR ?8=0 OR stat IS ?7)" - ); - } if( rc==SQLITE_OK ){ rc = sessionPrepare(db, &p->pDelete, "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS " @@ -206247,7 +214361,7 @@ static int sessionBindRow( for(i=0; rc==SQLITE_OK && ipDelete && p->pUpdate && p->pInsert && p->pSelect ); + assert( p->pDelete && p->pInsert && p->pSelect ); assert( p->azCol && p->abPK ); assert( !pbReplace || *pbReplace==0 ); @@ -206538,29 +214652,28 @@ static int sessionApplyOneOp( }else if( op==SQLITE_UPDATE ){ int i; + sqlite3_stmt *pUp = 0; + int bPatchset = (pbRetry==0 || pIter->bPatchset); + + rc = sessionUpdateFind(pIter, p, bPatchset, &pUp); /* Bind values to the UPDATE statement. */ for(i=0; rc==SQLITE_OK && ipUpdate, i*3+2, !!pNew); - if( pOld ){ - rc = sessionBindValue(p->pUpdate, i*3+1, pOld); + if( p->abPK[i] || (bPatchset==0 && pOld) ){ + rc = sessionBindValue(pUp, i*2+2, pOld); } if( rc==SQLITE_OK && pNew ){ - rc = sessionBindValue(p->pUpdate, i*3+3, pNew); + rc = sessionBindValue(pUp, i*2+1, pNew); } } - if( rc==SQLITE_OK ){ - sqlite3_bind_int(p->pUpdate, nCol*3+1, pbRetry==0 || pIter->bPatchset); - } if( rc!=SQLITE_OK ) return rc; /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict, ** the result will be SQLITE_OK with 0 rows modified. */ - sqlite3_step(p->pUpdate); - rc = sqlite3_reset(p->pUpdate); + sqlite3_step(pUp); + rc = sqlite3_reset(pUp); if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){ /* A NOTFOUND or DATA error. Search the table to see if it contains @@ -206692,7 +214805,7 @@ static int sessionRetryConstraints( memset(&pApply->constraints, 0, sizeof(SessionBuffer)); rc = sessionChangesetStart( - &pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints + &pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints, 1 ); if( rc==SQLITE_OK ){ size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*); @@ -206783,14 +214896,13 @@ static int sessionChangesetApply( ); if( rc!=SQLITE_OK ) break; + sessionUpdateFree(&sApply); sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_finalize(sApply.pDelete); - sqlite3_finalize(sApply.pUpdate); sqlite3_finalize(sApply.pInsert); sqlite3_finalize(sApply.pSelect); sApply.db = db; sApply.pDelete = 0; - sApply.pUpdate = 0; sApply.pInsert = 0; sApply.pSelect = 0; sApply.nCol = 0; @@ -206818,7 +214930,7 @@ static int sessionChangesetApply( int i; sqlite3changeset_pk(pIter, &abPK, 0); - rc = sessionTableInfo( + rc = sessionTableInfo(0, db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK ); if( rc!=SQLITE_OK ) break; @@ -206854,11 +214966,10 @@ static int sessionChangesetApply( } sApply.bStat1 = 1; }else{ - if((rc = sessionSelectRow(db, zTab, &sApply)) - || (rc = sessionUpdateRow(db, zTab, &sApply)) - || (rc = sessionDeleteRow(db, zTab, &sApply)) - || (rc = sessionInsertRow(db, zTab, &sApply)) - ){ + if( (rc = sessionSelectRow(db, zTab, &sApply)) + || (rc = sessionDeleteRow(db, zTab, &sApply)) + || (rc = sessionInsertRow(db, zTab, &sApply)) + ){ break; } sApply.bStat1 = 0; @@ -206917,9 +215028,9 @@ static int sessionChangesetApply( *pnRebase = sApply.rebase.nBuf; sApply.rebase.aBuf = 0; } + sessionUpdateFree(&sApply); sqlite3_finalize(sApply.pInsert); sqlite3_finalize(sApply.pDelete); - sqlite3_finalize(sApply.pUpdate); sqlite3_finalize(sApply.pSelect); sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_free((char*)sApply.constraints.aBuf); @@ -206950,8 +215061,8 @@ SQLITE_API int sqlite3changeset_apply_v2( int flags ){ sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ - int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); - int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse); + int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); + int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1); if( rc==SQLITE_OK ){ rc = sessionChangesetApply( db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags @@ -207009,7 +215120,7 @@ SQLITE_API int sqlite3changeset_apply_v2_strm( ){ sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); - int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse); + int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse, 1); if( rc==SQLITE_OK ){ rc = sessionChangesetApply( db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags @@ -207297,7 +215408,7 @@ static int sessionChangesetToHash( } } - if( sessionGrowHash(pIter->bPatchset, pTab) ){ + if( sessionGrowHash(0, pIter->bPatchset, pTab) ){ rc = SQLITE_NOMEM; break; } @@ -207393,9 +215504,9 @@ static int sessionChangegroupOutput( if( rc==SQLITE_OK ){ if( xOutput ){ if( buf.nBuf>0 ) 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; } } @@ -207483,7 +215594,7 @@ SQLITE_API int sqlite3changegroup_output_strm( */ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ if( pGrp ){ - sessionDeleteTable(pGrp->pList); + sessionDeleteTable(0, pGrp->pList); sqlite3_free(pGrp); } } @@ -207629,7 +215740,7 @@ static void sessionAppendPartialUpdate( int n1 = sessionSerialLen(a1); int n2 = sessionSerialLen(a2); if( pIter->abPK[i] || a2[0]==0 ){ - if( !pIter->abPK[i] ) bData = 1; + if( !pIter->abPK[i] && a1[0] ) bData = 1; memcpy(pOut, a1, n1); pOut += n1; }else if( a2[0]!=0xFF ){ @@ -207795,7 +215906,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; @@ -207884,7 +215995,7 @@ SQLITE_API int sqlite3rebaser_rebase_strm( */ SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){ if( p ){ - sessionDeleteTable(p->grp.pList); + sessionDeleteTable(0, p->grp.pList); sqlite3_free(p); } } @@ -208538,8 +216649,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)) @@ -208599,7 +216722,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. */ @@ -208687,6 +216810,7 @@ struct Fts5Config { Fts5Tokenizer *pTok; fts5_tokenizer *pTokApi; int bLock; /* True when table is preparing statement */ + int ePattern; /* FTS_PATTERN_XXX constant */ /* Values loaded from the %_config table */ int iCookie; /* Incremented when %_config is modified */ @@ -208707,17 +216831,19 @@ struct Fts5Config { }; /* Current expected value of %_config table 'version' field */ -#define FTS5_CURRENT_VERSION 4 +#define FTS5_CURRENT_VERSION 4 #define FTS5_CONTENT_NORMAL 0 #define FTS5_CONTENT_NONE 1 #define FTS5_CONTENT_EXTERNAL 2 -#define FTS5_DETAIL_FULL 0 -#define FTS5_DETAIL_NONE 1 -#define FTS5_DETAIL_COLUMNS 2 - +#define FTS5_DETAIL_FULL 0 +#define FTS5_DETAIL_NONE 1 +#define FTS5_DETAIL_COLUMNS 2 +#define FTS5_PATTERN_NONE 0 +#define FTS5_PATTERN_LIKE 65 /* matches SQLITE_INDEX_CONSTRAINT_LIKE */ +#define FTS5_PATTERN_GLOB 66 /* matches SQLITE_INDEX_CONSTRAINT_GLOB */ static int sqlite3Fts5ConfigParse( Fts5Global*, sqlite3*, int, const char **, Fts5Config**, char** @@ -208935,6 +217061,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*); /* @@ -208987,7 +217116,7 @@ static int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int); /* ** Functions called by the storage module as part of integrity-check. */ -static int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum); +static int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum, int bUseCksum); /* ** Called during virtual module initialization to register UDF @@ -209057,8 +217186,7 @@ static int sqlite3Fts5GetTokenizer( Fts5Global*, const char **azArg, int nArg, - Fts5Tokenizer**, - fts5_tokenizer**, + Fts5Config*, char **pzErr ); @@ -209142,7 +217270,7 @@ static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**); static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*); static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64); -static int sqlite3Fts5StorageIntegrity(Fts5Storage *p); +static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg); static int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt**, char**); static void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*); @@ -209187,11 +217315,19 @@ struct Fts5Token { /* Parse a MATCH expression. */ static int sqlite3Fts5ExprNew( Fts5Config *pConfig, + int bPhraseToAnd, int iCol, /* Column on LHS of MATCH operator */ const char *zExpr, Fts5Expr **ppNew, char **pzErr ); +static int sqlite3Fts5ExprPattern( + Fts5Config *pConfig, + int bGlob, + int iCol, + const char *zText, + Fts5Expr **pp +); /* ** for(rc = sqlite3Fts5ExprFirst(pExpr, pIdx, bDesc); @@ -209300,6 +217436,10 @@ static int sqlite3Fts5AuxInit(fts5_api*); */ static int sqlite3Fts5TokenizerInit(fts5_api*); +static int sqlite3Fts5TokenizerPattern( + int (*xCreate)(void*, const char**, int, Fts5Tokenizer**), + Fts5Tokenizer *pTok +); /* ** End of interface to code in fts5_tokenizer.c. **************************************************************************/ @@ -209346,6 +217486,8 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); #define FTS5_PLUS 14 #define FTS5_STAR 15 +/* This file is automatically generated by Lemon from input grammar +** source file "fts5parse.y". */ /* ** 2000-05-29 ** @@ -209370,8 +217512,6 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); ** The following is the concatenation of all %include directives from the ** input grammar file: */ -/* #include */ -/* #include */ /************ Begin %include sections from the grammar ************************/ /* #include "fts5Int.h" */ @@ -209401,11 +217541,26 @@ static void sqlite3Fts5UnicodeAscii(u8*, u8*); #define fts5YYMALLOCARGTYPE u64 /**************** End of %include directives **********************************/ -/* These constants specify the various numeric values for terminal symbols -** in a format understandable to "makeheaders". This section is blank unless -** "lemon" is run with the "-m" command-line option. -***************** Begin makeheaders token definitions *************************/ -/**************** End makeheaders token definitions ***************************/ +/* These constants specify the various numeric values for terminal symbols. +***************** Begin token definitions *************************************/ +#ifndef FTS5_OR +#define FTS5_OR 1 +#define FTS5_AND 2 +#define FTS5_NOT 3 +#define FTS5_TERM 4 +#define FTS5_COLON 5 +#define FTS5_MINUS 6 +#define FTS5_LCP 7 +#define FTS5_RCP 8 +#define FTS5_STRING 9 +#define FTS5_LP 10 +#define FTS5_RP 11 +#define FTS5_CARET 12 +#define FTS5_COMMA 13 +#define FTS5_PLUS 14 +#define FTS5_STAR 15 +#endif +/**************** End token definitions ***************************************/ /* The next sections is a series of control #defines. ** various aspects of the generated parser. @@ -209686,6 +217841,7 @@ struct fts5yyParser { }; typedef struct fts5yyParser fts5yyParser; +/* #include */ #ifndef NDEBUG /* #include */ static FILE *fts5yyTraceFILE = 0; @@ -210102,7 +218258,7 @@ static fts5YYACTIONTYPE fts5yy_find_shift_action( #endif /* fts5YYWILDCARD */ return fts5yy_default[stateno]; }else{ - assert( i>=0 && i=0 && i<(int)(sizeof(fts5yy_action)/sizeof(fts5yy_action[0])) ); return fts5yy_action[i]; } }while(1); @@ -210316,54 +218472,6 @@ static fts5YYACTIONTYPE fts5yy_reduce( (void)fts5yyLookahead; (void)fts5yyLookaheadToken; fts5yymsp = fts5yypParser->fts5yytos; -#ifndef NDEBUG - if( fts5yyTraceFILE && fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ){ - fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno]; - if( fts5yysize ){ - fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", - fts5yyTracePrompt, - fts5yyruleno, fts5yyRuleName[fts5yyruleno], - fts5yyrulenofts5yytos - fts5yypParser->fts5yystack)>fts5yypParser->fts5yyhwm ){ - fts5yypParser->fts5yyhwm++; - assert( fts5yypParser->fts5yyhwm == (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)); - } -#endif -#if fts5YYSTACKDEPTH>0 - if( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystackEnd ){ - fts5yyStackOverflow(fts5yypParser); - /* The call to fts5yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } -#else - if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz-1] ){ - if( fts5yyGrowStack(fts5yypParser) ){ - fts5yyStackOverflow(fts5yypParser); - /* The call to fts5yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } - fts5yymsp = fts5yypParser->fts5yytos; - } -#endif - } switch( fts5yyruleno ){ /* Beginning here are the reduction cases. A typical example @@ -210666,12 +218774,56 @@ static void sqlite3Fts5Parser( } #endif - do{ + while(1){ /* Exit by "break" */ + assert( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystack ); assert( fts5yyact==fts5yypParser->fts5yytos->stateno ); fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact); if( fts5yyact >= fts5YY_MIN_REDUCE ){ - fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE,fts5yymajor, - fts5yyminor sqlite3Fts5ParserCTX_PARAM); + unsigned int fts5yyruleno = fts5yyact - fts5YY_MIN_REDUCE; /* Reduce by this rule */ +#ifndef NDEBUG + assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ); + if( fts5yyTraceFILE ){ + int fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno]; + if( fts5yysize ){ + fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + fts5yyTracePrompt, + fts5yyruleno, fts5yyRuleName[fts5yyruleno], + fts5yyrulenofts5yytos[fts5yysize].stateno); + }else{ + fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s.\n", + fts5yyTracePrompt, fts5yyruleno, fts5yyRuleName[fts5yyruleno], + fts5yyrulenofts5yytos - fts5yypParser->fts5yystack)>fts5yypParser->fts5yyhwm ){ + fts5yypParser->fts5yyhwm++; + assert( fts5yypParser->fts5yyhwm == + (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)); + } +#endif +#if fts5YYSTACKDEPTH>0 + if( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystackEnd ){ + fts5yyStackOverflow(fts5yypParser); + break; + } +#else + if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz-1] ){ + if( fts5yyGrowStack(fts5yypParser) ){ + fts5yyStackOverflow(fts5yypParser); + break; + } + } +#endif + } + fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyruleno,fts5yymajor,fts5yyminor sqlite3Fts5ParserCTX_PARAM); }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){ fts5yy_shift(fts5yypParser,fts5yyact,(fts5YYCODETYPE)fts5yymajor,fts5yyminor); #ifndef fts5YYNOERRORRECOVERY @@ -210727,14 +218879,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 @@ -210784,7 +218935,7 @@ static void sqlite3Fts5Parser( break; #endif } - }while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ); + } #ifndef NDEBUG if( fts5yyTraceFILE ){ fts5yyStackEntry *i; @@ -211382,7 +219533,7 @@ static int fts5Bm25GetData( int rc = SQLITE_OK; /* Return code */ Fts5Bm25Data *p; /* Object to return */ - p = pApi->xGetAuxdata(pFts, 0); + p = (Fts5Bm25Data*)pApi->xGetAuxdata(pFts, 0); if( p==0 ){ int nPhrase; /* Number of phrases in query */ sqlite3_int64 nRow = 0; /* Number of rows in table */ @@ -211456,7 +219607,7 @@ static void fts5Bm25Function( ){ const double k1 = 1.2; /* Constant "k1" from BM25 formula */ const double b = 0.75; /* Constant "b" from BM25 formula */ - int rc = SQLITE_OK; /* Error code */ + int rc; /* Error code */ double score = 0.0; /* SQL function return value */ Fts5Bm25Data *pData; /* Values allocated/calculated once only */ int i; /* Iterator variable */ @@ -211488,17 +219639,15 @@ static void fts5Bm25Function( D = (double)nTok; } - /* Determine the BM25 score for the current row. */ - for(i=0; rc==SQLITE_OK && inPhrase; i++){ - score += pData->aIDF[i] * ( - ( aFreq[i] * (k1 + 1.0) ) / - ( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) ) - ); - } - - /* If no error has occurred, return the calculated score. Otherwise, - ** throw an SQL exception. */ + /* Determine and return the BM25 score for the current row. Or, if an + ** error has occurred, throw an exception. */ if( rc==SQLITE_OK ){ + for(i=0; inPhrase; i++){ + score += pData->aIDF[i] * ( + ( aFreq[i] * (k1 + 1.0) ) / + ( aFreq[i] + k1 * (1 - b + b * D / pData->avgdl) ) + ); + } sqlite3_result_double(pCtx, -1.0 * score); }else{ sqlite3_result_error_code(pCtx, rc); @@ -211599,7 +219748,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); @@ -211709,7 +219857,7 @@ static int sqlite3Fts5PoslistNext64( return 1; }else{ i64 iOff = *piOff; - int iVal; + u32 iVal; fts5FastGetVarint32(a, i, iVal); if( iVal<=1 ){ if( iVal==0 ){ @@ -211718,15 +219866,19 @@ 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. */ *piOff = -1; return 1; } + *piOff = iOff + ((iVal-2) & 0x7FFFFFFF); + }else{ + *piOff = (iOff & (i64)0x7FFFFFFF<<32)+((iOff + (iVal-2)) & 0x7FFFFFFF); } - *piOff = iOff + ((iVal-2) & 0x7FFFFFFF); *pi = i; + assert_nc( *piOff>=iOff ); return 0; } } @@ -211765,14 +219917,16 @@ static void sqlite3Fts5PoslistSafeAppend( i64 *piPrev, i64 iPos ){ - static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32; - if( (iPos & colmask) != (*piPrev & colmask) ){ - pBuf->p[pBuf->n++] = 1; - pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32)); - *piPrev = (iPos & colmask); + if( iPos>=*piPrev ){ + static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32; + if( (iPos & colmask) != (*piPrev & colmask) ){ + pBuf->p[pBuf->n++] = 1; + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32)); + *piPrev = (iPos & colmask); + } + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2); + *piPrev = iPos; } - pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2); - *piPrev = iPos; } static int sqlite3Fts5PoslistWriterAppend( @@ -212262,7 +220416,7 @@ static int fts5ConfigParseSpecial( rc = SQLITE_ERROR; }else{ rc = sqlite3Fts5GetTokenizer(pGlobal, - (const char**)azArg, (int)nArg, &pConfig->pTok, &pConfig->pTokApi, + (const char**)azArg, (int)nArg, pConfig, pzErr ); } @@ -212334,9 +220488,7 @@ static int fts5ConfigParseSpecial( */ static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){ assert( pConfig->pTok==0 && pConfig->pTokApi==0 ); - return sqlite3Fts5GetTokenizer( - pGlobal, 0, 0, &pConfig->pTok, &pConfig->pTokApi, 0 - ); + return sqlite3Fts5GetTokenizer(pGlobal, 0, 0, pConfig, 0); } /* @@ -212476,7 +220628,7 @@ static int sqlite3Fts5ConfigParse( nByte = nArg * (sizeof(char*) + sizeof(u8)); pRet->azCol = (char**)sqlite3Fts5MallocZero(&rc, nByte); - pRet->abUnindexed = (u8*)&pRet->azCol[nArg]; + pRet->abUnindexed = pRet->azCol ? (u8*)&pRet->azCol[nArg] : 0; pRet->zDb = sqlite3Fts5Strndup(&rc, azArg[1], -1); pRet->zName = sqlite3Fts5Strndup(&rc, azArg[2], -1); pRet->bColumnsize = 1; @@ -212501,6 +220653,7 @@ static int sqlite3Fts5ConfigParse( z = fts5ConfigSkipWhitespace(z); if( z && *z=='=' ){ bOption = 1; + assert( zOne!=0 ); z++; if( bMustBeCol ) z = 0; } @@ -212517,7 +220670,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; @@ -213028,12 +221185,14 @@ struct Fts5Parse { int nPhrase; /* Size of apPhrase array */ Fts5ExprPhrase **apPhrase; /* Array of all phrases */ Fts5ExprNode *pExpr; /* Result of a successful parse */ + int bPhraseToAnd; /* Convert "a+b" to "a AND b" */ }; 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; } @@ -213116,6 +221275,7 @@ static void fts5ParseFree(void *p){ sqlite3_free(p); } static int sqlite3Fts5ExprNew( Fts5Config *pConfig, /* FTS5 Configuration */ + int bPhraseToAnd, int iCol, const char *zExpr, /* Expression text */ Fts5Expr **ppNew, @@ -213131,6 +221291,7 @@ static int sqlite3Fts5ExprNew( *ppNew = 0; *pzErr = 0; memset(&sParse, 0, sizeof(sParse)); + sParse.bPhraseToAnd = bPhraseToAnd; pEngine = sqlite3Fts5ParserAlloc(fts5ParseAlloc); if( pEngine==0 ){ return SQLITE_NOMEM; } sParse.pConfig = pConfig; @@ -213173,6 +221334,7 @@ static int sqlite3Fts5ExprNew( pNew->pConfig = pConfig; pNew->apExprPhrase = sParse.apPhrase; pNew->nPhrase = sParse.nPhrase; + pNew->bDesc = 0; sParse.apPhrase = 0; } }else{ @@ -213184,6 +221346,81 @@ static int sqlite3Fts5ExprNew( return sParse.rc; } +/* +** This function is only called when using the special 'trigram' tokenizer. +** Argument zText contains the text of a LIKE or GLOB pattern matched +** against column iCol. This function creates and compiles an FTS5 MATCH +** expression that will match a superset of the rows matched by the LIKE or +** GLOB. If successful, SQLITE_OK is returned. Otherwise, an SQLite error +** code. +*/ +static int sqlite3Fts5ExprPattern( + Fts5Config *pConfig, int bGlob, int iCol, const char *zText, Fts5Expr **pp +){ + i64 nText = strlen(zText); + char *zExpr = (char*)sqlite3_malloc64(nText*4 + 1); + int rc = SQLITE_OK; + + if( zExpr==0 ){ + rc = SQLITE_NOMEM; + }else{ + char aSpec[3]; + int iOut = 0; + int i = 0; + int iFirst = 0; + + if( bGlob==0 ){ + aSpec[0] = '_'; + aSpec[1] = '%'; + aSpec[2] = 0; + }else{ + aSpec[0] = '*'; + aSpec[1] = '?'; + aSpec[2] = '['; + } + + while( i<=nText ){ + if( i==nText + || zText[i]==aSpec[0] || zText[i]==aSpec[1] || zText[i]==aSpec[2] + ){ + if( i-iFirst>=3 ){ + int jj; + zExpr[iOut++] = '"'; + for(jj=iFirst; jj0 ){ + int bAnd = 0; + if( pConfig->eDetail!=FTS5_DETAIL_FULL ){ + bAnd = 1; + if( pConfig->eDetail==FTS5_DETAIL_NONE ){ + iCol = pConfig->nCol; + } + } + zExpr[iOut] = '\0'; + rc = sqlite3Fts5ExprNew(pConfig, bAnd, iCol, zExpr, pp,pConfig->pzErrmsg); + }else{ + *pp = 0; + } + sqlite3_free(zExpr); + } + + return rc; +} + /* ** Free the expression node object passed as the only argument. */ @@ -213254,6 +221491,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){ @@ -214321,8 +222559,8 @@ static int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bD } /* If the iterator is not at a real match, skip forward until it is. */ - while( pRoot->bNomatch ){ - assert( pRoot->bEof==0 && rc==SQLITE_OK ); + while( pRoot->bNomatch && rc==SQLITE_OK ){ + assert( pRoot->bEof==0 ); rc = fts5ExprNodeNext(p, pRoot, 0, 0); } return rc; @@ -214561,6 +222799,20 @@ static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){ pParse->pExpr = p; } +static int parseGrowPhraseArray(Fts5Parse *pParse){ + if( (pParse->nPhrase % 8)==0 ){ + sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8); + Fts5ExprPhrase **apNew; + apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte); + if( apNew==0 ){ + pParse->rc = SQLITE_NOMEM; + return SQLITE_NOMEM; + } + pParse->apPhrase = apNew; + } + return SQLITE_OK; +} + /* ** This function is called by the parser to process a string token. The ** string may or may not be quoted. In any case it is tokenized and a @@ -214596,16 +222848,9 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm( }else{ if( pAppend==0 ){ - if( (pParse->nPhrase % 8)==0 ){ - sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8); - Fts5ExprPhrase **apNew; - apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte); - if( apNew==0 ){ - pParse->rc = SQLITE_NOMEM; - fts5ExprPhraseFree(sCtx.pPhrase); - return 0; - } - pParse->apPhrase = apNew; + if( parseGrowPhraseArray(pParse) ){ + fts5ExprPhraseFree(sCtx.pPhrase); + return 0; } pParse->nPhrase++; } @@ -214687,7 +222932,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; @@ -214958,9 +223203,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); @@ -215012,6 +223256,67 @@ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ } } +/* +** This function is used when parsing LIKE or GLOB patterns against +** trigram indexes that specify either detail=column or detail=none. +** It converts a phrase: +** +** abc + def + ghi +** +** into an AND tree: +** +** abc AND def AND ghi +*/ +static Fts5ExprNode *fts5ParsePhraseToAnd( + Fts5Parse *pParse, + Fts5ExprNearset *pNear +){ + int nTerm = pNear->apPhrase[0]->nTerm; + int ii; + int nByte; + Fts5ExprNode *pRet; + + assert( pNear->nPhrase==1 ); + assert( pParse->bPhraseToAnd ); + + nByte = sizeof(Fts5ExprNode) + nTerm*sizeof(Fts5ExprNode*); + pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); + if( pRet ){ + pRet->eType = FTS5_AND; + pRet->nChild = nTerm; + fts5ExprAssignXNext(pRet); + pParse->nPhrase--; + for(ii=0; iirc, sizeof(Fts5ExprPhrase) + ); + if( pPhrase ){ + if( parseGrowPhraseArray(pParse) ){ + fts5ExprPhraseFree(pPhrase); + }else{ + pParse->apPhrase[pParse->nPhrase++] = pPhrase; + pPhrase->nTerm = 1; + pPhrase->aTerm[0].zTerm = sqlite3Fts5Strndup( + &pParse->rc, pNear->apPhrase[0]->aTerm[ii].zTerm, -1 + ); + pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING, + 0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase) + ); + } + } + } + + if( pParse->rc ){ + sqlite3Fts5ParseNodeFree(pRet); + pRet = 0; + }else{ + sqlite3Fts5ParseNearsetFree(pNear); + } + } + + return pRet; +} + /* ** Allocate and return a new expression object. If anything goes wrong (i.e. ** OOM error), leave an error code in pParse and return NULL. @@ -215036,51 +223341,55 @@ static Fts5ExprNode *sqlite3Fts5ParseNode( if( eType!=FTS5_STRING && pLeft==0 ) return pRight; if( eType!=FTS5_STRING && pRight==0 ) return pLeft; - if( eType==FTS5_NOT ){ - nChild = 2; - }else if( eType==FTS5_AND || eType==FTS5_OR ){ - nChild = 2; - if( pLeft->eType==eType ) nChild += pLeft->nChild-1; - if( pRight->eType==eType ) nChild += pRight->nChild-1; - } + if( eType==FTS5_STRING + && pParse->bPhraseToAnd + && pNear->apPhrase[0]->nTerm>1 + ){ + pRet = fts5ParsePhraseToAnd(pParse, pNear); + }else{ + if( eType==FTS5_NOT ){ + nChild = 2; + }else if( eType==FTS5_AND || eType==FTS5_OR ){ + nChild = 2; + if( pLeft->eType==eType ) nChild += pLeft->nChild-1; + if( pRight->eType==eType ) nChild += pRight->nChild-1; + } - nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1); - pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); + nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1); + pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); - if( pRet ){ - pRet->eType = eType; - pRet->pNear = pNear; - fts5ExprAssignXNext(pRet); - if( eType==FTS5_STRING ){ - int iPhrase; - for(iPhrase=0; iPhrasenPhrase; iPhrase++){ - pNear->apPhrase[iPhrase]->pNode = pRet; - if( pNear->apPhrase[iPhrase]->nTerm==0 ){ - pRet->xNext = 0; - pRet->eType = FTS5_EOF; + if( pRet ){ + pRet->eType = eType; + pRet->pNear = pNear; + fts5ExprAssignXNext(pRet); + if( eType==FTS5_STRING ){ + int iPhrase; + for(iPhrase=0; iPhrasenPhrase; iPhrase++){ + pNear->apPhrase[iPhrase]->pNode = pRet; + if( pNear->apPhrase[iPhrase]->nTerm==0 ){ + pRet->xNext = 0; + pRet->eType = FTS5_EOF; + } } - } - if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){ - Fts5ExprPhrase *pPhrase = pNear->apPhrase[0]; - if( pNear->nPhrase!=1 - || 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( - "fts5: %s queries are not supported (detail!=full)", - pNear->nPhrase==1 ? "phrase": "NEAR" - ); - sqlite3_free(pRet); - pRet = 0; + if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){ + Fts5ExprPhrase *pPhrase = pNear->apPhrase[0]; + if( pNear->nPhrase!=1 + || pPhrase->nTerm>1 + || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst) + ){ + sqlite3Fts5ParseError(pParse, + "fts5: %s queries are not supported (detail!=full)", + pNear->nPhrase==1 ? "phrase": "NEAR" + ); + sqlite3_free(pRet); + pRet = 0; + } } + }else{ + fts5ExprAddChildren(pRet, pLeft); + fts5ExprAddChildren(pRet, pRight); } - }else{ - fts5ExprAddChildren(pRet, pLeft); - fts5ExprAddChildren(pRet, pRight); } } } @@ -215158,6 +223467,7 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( return pRet; } +#ifdef SQLITE_TEST static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ sqlite3_int64 nByte = 0; Fts5ExprTerm *p; @@ -215301,8 +223611,17 @@ static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){ int iTerm; if( pNear->pColset ){ - int iCol = pNear->pColset->aiCol[0]; - zRet = fts5PrintfAppend(zRet, "%s : ", pConfig->azCol[iCol]); + int ii; + Fts5Colset *pColset = pNear->pColset; + if( pColset->nCol>1 ) zRet = fts5PrintfAppend(zRet, "{"); + for(ii=0; iinCol; ii++){ + zRet = fts5PrintfAppend(zRet, "%s%s", + pConfig->azCol[pColset->aiCol[ii]], ii==pColset->nCol-1 ? "" : " " + ); + } + if( zRet ){ + zRet = fts5PrintfAppend(zRet, "%s : ", pColset->nCol>1 ? "}" : ""); + } if( zRet==0 ) return 0; } @@ -215425,7 +223744,7 @@ static void fts5ExprFunction( rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr); if( rc==SQLITE_OK ){ - rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr); + rc = sqlite3Fts5ExprNew(pConfig, 0, pConfig->nCol, zExpr, &pExpr, &zErr); } if( rc==SQLITE_OK ){ char *zText; @@ -215515,12 +223834,14 @@ static void fts5ExprFold( sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics)); } } +#endif /* ifdef SQLITE_TEST */ /* ** This is called during initialization to register the fts5_expr() scalar ** UDF with the SQLite handle passed as the only argument. */ static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ +#ifdef SQLITE_TEST struct Fts5ExprFunc { const char *z; void (*x)(sqlite3_context*,int,sqlite3_value**); @@ -215538,6 +223859,10 @@ static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ struct Fts5ExprFunc *p = &aFunc[i]; rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0); } +#else + int rc = SQLITE_OK; + UNUSED_PARAM2(pGlobal,db); +#endif /* Avoid warnings indicating that sqlite3Fts5ParserTrace() and ** sqlite3Fts5ParserFallback() are unused */ @@ -215588,6 +223913,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); @@ -215597,7 +223931,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) ){ @@ -216098,7 +224432,6 @@ static int sqlite3Fts5HashWrite( p->iCol = (pHash->eDetail==FTS5_DETAIL_FULL ? 0 : -1); } - nIncr += p->nData; }else{ /* Appending to an existing hash-entry. Check that there is enough @@ -216131,8 +224464,9 @@ static int sqlite3Fts5HashWrite( /* If this is a new rowid, append the 4-byte size field for the previous ** entry, and the new rowid for this entry. */ if( iRowid!=p->iRowid ){ + u64 iDiff = (u64)iRowid - (u64)p->iRowid; fts5HashAddPoslistSize(pHash, p, 0); - p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iRowid - p->iRowid); + p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iDiff); p->iRowid = iRowid; bNew = 1; p->iSzPoslist = p->nData; @@ -216148,7 +224482,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; @@ -216784,7 +225118,7 @@ struct Fts5SegIter { int iLeafPgno; /* Current leaf page number */ Fts5Data *pLeaf; /* Current leaf data */ Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */ - int iLeafOffset; /* Byte offset within current leaf */ + i64 iLeafOffset; /* Byte offset within current leaf */ /* Next method */ void (*xNext)(Fts5Index*, Fts5SegIter*, int*); @@ -216953,8 +225287,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); } @@ -217050,6 +225387,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ return pRet; } + /* ** Release a reference to data record returned by an earlier call to ** fts5DataRead(). @@ -217174,6 +225512,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. @@ -217275,9 +225665,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; @@ -217964,7 +226356,7 @@ static void fts5SegIterLoadNPos(Fts5Index *p, Fts5SegIter *pIter){ static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){ u8 *a = pIter->pLeaf->p; /* Buffer to read data from */ - int iOff = pIter->iLeafOffset; + i64 iOff = pIter->iLeafOffset; ASSERT_SZLEAF_OK(pIter->pLeaf); if( iOff>=pIter->pLeaf->szLeaf ){ @@ -217997,7 +226389,7 @@ static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){ */ static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){ u8 *a = pIter->pLeaf->p; /* Buffer to read data from */ - int iOff = pIter->iLeafOffset; /* Offset to read at */ + i64 iOff = pIter->iLeafOffset; /* Offset to read at */ int nNew; /* Bytes of new data */ iOff += fts5GetVarint32(&a[iOff], nNew); @@ -218071,6 +226463,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; @@ -218107,7 +226500,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){ ASSERT_SZLEAF_OK(pIter->pLeaf); while( 1 ){ - i64 iDelta = 0; + u64 iDelta = 0; if( eDetail==FTS5_DETAIL_NONE ){ /* todo */ @@ -218122,7 +226515,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){ i += nPos; } if( i>=n ) break; - i += fts5GetVarint(&a[i], (u64*)&iDelta); + i += fts5GetVarint(&a[i], &iDelta); pIter->iRowid += iDelta; /* If necessary, grow the pIter->aRowidOffset[] array. */ @@ -218173,8 +226566,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; + } } } @@ -218221,7 +226618,7 @@ static void fts5SegIterNext_Reverse( if( pIter->iRowidOffset>0 ){ u8 *a = pIter->pLeaf->p; int iOff; - i64 iDelta; + u64 iDelta; pIter->iRowidOffset--; pIter->iLeafOffset = pIter->aRowidOffset[pIter->iRowidOffset]; @@ -218230,7 +226627,7 @@ static void fts5SegIterNext_Reverse( if( p->pConfig->eDetail!=FTS5_DETAIL_NONE ){ iOff += pIter->nPos; } - fts5GetVarint(&a[iOff], (u64*)&iDelta); + fts5GetVarint(&a[iOff], &iDelta); pIter->iRowid -= iDelta; }else{ fts5SegIterReverseNewPage(p, pIter); @@ -218423,14 +226820,9 @@ static void fts5SegIterNext( }else{ /* The following could be done by calling fts5SegIterLoadNPos(). But ** this block is particularly performance critical, so equivalent - ** code is inlined. - ** - ** Later: Switched back to fts5SegIterLoadNPos() because it supports - ** detail=none mode. Not ideal. - */ + ** code is inlined. */ int nSz; - assert( p->rc==SQLITE_OK ); - assert( pIter->iLeafOffset<=pIter->pLeaf->nn ); + assert_nc( pIter->iLeafOffset<=pIter->pLeaf->nn ); fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz); pIter->bDel = (nSz & 0x0001); pIter->nPos = nSz>>1; @@ -218459,7 +226851,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 */ @@ -218486,7 +226878,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); @@ -218517,6 +226909,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; @@ -218525,7 +226921,6 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){ }else{ pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast); } - } fts5SegIterReverseInitPage(p, pIter); @@ -218577,21 +226972,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 ){ @@ -218657,15 +227051,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; } @@ -219033,7 +227427,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; @@ -219422,7 +227816,7 @@ static void fts5ChunkIterate( int pgno = pSeg->iLeafPgno; int pgnoSave = 0; - /* This function does notmwork with detail=none databases. */ + /* This function does not work with detail=none databases. */ assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE ); if( (pSeg->flags & FTS5_SEGITER_REVERSE)==0 ){ @@ -219435,6 +227829,9 @@ static void fts5ChunkIterate( fts5DataRelease(pData); if( nRem<=0 ){ break; + }else if( pSeg->pSeg==0 ){ + p->rc = FTS5_CORRUPT; + return; }else{ pgno++; pData = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno)); @@ -219462,7 +227859,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); @@ -219486,66 +227887,72 @@ static void fts5SegiterPoslist( } /* -** IN/OUT parameter (*pa) points to a position list n bytes in size. If -** the position list contains entries for column iCol, then (*pa) is set -** to point to the sub-position-list for that column and the number of -** bytes in it returned. Or, if the argument position list does not -** contain any entries for column iCol, return 0. +** Parameter pPos points to a buffer containing a position list, size nPos. +** This function filters it according to pColset (which must be non-NULL) +** and sets pIter->base.pData/nData to point to the new position list. +** If memory is required for the new position list, use buffer pIter->poslist. +** Or, if the new position list is a contiguous subset of the input, set +** pIter->base.pData/nData to point directly to it. +** +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. If an OOM error is encountered, *pRc is set to SQLITE_NOMEM +** before returning. */ -static int fts5IndexExtractCol( - const u8 **pa, /* IN/OUT: Pointer to poslist */ - int n, /* IN: Size of poslist in bytes */ - int iCol /* Column to extract from poslist */ -){ - int iCurrent = 0; /* Anything before the first 0x01 is col 0 */ - const u8 *p = *pa; - const u8 *pEnd = &p[n]; /* One byte past end of position list */ - - while( iCol>iCurrent ){ - /* Advance pointer p until it points to pEnd or an 0x01 byte that is - ** not part of a varint. Note that it is not possible for a negative - ** or extremely large varint to occur within an uncorrupted position - ** list. So the last byte of each varint may be assumed to have a clear - ** 0x80 bit. */ - while( *p!=0x01 ){ - while( *p++ & 0x80 ); - if( p>=pEnd ) return 0; - } - *pa = p++; - iCurrent = *p++; - if( iCurrent & 0x80 ){ - p--; - p += fts5GetVarint32(p, iCurrent); - } - } - if( iCol!=iCurrent ) return 0; - - /* Advance pointer p until it points to pEnd or an 0x01 byte that is - ** not part of a varint */ - while( pnCol; i++){ - const u8 *pSub = pPos; - int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]); - if( nSub ){ - fts5BufferAppendBlob(pRc, pBuf, nSub, pSub); + const u8 *p = pPos; + const u8 *aCopy = p; + const u8 *pEnd = &p[nPos]; /* One byte past end of position list */ + int i = 0; + int iCurrent = 0; + + if( pColset->nCol>1 && sqlite3Fts5BufferSize(pRc, &pIter->poslist, nPos) ){ + return; + } + + while( 1 ){ + while( pColset->aiCol[i]nCol ){ + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; + return; + } + } + + /* Advance pointer p until it points to pEnd or an 0x01 byte that is + ** not part of a varint */ + while( paiCol[i]==iCurrent ){ + if( pColset->nCol==1 ){ + pIter->base.pData = aCopy; + pIter->base.nData = p-aCopy; + return; + } + fts5BufferSafeAppendBlob(&pIter->poslist, aCopy, p-aCopy); + } + if( p>=pEnd ){ + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; + return; + } + aCopy = p++; + iCurrent = *p++; + if( iCurrent & 0x80 ){ + p--; + p += fts5GetVarint32(p, iCurrent); } } } + } /* @@ -219665,16 +228072,9 @@ static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){ /* All data is stored on the current page. Populate the output ** variables to point into the body of the page object. */ const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset]; - if( pColset->nCol==1 ){ - pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]); - pIter->base.pData = a; - }else{ - int *pRc = &pIter->pIndex->rc; - fts5BufferZero(&pIter->poslist); - fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, &pIter->poslist); - pIter->base.pData = pIter->poslist.p; - pIter->base.nData = pIter->poslist.n; - } + int *pRc = &pIter->pIndex->rc; + fts5BufferZero(&pIter->poslist); + fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, pIter); }else{ /* The data is distributed over two or more pages. Copy it into the ** Fts5Iter.poslist buffer and then set the output pointer to point @@ -219687,6 +228087,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 ){ @@ -219758,7 +228159,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; @@ -219822,6 +228226,10 @@ static void fts5MultiIterNew( fts5MultiIterFree(pNew); *ppOut = 0; } + +fts5MultiIterNew_post_check: + assert( (*ppOut)!=0 || p->rc!=SQLITE_OK ); + return; } /* @@ -219869,7 +228277,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); @@ -220673,6 +229082,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; @@ -220773,7 +229183,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 */ @@ -220896,14 +229306,14 @@ static void fts5FlushOneHash(Fts5Index *p){ fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist); }else{ i64 iRowid = 0; - i64 iDelta = 0; + u64 iDelta = 0; int iOff = 0; /* The entire doclist will not fit on this leaf. The following ** loop iterates through the poslists that make up the current ** doclist. */ while( p->rc==SQLITE_OK && iOffaPoslist + pIter->nSize + pIter->nPoslist; - assert( pIter->aPoslist ); + assert( pIter->aPoslist || (p==0 && pIter->aPoslist==0) ); if( p>=pIter->aEof ){ pIter->aPoslist = 0; }else{ @@ -221177,6 +229587,9 @@ static void fts5DoclistIterNext(Fts5DoclistIter *pIter){ } pIter->aPoslist = p; + if( &pIter->aPoslist[pIter->nPoslist]>pIter->aEof ){ + pIter->aPoslist = 0; + } } } @@ -221185,9 +229598,11 @@ static void fts5DoclistIterInit( Fts5DoclistIter *pIter ){ memset(pIter, 0, sizeof(*pIter)); - pIter->aPoslist = pBuf->p; - pIter->aEof = &pBuf->p[pBuf->n]; - fts5DoclistIterNext(pIter); + if( pBuf->n>0 ){ + pIter->aPoslist = pBuf->p; + pIter->aEof = &pBuf->p[pBuf->n]; + fts5DoclistIterNext(pIter); + } } #if 0 @@ -221241,16 +229656,20 @@ static void fts5NextRowid(Fts5Buffer *pBuf, int *piOff, i64 *piRowid){ static void fts5MergeRowidLists( Fts5Index *p, /* FTS5 backend object */ Fts5Buffer *p1, /* First list to merge */ - Fts5Buffer *p2 /* Second list to merge */ + int nBuf, /* Number of entries in apBuf[] */ + Fts5Buffer *aBuf /* Array of other lists to merge into p1 */ ){ int i1 = 0; int i2 = 0; i64 iRowid1 = 0; i64 iRowid2 = 0; i64 iOut = 0; - + Fts5Buffer *p2 = &aBuf[0]; Fts5Buffer out; + + (void)nBuf; memset(&out, 0, sizeof(out)); + assert( nBuf==1 ); sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n); if( p->rc ) return; @@ -221277,177 +229696,214 @@ static void fts5MergeRowidLists( fts5BufferFree(&out); } +typedef struct PrefixMerger PrefixMerger; +struct PrefixMerger { + Fts5DoclistIter iter; /* Doclist iterator */ + i64 iPos; /* For iterating through a position list */ + int iOff; + u8 *aPos; + PrefixMerger *pNext; /* Next in docid/poslist order */ +}; + +static void fts5PrefixMergerInsertByRowid( + PrefixMerger **ppHead, + PrefixMerger *p +){ + if( p->iter.aPoslist ){ + PrefixMerger **pp = ppHead; + while( *pp && p->iter.iRowid>(*pp)->iter.iRowid ){ + pp = &(*pp)->pNext; + } + p->pNext = *pp; + *pp = p; + } +} + +static void fts5PrefixMergerInsertByPosition( + PrefixMerger **ppHead, + PrefixMerger *p +){ + if( p->iPos>=0 ){ + PrefixMerger **pp = ppHead; + while( *pp && p->iPos>(*pp)->iPos ){ + pp = &(*pp)->pNext; + } + p->pNext = *pp; + *pp = p; + } +} + + /* -** Buffers p1 and p2 contain doclists. This function merges the content -** of the two doclists together and sets buffer p1 to the result before -** returning. -** -** If an error occurs, an error code is left in p->rc. If an error has -** already occurred, this function is a no-op. +** Array aBuf[] contains nBuf doclists. These are all merged in with the +** doclist in buffer p1. */ static void fts5MergePrefixLists( Fts5Index *p, /* FTS5 backend object */ Fts5Buffer *p1, /* First list to merge */ - Fts5Buffer *p2 /* Second list to merge */ -){ - if( p2->n ){ - i64 iLastRowid = 0; - Fts5DoclistIter i1; - Fts5DoclistIter i2; - Fts5Buffer out = {0, 0, 0}; - Fts5Buffer tmp = {0, 0, 0}; - - /* The maximum size of the output is equal to the sum of the two - ** input sizes + 1 varint (9 bytes). The extra varint is because if the - ** first rowid in one input is a large negative number, and the first in - ** the other a non-negative number, the delta for the non-negative - ** number will be larger on disk than the literal integer value - ** was. - ** - ** Or, if the input position-lists are corrupt, then the output might - ** include up to 2 extra 10-byte positions created by interpreting -1 - ** (the value PoslistNext64() uses for EOF) as a position and appending - ** it to the output. This can happen at most once for each input - ** position-list, hence two 10 byte paddings. */ - if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9+10+10) ) return; - fts5DoclistIterInit(p1, &i1); - fts5DoclistIterInit(p2, &i2); + int nBuf, /* Number of buffers in array aBuf[] */ + Fts5Buffer *aBuf /* Other lists to merge in */ +){ +#define fts5PrefixMergerNextPosition(p) \ + sqlite3Fts5PoslistNext64((p)->aPos,(p)->iter.nPoslist,&(p)->iOff,&(p)->iPos) +#define FTS5_MERGE_NLIST 16 + PrefixMerger aMerger[FTS5_MERGE_NLIST]; + PrefixMerger *pHead = 0; + int i; + int nOut = 0; + Fts5Buffer out = {0, 0, 0}; + Fts5Buffer tmp = {0, 0, 0}; + i64 iLastRowid = 0; + + /* Initialize a doclist-iterator for each input buffer. Arrange them in + ** a linked-list starting at pHead in ascending order of rowid. Avoid + ** linking any iterators already at EOF into the linked list at all. */ + assert( nBuf+1<=sizeof(aMerger)/sizeof(aMerger[0]) ); + memset(aMerger, 0, sizeof(PrefixMerger)*(nBuf+1)); + pHead = &aMerger[nBuf]; + fts5DoclistIterInit(p1, &pHead->iter); + for(i=0; in + 9 + 10*nBuf; + + /* The maximum size of the output is equal to the sum of the + ** input sizes + 1 varint (9 bytes). The extra varint is because if the + ** first rowid in one input is a large negative number, and the first in + ** the other a non-negative number, the delta for the non-negative + ** number will be larger on disk than the literal integer value + ** was. + ** + ** Or, if the input position-lists are corrupt, then the output might + ** include up to (nBuf+1) extra 10-byte positions created by interpreting -1 + ** (the value PoslistNext64() uses for EOF) as a position and appending + ** it to the output. This can happen at most once for each input + ** position-list, hence (nBuf+1) 10 byte paddings. */ + if( sqlite3Fts5BufferSize(&p->rc, &out, nOut) ) return; + + while( pHead ){ + fts5MergeAppendDocid(&out, iLastRowid, pHead->iter.iRowid); + + if( pHead->pNext && iLastRowid==pHead->pNext->iter.iRowid ){ + /* Merge data from two or more poslists */ + i64 iPrev = 0; + int nTmp = FTS5_DATA_ZERO_PADDING; + int nMerge = 0; + PrefixMerger *pSave = pHead; + PrefixMerger *pThis = 0; + int nTail = 0; + + pHead = 0; + while( pSave && pSave->iter.iRowid==iLastRowid ){ + PrefixMerger *pNext = pSave->pNext; + pSave->iOff = 0; + pSave->iPos = 0; + pSave->aPos = &pSave->iter.aPoslist[pSave->iter.nSize]; + fts5PrefixMergerNextPosition(pSave); + nTmp += pSave->iter.nPoslist + 10; + nMerge++; + fts5PrefixMergerInsertByPosition(&pHead, pSave); + pSave = pNext; + } + + if( pHead==0 || pHead->pNext==0 ){ + p->rc = FTS5_CORRUPT; + break; + } - while( 1 ){ - if( i1.iRowidp) + (i2.aPoslist-p2->p)+9+10+10) ); - } - else if( i2.iRowid!=i1.iRowid ){ - /* Copy entry from i2 */ - fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); - fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize); - fts5DoclistIterNext(&i2); - if( i2.aPoslist==0 ) break; - assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) ); + /* See the earlier comment in this function for an explanation of why + ** corrupt input position lists might cause the output to consume + ** at most nMerge*10 bytes of unexpected space. */ + if( sqlite3Fts5BufferSize(&p->rc, &tmp, nTmp+nMerge*10) ){ + break; } - else{ - /* Merge the two position lists. */ - i64 iPos1 = 0; - i64 iPos2 = 0; - int iOff1 = 0; - int iOff2 = 0; - u8 *a1 = &i1.aPoslist[i1.nSize]; - u8 *a2 = &i2.aPoslist[i2.nSize]; - int nCopy; - u8 *aCopy; - - i64 iPrev = 0; - Fts5PoslistWriter writer; - memset(&writer, 0, sizeof(writer)); - - /* See the earlier comment in this function for an explanation of why - ** corrupt input position lists might cause the output to consume - ** at most 20 bytes of unexpected space. */ - fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); - fts5BufferZero(&tmp); - sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist + 10 + 10); - if( p->rc ) break; - - sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - assert_nc( iPos1>=0 && iPos2>=0 ); - - if( iPos1=0 && iPos2>=0 ){ - while( 1 ){ - if( iPos1=0 ){ - if( iPos1!=iPrev ){ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); - } - aCopy = &a1[iOff1]; - nCopy = i1.nPoslist - iOff1; - }else{ - assert_nc( iPos2>=0 && iPos2!=iPrev ); - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); - aCopy = &a2[iOff2]; - nCopy = i2.nPoslist - iOff2; - } - if( nCopy>0 ){ - fts5BufferSafeAppendBlob(&tmp, aCopy, nCopy); + pThis = pHead; + pHead = pThis->pNext; + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos); + fts5PrefixMergerNextPosition(pThis); + fts5PrefixMergerInsertByPosition(&pHead, pThis); + + while( pHead->pNext ){ + pThis = pHead; + if( pThis->iPos!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos); } + fts5PrefixMergerNextPosition(pThis); + pHead = pThis->pNext; + fts5PrefixMergerInsertByPosition(&pHead, pThis); + } - /* WRITEPOSLISTSIZE */ - assert_nc( tmp.n<=i1.nPoslist+i2.nPoslist ); - assert( tmp.n<=i1.nPoslist+i2.nPoslist+10+10 ); - if( tmp.n>i1.nPoslist+i2.nPoslist ){ - if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT; - break; + if( pHead->iPos!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pHead->iPos); + } + nTail = pHead->iter.nPoslist - pHead->iOff; + + /* WRITEPOSLISTSIZE */ + assert_nc( tmp.n+nTail<=nTmp ); + assert( tmp.n+nTail<=nTmp+nMerge*10 ); + if( tmp.n+nTail>nTmp-FTS5_DATA_ZERO_PADDING ){ + if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT; + break; + } + fts5BufferSafeAppendVarint(&out, (tmp.n+nTail) * 2); + fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); + if( nTail>0 ){ + fts5BufferSafeAppendBlob(&out, &pHead->aPos[pHead->iOff], nTail); + } + + pHead = pSave; + for(i=0; iiter.aPoslist && pX->iter.iRowid==iLastRowid ){ + fts5DoclistIterNext(&pX->iter); + fts5PrefixMergerInsertByRowid(&pHead, pX); } - fts5BufferSafeAppendVarint(&out, tmp.n * 2); - fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); - fts5DoclistIterNext(&i1); - fts5DoclistIterNext(&i2); - assert_nc( out.n<=(p1->n+p2->n+9) ); - if( i1.aPoslist==0 || i2.aPoslist==0 ) break; - assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) ); } - } - if( i1.aPoslist ){ - fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid); - fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.aEof - i1.aPoslist); - } - else if( i2.aPoslist ){ - fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); - fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist); + }else{ + /* Copy poslist from pHead to output */ + PrefixMerger *pThis = pHead; + Fts5DoclistIter *pI = &pThis->iter; + fts5BufferSafeAppendBlob(&out, pI->aPoslist, pI->nPoslist+pI->nSize); + fts5DoclistIterNext(pI); + pHead = pThis->pNext; + fts5PrefixMergerInsertByRowid(&pHead, pThis); } - assert_nc( out.n<=(p1->n+p2->n+9) ); - - fts5BufferSet(&p->rc, p1, out.n, out.p); - fts5BufferFree(&tmp); - fts5BufferFree(&out); } + + fts5BufferFree(p1); + fts5BufferFree(&tmp); + memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING); + *p1 = out; } static void fts5SetupPrefixIter( Fts5Index *p, /* Index to read from */ int bDesc, /* True for "ORDER BY rowid DESC" */ - const u8 *pToken, /* Buffer containing prefix to match */ + int iIdx, /* Index to scan for data */ + u8 *pToken, /* Buffer containing prefix to match */ int nToken, /* Size of buffer pToken in bytes */ Fts5Colset *pColset, /* Restrict matches to these columns */ Fts5Iter **ppIter /* OUT: New iterator */ ){ Fts5Structure *pStruct; Fts5Buffer *aBuf; - const int nBuf = 32; + int nBuf = 32; + int nMerge = 1; - void (*xMerge)(Fts5Index*, Fts5Buffer*, Fts5Buffer*); + void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); void (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Buffer*); if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ xMerge = fts5MergeRowidLists; xAppend = fts5AppendRowid; }else{ + nMerge = FTS5_MERGE_NLIST-1; + nBuf = nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */ xMerge = fts5MergePrefixLists; xAppend = fts5AppendPoslist; } @@ -221467,6 +229923,27 @@ static void fts5SetupPrefixIter( int bNewTerm = 1; memset(&doclist, 0, sizeof(doclist)); + if( iIdx!=0 ){ + int dummy = 0; + const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT; + pToken[0] = FTS5_MAIN_PREFIX; + fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1); + fts5IterSetOutputCb(&p->rc, p1); + for(; + fts5MultiIterEof(p, p1)==0; + fts5MultiIterNext2(p, p1, &dummy) + ){ + Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; + p1->xSetOutputs(p1, pSeg); + if( p1->base.nData ){ + xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist); + iLastRowid = p1->base.iRowid; + } + } + fts5MultiIterFree(p1); + } + + pToken[0] = FTS5_MAIN_PREFIX + iIdx; fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); fts5IterSetOutputCb(&p->rc, p1); for( /* no-op */ ; @@ -221487,13 +229964,21 @@ static void fts5SetupPrefixIter( if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ - assert( ibase.iRowid; } - for(i=0; irc==SQLITE_OK ){ - xMerge(p, &doclist, &aBuf[i]); + xMerge(p, &doclist, nMerge, &aBuf[i]); + } + for(iFree=i; iFreerc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ - if( nToken ) memcpy(&buf.p[1], pToken, nToken); + int iPrefixIdx = 0; /* +1 prefix index */ + 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 @@ -221783,7 +230273,9 @@ static int sqlite3Fts5IndexQuery( if( flags & FTS5INDEX_QUERY_PREFIX ){ int nChar = fts5IndexCharlen(pToken, nToken); for(iIdx=1; iIdx<=pConfig->nPrefix; iIdx++){ - if( pConfig->aPrefix[iIdx-1]==nChar ) break; + int nIdxChar = pConfig->aPrefix[iIdx-1]; + if( nIdxChar==nChar ) break; + if( nIdxChar==nChar+1 ) iPrefixIdx = iIdx; } } @@ -221800,13 +230292,16 @@ static int sqlite3Fts5IndexQuery( }else{ /* Scan multiple terms in the main index */ int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0; - buf.p[0] = FTS5_MAIN_PREFIX; - fts5SetupPrefixIter(p, bDesc, 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); + fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet); + 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); + } } } @@ -221874,8 +230369,9 @@ static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ int n; const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n); + assert_nc( z || n<=1 ); *pn = n-1; - return &z[1]; + return (z ? &z[1] : 0); } /* @@ -222053,7 +230549,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 ){ @@ -222412,12 +230908,13 @@ static void fts5IndexIntegrityCheckSegment( ** error, or some other SQLite error code if another error (e.g. OOM) ** occurs. */ -static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ +static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum){ int eDetail = p->pConfig->eDetail; u64 cksum2 = 0; /* Checksum based on contents of indexes */ 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 */ @@ -222428,15 +230925,16 @@ static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ /* 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); } } @@ -222473,6 +230971,7 @@ static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ }else{ poslist.n = 0; fts5SegiterPoslist(p, &pIter->aSeg[pIter->aFirst[1].iFirst], 0, &poslist); + fts5BufferAppendBlob(&p->rc, &poslist, 4, (const u8*)"\0\0\0\0"); while( 0==sqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){ int iCol = FTS5_POS2COLUMN(iPos); int iTokOff = FTS5_POS2OFFSET(iPos); @@ -222483,7 +230982,7 @@ static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3); fts5MultiIterFree(pIter); - if( p->rc==SQLITE_OK && cksum!=cksum2 ) p->rc = FTS5_CORRUPT; + if( p->rc==SQLITE_OK && bUseCksum && cksum!=cksum2 ) p->rc = FTS5_CORRUPT; fts5StructureRelease(pStruct); #ifdef SQLITE_DEBUG @@ -222499,6 +230998,7 @@ static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ ** function only. */ +#ifdef SQLITE_TEST /* ** Decode a segment-data rowid from the %_data table. This function is ** the opposite of macro FTS5_SEGMENT_ROWID(). @@ -222521,7 +231021,9 @@ static void fts5DecodeRowid( *piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1)); } +#endif /* SQLITE_TEST */ +#ifdef SQLITE_TEST static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ int iSegid, iHeight, iPgno, bDlidx; /* Rowid compenents */ fts5DecodeRowid(iKey, &iSegid, &bDlidx, &iHeight, &iPgno); @@ -222539,7 +231041,9 @@ static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ ); } } +#endif /* SQLITE_TEST */ +#ifdef SQLITE_TEST static void fts5DebugStructure( int *pRc, /* IN/OUT: error code */ Fts5Buffer *pBuf, @@ -222561,7 +231065,9 @@ static void fts5DebugStructure( sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}"); } } +#endif /* SQLITE_TEST */ +#ifdef SQLITE_TEST /* ** This is part of the fts5_decode() debugging aid. ** @@ -222586,7 +231092,9 @@ static void fts5DecodeStructure( fts5DebugStructure(pRc, pBuf, p); fts5StructureRelease(p); } +#endif /* SQLITE_TEST */ +#ifdef SQLITE_TEST /* ** This is part of the fts5_decode() debugging aid. ** @@ -222609,7 +231117,9 @@ static void fts5DecodeAverages( zSpace = " "; } } +#endif /* SQLITE_TEST */ +#ifdef SQLITE_TEST /* ** Buffer (a/n) is assumed to contain a list of serialized varints. Read ** each varint and append its string representation to buffer pBuf. Return @@ -222626,7 +231136,9 @@ static int fts5DecodePoslist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){ } return iOff; } +#endif /* SQLITE_TEST */ +#ifdef SQLITE_TEST /* ** The start of buffer (a/n) contains the start of a doclist. The doclist ** may or may not finish within the buffer. This function appends a text @@ -222659,7 +231171,9 @@ static int fts5DecodeDoclist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){ return iOff; } +#endif /* SQLITE_TEST */ +#ifdef SQLITE_TEST /* ** This function is part of the fts5_decode() debugging function. It is ** only ever used with detail=none tables. @@ -222700,7 +231214,9 @@ static void fts5DecodeRowidList( sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp); } } +#endif /* SQLITE_TEST */ +#ifdef SQLITE_TEST /* ** The implementation of user-defined scalar function fts5_decode(). */ @@ -222909,7 +231425,9 @@ static void fts5DecodeFunction( } fts5BufferFree(&s); } +#endif /* SQLITE_TEST */ +#ifdef SQLITE_TEST /* ** The implementation of user-defined scalar function fts5_rowid(). */ @@ -222943,6 +231461,7 @@ static void fts5RowidFunction( } } } +#endif /* SQLITE_TEST */ /* ** This is called as part of registering the FTS5 module with database @@ -222953,6 +231472,7 @@ static void fts5RowidFunction( ** SQLite error code is returned instead. */ static int sqlite3Fts5IndexInit(sqlite3 *db){ +#ifdef SQLITE_TEST int rc = sqlite3_create_function( db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0 ); @@ -222970,6 +231490,10 @@ static int sqlite3Fts5IndexInit(sqlite3 *db){ ); } return rc; +#else + return SQLITE_OK; + UNUSED_PARAM(db); +#endif } @@ -223005,7 +231529,9 @@ static int sqlite3Fts5IndexReset(Fts5Index *p){ ** assert() conditions in the fts5 code are activated - conditions that are ** only true if it is guaranteed that the fts5 database is not corrupt. */ +#ifdef SQLITE_DEBUG SQLITE_API int sqlite3_fts5_may_be_corrupt = 1; +#endif typedef struct Fts5Auxdata Fts5Auxdata; @@ -223447,6 +231973,23 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){ #endif } +static int fts5UsePatternMatch( + Fts5Config *pConfig, + struct sqlite3_index_constraint *p +){ + assert( FTS5_PATTERN_GLOB==SQLITE_INDEX_CONSTRAINT_GLOB ); + assert( FTS5_PATTERN_LIKE==SQLITE_INDEX_CONSTRAINT_LIKE ); + if( pConfig->ePattern==FTS5_PATTERN_GLOB && p->op==FTS5_PATTERN_GLOB ){ + return 1; + } + if( pConfig->ePattern==FTS5_PATTERN_LIKE + && (p->op==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB) + ){ + return 1; + } + return 0; +} + /* ** Implementation of the xBestIndex method for FTS5 tables. Within the ** WHERE constraint, it searches for the following: @@ -223476,7 +232019,9 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){ ** ** Match against table column: "m" ** Match against rank column: "r" -** Match against other column: "" +** Match against other column: "M" +** LIKE against other column: "L" +** GLOB against other column: "G" ** Equality constraint against the rowid: "=" ** A < or <= against the rowid: "<" ** A > or >= against the rowid: ">" @@ -223537,7 +232082,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ return SQLITE_ERROR; } - idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 6 + 1); + idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 8 + 1); if( idxStr==0 ) return SQLITE_NOMEM; pInfo->idxStr = idxStr; pInfo->needToFreeIdxStr = 1; @@ -223561,25 +232106,29 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ if( bSeenRank ) continue; idxStr[iIdxStr++] = 'r'; bSeenRank = 1; - }else{ + }else if( iCol>=0 ){ bSeenMatch = 1; - idxStr[iIdxStr++] = 'm'; - if( iColaConstraintUsage[i].argvIndex = ++iCons; pInfo->aConstraintUsage[i].omit = 1; } - } - else if( p->usable && bSeenEq==0 - && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 - ){ - idxStr[iIdxStr++] = '='; - bSeenEq = 1; - pInfo->aConstraintUsage[i].argvIndex = ++iCons; + }else if( p->usable ){ + if( iCol>=0 && iColop==FTS5_PATTERN_LIKE || p->op==FTS5_PATTERN_GLOB ); + idxStr[iIdxStr++] = p->op==FTS5_PATTERN_LIKE ? 'L' : 'G'; + sqlite3_snprintf(6, &idxStr[iIdxStr], "%d", iCol); + idxStr += strlen(&idxStr[iIdxStr]); + pInfo->aConstraintUsage[i].argvIndex = ++iCons; + assert( idxStr[iIdxStr]=='\0' ); + }else if( bSeenEq==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 ){ + idxStr[iIdxStr++] = '='; + bSeenEq = 1; + pInfo->aConstraintUsage[i].argvIndex = ++iCons; + } } } @@ -224212,19 +232761,14 @@ static int fts5FilterMethod( case 'r': pRank = apVal[i]; break; - case 'm': { + case 'M': { const char *zText = (const char*)sqlite3_value_text(apVal[i]); if( zText==0 ) zText = ""; - - if( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ){ - iCol = 0; - do{ - iCol = iCol*10 + (idxStr[iIdxStr]-'0'); - iIdxStr++; - }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ); - }else{ - iCol = pConfig->nCol; - } + iCol = 0; + do{ + iCol = iCol*10 + (idxStr[iIdxStr]-'0'); + iIdxStr++; + }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ); if( zText[0]=='*' ){ /* The user has issued a query of the form "MATCH '*...'". This @@ -224234,7 +232778,7 @@ static int fts5FilterMethod( goto filter_out; }else{ char **pzErr = &pTab->p.base.zErrMsg; - rc = sqlite3Fts5ExprNew(pConfig, iCol, zText, &pExpr, pzErr); + rc = sqlite3Fts5ExprNew(pConfig, 0, iCol, zText, &pExpr, pzErr); if( rc==SQLITE_OK ){ rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); pExpr = 0; @@ -224244,6 +232788,25 @@ static int fts5FilterMethod( break; } + case 'L': + case 'G': { + int bGlob = (idxStr[iIdxStr-1]=='G'); + const char *zText = (const char*)sqlite3_value_text(apVal[i]); + iCol = 0; + do{ + iCol = iCol*10 + (idxStr[iIdxStr]-'0'); + iIdxStr++; + }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ); + if( zText ){ + rc = sqlite3Fts5ExprPattern(pConfig, bGlob, iCol, zText, &pExpr); + } + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); + pExpr = 0; + } + if( rc!=SQLITE_OK ) goto filter_out; + break; + } case '=': pRowidEq = apVal[i]; break; @@ -224318,7 +232881,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); @@ -224491,7 +233055,8 @@ static int fts5SpecialInsert( int nMerge = sqlite3_value_int(pVal); rc = sqlite3Fts5StorageMerge(pTab->pStorage, nMerge); }else if( 0==sqlite3_stricmp("integrity-check", zCmd) ){ - rc = sqlite3Fts5StorageIntegrity(pTab->pStorage); + int iArg = sqlite3_value_int(pVal); + rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, iArg); #ifdef SQLITE_DEBUG }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){ pConfig->bPrefixIndex = sqlite3_value_int(pVal); @@ -224892,13 +233457,15 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){ nInst++; if( nInst>=pCsr->nInstAlloc ){ - pCsr->nInstAlloc = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32; + int nNewSize = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32; aInst = (int*)sqlite3_realloc64( - pCsr->aInst, pCsr->nInstAlloc*sizeof(int)*3 + pCsr->aInst, nNewSize*sizeof(int)*3 ); if( aInst ){ pCsr->aInst = aInst; + pCsr->nInstAlloc = nNewSize; }else{ + nInst--; rc = SQLITE_NOMEM; break; } @@ -225122,7 +233689,8 @@ static int fts5ApiPhraseFirst( int n; int rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n); if( rc==SQLITE_OK ){ - pIter->b = &pIter->a[n]; + assert( pIter->a || n==0 ); + pIter->b = (pIter->a ? &pIter->a[n] : 0); *piCol = 0; *piOff = 0; fts5ApiPhraseNext(pCtx, pIter, piCol, piOff); @@ -225181,7 +233749,8 @@ static int fts5ApiPhraseFirstColumn( rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n); } if( rc==SQLITE_OK ){ - pIter->b = &pIter->a[n]; + assert( pIter->a || n==0 ); + pIter->b = (pIter->a ? &pIter->a[n] : 0); *piCol = 0; fts5ApiPhraseNextColumn(pCtx, pIter, piCol); } @@ -225189,7 +233758,8 @@ static int fts5ApiPhraseFirstColumn( int n; rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n); if( rc==SQLITE_OK ){ - pIter->b = &pIter->a[n]; + assert( pIter->a || n==0 ); + pIter->b = (pIter->a ? &pIter->a[n] : 0); if( n<=0 ){ *piCol = -1; }else if( pIter->a[0]==0x01 ){ @@ -225654,8 +234224,7 @@ static int sqlite3Fts5GetTokenizer( Fts5Global *pGlobal, const char **azArg, int nArg, - Fts5Tokenizer **ppTok, - fts5_tokenizer **ppTokApi, + Fts5Config *pConfig, char **pzErr ){ Fts5TokenizerModule *pMod; @@ -225667,16 +234236,22 @@ static int sqlite3Fts5GetTokenizer( rc = SQLITE_ERROR; *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); }else{ - rc = pMod->x.xCreate(pMod->pUserData, &azArg[1], (nArg?nArg-1:0), ppTok); - *ppTokApi = &pMod->x; - if( rc!=SQLITE_OK && pzErr ){ - *pzErr = sqlite3_mprintf("error in tokenizer constructor"); + rc = pMod->x.xCreate( + pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok + ); + pConfig->pTokApi = &pMod->x; + if( rc!=SQLITE_OK ){ + if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor"); + }else{ + pConfig->ePattern = sqlite3Fts5TokenizerPattern( + pMod->x.xCreate, pConfig->pTok + ); } } if( rc!=SQLITE_OK ){ - *ppTokApi = 0; - *ppTok = 0; + pConfig->pTokApi = 0; + pConfig->pTok = 0; } return rc; @@ -225725,7 +234300,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0ff3f", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2022-02-22 18:58:40 40fa792d359f84c3b9e9d6623743e1a59826274e221df1bde8f47086968a1bab", -1, SQLITE_TRANSIENT); } /* @@ -226276,21 +234851,32 @@ 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, zText, nText, (void*)&ctx, fts5StorageInsertCallback ); p->aTotalSize[iCol-1] -= (i64)ctx.szCol; + if( p->aTotalSize[iCol-1]<0 ){ + rc = FTS5_CORRUPT; + } } } - p->nTotalRow--; + if( rc==SQLITE_OK && p->nTotalRow<1 ){ + rc = FTS5_CORRUPT; + }else{ + p->nTotalRow--; + } rc2 = sqlite3_reset(pSeek); if( rc==SQLITE_OK ) rc = rc2; @@ -226733,13 +235319,14 @@ static int fts5StorageIntegrityCallback( ** some other SQLite error code if an error occurs while attempting to ** determine this. */ -static int sqlite3Fts5StorageIntegrity(Fts5Storage *p){ +static int sqlite3Fts5StorageIntegrity(Fts5Storage *p, int iArg){ Fts5Config *pConfig = p->pConfig; - int rc; /* Return code */ + int rc = SQLITE_OK; /* Return code */ int *aColSize; /* Array of size pConfig->nCol */ i64 *aTotalSize; /* Array of size pConfig->nCol */ Fts5IntegrityCtx ctx; sqlite3_stmt *pScan; + int bUseCksum; memset(&ctx, 0, sizeof(Fts5IntegrityCtx)); ctx.pConfig = p->pConfig; @@ -226748,83 +235335,88 @@ static int sqlite3Fts5StorageIntegrity(Fts5Storage *p){ aColSize = (int*)&aTotalSize[pConfig->nCol]; memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol); - /* Generate the expected index checksum based on the contents of the - ** %_content table. This block stores the checksum in ctx.cksum. */ - rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0); - if( rc==SQLITE_OK ){ - int rc2; - while( SQLITE_ROW==sqlite3_step(pScan) ){ - int i; - ctx.iRowid = sqlite3_column_int64(pScan, 0); - ctx.szCol = 0; - if( pConfig->bColumnsize ){ - rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize); - } - if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){ - rc = sqlite3Fts5TermsetNew(&ctx.pTermset); - } - for(i=0; rc==SQLITE_OK && inCol; i++){ - if( pConfig->abUnindexed[i] ) continue; - ctx.iCol = i; + bUseCksum = (pConfig->eContent==FTS5_CONTENT_NORMAL + || (pConfig->eContent==FTS5_CONTENT_EXTERNAL && iArg) + ); + if( bUseCksum ){ + /* Generate the expected index checksum based on the contents of the + ** %_content table. This block stores the checksum in ctx.cksum. */ + rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0); + if( rc==SQLITE_OK ){ + int rc2; + while( SQLITE_ROW==sqlite3_step(pScan) ){ + int i; + ctx.iRowid = sqlite3_column_int64(pScan, 0); ctx.szCol = 0; - if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ - rc = sqlite3Fts5TermsetNew(&ctx.pTermset); - } - if( rc==SQLITE_OK ){ - const char *zText = (const char*)sqlite3_column_text(pScan, i+1); - int nText = sqlite3_column_bytes(pScan, i+1); - rc = sqlite3Fts5Tokenize(pConfig, - FTS5_TOKENIZE_DOCUMENT, - zText, nText, - (void*)&ctx, - fts5StorageIntegrityCallback - ); + if( pConfig->bColumnsize ){ + rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize); } - if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){ - rc = FTS5_CORRUPT; + if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){ + rc = sqlite3Fts5TermsetNew(&ctx.pTermset); } - aTotalSize[i] += ctx.szCol; - if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ - sqlite3Fts5TermsetFree(ctx.pTermset); - ctx.pTermset = 0; + for(i=0; rc==SQLITE_OK && inCol; i++){ + if( pConfig->abUnindexed[i] ) continue; + ctx.iCol = i; + ctx.szCol = 0; + if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ + rc = sqlite3Fts5TermsetNew(&ctx.pTermset); + } + if( rc==SQLITE_OK ){ + const char *zText = (const char*)sqlite3_column_text(pScan, i+1); + int nText = sqlite3_column_bytes(pScan, i+1); + rc = sqlite3Fts5Tokenize(pConfig, + FTS5_TOKENIZE_DOCUMENT, + zText, nText, + (void*)&ctx, + fts5StorageIntegrityCallback + ); + } + if( rc==SQLITE_OK && pConfig->bColumnsize && ctx.szCol!=aColSize[i] ){ + rc = FTS5_CORRUPT; + } + aTotalSize[i] += ctx.szCol; + if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ + sqlite3Fts5TermsetFree(ctx.pTermset); + ctx.pTermset = 0; + } } - } - sqlite3Fts5TermsetFree(ctx.pTermset); - ctx.pTermset = 0; + sqlite3Fts5TermsetFree(ctx.pTermset); + ctx.pTermset = 0; - if( rc!=SQLITE_OK ) break; + if( rc!=SQLITE_OK ) break; + } + rc2 = sqlite3_reset(pScan); + if( rc==SQLITE_OK ) rc = rc2; } - rc2 = sqlite3_reset(pScan); - if( rc==SQLITE_OK ) rc = rc2; - } - /* Test that the "totals" (sometimes called "averages") record looks Ok */ - if( rc==SQLITE_OK ){ - int i; - rc = fts5StorageLoadTotals(p, 0); - for(i=0; rc==SQLITE_OK && inCol; i++){ - if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT; + /* Test that the "totals" (sometimes called "averages") record looks Ok */ + if( rc==SQLITE_OK ){ + int i; + rc = fts5StorageLoadTotals(p, 0); + for(i=0; rc==SQLITE_OK && inCol; i++){ + if( p->aTotalSize[i]!=aTotalSize[i] ) rc = FTS5_CORRUPT; + } } - } - /* Check that the %_docsize and %_content tables contain the expected - ** number of rows. */ - if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ - i64 nRow = 0; - rc = fts5StorageCount(p, "content", &nRow); - if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT; - } - if( rc==SQLITE_OK && pConfig->bColumnsize ){ - i64 nRow = 0; - rc = fts5StorageCount(p, "docsize", &nRow); - if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT; + /* Check that the %_docsize and %_content tables contain the expected + ** number of rows. */ + if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ + i64 nRow = 0; + rc = fts5StorageCount(p, "content", &nRow); + if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT; + } + if( rc==SQLITE_OK && pConfig->bColumnsize ){ + i64 nRow = 0; + rc = fts5StorageCount(p, "docsize", &nRow); + if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT; + } } /* Pass the expected checksum down to the FTS index module. It will ** verify, amongst other things, that it matches the checksum generated by ** inspecting the index itself. */ if( rc==SQLITE_OK ){ - rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum); + rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum, bUseCksum); } sqlite3_free(aTotalSize); @@ -226904,8 +235496,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); @@ -226918,6 +235511,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; @@ -228266,6 +236861,133 @@ static int fts5PorterTokenize( ); } +/************************************************************************** +** Start of trigram implementation. +*/ +typedef struct TrigramTokenizer TrigramTokenizer; +struct TrigramTokenizer { + int bFold; /* True to fold to lower-case */ +}; + +/* +** Free a trigram tokenizer. +*/ +static void fts5TriDelete(Fts5Tokenizer *p){ + sqlite3_free(p); +} + +/* +** Allocate a trigram tokenizer. +*/ +static int fts5TriCreate( + void *pUnused, + const char **azArg, + int nArg, + Fts5Tokenizer **ppOut +){ + int rc = SQLITE_OK; + TrigramTokenizer *pNew = (TrigramTokenizer*)sqlite3_malloc(sizeof(*pNew)); + UNUSED_PARAM(pUnused); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + int i; + pNew->bFold = 1; + for(i=0; rc==SQLITE_OK && ibFold = (zArg[0]=='0'); + } + }else{ + rc = SQLITE_ERROR; + } + } + if( rc!=SQLITE_OK ){ + fts5TriDelete((Fts5Tokenizer*)pNew); + pNew = 0; + } + } + *ppOut = (Fts5Tokenizer*)pNew; + return rc; +} + +/* +** Trigram tokenizer tokenize routine. +*/ +static int fts5TriTokenize( + Fts5Tokenizer *pTok, + void *pCtx, + int unusedFlags, + const char *pText, int nText, + int (*xToken)(void*, int, const char*, int, int, int) +){ + TrigramTokenizer *p = (TrigramTokenizer*)pTok; + int rc = SQLITE_OK; + char aBuf[32]; + const unsigned char *zIn = (const unsigned char*)pText; + const unsigned char *zEof = &zIn[nText]; + u32 iCode; + + UNUSED_PARAM(unusedFlags); + while( 1 ){ + char *zOut = aBuf; + int iStart = zIn - (const unsigned char*)pText; + const unsigned char *zNext; + + READ_UTF8(zIn, zEof, iCode); + if( iCode==0 ) break; + zNext = zIn; + if( zInbFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); + WRITE_UTF8(zOut, iCode); + READ_UTF8(zIn, zEof, iCode); + if( iCode==0 ) break; + }else{ + break; + } + if( zInbFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); + WRITE_UTF8(zOut, iCode); + READ_UTF8(zIn, zEof, iCode); + if( iCode==0 ) break; + if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); + WRITE_UTF8(zOut, iCode); + }else{ + break; + } + rc = xToken(pCtx, 0, aBuf, zOut-aBuf, iStart, iStart + zOut-aBuf); + if( rc!=SQLITE_OK ) break; + zIn = zNext; + } + + return rc; +} + +/* +** Argument xCreate is a pointer to a constructor function for a tokenizer. +** pTok is a tokenizer previously created using the same method. This function +** returns one of FTS5_PATTERN_NONE, FTS5_PATTERN_LIKE or FTS5_PATTERN_GLOB +** indicating the style of pattern matching that the tokenizer can support. +** In practice, this is: +** +** "trigram" tokenizer, case_sensitive=1 - FTS5_PATTERN_GLOB +** "trigram" tokenizer, case_sensitive=0 (the default) - FTS5_PATTERN_LIKE +** all other tokenizers - FTS5_PATTERN_NONE +*/ +static int sqlite3Fts5TokenizerPattern( + int (*xCreate)(void*, const char**, int, Fts5Tokenizer**), + Fts5Tokenizer *pTok +){ + if( xCreate==fts5TriCreate ){ + TrigramTokenizer *p = (TrigramTokenizer*)pTok; + return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB; + } + return FTS5_PATTERN_NONE; +} + /* ** Register all built-in tokenizers with FTS5. */ @@ -228277,6 +236999,7 @@ static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ { "unicode61", {fts5UnicodeCreate, fts5UnicodeDelete, fts5UnicodeTokenize}}, { "ascii", {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }}, { "porter", {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }}, + { "trigram", {fts5TriCreate, fts5TriDelete, fts5TriTokenize}}, }; int rc = SQLITE_OK; /* Return code */ @@ -229069,8 +237792,10 @@ static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){ } iTbl++; } + aAscii[0] = 0; /* 0x00 is never a token character */ } + /* ** 2015 May 30 ** @@ -229478,6 +238203,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 */ @@ -229791,7 +238517,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); } @@ -229811,6 +238537,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; @@ -229888,9 +238616,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 ){ @@ -230064,6 +238794,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); @@ -230508,10 +239241,6 @@ SQLITE_API int sqlite3_stmt_init( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ -#if __LINE__!=230511 -#undef SQLITE_SOURCE_ID -#define SQLITE_SOURCE_ID "2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0alt2" -#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/ext_libs/sqlite/sqlite3.h b/ext_libs/sqlite/sqlite3.h index 910b687a..34636b9b 100644 --- a/ext_libs/sqlite/sqlite3.h +++ b/ext_libs/sqlite/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.33.0" -#define SQLITE_VERSION_NUMBER 3033000 -#define SQLITE_SOURCE_ID "2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0ff3f" +#define SQLITE_VERSION "3.38.0" +#define SQLITE_VERSION_NUMBER 3038000 +#define SQLITE_SOURCE_ID "2022-02-22 18:58:40 40fa792d359f84c3b9e9d6623743e1a59826274e221df1bde8f47086968a1bab" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -504,6 +527,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) +#define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) @@ -536,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 @@ -549,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() */ @@ -571,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: */ @@ -1127,6 +1166,23 @@ struct sqlite3_io_methods { ** file to the database file, but before the *-shm file is updated to ** record the fact that the pages have been checkpointed. ** +** +**
  • [[SQLITE_FCNTL_EXTERNAL_READER]] +** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect +** whether or not there is a database client in another process with a wal-mode +** transaction open on the database or not. It is only available on unix.The +** (void*) argument passed with this file-control should be a pointer to a +** value of type (int). The integer value is set to 1 if the database is a wal +** mode database and there exists at least one client in another process that +** currently has an SQL transaction open on the database. It is set to 0 if +** the database is not a wal-mode db, or if there is no such connection in any +** other process. This opcode cannot be used to detect transactions opened +** by clients within the current process, only within other processes. +** +** +**
  • [[SQLITE_FCNTL_CKSM_FILE]] +** Used by the cksmvfs VFS module only. +** */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 @@ -1166,6 +1222,8 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_CKPT_DONE 37 #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 +#define SQLITE_FCNTL_EXTERNAL_READER 40 +#define SQLITE_FCNTL_CKSM_FILE 41 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE @@ -2114,7 +2172,13 @@ struct sqlite3_mem_methods { ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in -** which case the trigger setting is not reported back. +** which case the trigger setting is not reported back. +** +**

    Originally this option disabled all triggers. ^(However, since +** SQLite version 3.35.0, TEMP triggers are still allowed even if +** this option is off. So, in other words, this option now only disables +** triggers in the main database schema or in the schemas of ATTACH-ed +** databases.)^ ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] **

    SQLITE_DBCONFIG_ENABLE_VIEW
    @@ -2125,7 +2189,13 @@ struct sqlite3_mem_methods { ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether views are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in -** which case the view setting is not reported back. +** which case the view setting is not reported back. +** +**

    Originally this option disabled all views. ^(However, since +** SQLite version 3.35.0, TEMP views are still allowed even if +** this option is off. So, in other words, this option now only disables +** views in the main database schema or in the schemas of ATTACH-ed +** databases.)^ ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] **

    SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
    @@ -2432,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], @@ -2485,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 @@ -2522,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 @@ -3351,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
    ** )^ @@ -3358,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 @@ -3498,6 +3593,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** that uses dot-files in place of posix advisory locking. **
  • file:data.db?mode=readonly ** An error. "readonly" is not a valid option for the "mode" parameter. +** Use "ro" instead: "file:data.db?mode=ro". **
    ** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and @@ -3696,7 +3792,7 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*); ** If the Y parameter to sqlite3_free_filename(Y) is anything other ** than a NULL pointer or a pointer previously acquired from ** sqlite3_create_filename(), then bad things such as heap -** corruption or segfaults may occur. The value Y should be +** corruption or segfaults may occur. The value Y should not be ** used again after sqlite3_free_filename(Y) has been called. This means ** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y, ** then the corresponding [sqlite3_module.xClose() method should also be @@ -3728,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 @@ -3749,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. @@ -3768,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 @@ -4125,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 @@ -4165,6 +4275,19 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); ** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and ** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so ** sqlite3_stmt_readonly() returns false for those commands. +** +** ^This routine returns false if there is any possibility that the +** statement might change the database file. ^A false return does +** not guarantee that the statement will change the database file. +** ^For example, an UPDATE statement might have a WHERE clause that +** makes it a no-op, but the sqlite3_stmt_readonly() result would still +** 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); @@ -4233,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 @@ -4334,18 +4459,22 @@ typedef struct sqlite3_context sqlite3_context; ** contain embedded NULs. The result of expressions involving strings ** with embedded NULs is undefined. ** -** ^The fifth argument to the BLOB and string binding interfaces -** is a destructor used to dispose of the BLOB or -** string after SQLite has finished with it. ^The destructor is called -** to dispose of the BLOB or string even if the call to the bind API fails, -** except the destructor is not called if the third parameter is a NULL -** pointer or the fourth parameter is negative. -** ^If the fifth argument is -** the special value [SQLITE_STATIC], then SQLite assumes that the -** information is in static, unmanaged space and does not need to be freed. -** ^If the fifth argument has the value [SQLITE_TRANSIENT], then -** SQLite makes its own private copy of the data immediately, before -** the sqlite3_bind_*() routine returns. +** ^The fifth argument to the BLOB and string binding interfaces controls +** or indicates the lifetime of the object referenced by the third parameter. +** These three options exist: +** ^ (1) A destructor to dispose of the BLOB or string after SQLite has finished +** with it may be passed. ^It is called to dispose of the BLOB or string even +** if the call to the bind API fails, except the destructor is not called if +** the third parameter is a NULL pointer or the fourth parameter is negative. +** ^ (2) The special constant, [SQLITE_STATIC], may be passsed to indicate that +** the application remains responsible for disposing of the object. ^In this +** case, the object and the provided pointer to it must remain valid until +** either the prepared statement is finalized or the same SQL parameter is +** bound to something else, whichever occurs sooner. +** ^ (3) The constant, [SQLITE_TRANSIENT], may be passed to indicate that the +** object is to be copied prior to the return from sqlite3_bind_*(). ^The +** object and pointer to it must remain valid until then. ^SQLite will then +** manage the lifetime of its private copy. ** ** ^The sixth argument to sqlite3_bind_text64() must be one of ** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] @@ -5087,7 +5216,6 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, ** index expressions, or the WHERE clause of partial indexes. ** -** ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** all application-defined SQL functions that do not need to be ** used inside of triggers, view, CHECK constraints, or other elements of @@ -5097,7 +5225,6 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** a database file to include invocations of the function with parameters ** chosen by the attacker, which the application will then execute when ** the database file is opened and read. -** ** ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ @@ -6186,6 +6313,57 @@ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); */ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); +/* +** CAPI3REF: Determine the transaction state of a database +** METHOD: sqlite3 +** +** ^The sqlite3_txn_state(D,S) interface returns the current +** [transaction state] of schema S in database connection D. ^If S is NULL, +** then the highest transaction state of any schema on database connection D +** is returned. Transaction states are (in order of lowest to highest): +**
      +**
    1. SQLITE_TXN_NONE +**
    2. SQLITE_TXN_READ +**
    3. SQLITE_TXN_WRITE +**
    +** ^If the S argument to sqlite3_txn_state(D,S) is not the name of +** a valid schema, then -1 is returned. +*/ +SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema); + +/* +** CAPI3REF: Allowed return values from [sqlite3_txn_state()] +** KEYWORDS: {transaction state} +** +** These constants define the current transaction state of a database file. +** ^The [sqlite3_txn_state(D,S)] interface returns one of these +** constants in order to describe the transaction state of schema S +** in [database connection] D. +** +**
    +** [[SQLITE_TXN_NONE]]
    SQLITE_TXN_NONE
    +**
    The SQLITE_TXN_NONE state means that no transaction is currently +** pending.
    +** +** [[SQLITE_TXN_READ]]
    SQLITE_TXN_READ
    +**
    The SQLITE_TXN_READ state means that the database is currently +** in a read transaction. Content has been read from the database file +** but nothing in the database file has changed. The transaction state +** will advanced to SQLITE_TXN_WRITE if any changes occur and there are +** no other conflicting concurrent write transactions. The transaction +** state will revert to SQLITE_TXN_NONE following a [ROLLBACK] or +** [COMMIT].
    +** +** [[SQLITE_TXN_WRITE]]
    SQLITE_TXN_WRITE
    +**
    The SQLITE_TXN_WRITE state means that the database is currently +** in a write transaction. Content has been written to the database file +** but has not yet committed. The transaction state will change to +** to SQLITE_TXN_NONE at the next [ROLLBACK] or [COMMIT].
    +*/ +#define SQLITE_TXN_NONE 0 +#define SQLITE_TXN_READ 1 +#define SQLITE_TXN_WRITE 2 + /* ** CAPI3REF: Find the next prepared statement ** METHOD: sqlite3 @@ -6252,6 +6430,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 @@ -6893,24 +7137,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]. -*/ -#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 +** +** ^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_LIMIT 73 +#define SQLITE_INDEX_CONSTRAINT_OFFSET 74 +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 /* ** CAPI3REF: Register A Virtual Table Implementation @@ -6939,7 +7215,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()] @@ -7712,7 +7988,11 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_RESULT_INTREAL 27 #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 -#define SQLITE_TESTCTRL_LAST 29 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_SEEK_COUNT 30 +#define SQLITE_TESTCTRL_TRACEFLAGS 31 +#define SQLITE_TESTCTRL_TUNE 32 +#define SQLITE_TESTCTRL_LOGEST 33 +#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -8235,6 +8515,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 @@ -8249,6 +8539,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 /* @@ -8912,8 +9204,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. */ @@ -9192,10 +9485,11 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); ** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE ** ** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] -** method of a [virtual table], then it returns true if and only if the +** method of a [virtual table], then it might return true if the ** column is being fetched as part of an UPDATE operation during which the -** column value will not change. Applications might use this to substitute -** a return value that is less expensive to compute and that the corresponding +** column value will not change. The virtual table implementation can use +** this hint as permission to substitute a return value that is less +** expensive to compute and that the corresponding ** [xUpdate] method understands as a "no-change" value. ** ** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that @@ -9204,24 +9498,280 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); ** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. ** In that case, [sqlite3_value_nochange(X)] will return true for the ** same column in the [xUpdate] method. +** +** The sqlite3_vtab_nochange() routine is an optimization. Virtual table +** implementations should continue to give a correct answer even if the +** sqlite3_vtab_nochange() interface were to always return false. In the +** current implementation, the sqlite3_vtab_nochange() interface does always +** returns false for the enhanced [UPDATE FROM] statement. */ 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 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: ** -** 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. +**
      +**
    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 appreviation 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} @@ -9345,6 +9895,7 @@ SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* ** CAPI3REF: Flush caches to disk mid-transaction +** METHOD: sqlite3 ** ** ^If a write-transaction is open on [database connection] D when the ** [sqlite3_db_cacheflush(D)] interface invoked, any dirty @@ -9377,6 +9928,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); /* ** CAPI3REF: The pre-update hook. +** METHOD: sqlite3 ** ** ^These interfaces are only available if SQLite is compiled using the ** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option. @@ -9417,7 +9969,7 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** seventh parameter is the final rowid value of the row being inserted ** or updated. The value of the seventh parameter passed to the callback ** function is not defined for operations on WITHOUT ROWID tables, or for -** INSERT operations on rowid tables. +** DELETE operations on rowid tables. ** ** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], ** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces @@ -9455,6 +10007,15 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*); ** triggers; or 2 for changes resulting from triggers called by top-level ** triggers; and so forth. ** +** When the [sqlite3_blob_write()] API is used to update a blob column, +** the pre-update hook is invoked with SQLITE_DELETE. This is because the +** in this case the new values are not available. In this case, when a +** callback made with op==SQLITE_DELETE is actuall a write using the +** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns +** the index of the column being written. In other cases, where the +** pre-update hook is being invoked for some other reason, including a +** regular DELETE, sqlite3_preupdate_blobwrite() returns -1. +** ** See also: [sqlite3_update_hook()] */ #if defined(SQLITE_ENABLE_PREUPDATE_HOOK) @@ -9475,10 +10036,12 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); SQLITE_API int sqlite3_preupdate_count(sqlite3 *); SQLITE_API int sqlite3_preupdate_depth(sqlite3 *); SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); +SQLITE_API int sqlite3_preupdate_blobwrite(sqlite3 *); #endif /* ** CAPI3REF: Low-level system error code +** METHOD: sqlite3 ** ** ^Attempt to return the underlying operating system error code or error ** number that caused the most recent I/O error or failure to open a file. @@ -9712,8 +10275,8 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c ** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory ** allocation error occurs. ** -** This interface is only available if SQLite is compiled with the -** [SQLITE_ENABLE_DESERIALIZE] option. +** This interface is omitted if SQLite is compiled with the +** [SQLITE_OMIT_DESERIALIZE] option. */ SQLITE_API unsigned char *sqlite3_serialize( sqlite3 *db, /* The database connection */ @@ -9760,12 +10323,16 @@ 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. ** -** This interface is only available if SQLite is compiled with the -** [SQLITE_ENABLE_DESERIALIZE] option. +** This interface is omitted if SQLite is compiled with the +** [SQLITE_OMIT_DESERIALIZE] option. */ SQLITE_API int sqlite3_deserialize( sqlite3 *db, /* The database connection */ @@ -10014,6 +10581,38 @@ SQLITE_API int sqlite3session_create( */ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); +/* +** CAPIREF: Conigure a Session Object +** METHOD: sqlite3_session +** +** This method is used to configure a session object after it has been +** created. At present the only valid value for the second parameter is +** [SQLITE_SESSION_OBJCONFIG_SIZE]. +** +** Arguments for sqlite3session_object_config() +** +** The following values may passed as the the 4th parameter to +** sqlite3session_object_config(). +** +**
    SQLITE_SESSION_OBJCONFIG_SIZE
    +** This option is used to set, clear or query the flag that enables +** the [sqlite3session_changeset_size()] API. Because it imposes some +** computational overhead, this API is disabled by default. Argument +** pArg must point to a value of type (int). If the value is initially +** 0, then the sqlite3session_changeset_size() API is disabled. If it +** is greater than 0, then the same API is enabled. Or, if the initial +** value is less than zero, no change is made. In all cases the (int) +** variable is set to 1 if the sqlite3session_changeset_size() API is +** enabled following the current call, or 0 otherwise. +** +** It is an error (SQLITE_MISUSE) to attempt to modify this setting after +** the first table has been attached to the session object. +*/ +SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); + +/* +*/ +#define SQLITE_SESSION_OBJCONFIG_SIZE 1 /* ** CAPI3REF: Enable Or Disable A Session Object @@ -10258,6 +10857,22 @@ SQLITE_API int sqlite3session_changeset( void **ppChangeset /* OUT: Buffer containing changeset */ ); +/* +** CAPI3REF: Return An Upper-limit For The Size Of The Changeset +** METHOD: sqlite3_session +** +** By default, this function always returns 0. For it to return +** a useful result, the sqlite3_session object must have been configured +** to enable this API using sqlite3session_object_config() with the +** SQLITE_SESSION_OBJCONFIG_SIZE verb. +** +** When enabled, this function returns an upper limit, in bytes, for the size +** of the changeset that might be produced if sqlite3session_changeset() were +** called. The final changeset size might be equal to or smaller than the +** size in bytes returned by this function. +*/ +SQLITE_API sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession); + /* ** CAPI3REF: Load The Difference Between Tables Into A Session ** METHOD: sqlite3_session @@ -10375,6 +10990,14 @@ SQLITE_API int sqlite3session_patchset( */ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession); +/* +** CAPI3REF: Query for the amount of heap memory used by a session object. +** +** This API returns the total amount of heap memory in bytes currently +** used by the session object passed as the only argument. +*/ +SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession); + /* ** CAPI3REF: Create An Iterator To Traverse A Changeset ** CONSTRUCTOR: sqlite3_changeset_iter @@ -10477,18 +11100,23 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter); ** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this ** is not the case, this function returns [SQLITE_MISUSE]. ** -** If argument pzTab is not NULL, then *pzTab is set to point to a -** nul-terminated utf-8 encoded string containing the name of the table -** affected by the current change. The buffer remains valid until either -** sqlite3changeset_next() is called on the iterator or until the -** conflict-handler function returns. If pnCol is not NULL, then *pnCol is -** set to the number of columns in the table affected by the change. If -** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change +** Arguments pOp, pnCol and pzTab may not be NULL. Upon return, three +** outputs are set through these pointers: +** +** *pOp is set to one of [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], +** depending on the type of change that the iterator currently points to; +** +** *pnCol is set to the number of columns in the table affected by the change; and +** +** *pzTab is set to point to a nul-terminated utf-8 encoded string containing +** the name of the table affected by the current change. The buffer remains +** valid until either sqlite3changeset_next() is called on the iterator +** or until the conflict-handler function returns. +** +** If pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change ** is an indirect change, or false (0) otherwise. See the documentation for ** [sqlite3session_indirect()] for a description of direct and indirect -** changes. Finally, if pOp is not NULL, then *pOp is set to one of -** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the -** type of change that the iterator currently points to. +** changes. ** ** If no error occurs, SQLITE_OK is returned. If an error does occur, an ** SQLite error code is returned. The values of the output variables may not diff --git a/include/mtcr_ul/mtcr.h b/include/mtcr_ul/mtcr.h index cb770f55..fb960545 100644 --- a/include/mtcr_ul/mtcr.h +++ b/include/mtcr_ul/mtcr.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2013 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -140,6 +141,8 @@ int maccess_reg(mfile *mf, // if you dont know what you are doing then r_size_reg = w_size_reg = your_register_size int *reg_status); +int is_livefish_device(mfile *mf); + int icmd_send_command(mfile *mf, int opcode, void *data, int data_size, int skip_write); int icmd_clear_semaphore(mfile *mf); @@ -173,6 +176,8 @@ int mvpd_read4(mfile *mf, unsigned int offset, u_int8_t value[4]); int mvpd_write4(mfile *mf, unsigned int offset, u_int8_t value[4]); +int is_pci_device(mfile* mf); + MTCR_API int MWRITE4_SEMAPHORE(mfile* mf, int offset, int value); MTCR_API int MREAD4_SEMAPHORE(mfile* mf, int offset, u_int32_t* ptr); diff --git a/include/mtcr_ul/mtcr_com_defs.h b/include/mtcr_ul/mtcr_com_defs.h index 6d70dfa2..fc2b365a 100644 --- a/include/mtcr_ul/mtcr_com_defs.h +++ b/include/mtcr_ul/mtcr_com_defs.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2013 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -39,11 +40,15 @@ #include #include +#ifdef __AARCH64EL__ +#define MTCR_API +#else #ifdef MTCR_EXPORTS #define MTCR_API __declspec(dllexport) #else #define MTCR_API __declspec(dllimport) #endif +#endif #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) #include @@ -459,7 +464,14 @@ typedef void (*f_mpci_change) (mfile *mf); #define GEARBOX_SLAVE_ADDR 0x48 #define GB_MNGR_SLAVE_ADDR 0x33 +typedef enum { + GB_UNKNOWN = 0, + GB_AMOS, + GB_ABIR +} gearbox_type; + typedef struct gearbox_info_t { + gearbox_type gb_type; u_int8_t is_gearbox; u_int8_t is_gb_mngr; int gearbox_index; diff --git a/include/mtcr_ul/mtcr_mf.h b/include/mtcr_ul/mtcr_mf.h index 6c4246de..d162c54a 100644 --- a/include/mtcr_ul/mtcr_mf.h +++ b/include/mtcr_ul/mtcr_mf.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2013-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2013 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/libmfa/Makefile.am b/libmfa/Makefile.am index c5ffe905..13371ba0 100644 --- a/libmfa/Makefile.am +++ b/libmfa/Makefile.am @@ -1,5 +1,6 @@ #-- -# Copyright (c) 2004-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2004-2010 Mellanox Technologies LTD. All rights reserved. +# Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # This software is available to you under a choice of one of two # licenses. You may choose to be licensed under the terms of the GNU @@ -35,7 +36,7 @@ USER_DIR = $(top_srcdir) #INCLUDES = -I. -I$(USER_DIR)/ext_libs/libtar -I$(USER_DIR)/ext_libs/libtar/listhash -I$(USER_DIR)/ext_libs/minixz INCLUDES = -I. -I$(USER_DIR)/ext_libs/minixz -I$(USER_DIR)/common -AM_CFLAGS = -MD -pipe -Wall -W -g $(COMPILER_FPIC) +AM_CFLAGS = -MD -pipe -Wall -W -g -Werror $(COMPILER_FPIC) noinst_LTLIBRARIES = libmfa.a libmfa_a_LIBADD = -L$(USER_DIR)/ext_libs/minixz -lminixz diff --git a/libmfa/mfa.c b/libmfa/mfa.c index 3080e8c0..4622e7cc 100644 --- a/libmfa/mfa.c +++ b/libmfa/mfa.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2006 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/libmfa/mfa.h b/libmfa/mfa.h index 575be898..cf52caa9 100644 --- a/libmfa/mfa.h +++ b/libmfa/mfa.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2006 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/libmfa/mfa_section.c b/libmfa/mfa_section.c index d8bdd63a..65d229d7 100644 --- a/libmfa/mfa_section.c +++ b/libmfa/mfa_section.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2006 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/libmfa/mfa_section.h b/libmfa/mfa_section.h index 7b6dfee3..4dcf585a 100644 --- a/libmfa/mfa_section.h +++ b/libmfa/mfa_section.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2006 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/libmfa/mfaerr.h b/libmfa/mfaerr.h index 683c7fc2..4c6a04e6 100644 --- a/libmfa/mfaerr.h +++ b/libmfa/mfaerr.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2006 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/libmfa/test.c b/libmfa/test.c index 534acff5..3ad28d5b 100644 --- a/libmfa/test.c +++ b/libmfa/test.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2006 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/libmfa/xz_io_ops.c b/libmfa/xz_io_ops.c index 192c39ec..670b5908 100644 --- a/libmfa/xz_io_ops.c +++ b/libmfa/xz_io_ops.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2006 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU @@ -183,6 +184,8 @@ ssize_t xz_stream_len(u_int8_t *buffer, ssize_t len) total_unpadded += unpadded; total_uncompressed += uncompressed; } + (void)total_unpadded; + (void)total_uncompressed; //printf("Totals: Unpadded: %8u Uncompressed: %8u\n", total_unpadded, total_uncompressed); return total_uncompressed; diff --git a/libmfa/xz_io_ops.h b/libmfa/xz_io_ops.h index 9c222327..5461d3e7 100644 --- a/libmfa/xz_io_ops.h +++ b/libmfa/xz_io_ops.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2006 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/libmfa/xz_io_ops_llzma.c b/libmfa/xz_io_ops_llzma.c index 0821eea5..3e0e80c9 100644 --- a/libmfa/xz_io_ops_llzma.c +++ b/libmfa/xz_io_ops_llzma.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2006-2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (C) Jan 2006 Mellanox Technologies Ltd. All rights reserved. + * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * This software is available to you under a choice of one of two * licenses. You may choose to be licensed under the terms of the GNU diff --git a/mad_ifc/Makefile.am b/mad_ifc/Makefile.am index 4224173f..08d10429 100644 --- a/mad_ifc/Makefile.am +++ b/mad_ifc/Makefile.am @@ -37,7 +37,7 @@ MTCR_INC_DIR = $(top_srcdir)/include/mtcr_ul INCLUDES = -I. -I.. -I$(MTCR_INC_DIR) -I../${MTCR_CONF_DIR} -I$(USER_DIR)/tools_ayouts/ -AM_CFLAGS = -W -Wall -g -MP -MD $(COMPILER_FPIC) +AM_CFLAGS = -W -Wall -Werror -g -MP -MD $(COMPILER_FPIC) noinst_LIBRARIES = libmad_ifc.a diff --git a/mflash/Makefile.am b/mflash/Makefile.am index 652055ef..581fc908 100644 --- a/mflash/Makefile.am +++ b/mflash/Makefile.am @@ -34,7 +34,7 @@ AM_CPPFLAGS = -I. -I$(top_srcdir)/include/mtcr_ul -I$(top_srcdir)/common -I$(top_srcdir)/tools_layouts -I$(top_srcdir)/reg_access \ -I$(top_srcdir)/cmdif -I$(top_srcdir)/tools_res_mgmt $(COMPILER_FPIC) -AM_CFLAGS = -MD -pipe -Wall -W -DMST_UL -g ${MFLASH_INBAND_FLAG} $(COMPILER_FPIC) +AM_CFLAGS = -MD -pipe -Wall -W -Werror -DMST_UL -g ${MFLASH_INBAND_FLAG} $(COMPILER_FPIC) noinst_LTLIBRARIES = libmflash.a diff --git a/mflash/mflash_dev_capability.c b/mflash/mflash_dev_capability.c index f5ccc951..18fe515f 100644 --- a/mflash/mflash_dev_capability.c +++ b/mflash/mflash_dev_capability.c @@ -172,4 +172,3 @@ int is_icmdif_supported(mflash *mfl, MfError *status, int *is7NmSuppported) return 1; } } - diff --git a/mflash/mflash_new_gw.c b/mflash/mflash_new_gw.c index 1c6ab890..8fde9873 100644 --- a/mflash/mflash_new_gw.c +++ b/mflash/mflash_new_gw.c @@ -46,12 +46,12 @@ if (reacDebug != NULL) { printf("\33[2K\r"); \ printf("[FLASH_DEBUG]: -D- "); printf args; fflush(stdout);} } while (0) #ifdef __WIN__ - // - // Windows (Under DDK) - // -#define OP_NOT_SUPPORTED EINVAL -#define usleep(x) Sleep(((x + 999) / 1000)) - + // + // Windows (Under DDK) + // +#define OP_NOT_SUPPORTED EINVAL +#define usleep(x) Sleep(((x + 999) / 1000)) + #endif // __WIN_ #define CHECK_RC_REL_SEM(mfl, rc) do {if (rc) {release_semaphore(mfl, 0); return rc;}} while (0) diff --git a/mft_utils/Makefile.am b/mft_utils/Makefile.am index 93c7f5a4..da5286f8 100644 --- a/mft_utils/Makefile.am +++ b/mft_utils/Makefile.am @@ -34,7 +34,9 @@ USER_DIR = $(top_srcdir) AM_CPPFLAGS = -I. -I$(USER_DIR)/common $(COMPILER_FPIC) -AM_CFLAGS = -MD -pipe -Wall -W $(COMPILER_FPIC) +AM_CFLAGS = -MD -pipe -Wall -W -Werror $(COMPILER_FPIC) + +AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe -Werror $(COMPILER_FPIC) noinst_HEADERS = mft_sig_handler.h errmsg.h diff --git a/mft_utils/hsmclient/Makefile.am b/mft_utils/hsmclient/Makefile.am index a0244966..58f17a2c 100644 --- a/mft_utils/hsmclient/Makefile.am +++ b/mft_utils/hsmclient/Makefile.am @@ -34,7 +34,7 @@ USER_DIR = $(top_srcdir) AM_CPPFLAGS = -I$(USER_DIR)/common -Iinc -Iinc/rsa $(COMPILER_FPIC) -DUNIX -DOS_UNIX -DOS_LINUX -AM_CFLAGS = -MD -pipe -Wall -W $(COMPILER_FPIC) +AM_CFLAGS = -Wall -W -g -MP -MD -pipe -Werror $(COMPILER_FPIC) noinst_HEADERS = diff --git a/mlxarchive/Makefile.am b/mlxarchive/Makefile.am index 39e02e2e..9fac02f7 100755 --- a/mlxarchive/Makefile.am +++ b/mlxarchive/Makefile.am @@ -63,8 +63,10 @@ libmstarchive_a_SOURCES = \ mlxarchive_mfa2_package_gen.h mlxarchive_mfa2_package_gen.cpp\ mfa2_buff.h mfa2_buff.cpp -AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe $(INCLUDES) $(COMPILER_FPIC) -bin_PROGRAMS = mstarchive +AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe -Werror $(INCLUDES) -pthread $(COMPILER_FPIE) +AM_LDFLAGS = $(COMPILER_PIE_LINK) + +bin_PROGRAMS = mlxarchive mstarchive_SOURCES = mlxarchive.cpp mlxarchive.h mstarchive_LDADD = libmstarchive.a\ diff --git a/mlxarchive/mlxarchive_mfa2_extension.h b/mlxarchive/mlxarchive_mfa2_extension.h index a5619a7a..84e2e50b 100644 --- a/mlxarchive/mlxarchive_mfa2_extension.h +++ b/mlxarchive/mlxarchive_mfa2_extension.h @@ -240,6 +240,6 @@ class PSIDExtension : public StringExtension { explicit PSIDExtension(string psid) : StringExtension(ELEMENT_VERSION, PSIDExtensionType, psid) {}; }; - } #endif + diff --git a/mlxconfig/Makefile.am b/mlxconfig/Makefile.am index 499e3bad..53625fea 100755 --- a/mlxconfig/Makefile.am +++ b/mlxconfig/Makefile.am @@ -53,7 +53,7 @@ AM_CPPFLAGS = -I. -I$(USER_DIR) -I$(top_srcdir)/include/mtcr_ul -I$(MTCR_DIR) -I -I$(LAYOUTS_DIR) -I$(UTILS_DIR) -I$(DEV_MGT_DIR) -I$(CMDIF_DIR) -I$(TOOLS_RES_MGMT_DIR) $(MUPARSER_CFLAGS) $(SQLITE_CFLAGS) $(COMPILER_FPIC) -AM_CXXFLAGS = -pthread -Wall -W -g -MP -MD -pipe -Wno-deprecated-declarations $(COMPILER_FPIC) -DDATA_PATH=\"$(pkgdatadir)\" +AM_CXXFLAGS = -pthread -Wall -W -g -MP -MD -pipe -Werror -Wno-deprecated-declarations $(COMPILER_FPIC) -DDATA_PATH=\"$(pkgdatadir)\" bin_PROGRAMS = mstconfig MLXPRIVHOST_PYTHON_WRAPPER=mstprivhost bin_SCRIPTS = ${MLXPRIVHOST_PYTHON_WRAPPER} diff --git a/mlxconfig/mlxcfg_commander.cpp b/mlxconfig/mlxcfg_commander.cpp index fa736d72..ef786a49 100644 --- a/mlxconfig/mlxcfg_commander.cpp +++ b/mlxconfig/mlxcfg_commander.cpp @@ -47,7 +47,7 @@ using namespace std; -Commander* Commander::create(std::string device, std::string dbName) +Commander* Commander::create(std::string device, std::string dbName, bool forceCreate) { mfile *mf; int rc; @@ -61,8 +61,10 @@ Commander* Commander::create(std::string device, std::string dbName) if (rc) { throw MlxcfgException("Failed to get device type"); } - if (type & (MST_USB | MST_USB_DIMAX)) { - throw MlxcfgException("MTUSB device is not supported."); + if(!forceCreate) { + if (type & (MST_USB | MST_USB_DIMAX)) { + throw MlxcfgException("MTUSB device is not supported."); + } } Commander *cmdr = NULL; diff --git a/mlxconfig/mlxcfg_commander.h b/mlxconfig/mlxcfg_commander.h index 9aba74c7..48044a3a 100644 --- a/mlxconfig/mlxcfg_commander.h +++ b/mlxconfig/mlxcfg_commander.h @@ -46,7 +46,7 @@ class Commander { public: - static Commander* create(std::string device, std::string dbName); + static Commander* create(std::string device, std::string dbName, bool forceCreate = false); //clients can force create skiping any support check, and move the responsebility to the client. static Commander* create(mfile *mf, std::string device, std::string dbName); virtual void printLongDesc(FILE*) = 0; virtual bool isDefaultSupported() = 0; diff --git a/mlxconfig/mlxcfg_generic_commander.cpp b/mlxconfig/mlxcfg_generic_commander.cpp index 0c49ba39..98566f77 100644 --- a/mlxconfig/mlxcfg_generic_commander.cpp +++ b/mlxconfig/mlxcfg_generic_commander.cpp @@ -1365,6 +1365,10 @@ void GenericCommander::checkConfTlvs(const vector& tlvs, bool csCompFound = false; bool foundApplicableTLV = false; bool idMlnxCompFound = false; + compsId = FwComponent::COMPID_UNKNOWN; + u_int32_t type = 0; + mget_mdevs_type(_mf, &type); + CONST_VECTOR_ITERATOR(TLVConf*, tlvs, it) { const TLVConf *tlv = *it; if (tlv->_tlvClass == NVFile && @@ -1394,8 +1398,14 @@ void GenericCommander::checkConfTlvs(const vector& tlvs, } else if (tlv->_name == "file_applicable_to") { foundApplicableTLV = true; } + + if ( (type & (MST_USB | MST_USB_DIMAX)) && + (compsId == FwComponent::COMPID_UNKNOWN)) { //MST_USB tlv's must have component + throw MlxcfgException("MTUSB device is not supported."); + } } + if (!dbgCompFound && !csCompFound && !idMlnxCompFound) { throw MlxcfgException("Unsupported device: No debug tokens or CS tokens or MLNX ID Components were found for this device"); } diff --git a/mlxconfig/mlxcfg_param.cpp b/mlxconfig/mlxcfg_param.cpp index 9976d49c..31d87fa7 100644 --- a/mlxconfig/mlxcfg_param.cpp +++ b/mlxconfig/mlxcfg_param.cpp @@ -566,8 +566,9 @@ u_int32_t UnsignedParamValue::getIntVal() void UnsignedParamValue::parseValueAux(string strToParse, u_int32_t& value, string& strValue, int base) { if (strToNum(strToParse, value, base)) { - if ((_size == 32 && value == MLXCFG_UNKNOWN) || - ((_size != 32) && value > (unsigned)((1 << _size) - 1))) { + if ( (_size == 32) && (value == MLXCFG_UNKNOWN)){ + throw MlxcfgException("The value %s is reserved and cannot be used" ,strToParse.c_str(), _size); + }else if( (_size != 32) && (value > (unsigned)((1 << _size) - 1)) ) { throw MlxcfgException("The value %s is not valid, as its size is %d bits", strToParse.c_str(), _size); } diff --git a/mlxconfig/mlxcfg_parser.cpp b/mlxconfig/mlxcfg_parser.cpp index e887b1d2..4339ba51 100644 --- a/mlxconfig/mlxcfg_parser.cpp +++ b/mlxconfig/mlxcfg_parser.cpp @@ -55,8 +55,7 @@ using namespace std; #define IDENT2 IDENT IDENT #define IDENT3 "\t\t" #define IDENT4 IDENT2 IDENT - -#define MAX_SESSION_TIME_IN_MINUTES 10080 // 1 week = 7 * 24 hours * 60 minutes +#define MAX_SESSION_TIME_IN_MINUTES 10080 // 1 week = 7 * 24 hours * 60 minutes static void printFlagLine(string flag_s, string flag_l, string param, string desc) @@ -146,8 +145,8 @@ void MlxCfg::printHelp() printf(IDENT "Supported devices:\n"); printf(IDENT2 "4th Generation devices: ConnectX3, ConnectX3-Pro (FW 2.31.5000 and above).\n"); printf(IDENT2 "5th Generation devices: ConnectIB, ConnectX4, ConnectX4-LX, ConnectX5, connectX5-Ex.\n"); - printf(IDENT2 "6th Generation devices: BlueField, COnnectX6, ConnectX6-DX\n"); - printf(IDENT2 "Switches: Switch-IB, Switch-IB2,Spectrum, Spectrum2, Quantum\n"); + printf(IDENT2 "6th Generation devices: BlueField, BlueField2, ConnectX6, ConnectX6-DX, ConnectX6-LX\n"); + printf(IDENT2 "Switches: Switch-IB, Switch-IB2,Spectrum, Spectrum2, Spectrum3, Quantum, Quantum2\n"); printf("\n"); printf(IDENT "Note: query device to view supported configurations by Firmware.\n"); @@ -579,6 +578,7 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) if (i != argc && (_mlxParams.cmd == Mc_Reset)) { return err(true, "%s command expects no argument but %d argument received", "reset", argc - i); } + if ((_mlxParams.cmd == Mc_Set || _mlxParams.cmd == Mc_Clr_Sem || _mlxParams.cmd == Mc_Set_Raw || _mlxParams.cmd == Mc_Backup || _mlxParams.cmd == Mc_ShowConfs || _mlxParams.cmd == Mc_Apply || _mlxParams.cmd == Mc_RemoteTokenKeepAlive || _mlxParams.cmd == Mc_ChallengeRequest || _mlxParams.cmd == Mc_TokenSupported || _mlxParams.cmd == Mc_QueryTokenSession diff --git a/mlxconfig/mlxcfg_ui.cpp b/mlxconfig/mlxcfg_ui.cpp index b35800a2..83d43674 100644 --- a/mlxconfig/mlxcfg_ui.cpp +++ b/mlxconfig/mlxcfg_ui.cpp @@ -199,7 +199,7 @@ void MlxCfg::printErr() bool MlxCfg::askUser(const char *question, bool add_prefix, bool add_suffix) { const char * prefix = ""; - if(add_prefix){ + if(add_prefix) { prefix = "\n "; } @@ -670,7 +670,7 @@ mlxCfgStatus MlxCfg::setDevCfg() //for mlx_config_name VECTOR_ITERATOR(ParamView, _mlxParams.setParams, p) { const char * warning_msg = getConfigWarning(p->mlxconfigName, p->setVal); - if(warning_msg){ + if(warning_msg) { if(!askUser(warning_msg, false, false)) { delete commander; printErr(); @@ -1340,7 +1340,7 @@ mlxCfgStatus MlxCfg::apply() copyDwVectorToBytesVector(buff, bytesBuff); try { - commander = Commander::create(_mlxParams.device, _mlxParams.dbName); + commander = Commander::create(_mlxParams.device, _mlxParams.dbName, true); printf("Applying...\n"); ((GenericCommander*)commander)->apply(bytesBuff); } catch (MlxcfgException& e) { @@ -1371,7 +1371,7 @@ mlxCfgStatus MlxCfg::remoteTokenKeepAlive() return MLX_CFG_ERROR; } - if ((mf->flags & MDEVS_IB) == 0) { //not IB device + if ((mf->flags & (MDEVS_IB)) == 0) { //not IB device return err(true, "specified device is not an IB device.\n"); } @@ -1397,7 +1397,7 @@ mlxCfgStatus MlxCfg::remoteTokenKeepAlive() return status; } -bool MlxCfg::runMTCQ(mfile* mf, struct reg_access_switch_mtcq_reg_ext* mtcq_reg) +void MlxCfg::runMTCQ(mfile* mf, struct reg_access_switch_mtcq_reg_ext* mtcq_reg) { reg_access_status_t rc = ME_REG_ACCESS_OK; @@ -1405,10 +1405,8 @@ bool MlxCfg::runMTCQ(mfile* mf, struct reg_access_switch_mtcq_reg_ext* mtcq_reg) rc = reg_access_mtcq(mf, REG_ACCESS_METHOD_GET, mtcq_reg); dealWithSignal(); if (rc) { - return err(true, "failed getting response from the device, error %d.", rc); + throw MlxcfgException("Failed getting response from the device.\n"); } - - return true; } void MlxCfg::printArray(const u_int32_t arr[], int len) @@ -1425,18 +1423,17 @@ void MlxCfg::printArray(const u_int32_t arr[], int len) printf("\n"); } -void MlxCfg::printHexArrayAsAscii(const u_int32_t arr[], int len) +void MlxCfg::printHexArrayAsAscii(const u_int32_t arr[], int len) { - u_int8_t byteArray[4]; + u_int8_t byteArray[4]; int i = 0, j = 0; if (len < 0) { throw MlxcfgException("Invalid array length was given.\n"); - } + } for (i = 0; i < len; ++i) { - - memcpy(byteArray, &arr[i], 4); + memcpy(byteArray, &arr[i], 4); for (j = 3; j >= 0; --j) { printf("%c", byteArray[j]); } @@ -1447,23 +1444,19 @@ void MlxCfg::printHexArrayAsAscii(const u_int32_t arr[], int len) mlxCfgStatus MlxCfg::getChallenge() { u_int32_t base_mac[2]; - mfile *mf = mopen(_mlxParams.device.c_str()); if (!mf) { - printf("-E- failed to open the device.\n"); - return MLX_CFG_ERROR; + throw MlxcfgException("-E- failed to open the device.\n"); } - if ((mf->flags & MDEVS_IB) == 0) { //not IB device - return err(true, "specified device is not an IB device.\n"); + if ((mf->flags & (MDEVS_IB)) == 0) { //not IB device + throw MlxcfgException("Specified device is not an IB device.\n"); } struct reg_access_switch_mtcq_reg_ext mtcq_reg; memset(&mtcq_reg, 0, sizeof(mtcq_reg)); mtcq_reg.token_opcode = _mlxParams.tokenID; - if (!runMTCQ(mf, &mtcq_reg)) { - return MLX_CFG_ERROR; - } + runMTCQ(mf, &mtcq_reg); base_mac[0] = mtcq_reg.base_mac & 0xffffffff; base_mac[1] = (mtcq_reg.base_mac >> 32) & 0xffffffff; @@ -1488,8 +1481,7 @@ mlxCfgStatus MlxCfg::queryTokenSupport() { mfile *mf = mopen(_mlxParams.device.c_str()); if (!mf) { - printf("-E- failed opening the device.\n"); - return MLX_CFG_ERROR; + throw MlxcfgException("-E- failed to open the device.\n"); } tools_open_mcam mcam; @@ -1497,7 +1489,7 @@ mlxCfgStatus MlxCfg::queryTokenSupport() reg_access_status_t rc = ME_REG_ACCESS_OK; rc = reg_access_mcam(mf, REG_ACCESS_METHOD_GET, &mcam); if (rc) { - return err(true, "failed getting response from the device, error %d.", rc); + throw MlxcfgException("Failed getting response from the device.\n"); } printf("CS tokens supported: %d\n", EXTRACT(mcam.mng_feature_cap_mask[2], 6, 1)); @@ -1506,33 +1498,29 @@ mlxCfgStatus MlxCfg::queryTokenSupport() return MLX_CFG_OK; } -bool MlxCfg::runMDSR(mfile* mf, struct reg_access_switch_mdsr_reg_ext* mdsr_reg, reg_access_method_t method) +void MlxCfg::runMDSR(mfile* mf, struct reg_access_switch_mdsr_reg_ext* mdsr_reg, reg_access_method_t method) { reg_access_status_t rc = ME_REG_ACCESS_OK; mft_signal_set_handling(1); rc = reg_access_mdsr(mf, method, mdsr_reg); dealWithSignal(); - + if (rc) { - return err(true, "failed getting response from the device, error %d.", rc); + throw MlxcfgException("Failed getting response from the device.\n"); } - - return true; } mlxCfgStatus MlxCfg::queryTokenSession() { mfile *mf = mopen(_mlxParams.device.c_str()); if (!mf) { - return err(true, "failed opening the device."); + throw MlxcfgException("Failed opening the device.\n"); } struct reg_access_switch_mdsr_reg_ext mdsr_reg; memset(&mdsr_reg, 0, sizeof(mdsr_reg)); - if (!runMDSR(mf, &mdsr_reg, REG_ACCESS_METHOD_GET)) { - return MLX_CFG_ERROR; - } + runMDSR(mf, &mdsr_reg, REG_ACCESS_METHOD_GET); processMDSRData(mdsr_reg, true); return MLX_CFG_OK; @@ -1569,16 +1557,13 @@ mlxCfgStatus MlxCfg::endTokenSession() { mfile *mf = mopen(_mlxParams.device.c_str()); if (!mf) { - return err(true, "failed opening the device."); + throw MlxcfgException("-E- failed to open the device.\n"); } struct reg_access_switch_mdsr_reg_ext mdsr_reg; memset(&mdsr_reg, 0, sizeof(mdsr_reg)); mdsr_reg.end = 1; - if (!runMDSR(mf, &mdsr_reg, REG_ACCESS_METHOD_SET)) { - return MLX_CFG_ERROR; - } - + runMDSR(mf, &mdsr_reg, REG_ACCESS_METHOD_SET); processMDSRData(mdsr_reg, false); return MLX_CFG_OK; @@ -1670,6 +1655,7 @@ mlxCfgStatus MlxCfg::execute(int argc, char *argv[]) case Mc_EndTokenSession: ret = endTokenSession(); break; + default: // should not reach here. return err(true, "invalid command."); @@ -1692,14 +1678,14 @@ int main(int argc, char *argv[]) } } -const char* KeepAliveSession::_mkdcErrorToString[5] = {"OK", "BAD_SESSION_ID", "BAD_KEEP_ALIVE_COUNTER", +const char* KeepAliveSession::_mkdcErrorToString[5] = {"OK", "BAD_SESSION_ID", "BAD_KEEP_ALIVE_COUNTER", "BAD_SOURCE_ADDRESS", "SESSION_TIMEOUT"}; -const u_int32_t KeepAliveSession::_keepAliveTimestampInSec = 600; +const u_int32_t KeepAliveSession::_keepAliveTimestampInSec = 600; KeepAliveSession::KeepAliveSession(mfile *mf, u_int16_t sessionId, u_int32_t sessionTimeInSec): - _mf(mf), - _sessionId(sessionId), + _mf(mf), + _sessionId(sessionId), _sessionTimeLeftInSec(sessionTimeInSec), _SleepTimeOnCommandTO(1), _SleepTimeBetweenCommands(300) @@ -1758,26 +1744,25 @@ keepAliveStatus KeepAliveSession::runMKDC(mfile* mf, reg_access_switch_mkdc_reg_ { reg_access_status_t rc = ME_REG_ACCESS_OK; time_t start = 0; - int status = 0; start = time(NULL); mft_signal_set_handling(1); rc = reg_access_mkdc(mf, REG_ACCESS_METHOD_GET, mkdc_reg); dealWithSignal(); timer = time(NULL) - start; - + while ((rc == ME_ICMD_STATUS_EXECUTE_TO) && ((u_int32_t)timer < _keepAliveTimestampInSec)) { u_int32_t sleep_time_in_sec = _SleepTimeOnCommandTO; - + msleep(sleep_time_in_sec * 1000); - + mft_signal_set_handling(1); - rc = reg_access_mkdc(mf, REG_ACCESS_METHOD_GET, mkdc_reg); + rc = reg_access_mkdc(mf, REG_ACCESS_METHOD_GET, mkdc_reg); dealWithSignal(); - + timer = time(NULL) - start; } - + if (rc == ME_REG_ACCESS_REG_NOT_SUPP) { return err(true, "MKDC access register is not supported."); } diff --git a/mlxconfig/mlxcfg_ui.h b/mlxconfig/mlxcfg_ui.h index 9031bffc..8518057a 100644 --- a/mlxconfig/mlxcfg_ui.h +++ b/mlxconfig/mlxcfg_ui.h @@ -85,7 +85,7 @@ typedef enum { } Device_Type; typedef enum { - KEEP_ALIVE_OK, + KEEP_ALIVE_OK, KEEP_ALIVE_ERROR } keepAliveStatus; @@ -113,7 +113,7 @@ class MlxCfgParams isSessionIDGiven(false), sessionTimeInSec(600), isSessionTimeGiven(false), keepAliveSleepTimeBetweenCommands(0), isSleepTimeBetweenCommandsInput(false), keepAliveSleepTimeOnCommandTO(0), isSleepTimeOnCommandTOInput(false) {} - + ~MlxCfgParams() {} std::string device; @@ -153,14 +153,16 @@ class KeepAliveSession void setSleepTimeBetweenCommands(u_int32_t sleepTime); private: + keepAliveStatus runMKDC(mfile* mf, reg_access_switch_mkdc_reg_ext* mkdc_reg, time_t& timer); keepAliveStatus processMKDCData(reg_access_switch_mkdc_reg_ext* mkdc_reg); keepAliveStatus err(bool report, const char *fmt, ...); + static const char* _mkdcErrorToString[5]; static const u_int32_t _keepAliveTimestampInSec; - + mfile* _mf; u_int16_t _sessionId; u_int32_t _sessionTimeLeftInSec; @@ -244,8 +246,8 @@ class MlxCfg mlxCfgStatus queryTokenSession(); mlxCfgStatus endTokenSession(); void processMDSRData(const struct reg_access_switch_mdsr_reg_ext& mdsr_reg, bool isQuery); - bool runMDSR(mfile* mf, struct reg_access_switch_mdsr_reg_ext* mdsr_reg, reg_access_method_t method); - bool runMTCQ(mfile* mf, struct reg_access_switch_mtcq_reg_ext* mtcq_reg); + void runMDSR(mfile* mf, struct reg_access_switch_mdsr_reg_ext* mdsr_reg, reg_access_method_t method); + void runMTCQ(mfile* mf, struct reg_access_switch_mtcq_reg_ext* mtcq_reg); void printArray(const u_int32_t arr[], int len); void printHexArrayAsAscii(const u_int32_t arr[], int len); mlxCfgToken getTokenType(const char* tokenStr); @@ -261,6 +263,7 @@ class MlxCfg mlxCfgStatus err(bool report, const char *errMsg, ...); void printErr(); // data members + MlxCfgParams _mlxParams; std::string _errStr; MlxCfgAllInfo _allInfo; diff --git a/mlxconfig/mlxcfg_utils.cpp b/mlxconfig/mlxcfg_utils.cpp index 605666ab..7ca93426 100644 --- a/mlxconfig/mlxcfg_utils.cpp +++ b/mlxconfig/mlxcfg_utils.cpp @@ -438,7 +438,7 @@ bool getDeviceInformationString(const char* dev, info_type_t op, vector& i int maxDataSize = sizeof(mqisRegister.info_string); memset(&mqisRegister, 0, sizeof(mqisReg)); - if (op == Device_Name){ + if (op == Device_Name) { mqisRegister.info_type = 0x1; } else if (op == Device_Description) { mqisRegister.info_type = 0x2; @@ -485,7 +485,8 @@ bool getDeviceInformationString(const char* dev, info_type_t op, vector& i } } - mclose(mf); + // mf is needed to be open for QueryTLV function + // mclose(mf); string str = string (infoString.data()); if (str.length() == 0) { return false; diff --git a/mlxconfig/mlxconfig_dbs/mlxconfig_host.db b/mlxconfig/mlxconfig_dbs/mlxconfig_host.db index bee46d81d7adfb746afdb2af54513830b1dbdbb4..543bfe2bca2ef9502b361843abe70715a19082d5 100644 GIT binary patch delta 52854 zcmcHi2Y6M*_6CgaHM93QCxo8fNbez)G(rm@KxhdGAP5oy2@px6geruShLyG@gNle) zu2=wxaBLtbVn?u`pdwhXU_q~4k?)<^pj^rQ|L^a6o-dr|oi(#(&z?SO)><>H{5)vo z=RrH&b$YeEv%Z60bI3VI(`c`A8gPqq9B`>~FmR+Z5g6z60cuXJY1-4ZfCnc5mJbDt zNdxqX00i}5KpP)Ri2Dlvl)ua$+9^AiANK>^(6Je%*v{Y(#rDEg%vgBwe$Mz z>g?_?D)?{whl`mUv{QeDhVNh19WOo8RLtn8=C8dRi@eO^GuT~h1C6AQcr3fXma$ki zjF$2|W@E3h2kB1!6va?iekXm!o2gy!uH|0bLln2!c{iNdos_nZu* z{8QeCr6pqu^maVE){FOMMZ+hR7Uz!3FCCp*GP1NNMbE;M zDMGwKy}G>wveDog<42LTr^FUNo1YlyZ?kpMe#4`C0(dqPs|)Pj!TK*O1|ig^2ajZ9 z#*Z#799lXque2zW??dpjV%l`>Ij|3#!3Jpf^+1^X11W1j)7s@n^f!>edJh!4xM)~u zZh@7pqIA^3G(34!oNnfUk#{h306Nf}hqEDhgC~~e<>w>Ud@7rxxv8`OpKWmJK|X1` zh5cLWWCgOr>_JVw`M$`t**yX?m~7&F`CW#>X)%(bHW{N%)Ya-iwnrqLAnI0eub@nx z#_Kfs8-#y#T4#+9*Wy&lbd5MwX@rONVP){YEUR>IVd1#aA%m^T9#T9(m!JAwto>Q{ zi^*Uc;fa=C)AsO>H2$gPsnWRw2*Y<*igV|gr*R$V#bV3X%*Q>A`6Il)s`Asfk#~3U zy7Y>21J>pGbVruaShoQwg}=>j`+H2xCbxbUlkxSYI}kHM0lV3GUAO@oK)Azi#IGHkO#UKs7Q1ayf5RuFh{(uEEzU z*Ty$WH{H%R%XatHp2k$7ozQ+Gf6AsQR8Je}X*$ljvEi(aZDjk|=iGy5@@f1={)9+A zrI%wEMcIOka14C2>^dKsVV=qfHp+vI;NIr>NdYw6yslp_8fMy$l zznLQj#Mz$>H-hneLyCc(B4TzzA=CcE0=|S_W0g3dy889%Eo;LdrjGzO%2I<|q z+q9D!U&_8`c_`5k?W7qx{N>v6Y>(&^KOeusiw&)54u@l5SrsOtikb!UDl6uzd8xc& zVdad9()yapx%Cyvi<1*mlO^^UTreiLc+!~q>gg5pLTYD*SP?Ld^{%O{nNbmPF^%FZ z50CVK0G~87G&j7xZtSfrss~NhXfid^BlHIS%EH)aHlJ-`&$6?;yQ^mcjV7wp(3Yka`bKCeRddNI7K88HZU&qJU zAF*B&x2&aJjJlg6Cd9Zu_*YUXLMG+YvkR)wuHB(=Z`Oo5-a)n6d)gi7@huGl26_0U z1o-*LDAu0?bH1#h)Q+k*1NGY{d2woTV)EcgxxqK|6fY=&(y5MtSb87 z3f1s`DOJD!R;uKGluG3z<%*{2o`XX9{YO(ZbkJ5Ere@X9|5m8~Lzxk ze_?2G9%2_Rn2jk0GgCbhE}K^oQd}{=V&1}va(uHtKAwP-;HFrkFh>J>mw?%NA|0e= zrsZH5M)Jm?!`h#`dMGsv82aBDIlZH57;?ehy1rf_4!AktnoPb zimuxu?|&)PKT}iVAou^$b^lM}aqxdDRoXvFrSg$=WmDx|QK*i_W5=oeUuK#AeL#9S zWG}U8DH<5`Xe8h+PnJGIl=@8m;$X(~0+{q!<@!+Np| zHlEe94Qw}ioBhbWc)HkB&Jx7VG+rdWE?~(4-}xCH@eWpAwgmi@s$6gZ)m1f%>2|aB z<^bAi-gI*qm73dc4yWnBP|kUUa&Cr`=W~_o;0w$LZ|P-A0Y?-| z=8jwZ>@5Eh?d#xd(%&APRsZcVnDcLsjcxebV`tm`_Bhzy5FFid#YGJO?NPwsIh}IQNBG2Z&#MIPn%QVqr3iDyvJE;oS1Mwse!N#z~Y%6<}{lr7~0A9{-<-7UYXq8KUs&hElKJ#&Oj!(@K zYa(f#C>+6Jj2I)Sx0`r$0Sl)tZS^b~U8<{cIqL>DmbxpS!Fnjy#(FB(&OD^s;9#Dy zMpDX^Oj-vEe@@3SJ79eJcO3Id#;>7bV8>BAnCEgkj@iLHpVx8B4%Ruh{2;>%o3--U zf?l_IGW}L@uAW8GyTW@ROR`@bV#J4n zQo6=`eDQ9Y(q6M9foO939ZMf2?5;*%cgStJ=dg4?pCIQfbIS@(GkN(#RA#=v{3)7d zZd|d~t<*C&-3L#z)zgS$QRc>m2We(|-pU0;7445Z-y0A8lCJ8795z_l2_ z!L!>}w1g7PYTwd2lREd;*c$qoDz!JY{$L^ExznTCtTs)!RpyxMH_#mOlk0D0Ue}tx z-5{v4ef^E|sNrUc)F_f-DG?juEb32#X&7dQu`~f2o@rD;*WyzPXbG*LCc2((q4gwa z6WxtY`w;D<-58wDfNgn+4%3_TE`2~B(P#7(eMdjh?@VI`>x9jyC-Y;ySU8Jey;&;D zWc^q!8_GtqB6iJqb~P(y<*bs`U{AG}EoY5v6{ekatc~5lwy^uKC*Q#yV^6Ss>^b%# zWJGVUci8*vG&{r2vUBW5_8Yr^?Y$fCik+@658`1wnkVoSp22g(=3gkk{kjcTQDVN% zH5w{mn1taH3M7n>FjB%O38N*9F;BMnx=)bgRT3teB*M@LX(Fs)z6@9(pELU=nl?t5-mAFZ3QuJztYZR_kxL%>D@K%Kz6t*e66X?aXdz9y1h4(4E z-<)>a)w?!UP=ibPA6NK98+3J)lJR^f9B4=Q|7;VTM{DmTap!tWLSsPHF=q$wnYOd(gOE9|VWi^8r7 zyD98vn9tq*{;V?PnXYh#!g7Tb3TG;urEs>wN`==doTIQxVYR{b{bf@z+*s`0dn=YTuIw^`VKF)Z1t;eT}}K%nI2o*1{e}$Nd%^G=pEwmvEEs5Xr+? zABbZ@9HE8}BnC4VnFj{?iL2U;Q2Xy8Mx+!gCGTavd^*#`Q|(4CUPk975zLrPyx(qw z(;w0a4WG^oKO+cJ)U0|iLA7=BFN&NhYbxoQC?gtEn_2y7FvAA__lJ|{DKq|&P)t6f z9|-|-R`Wb^&56= zI;qoq^TRDq)4cXgcXuV4+y2nj8b*xKG5xvViup^NEWuDv-N?(cXBUuo=Cia3| zp)bX$EDEP{(vghmPZpu`KPct4xs$ycoDOL3g(ffm8_ z5R1_D2uUPRjODlK2^L}3lP$ub_gTO5Yg*d=&CabvOWN1%YGA1T9=n&&b>>aGpLAPh zRawgS}HpLY_>b9y4#Od%OREGGb0!`*qJYQ;2h#)9?(E&FgIFpVGzp zgREfQ{MnV&rFApSK?i&&%{<+l6BDy&c0~<@LuCugDyyVSC^lq4Z3y=1Ar*@kRLrX> zs|uN2JAXl<>3vhMIsK+czv7bN1*5Ir*j;0@=rJkEZwhgCYWF_468%ty|D@G=aX-20sA@m&HL8BJCJ;$JYcjx{L|Icxm@Gb z>@Ai{yQs71ek&{1oe|Dh^Y>r=MKR_*zurgDX2EZ(DaxGuLxA|#7(HBsa5Bt*-wP?y zob&qz-Pz3RBpnn9nMOSA785g#D0)sbWEu&yM?5TjkBc{@&n4mu!Ox8sk0r1enkYU<024h< zP;ZuE9~*D+!4Aj{XK0%=9>rR**Pf?sLf5}h zcNRMn#ZscTskbO%;KLHcaYi>%yeQ|iNq0_g#+jkN9P^Z~+q4*Ha@dnhr>WZGTFkm! zPuk5x3R15~aA>P6ZcEvoq^3*al{3dFx+N0X%)Dx9nA?k(mT7Y<;zu>wu*HTp{a5?dDZ~#M#$p7`d6~ zI@iWf64PEWpZFt|2ALoK5k z{(Xv(iMMMOR#%ANM(QP2k0FOc`!3N)%0{A{XHax!?QDV(51)#(;{%(o7%++4nD&Wz z^v@Lf%H$VP=yNmuLMnY}&c2Xs|02;yL7HuID7vS1PWBXCo29XT(^>6;HVfVCD&6Vn z%o2;cfWyxe-Mi9R%5eSBm2}b@-JI#J3Z2|Y32(f$VVbs4dr`YUy|G!S$F6)BUV56o zVBRc;O@Suu5%xO!jmPp*-o~FGC6UEWpdNSwwWQ)-Csgg*gGRtq%%Z0PmmP)fMzeB%PeAa3UrNhE) zl`YQpZnV)G5{a@^vTifQTHO|fRC6qX>jN!9*YhmG(1%%sO&@6ycD+y%F}9LqBRAen zgc`Oure7si8nz^)bhSlr{TfAd)Aebx9hel7*(?E>2kA{SoI_nfVe~QS&V|l=p?lF! zZJx~LctXQKeOP+}t@M!YtaTQM?NQjX4i{UZX`0?t?HuMx2%)d3?FT~->!wZ8_;dVv zehu%#i5*0945DAL`K_c7?YOo@n}lT2Sbmz=m_S1*6*8$_0>j!L)2nZ9gd}6(py8Ax z9+197@vZdr7Fmh#C5VPZ_~ONjiPX1qoO?Et0yJ`@IYi1N@)i-0T2ZVRltiiE=;kM( z<3)>2N$8_d;)Nv2W;u~&R#i@04A#SuVnPf(OCwxQX^kj-68tsZt!DL3GT!&KW z1fxRN-RTgw(iqnh8QAK#^~0i4EROY~Z)mJ|zCU_zk!$(@%3w6kb=x4C#W1;39$ko& zov9~q6N+XB%VO7IZ*v-3@E9=1br4!TE<$!1zlb_;y3FV-X5~Djvu|p?(rabFk(bZsN#DmPBufg4>KdNMLTc%}Bza z-g}$T$NpiM5gG5s#NE&70gPWGoVOdHP?=A&2+n6%gwAJ5A{;Y=ieckb7GdYL7UAIY z+J;~vxmqL+fzEuAxOWJ-u=Y>M$Hwg{aXg<|Xo4smO54B}xDBJ9i)7&=v=R-!-PkC6 zto;ZJf=Gx<#$%~yrY)HJj-bwMED)mW5p0&WR@=&!GLvm*FGEY*g(vbNRL(lSi@&8U z;Ah3yQ50@F8lcM=sH~Q}qP4?4bj*g>L{!YEn<EGQ$k5zU$Gv+O+TTrWPentf9ISvwcw=*BVF+KHY_1rQ_ zsID!qNcYv#@c8sz=7H{T-5Bz>#Rurvma1-Oiwn{7K+l~`evY!b-l2NF|_!T15&H%x3}X$I!c)$}h&q>j_SSy$~D?Ffrw zLlEs>5Hc-fH$tSe6Kean**Dz5BY7Uy^hNv@elLHDzab_(#=@~54-o5$$a~UHKCpF? zl`ppirFHWv7g`opKX%vAk!ARdGSy12TxvHJARFmrA04t(xgD&kSX^3HHV?`_88txF zvFWVwu=)F=|LiV)LE$ZNh0rieF3Kwdgo)Q_Z__Kd^C*=f2*d^VWv zMOvn~dkT4of#V@gEfZ(PLy9`hwR-|BCu62(O17WqHi`U1(L_jDD}?(bI!5KLk0udh z9Wz|tU5%IMTCs5oAe zF+H0ST8fis+Mn;WLbm3m|@uR5AzLNg;SHi`YM<~Du zRWY|eNzRMWr})c~`8(K3CRUuno8S!Kc-yV7#|eKJHyX(yFsc+g=3|!CehA~k6zwIt zSCWHi{}#*NAitECzSE}VdNaI!bMCYws@Kd|+4koy25FCQ$=E!SgS+x$H97RiO!*^*nnG4^8k00%kx8vXMS%V|;? zqb}muNn18UtM&NM2BxC(#i!ffl20?lnh$N+_H;;no}8?)i)>6Q*tOQACkRvVhz;0)_H>=zKm~*;Iq?Abh{1yP zjk5SDSf$r$&6?15XwN}G{iXH?d18GS3~k`Gw2anb>-Z$rh)*ySWr+C{_c2}AXI z^^u`*>Z7pL#z!XPjw%?UwO;&+jEZFBm-YF6Je`?ypZ9FgZoKUA#f<3-E{2t;ys0nh z^Q3(?-XB*uE_W14rPr!_!PY!?{J6r>G5N!!sd@U9fvI}-m4Rt`e-$VWy-D3BrL>l(xAbcTOQ2uo6 z$`z4;UAZDMu`5?ZmR=$T{HgcC@PiY`Q}wA?@;3A|@^nqR9TWGSdubezk8AvW(2|h1YY7+~xsIdT`iLL?v<0{xc|h)A z{j3iB{x+y;d|enP(=W-V)@#~&ZNK&n*2X~)Ro(~-*SFAVdqL(=$<{I#W-0?(;u5}; z-=i$Or;2{-^>}XM$rfSf8H#W?c)xHX7Q)>+6U7BbZR%mzbV6_;3CWZTi=IQq(QB@;+AB_c z_OeW4n51Ktr`V>)8vR4v#HqU}obeaM&buiF?eVHbaDK!hbpDn_82nvH#NmL2ifZSl zEW*J**|Q(Q1W0L6@9%;aQxkUZv$AHRUDeN_+Kq(2+u^N)vK`_@_#sqp+{G$CB&$40 zjCcuQiLTQx$tv%CvC3b8{3_KI^(t5uNR+0$MyDy+HQ+EEq9Gx$CDLw$2xmW2uAJjo;AALv%q3QbY4ni~ZQQjQ{XX-`b z$OYXid7PZ0i;4>hOULC718Y2Xd_i&k5G)fk-;?*IqGBuuMY+W#`K7~(bBl)06-Sra zLa@%HSwt!uW)W!&0!{g-5399^bk-z^FcOwOlRab+S?n3{;WAq^kAsceWvq_K$> z(T7!8L^@k3i4eNg@@KLKEFz0NEk67Ts^3N8{8uc%SlEjXWa800m=bAks*^8B-`gTm znQz-$XtoS-`&;C4Pxs8p10(1303$c(V=x#C-ljXKkLZ334V&hA?HFZJuP$hI?IRos zn*qt)+psq%f_Uv9Ay3N7e*M@$d8Y`j`ASHZhIf{_r9*s_pw_>Rz`k6 zKX=aZEL6qx(F&J~+>eo;>JPvW)t-b9C(~8%p`2g_itA2+gC8JrPSZN%dg>!u>XzdAJn>`NJ{T6)Pw};U z7AnaNjLUrx4dubi@ke|@&}_=leuAOnLM;bV*x!HIL)|l(hnp16rZ~iD2u#G*Pax#Y z7kfW}dEyZ9+b5Xg@bsmUAPF4cF9p=$-o+9E5 zR?Rf`P_MSnk@Rp8`8l>b!$kGxFzOmAUizF$k?q(oXeP3~ z_6w+R^27&UKyNTu^!t+LBHP=)gm7VyYy4R(pEOz={+|3?JHEndN~0{#r(a{Aj#ZDo z#WXiU6n=|Er9j;EE#|KYBI6w9ukm8#Iec}Tc<~%o;1ZGe9RiER;_o1+8!KLxz9QlI zJ!~xs#a!u(ap5yB5acFpKOhrRgyTnuS0{_9KSJPqwRrJIX@x3g{DjGEqHz60_drxT z`DfY|)<8CmY}haLgg&wt3LJ+z%Rrk9hGcyVSc$7m$Hr5xLlxvl4N89qJu~!&TR6c5j$aaMK<#EM@jys%I`C{j39VX?vz zh2s>CS2#i8RSG96oTTt-g_9LxkN+zTZ~Fsctr=qe9}rAU7vKFsS3_Dg>O9raG_m(Q z1V^Q!9R_@&y(KrQPrsVA;7y)VzQJ zze(Ki0t>X?8*hZl$?)V_7U7_GdK=Nm4;E$?#pt~@2Wy6St;NCafOsv`jje{xYo{Cg zfo6*PIXc6T;2M6x|TTD^wf-P&u~IdHXE=-VslUV4$fVm*Z8pgvxl zI<3dTJ{Rr~JO!4$bdKk8GAAY2VL*fBPS_S!Agw8`O!r)P&_G83Iu>5wOY7q{e zCEoiOOlW`c`XN0WTuiP-aGq}wIxnyYgO9cdoG_L|B!;Pa$H6CwfEV-xTaVsGc07rY z7xX9x<34}+Vr)Tw(NPYahyU%v0E*qynUxR(FXOtfom4H1uF#QHiJ@KD0}udx+m+n_ zN#&Am>^#Iai@LLysm?XH2M)YYt?Q1S>{nQ8i4C6YA&6vhz1YJ<^IYF}!`c%K@s z&_dT-e`Y7D7fS-zstl`=Z`HJ0Vc_rqwg%Cd!scS?c?t}VjuXXWU`x6Y9q%LX)bV^Q zl&E*}m%(FB6@NmyX;jRpfwW{DXTdf}vK&Q=fiNh*WOON9XEXky4YtUNvvVLfU|n)4 zj-B207wur}GWl?NUIt;4zz$mkXYW{q&Q3`pg1)f)Huk+m*xB!jh;?v1)ChvX-X#+z zh{-OB`0Hj|JmcLGWyB|m{W{o&9Xh*4jMCAgyNS*Qi?Mf2H!@}CJ+dAHpvXWUKhYM* zAf$2i31kj}ps9Zl`-nln6cWO6AYc-3!(9!b%vVa8HiqHIrLn@ZcZ#2w7RrKM+asAD z(Q+%+*(hwFSd->*k7Yv%#-_z_Y&*3jvlP~(i?n2Ht(v&loD6HnCgzGvLAF>ExkjbJ zLWebBN$&%NSd*L3(_tXc~-a<9x4P<+hWe4%Z!4mB> zOog&AT`h(P=UJHZbz|8uHog@bz>m>u6Zu5m$RAc>%|~s)MgTNE;>c9y>!ABGjA2sJ zShPMF(!Em#3$^D#sRgx~xj)`V1l!nGP*Qfbvm`nx`q?qHEE1)581>vBZnCpb+AJQi zvluk=sjnauVfG8z($G#PR1zdg(qU-x9% z7EyK&bl4Awo%c{AD)C`SMAJ^ouk*(&!hp(I#jx?GEyB+CTZDrj6!BwO6rB+%Wja{h zRYq4N^wniP&cDCRr}JMf^BMfl%X~InzszUXJN@k&{4o;NK%ox9fp+2RjJQy&`!I%;Y#54bPqCqYGnV)phh^eU{Spf>t`5N&sJ#X z<=!R-jQVYu13rd6YBDShUPfFPwZ6y_y4d+9cm{_Vu~I5BFhy!TUPDMfwbpjFae0=s z_3t&yZsSP^c}EF(!0E-oQ)8ZbJKb0TYQ9L>N|BwQ@7Fda7`fqYVrL19vgx>z079p) zr|W(O4xwX#`|wF4&93uN@Pvv7GK^^VXYtP945L6!CBKcQq*yr(X^-?W{G?9!zZ|0; zg!dV4er z134ze$Wzu4vtfUuk4L=J^DXvW)o%F^xS5sl~b_2%lXBzAR4stBid^v97l1 ztOn1=ztkZ0Q&q)z?b(_`G9yzGHG+8!ouLb(0uOK00( zk!Ra`i{tOy*~Jl&pP{=Oi_{m@^jWvJ8blxU8qk8yv| zN(?9NGsVgiy1zXZ-A-OoFzq@hIO#d_nfe%tH$ShBbASG?6f!SnG{($c7-N6-;@1uz zl3$B6uU{BL2ivOHBap*vuVP=I^KGm~9VCfWHLMzfn;&b~RRn%c)zXYQ)KZ4nT89{@ zfVpf6cGapbjd`fcG%MDzd5D!NyymmBZFLNqsl{wE7&%q{ix;E*`&sWCTa0(Ws4PJ< z^%ZB9VA9XFVtu(3v9er989TDPi{HKusSXxfuS2w4E86|b5p9r_n7#su4YZ=Zy#i4O zxI7!!D8d%5Y$ftJ+=}-0N<>gsI4E|CyAV%lh;?b9qIV(e=jjw|EKr&Zs z^)u%6;<;p&uJg~VlQr+FjnK4*Q0EsgU*dlSc0Bnr@-^X z@j@tbZ7!p=4;!r@@MQjK8{!_yp=0GXy*d5}_eTQe;0N4aJ+BUnn|TX8~e zge!3sn@_yhW0?5ydKM*Kz8*8kSn==cF+7XJ$Q#&Q;PcPkz?RY&G4n>&1}nMqH$qTK z<6PmlV4;DyB5e)(5pssuwQLJr<$8H7gF1GC>z#FyA0F@eZau4)l8RZkvIa;hKD(8D ziV6I+4YzwAZ!G zTD8_s^x4D)a3cw(m+!Get|wh(5j<&vMX<#2BKuA-oa030oj7|~B5svVv3TZAmVwg! zbSLYB(#3B^n-+?Rn=v@Yh`Tmp*p3z_H)F0JC3@V2dKfAC-i7x@h>E)qvp}rB3q0a* z@!DN1jinD0BR`?^wvB8W_V#5P*&ncKnR*-eQJU)7c{}EwPMk1ir?Q^Jv4{V$Tcdl^ z4A1CTDUYkK2P+wVH~ZGBa#l?(%(u!baNGx%cFb7PIJ{}P%X=%>PDl=>-@`Vy{bAFS zeYF}*TL)$1>o7!toC^7pF(@VK7;b z9nFL29x-e*kHFxr8qMP(oYsXsHRT;$*t5~vl!;BdZT=2j1k1&oiRDk*e3^cS_-Ql` zhb+N=43DBa#rjb^Lf@Qh62lE*Z(%yW zUt6Os*2*9_Tu7@S8{7w5q-2QOzQKghjvgB-eS#T%!}J_IhG1G zv;!8QYx^yNYtJYGlJI?AI#?I%b=7rab+eZ!%euWHc{ezZq}|Nh->yB?k?EB~yH!lX za~$zNTrZAGr!0bNE{o8$$1TFpa03$J46pW6eyn!Z?iy=aLFWwxc3YhR{ZU&nQS)$+v*m(Q5KSZfibF6KR?^-}d- zsuTH;YpXg6*0t+93O2+Mq?BUQZtUo(UAw8HV25_|o`>0S9aH~_otQrBMa!cs6Y`+F zkFwdY?upt3erTR(+{J#z_+Hx1TIkU|R;pz}7|4==;3YC;r zS5jJCNon;|6`rQBkEr{da#Ko`XPUw?h0_(zP*|?8Lg7q>v&6pNDZD`)K-KG1&|HNJ z6)sY^Sm6?dOBF6t*r0HwLZ`xJg)ItO6|Pcvv%<9sw<&y3;Zq8q6?-e#xVFb3n_DdQ z?`0vbS09Ijl@_@UKfxY=AW4+Ij*)-=(^wCeiD}QVK=I6e)?EzW%N9YPgf~KQ#!$U! zb{^m{O;a_DBj47J{ zG%O!-&&dr|ZxJ?jgGJccor(af@MxG34OXFcmmUNLeDyAfQyCi}iEwZv%CFuH*41as+Shl%*EZWf+MLq0I69s6L%e8lQD6NKMvp^JS=Y}J`1U6gLqUrD@3Q~ zAOc!0U*FR9D(+2e?kwNFiZ#2-7h^=&Ygn_JJIS|WM8j*a!fJMtNkoa`ugUZsGNEXZ zb{NNyo9!~WNO9v~mc*KEGSLL_*D7zL47+wQ{s8RFFf>ddtF z#kL`kk{^yU(s9yNoW2o^jcW=D1ijlm!LX z$~JJY1+@!c<-BkvqQf};k|pyB)Sg+Gw_W_9tLLMTQPSSPEVIX zBMHKfF}t{V7*4$~E?vKY(^+Q-^dK!*FuxRs`RW(QlgSI=nO=q~FUuJF|M7G>b8kDs z?uFEG`B8R2%sh$}sGFqUf!I<7dB2GXxw(t0_nT6d>1hR4yp4Ds7Ty0C=$;ns^$zGB z7X9@*%r9}M#$U%3gw=dF4`Y8oMY$8U>*Z_!>j7JU-Plb{qIm5**ru&GdNovJzRL!3 zo=_u_k7M1P_B;3L%HpdbrB!E1+#tSq6dV*wsFD%l$Q1l-ZjYEQec{{|QKkqo#A!U`dPJ%9fJaQV z2o`>gSoR)R{V5h#>qvq|{yj_~ufNBV$=3EhI|>EQkyGqJaoq=KR39x z7F8$N8|390_#spSz?0}@c9e^_~H}#%$ogu(M&TwEZ%tdkijJ%6h8{(9LwqedJV1aWW zaD;ORaFlZ>aI~`kSm+!HEON>cj&;gQ7mJ<68opm5ueR03J7qB^I!l3*oYR3vo0*Lc;H<{Zz}b!RzSPP_58#|e zNZYikMp?+}Mt@*!BW@II(CQjP;F;Sf%QUYs3b>$AmaM)p0l2VH%JmjCrUI8VW&oEp z_61(oC`-AbaX7G{QI=_Cqiif^BZL-OQ=@FDmc~lpsz#ah>l^0+Z)jWqys>c+@a9HY zfQDNdWeHX{N;%=0CV;lKNw(IyCfQEwo4Nwcrk=nJO)~FoO~|z-nq+qGXo>-DYU&N# z+>`>mt0@z>rKvyg?xsB8)+Sl`_ce`@l~aR5_mJ)7P!%+=i*X4{v&;JzHi;Vk)g;^C zfu@PTZB4QW4>e5#KHMY=vb{-mw;fHgtL}R{1WZqrPGQW>E%Nl>OS=RVd z&7Q!$&9W=)YnGkpx#key!R83y^UX5Xhni*ezR;Wue6gW94bDr=vj4o&+zdnd#Fl0PW)z4*aC0!2#z?i!8zCEwTh(w8#>C*&=KFY>Oj~1Er z^DR?=7h1|N3W!=NfUE`Go%9y;88TYX-O1L1-a_^kIQUgMF*iS zt;jTWZAGT3TdOy)dn>v)^=L)bsb^~l(4#dB=+%lIPTs930Qt0{3COoK5ur+%K8ik@;Q8J2Y#W0}Q z)=9wlR+Nu=x1tYGQmZUjYAc2TrM1c;rME5xX0)Q`kD|;~44$l2vSit-WXbxj>MTcq zFH}Sjy?;-=vo|67*2T2l<<{ON zrhLW%4Ku<>3l- zLjv-?wl^$-v-d1QXP-zS6oM`l!^VEH2s^u=2v~nQEHl!%19=bwx3+E|ZYpA|pG9z1 zq=>OPE0>iRW!>z1R6B#q@w&sTsxPXt9CnwhVfOMAu39?FIBqRY!zD^HaBI>nxHrs& zo5N1y?l5;AiaTjX^BK6QWDUPhj47f#9BYejkaofH=IP;oT|J$_)?OKy$?m-}FpE8Y zDR6Y|#EUmqr?9vy15??6D+AM5v1h}@&;R{?A2##KsOfC!m4O*-^_78{Z0nVQS!|CK z#maJyE*OJL!ShOo=HjC66xNW~;e%8*xWn)?Hlf4tKJ3~K!_(P{4#P9pdMkY3KXR1G z?(gu0EcWDI#X=Xal>({W}OvV`DoA?ZYZM2u){8{uvsG&t94aJ@6}FvXuS4l{(G5Yt29(FPMzY#rD4EQ&q-^*3D(=c*YT?QI!3q$E1#W|q=^ao0 z0k*fhz3_UvxZ0aP3H_3n4?inqt6_t*&#@H!|1pY72P5*E_Jj6~_Bn1r_rdT7+r~AbR~k(l?X;xA{bqXVDwL9Li(o)&nWy%Y?#TyCu!;nq>w4( z3U!5sLYqS9bCEA)xo5a3T3PNH%5u+8mV1V>+%vqSI!MgTATOKtx}u$-1WDR&;@g=l zF!pVEA}@E;sKTpCi-(lv6^F2A@$zd@e<$Q@U5Q9Uz6|4y8o#e!j3z0@L7`AUmO z@w>3qE;LTRJr&*YoMib#8C)V=Z$%jH+=>+58}`xqNSc|I=fdcy|Gx%=CE`2)}xZu3RI%Mo+^_#P+=WBmC(%65I`&v8@FATckH zzX;`DP7pr;z2EsD4!LK45gp7=_NEcI5D#0VTX9o&Y>OfwL3zwt^S;||!5q9>6B*Gat#NNf+N11N*7P&6n9|`4J1ZU$dLT8m0VKA5y%Q!Z+ z&LZsWK1l@96Ed9udPVwt#JR;-^WSQV;5kra_KV;bpg`>x$?t>i^rJ}r6Xm*&N1;Y( zn5!{H*3(e&a4d#fzH4k8KO>D{vl962(5Sqbz)wP>va2^%xGGwca6Z5jrDkUN(8?938I-f1SHdaLE@Z)V+ zGKmPD4s}$&LCE4&qF*k)GeLZmi!6?J9Usi2sqGV{_wmK;1o*uRrlA+*f?-$%8=Y5i zJg+B9XA|)sO>D-2&W~|8B^Gxz)bjPXVDtnA^>R`AD(@t+m%*-rv-d^PGU!`$_Nhe} z>>Ejh(a)CO&T;w|F~HNfg&L7y!BX~eU)3^kB4i&AvbeATf6<&3E8611W?Ho3!j@XJ z;=)#2wBo|HUZf=#w&$;J1TglZd;rZPJ8BV}osa~s_^|v2`^qA0>_>~Rvp+4u0rk(r z`=Ibi6i4^*$kBr(pA{xeD~@8Syg=R{ABSO64umUWj8;}KSL!>5RXs8a@0*6p2mG422yKKI_w4&k-=_~gf|pd z(%&PCwRZs{Sb`%B6EKZvn?=zKB%8v&u!vMxjH!?`Sd1y64=lzMkq(P7MP%r9NnqS} zQ30h{x`$*btb^BoX}59IO}kmnZ6%n+^79HO`=br(&4f-*!V*wb{2Oq_d#b_0hatl-1XQKccGNB zR-Chu3d=AUe=Wq#5^tbuOg8>DJaX81`ei-`&#~snb1`}l;{!zZSarT^utjh_)FN~~ z!XgYl#v*JSC$VGo2+RZO9S6T!)WpG}x0^_g*CRONUKYW5fJNv$)FKQXEr}?Y*r=#> zo~8(l=XWb`@Y& zx<*VKf!S}0@Epm{#dttU2}6(&8bY(_W?UKb7B+%`Y#64Zd)ZNN7)g98Uk$Upkb}0P z;-O@WDLl>o zUW^eh)wDZ$!bA~D(8N@pfMh49$^%2r7@VxKSvNIX5TbK7%hgT z@i6IgQU2^Cn^%pCxi8 zVH%(5IzLHvq6$~^WRBB~RifV%Oy6@vziUuY*NTs>!Sr3}IzClS-xIkm^ccPz7SWC6 z@~s;2a0R+vwQKB5xzsEWS+h~u^TnI9QQ7mvu1cgaS4_MXm0joZoWpO0b+6b~g}f~i zbE}cJg(9W~d8>DQRwMIvotRgLye$(sbCI{DuJd!{SC+V<=W`E8F*MO{0W#Mh`qd-h z72>0MWNx|Z_(C2}sXm$uVk4MZbBI9;sU9aW{-4Ia13Zgjdw-|w?ngokq!2~|$E$dDv`{~FEcXV+*>zr9B5^x`$z zpjT{KOgw_eGI}k+!Q92tqs-qPqz1m)2j0E2&oNqamg!zAo^Ec1Qgy|;iqM&HM< zlfWjydt!&(r(_tt^c-oS+;&w0>Qc}Gm~^xk!xvzS%uCcPfE`Z9cs*TOA?{j0{Q=(C z)}cKdqxX?;XrEP?5tz4&(+jXS(?OICg;9x*IME*Uev!D^p2a`{I7Pt;VWlECj4y1C z&eki!U_ucl+pGu&dsqzZ02>IH5_e#MpwySAbYwH7;^ z>usCb^xf~1fv7|qNg zHDo|< zqe!gFXKicZS?P^Iwi4Ks8ySgg+Kr4PcKeNtWH#$YMhdIEk&(*g$nn(<<&~AGVtL&r zIW^a@;@QL&nG)FK7Mw&jwFM`MmABv|vzaY8DXgLeCzVyp<^G@=8C-01R(5t)uJl!B zB{ug4W;~m8Gc$pe-ONm6({E-bFwh3dP}^S2XyR-@-{YyG|2?x@;W5o_hJ-0Tx;p1c7d9NHNyv6SOFdBJT1ui)nbrGo>FdF%ZlN&G^ zbrw%=#I3$!%>5XRItkAQu<*HCu3ENY;S(fwY{jS)D5|z$R0Ymr{Yv z(boY|^fR;p;h1#Y&Jc}D#BL=y(0Z;ApB`jweV&smX?xNqaU(DR9+)>GlOGTSb4mcg zR$$`SVV`WccAlYGS(wN2wPN|J4DP?|J4M8^pA?b6E-NCD{h^2?t|=m!8;VHbttAlz zd2V}^`Bq>>4vk`FMp0g2Nk)2hMhRxN((07VlNBF^s5bywY?aeoX`Pw{cjlrjOxAPq z24#}v@@IgZn>PrtG@9n-+G<%Hz#Ww@9inaAj0Umo2gBE)uCNz-+Yi8Dgi|fJ{ycv$ z_I^PH8pH@=IZ%K63m@{rB%&L{J)Gs)3@>qR6E^?hS=;VM1AcH0*E+0`BSqiGQB@*D z-yQhg;o{33s48LB>7BBw^sw&SEk9m&vHJ;Bm2OtSlmE<_hr(3WGA1Z~c_UewP)R%76_GsRN?NTg6x>_Sc~ zWnK;&=$A z+P)#EN_!>COKkd&RK{3hS_l^HdlYZkH<@s+pvr7~^_Mr_Wh^lAMhT=u!ezc)D>)ZXZ4W)|eXVHdI zM4tm_L&?_P2jpi+5)scsdGM@khU@SieMR5b@a_7DzOSSF-r~#G@$Gt9r{9p@Zh&>? zTk@vkSgA$MJd@;^c9>-azs63EZA8#=M8uOS3#rGWh*viRq`< zRx)&ZtM?g{CBp3k_5v9!-u!^=fF(%PhwK98)ukV?##T9=Vcn!tdn-|Unt6(Gtynt| zbefHUG#8y_$H{PO*vI%7(4|cHgk6F{B>z)rSqsH)pR#SFz}k2Q;QS%!3eKf4GdnMR&}4V!O9$uYqmgNwWSbkB zH3+de0hkaEC>iYm@#JM5h!x|}%iO=qH~_4Wp?M>UN;0tDk}C&U*@TNj*l^Og@Qy%z zybT19Q(^kn=pJ(AYiDli73@+K41?ZYu5E8fw4urMje7g(1BD(#`{d|9wKOt)% zjN?ZZHA_OyIerkg{mOlm@%&B634q04jpVGqZh3bSr?=!MbH^?DDS*&FkK%MsTa_{3 zH{QwjtQ=gkGUWSa3`K-k*~gx;)u~IfNEfPoZpSpmyC*6lo(`3SA6BEgq#Fwx}xuoc|Ffb>7*tA?x$+BeBf9Z$8C{5X)Lg0&DPs z`zmQLiY$|7F)mIeh#E!slWlgogFYjR2(VXiZ-Nz|7IDX$Nk&gMlbn9pOzQN*~b14Me8b>Ro*L1NoTNok`r_8ycj^IZKXB}3)FBi>US2y&8S-7hFxJjxDi!L6s1Si zYBt4qREVMT)MH^g=~% zlQdT7^4=4Yp08-~C+K;??@z40=1Q|G+mOo#3;t%>iZu(Mi+SAy0d=;>m^FA(%J;r}ZH zJ=MDKD+JvH01k_%0*vPSv~REnFbtx-2mZA`*m%Gbpeo%2jlgx`G9<>#V=J&Q&Hu#k zqkOj<{=7usN?=I*TWnb=6IKFT;weS1IW03iDKFy4K5=3tP@r##;F6JOVn(4gs^biZH+oi}?*`Hg0VqYxKL&Il^D83?ek zMPOX)jt!jmJM2Bvs6!7#~GA6oRo9BpP&UZq6W7lQ_Laq`UbiM+n`u+w#0p-sHgQJ63ph`7R>U>qI zfl}wGQVo)PT}8~ABT^Db)mCebSqV~ zqc)({Qbw<+*2l6pcj*kiAuhY6VA~2XQpmnXqhG1E$yYTNSOLem@ zbmbl-T=stLNdoLo$Zd#S@Cx~bMxs5h!N`4?b!Gz)O2^5X0_nsKJuU8*zSa)jQA{|G z(bq?;JCFI9pFBw@^FT##4m5em(RqX-4BkT#CWjA$Omgr9@ykyvjJzcLE?~>RCDJZn zdUsijyC5e9qTvE&gWJWP3#^NIPlBE$%J%@Y&uSCS z|4Up^{3`KuMe{eY)OstLFCrbRfiXNm;_%Jy$-g4r*4S8%pkZEC>v(<%r6KP&u_Xz5 zT3>m?Je}PcSJ%l(OXi8h&BwD>4+&1$N)rR_L|+p1Chshs>d6bl)f7IKbg{;!%EJ7t z*1ct6L8`ERC@fGF#!*;+mDXPt=Kp^eHUNcnwZ^8&!h)^V1NmhVX@3`O2Q1ID@1X*( zK`5|KFe*u~kG=F8sJ@4@rRarE*-F5YXE>bJM6YZ3IEN<#9Gv9hHQx})xxA0LTj_NhyT2ApwN>K& zTpnjW))eOGj>CZt?O#3hK4{^MxBU@mXxn?}adDy`k9#5-48BdhE0O4ViN-LBFcKg2z z9DxF3tg%J1z-X)WC=_Tr+%Q>$xI$1nmK6d|yQ{?ym^WgC!A-A8O|?csE6uJlZB&Ie1*So)89P^|(4jmtx;a zzjo+>IlCfi<@Hr{ZE#(jD8)VjcUKGt_YlF8;1si1p1iQp#XZqE*)*^t zIwH!Dx&W#KE|!VECPFyxink~6P+N%cN{Gb}Vw@792_eQ>X=9}jd;VWSgw^nLzNhBD z9!&u1&F10S&&`<7v&v?bE7S*G^ymMn+14_NQly_aPdtB(#bQB8K?5u(|QB=TvXl8y;x~wxR`xA_cOu*_y9n~Z*x&!V^9-pd?W2# zlL6-|8)^MIi+}CSX7KRJiUkT)J+k>DH*xUjh<3new;x?yF|B0s{Hw}o3(p}zTM z4<2lbwuwQt2U~EMR=Wk6uLd$0#<8P1iQCI#{Pjte=UZeX{OPzOpeIuu968L=r45 zBxVE5PXXa42?rZ5YM<8w$m?S3^LikLoP+XoM4XkU6O!qVyWdxY!A>i}WM>rNU|$HI zBt3#05(AR-E^vdvWBt&1zM}}njwyn(lZw#Uhl()RCyFrH=OQKREH^(PVbyhmtmzX<)wrS zw1QSbh~jDuKShQ}=54T^LWaRAfwS_uOey#2*44Xs5R@*GKT)c4YU}VZhRQNyDdyfX zkFMX@p)R}WF&w1~S0#$8|KisKe1TC`&_?+JBN3+qFHmItbiaIoV)X(Jyug^I=a?vEbn^>r;X1a@5I^_?aGokL zFKi1tjosK|9tKaO@5!^I9stH+uycD=dqAs}5rln3-XlDcv+!DPvA3rl1_-5EFLC4% zjBcL7?=c?D9Wk{X6=lZMc2JZNQ|qB9J*Kw3qIgVgJ4LaW+P0F41!8sfW0=xlLA_m- zgpDpqp(Hm&p`=!dLP-uqp(ImMv7&N2kKr`BRu?C68;h#tY6vv*A>hOwRnH=#R^QIQ`t7*w-WmX z3q>D!S_VZBPAkM>d0HhNkf(Lxd3kb)PvmKn_*0%95`J~8OU)5!>XDr}Bt4_J#5Pm| z5NA~iUdP;p*cJ`qBlH7qM_MQ|JP;GB!#JrGyu%~4Jbzg*bvx>ZD(JgL)~Cw6hTRUNfDg=rU;$=tq6lN zNkmiLN--R~o#-{y3?@H|aZ}B12+t`~k~mmn^7|F-)eFPeykq zY0ND6Y}Yh10PgC6)6DL$mK-+CjDkPmf@x+X7PecbnGsN(yfw{C!D{-+VYHVCulf+_ zy7<#-127wRx^_cIw=0Q!xEm5FR}#s70uq@n1-4pTd;vO;x!*d=k0J zRIbHOA=ea{YffYb?VJWg{;6a&^d9>FH|LHC`DD75KChiaAT2L82v{Z$u@e$`RpdWU zx?zCXCe|Gwp&+&@LT76fVX%7@VY2(hw&#FbiFLochq9%LVC*hMaMmD+9&lE$a~SMC zn}9jd1JQaP86oR!xxv0r!Xd?=B}-H!e5)0T;B1v5bhgeWQViyT0|!)QqjA($Kyf}= zJEVO<-0%z;l>A|+%+6z(R)pZEyXdDFVEeHp>;=>Vz-0VOl+H$YHIqJ$dv6neAP_^? zD!71b_R|AH0A5!yxvXUJ-0GS5n$u;N962S0I}9KIq}zk3(}lP=Vw+&PK@Z938Qi?X zwkk9!J&D9q(sm;R&{EPz>r17*{QM}>_0MtrKdB^?H#&eXplSaSGjw=sZU%X;4XW10 zMUh;Re)RsCrBXhxZm1 zE>|BhqFdp4 z{YDY-?3^MJ0KH}>B?5KLCXxWSW)sQ4TC<51?k0&Ky}f!^o!;4uW8XGk_!;cHqVLf` z|5wouN&1SScS`!IqW6R5x}smv{c5=a4!1X5u$?h7XJBTb_O9F}$i>cU zeqrX|Oqd|bja3;k08s}tXImCXo1zV1>t}=94Z3zIy-nEmmaKTTt0gO;hCS7im&pFz zl9j})maJsPnFCtGk5+0!jJFkx=N zNoLQv-r~og{yzQ|D&!*Z;M-7oEwt`A%r_%Mu(kdhK8qOfw6?HrsfhWIAD47$-4e0$ z4Bsz$9^=v{tLg-QR-8Y^-++e0PB0Q!?eKa89y`I0(0Wazy~mG|8mrw&{tTh@x&ZN$ znZW3s74^L75xAqUp2hEIGCa=sy&T6ab-PHpUxqN_|e87VQdOh`9l5{+%ohlu4YJFSv%AkkWw`uwZMBr&iLZMt5ip`~&uwz{dU>6I%dY7SQN&pzc3@CaZ!#v0LK{p^^@_dSYkCC8UJhX{;*L>fiDx|VkB$Rwpy&E-ngeI=bF)CZOk4IZ@ z;+bu2(|ix|B(Nu1{+?-i%f%ocrQ(~|MAQ!%uF9dJ`ZH+w@w~i zm{pWXK9gIwz{)SmLgW(obY;qoVC}eka^t!$5$1HGcxy8Wh<-y(Rb}+5^rAcomS*pc zE|g+w3TYMlPlzfX*EzlqD<|2OjbsD$zoV!+kEYr|r2T}Ght=)^M_eNx)t-_K*`B>)_aMV|28#PKh>mCOf;#^V&@h9JoMkHz5a>uuaj!7$(TH$xdy1_nqtc4>aU7V zF=g>xto2l{P@4$t$Yl+941-`IxEL`2pNEC^ugo6+BNf>6f0mskm#w%xcuz6=EgFPy z#rEXM!5$JHy-nBZzrX{bN8`41f2-jzbwkWG*LPUmb!~e6R0m!k;W1>F20FDq$QFa> zY3jN(da}DTQ~wNhGVeO{Inv}Q%}qZ_LacV~IxrCf)dNGAcInqo24lZQKGnhe7jO0N?Z0fAX!bIdqXML=U9uet}JTaC>fXoxu zoTn@D#9BwX>aaBN(TX(oA$yXoWaH7{wV~h8mjSp^g@tkm`HQ@V*ojL>0SVXsgxTez z+EURzhzE(HC_PdxkfX(pC@4Cj#EB@qyErbnW@K%5c^QFFt+m~33g$+6(Rz2zBWoj6 z5{s-2R}_t?4HN&1*1JInu)Pl9j?mf=Nrj8t7(J95p|!y(K@Y7BvMGXj0Ma=Ntqo8~ zG^EyF^unSYR%rIx-4R~vrzkVLwzH%n#h#wHM-Q*!Hai;7)_fI>t4ZT zM4i}~$K%K&;?q1HV&31h(YUEK>FUs)Q?a5OFPw*B+@EwX_jK2LV&4d1-$SUjRy^pB z?aeCj3Qk64q}~(JbK3_J>`*3&F9Jve6#EF>APL6%DT4EKMd&XMUPPRPa^$TQwCmkr2y_$b~Z~XXF>qu`|iTa4he#qF{^5`!G)UP?uK;-Fb z9T_O|3=ol-$kX5Q7%cOoH|H6KJZaXEVKPq!Ml$3XXnEx7b15u>>hksF*f=u_^aglO ztuN34K0U}fQmDh&WVraMNUw#-PuWO)70I$Lj@0`SXrH1->-z|-e2}_SXSHU1uFL`K zqC0!l=g3^CP-oQ^)n|*Sar!A0?U)SG;A>Ed!R!I(eNK@}2vh|-7+QwlW?K-u_iHTj z`XefJ1KY!n$WPdTh`=|DHsV~h-UfQU{St*0eq-!8MVRa*ML5_iqH>PzM;;Y>^C-N} z*bYT7_Jkrh%nt1&ojoH7>1$?Ro9soKXysssnvh+Cli)%r6~EiWvNwz%%-OfRVMN20 z?8qBNcd}mmE}0vI@0&(9b6?ZmR>jFcsx^w+-!!^l)1>}QBcA-%HAepeMpCwfI3!f4 zB*Y=1f+h)ZNGM-Kl{87nM>~Ku5M0E5gN0OIG8qvsPQWK48t_B^LdWvluEV2Cm|8wl0{hJ`#}aSe?DDF4WdpBEPP{pJ&~?d4HzyAc(<7RZaZBcx zRnIAhSZ;iV0}tsPt|x_v^gQM*Rw4HEFR2bi6*+L^d_dKIG@KlkaxtAJiyHi6Sr6CJ&mj`dTzp)UbYFi&%7!ZzyPV7gL=&#Q#FS|jCQ4B>`D83jaJ`F z$M+hgzL$>gHL~e@>G)nnB5JaJDosw;x+tGaiMw|<7UeG?D#|bDlA_>4GZ|)+_W*?J zAoc>!W3BIp&Pm$3&%#1|4co^)mi60>43q=;4Q`}a`TP+%khfrtO6HHs$-xcm+(G$# zgQyBOz4-%jE^{c{?C8kI8N@d=U+IG~NAb<#rEn~;9|RM|H2V!Ng9|(0=C*eXZ_2j_ zj|j7~{7J2z{cSgM3$yq}X(nbrAGUDtg&Ub)B#m;py^ON?+37Glm#l+wxo5NTv99H> zcFc#}n0;NCSp;XgjNBsrlKg2lZ)EPEEJT1)Ys%5-Sw(!!wfje9r|0q)QjG%#&4S2Qp7mnH|Vn+LYOW%oDAs1$uWvri#%E_21yjl($I# zlt3L8wOBuuB5Ppg&YcPs0^10AA#`VWRaGGOIsv z|AP!BHKw?Y+7|RJ4Ueg41A07xX)9PY&O$$8fCAVzJgrt|6bSl5jB}t!jtk2df}@ z^8PBo;gFLJOL2U!0ZKJ;q5+^%Zs;cEdy*-)tC*aMdqc3zBsB&CI=d%3e0NgiR1nT z0P2wb_42g_)cfF=R_}*ndVK(n8TDOp98@2MV`hB>j)UvF;W(sT-Ziv78po`9Sho|MTR#HF@%5u|oKO$2AyQIbg5$(`iEC3@FC{U#UP@(3{R|wZ)=Ti7Y4uWO<@IxM zyuE$_jx*{d-p#CfDc#x58u?)=oKoObPN*Hp9A_&W=Q;sGMCLi=N15-Gio*p?DTzf+ zDTBpM`RkWDC2r3$r~G|2&SV^Go$~kH<&>~JE1XiiE1mLJ);XoX>zz{gPN)2-4bC(i zS2+jb`Q&b={Kc!C64hsob1;r;o$}YObHcu!G&+ajc&}4R;y$PRqAq7Hj>0LWvcV}a ze>OS`alGFtCG>z()__e;iTU%OQ_5zG^L8A!IV*5{$SEc9uoIwHKl1(+MpYtfU2l zPi(=^OWW7nScoyHMHX{%3x;D#GxBWHb4w6^rmPuc_BtMraj>Z?O&G3YvS}@tv*qo4 zdJC>(>gBg!8n@qqY0kI>(=oHEuR#Twngt`yr=Fs{;T0-Y9FhM ziuVoNep0O8qWeNKwhJfkkFLKRfuxhW^O1N`aG)7Vwg1?4Yp%6?ovd4Pg#SILTh*3( zqpVvCn(7uX13Pk5t@+lK`()LcCxQj4*1bA>CRXT+$Q{=5t@3slQa*&+7Yg@>^sT^a1->#j`p**{m<(E3um^P`?f(v&F$Wr&X`Z7LWW>T*IawzRnk z$Ds-9kn=`8`fY?dHEa3fQouFBe#^? z90^1OKc#=ww+ksiUk#ye#HQuj``9928s8bjI z`}K3w$%VV6UkPnb!!@{VO@Mm%3Hm-{jM+GLiAoVow-G)xuhVcyIrv%qf5cl(bw}rA zLl8r3k2O9^xtuL-b~)3oMz8|7oGpeC_@4QsjiLP>Zu_7~#_G;S8~yKV8QMV$E0vGg z>BSI?_M3RMvk^i5619E?+-=z7iik&?Ae)oG_9!Be?NdY&A_dt=$$%UH(FwXfc^#U{ zUX%MhqecKP3}GBbW{;3gcY{VM?>p@asT~z-*3(XueCT=&Rl8Ml)y_oKHc>+z)|D6S z8fsd>FWYsywYB`9Ej^euzapjQX1TvAd!KgAmHTH^x!YP-Ubk;;BZA*V_w$)O?S{+63N&Ryh zV%dX~YryF*CzoM1^%5X}bFjg;2}+Q2SmO6(Q?S5)nw?g9EYZ8f3LIVzqg zF{Kf1Nr~wXg+~{h0v_q2`vWa^#+2DG=Cgr&6*;AJZmIT`cqbbHa^^+o(Fh)QJevlg z!&!XoDj4e7YZpQ2aO$tS(%I_kt_;?A-Id8UUU%hSTkH_ZBJMc?JJtDe^E@04$lhLO z>`vDyeGD|h7f$QTp&0Ua`iqi}^i7=2c6Je0KhkG$y4VS;iqrZXI;|zn&MGHGPG6Oi z&T@7VjUVb&Fel2rUQ_C3M{cNwiF0c#z#k)XNCsRmni7|J5dVm=GsUFK=)srsz zpV6Z^ta{QE1*@I`ih_L*Vq>3ymaLzsIHUK3N8X9g^q$-iTieH`;Ffvpj2_R8*xFty zNsp~fRTPh{O;Hq!txc9xeCs6l=q7~U2q+6b(?em-lqmLo4s#}`L=zMRm1w-8jPTkx zNkKXKIh3P3ytb#EK$z%tBI?Bt(j78IaE)%oQY9iHFa21}Qqw(wxSZWD|LD1!5@iqJXK$1)ErRuo~vh#Z`xLGdbT!@TNpd#W@GnyE?i zrj^Vrn_o7QZw%DCNf(gn@{&mv6?03f%jQ-uYRZS{0+|%1C&`_)lD}nmpHgwV5BH1S zq4ZJnOJ|l(K{cOSU0yb)g+2=Es9xc^PdaYhw#x{le4Tj02UEdg;+PLW;6IMjeMXD8 zM-5N$awpSW_|7ofk}t&GM~yI}bjp-!{)y`>8h4bEq_No9LsdxwRkFLPk_M_|H*w($ ze2+-6_Dg(^2-jEm9O0toEB!Fk*mfO;LxwY6-Qd6taq1&EW;j?T`4gN{?E{XQdJ#9-eADX7oG}wSlhpMR&(fJOc9bABR zREFrufYW3t%skxsc4JBcn7pZ`U@Ywo^PY6`Vov0J`TD%~elI+8ua z21Ja${xY7XUw;X>q3bUbY5Db+Npz`w*{`XrWV-(PGB2`(JF6r&)J$G|-c&jy_ZCuh;V;^EDnN98`&%qqb zfTppKE{DItXRHkdjT!8I_BJN7x5?OIJ>e)bQxOKAY7-8Vmxt;R*u6+Ii~!10MX6zg zpmq0^L>Q)u_BH2&6ruB>iZFP#B22{mmU$cwUId^dlyqsT;Um_XMtjQ9^O;5zitDWi z#`{Ym27bwQg3bpk!r;RcVe(v?Kyii1dJYVwP+TnKqg*C+~LzMJ=rqKYD&hPp$=^A~!mGL#UME1KG$TGmX*v3GXG^?>aLTuv& zj(Z_F-P-SM78bY=+VZ*MpKZP zOCK1WDSuoXA8qtRQ};k%F#w(oQ3Rvo6v1hQBx1>3>e`?}5hjJ=8uzqv(3hk2e%;{K zk&lsq(pcMQ3q?Wnu-<}O=NL)Ez~soj*6DIZ81&x#e_@}9WLOvdBhH3rGwI9MDH z!*9&A_J>Om46!bDlgUG^#wcjf$R%++)`&DNhVkL(8f&*3e#Y$5S!LP<5g2EL8bAHR z50IA4+Ib%ieOhyeJZJKp@{%djCs%4;iS&3Q&|UVG+Sd_04}}E>o7i9bUL1>q(en=> ze255)H@dKy^AOY~-Ut>K{Y_4_@8pf4#y5d*C_vvl9mW>gX>kHM#qmH>H_NAJU*IJ~ zS^~6u;5fwcIP}ta35J_EA8$CIce67uf6Op-?UP`hVP{pp;;iVGU_|rJdcx?^F5m|* zvxBaE9toE#`?}wD!`;+A{pVN0j@RHrwR8VyBxaRVOrA3Zhe?wP+@MSGq<$KA3UzW8$S=PVd*2P}3{$*Q@eP#8`701(&oMY`DD3kN7iFb}F6k9HUY}jdqn7i-5*}QfdzIL zVx`Uk_`owFpfCGaH8%%+L1b6J>~fV@SV5xolgavsFtMZpA0T%a@uu1tai#*!58i@& z4KHj;J1K(E&Whmp^hgT9r?+z$`1Cem;?vuNgNBOrGKZJA`Zeu}GJF)l@Ug)O#k1@L z*ikCNz{j>Z2xhAY2MuveH13Aou`LAbUO6Y(LeS?sOO+7x17+5<8X8cTSM0 z3t@LGZxmNQffX>HZpetxwqP9#oaO2+>{&Rc+jp7sozqmRxxhJ9rDFTTS%%aGY(B^v z#nl;x8D6YHWz5GEGnoE_SgY%>S>K;}0V8G$nNB)upCi0lF-9yHFx3``)iaGjtw*@0 z00^XA8$#k7LTZ-8&oi;#S|~csGI|4bGk2De1CWVLvy5bHKOg?h@Do4HGW=1&TF*B6 zVs|}jwjlxIs%K-fcDUF)+X%;2;%kzbCC<+_5&{0%wF3LIL&V4m3{Hc^iVBQMk-Fd#@4PB{-TVTwBq3M!hZDkrN)C~o+XwUsf;YKj@KIQG9dJ)ccK>GAx7P0>~uMeO4^`_ zYNxRVnhVlkRKv1(ZiBIpEVa6=GR_cVt;QCSwQ>!47ioRh)CTGu66WLMb*Gm&yV^*I zESg?EC#bTt8pFWcvg#mQASPUO+2qo>WmAHtR#XSsdvD|WG(PF{;p6*^?;|>{F$ReH z?!il!38S63YmMN&JgY+8kl#4eCmp6V*Yv~ zDgFQNskyL!%E%uHE2<%xCFA>y7@41+ot0TA-@@9p-YBMRb#1H0a$&9)Kq|GZs6%Ub zZFWN|G3q|!C~a_vaF?;$t-7Lq;IwW)cZ_!{~f59xDb9DoPJ~5PD^+N zonE*`8}#>Uw8_Xd+QHmJ?Hx_KB5Q* zh5F$LLu>KMCgT`wa2Ji6jV-jn%}RXGfK8VCJ*{b&hVCvGDu>OG;Pp5sLOgX9&F_%-_$qD)6&{EZYrfPJv31Q0a!D61ay~{_*@MktWi1(2 zHrTb*xE;GU+X_F!HmQ8tijW|YU?!o@7CUeH#H}I*g+kOXdmmKW_XDl zCSQ@iV7eBANy0?n*4%@-@e2JI;0kWA&F+mQScT~StdT9geb(^B$P8!&Ad_IMKN!R^ z0c=^{rOUL=h&*Vwv*sEPtd&s`w7$15-tacNP`V~?Q^z@ zZk{6I*gG%+B12G^*HJ&r z=Pmh3Y>ng(y6M5m?A}}6kizc2B|jDZAGX_799y7>c(zm#32^hU zlM-2jB9hozMI^KPTnCLb5@4ktH2M+ZZ`B+!3V^_7op=T7169S|GPaOl>#?_F-3+o0 zzKyCy0@kH~kDM?v2mxySdy?Nn zM1Nw02slOfiDyn38-VAP`@XS>bQ3?mZ(M{);-?=NKsD$oR)2&6AV!`-#oE)x0TL~; zJ~qCBVgm(y7~`d32l7K=V2Lu0)Im*u2IwFOfNxj}xVFpM5-pnrX}d7bUBDh;AFogE z%zNrSBScj1Ye5UFqp z*0CVqXKYoAS`zTj5URh+PTge zjcy5^aeXlQm1=Qf`6)aOxGK=4A;l5znIuzYiRC~f6V5LT3y$?^UmB;}W4-#w6hxTn zqi$Lf!UC-^U&$JhA{PF~_!)Yk8DFD|OcLY1F-}1(6#K1ls!JQ%S3?|^5<8B|A;1qI zvN}wT<|2Oc3l>0puOjYmCx3KJLmKz`dAY+hC<|+qtU)N|;EzV9W=Og?@!*d}FqYk5 z24azWR-WP;pY#hQm<#xI67OyzfI&$SvA#wa@6}YCIQRi+Me!<&d@vzoP6Py-W|${TEE{CWw+>j47DW zRtA`zM9*K<`q32Ue?f~HFMNJA#v&Z>KZ$ZdDIWM0iDSjWGO~jI9(QVG)nQOePuk^)sDh;C*kHt4O*iAkh4!iIc=U1%<`q)ErNuJZX-Goq)+0 zOjf}bdN+NM9>reeMS!JBSo1tq&hBEHnFVLsZ{(z-3xz7j^u*Zmq)0bRubNk+O?*Z! zOru7?J__2o)EgP`H2X$I0-bmxBazO%k7H!_mxrW+Y4bWan*t?9X`^fggxnzE}+ zQA9i)u80I$qKHH~M-fT1UJ||ljkfPep-c=t)0Y9;aHE0@EZ4i!kb!~9E{uugR|-^`nEP-z*^u+YqJ7tf$}!y z2CM~WTXPxK0<~?;l~@ay?aZxM3q0P=JkzSc)2G1K*SB`G*w)DmxYk3!*Qvd^7;BGy z9_AjbJ$~{)ak*kb2lFzP9V0rLZ<3LgpQi~olp^t*m-$w!5uQHdWI^TE3UU+02}XPI z7t|BteQ&e6RiUR(R?951YZEm-=E~0Qa0|nx-DnnoJ!|-IbGoMVAb-z$l1fZ|` zF2Ib&ip@LFoPf3Cyg)M*?y3{JG`Ab5VPe}9)Rwwu*$}cbW=n-4?mpGTVq zAoh(h=4M{%iS3C^oy-`yGtowT(8(NN?dxf-rN(7{-Uq+_(hA}er=5Zchz+7Kr)=^( z1oNI=F=uW*&^r`wK}qT4$z?Oks6^__Umo1 zjB$sTC)>qFL0kF+Ex=CdJLC~e&ifHJc=(>fUfg^!Dank7<;ZLSXX)`ud*`jbz?BK1CT`f0t7E6v;m0q;&T8zJDdbn`3Nhv5`1 zh7B}dgjAb*Cy4^B%g2i{<0Y6`kE_jE1G~Xw2Gn z!SJLR0Ba{ZCB@jDik=VXk(eJ2m|((V256l&!RUBJa9XJdovu)XK{qJE#L5|&yTKr& zd;(funQ+OgN^x)kI{Z6a6ESQ7%U~h~p|+M@YE~1vs*PAQ$y`TQwHEG^%}TloF$N}^ z^<7%it{Ux%_4;gJQ@=vLV;(GpO@zzUZuY(vx7*;92ilfjPY{0x@ekL-paKySE2YDN z)!24)BnfOx8QtCefYN0^ITA0{uOpo)>C)&#>i)*Pqr)2inCsSfc61=15WgD={VhJ{TkG* z)fY;gTvZFN)3fB@;(CvrzMwa6JXp zPgE6~fezi#P48ouGS>8w&8oHe-yV9pO#foA*;&>km~tDgndT7aREEwpW26Dgf?4KM z@EnYoje*}o9Gq?LfDY#N3e%;mTIfKH4y4mz=Cu!skV`N_3j}U-4(wSLBcjpc>?L@o z{vhi^C#tOJljuA}BqLV1ZD^lDH!C8Q?iE2ZbQwM_ToLiKw;~c~t|AiYBuRLqCE8h& z=_*B}&<7QfN}rZf1;Hv!}Fo%513;XLU|AF+W!a2fPu>Z delta 50459 zcmbS!cX$;=_y3-m-Ft5cJv}6(lZ22)NF%h61PBmP2)*2d5FnJ0KDyl0iWQ zdqa^ZR}>VmymrKbii%(Z8-j|yD(d$$v%rhu^ZVn+ljqEtv$K15r=IgUXNEOrg4di0 z-tDQ=8*T0NNBQKJTyr#yo^h3dZg-V}E_DqC9qCE{?dkH`J2X)T}xqkx4@*yB2 zQ$T_uLArHepf+AaxZ`#HIe(eY;d^)kcX#n;1Iaz;jO`*N(M`U3yn|IQb}pDd&$*~_ zMwPQ-e)SCP2=0BPiyq}5T$)!oud2dXQC`zkGv|6H7JiK%fo~#}>V{YYAXHEHng_R5BLj(7;_jDN3`EUHE zCz9z0LzSJ<~Xx(Go3CI~R)|y^bGa+t_2&Mh(1)&m(U>PCLhlJLm%z z$d0jtw2sEGHM}P!&@*f%8^FKh51L_v+UQ+za2pQ}OXZDt%p@Nk&vHf;IWv-a7deYc z@(Z0s>1+qC+#!-bp-}s+^c#MAmI$e)pb&pT&J+1d|LP5{F?}gYFAU+?Ol+7*KH`oa zbeq=+b(=O(7U21)cWu8o^rzu#j78x`#r)@Nfzhel#nLpp2BHx@AfAR44b66Dk0~v5 zmgJ2r%+4Ky`#v>~2Kse~V)to|OTYSo*iphG>+6s`=*{C;NzqVeLH;ObNp@+TvnZ9- z;=&?%p=j6y>uIC%hT^mIf$SnKMay@h7Iuv5TDwb+)U=^e$_}xMkm7Zcy6`AAYD|H% zaEP-s$61udABHq2l;^O5q9LQ51vz5h>$;bB3VIVC%7<#!AMT|AV&g$uxANN|(P)tT ztfG=a{C;-H=sf4plI)^km7Fh^KirwG(0utat*7-CbhtB*V7WPi$2)WK@Fgi6m8H=u zU3oMcTv%A@9GRU{L+t5%Bg#B2PJL~Q92C!gmXGQozeT%Ovg+S? z*~nvuI7b!cj>^w*=8ei8JTgyPBL@ZNHK6n%e~aJFYphNe+K1&5qXcpOkRIKE^V2AC zbE1))>0lzHl45MydytsIHPIf;ZEWqHP~E?`pO&ZLZ?3jodtSRhkyJwS=_Y!ZUZwAu z56fb6*mm|h`;#Z~GQNo)<|oa2GE(V~`C&#Py=r=9MjPKI86(2XPMLn@s7!B%{#SyL z9gUxSWH<$i^wHFTY5y_J%y?R19?A@&>&+9H!StDVF*BIyKbzh9K0|ZOBUuTY@dYa7 ze5p!xzFMUQZ&Im^uSJ?f8^w_dmPD=Q{(iwU#ys9HBz>&x4}RK84S(CTXYifBQFqFs zT6&P)qTg6J8_pK7Ti9XtE$_zr^J)AB%p)I~+5SWH?nZFDSu{D2GR@5X;q<9FxxYW< znTz^|8_ozLBGEk9-`m{X-;?Ui{r!We%>1B#Dm`X)8jwNb&0zzg=_|7a^lNh~=r`s; z&~ME%1A5vYk1#?~P!B~HZ9zb8YWCOHpJ7TrxA}IowjIUlE_}jLg_BEU~H79EyjqwEIv4o1vA=VZin1)mE2Xq zy3?KJH)A7-o1Mq?pxey!aWQ0=W#f9%9p;VWqKKJ~L9*RE4qg{aDp-vD_DCZn6~iIudaHNxd??BY!##M(-eS{s3S`t#oIy#tUv#Ok zN140FwWHobzE9+X9ni9d=C3g~ouLuh9(cpyk{ZUPYUi4y9q{u%*jrXxrhXUl0vxyMOs)>d{3j z)c8w$J65(t_B(rltz#2dAbm);(gX_9zSSPrmT86PsZlJZi~0VNm=2kpJ=4j{(WwJ- zBsBgRG7XVx8%8x|?QD zvi2ti$?e)g4Rg5lFDueBlgY=DBgG+(dXtyUvX%>9ME}bvFkr>QBMu%0&Yy$lSjuj=Gs=79~=k>AyII0?d(%Q``G{rjVD1d~&?Q zblv1-?pW+ce&&;l)5+I7w>XM?Oy4EZwKo zIymhW7pCFzNb%4*mQ01><8>^Iip0^ISSV)1(H6t`Sc}p51dB2FWQ(zJr^VR$w9QTZ zsL1T!w44gfC!3z2QEk=Dy@(3hwzWJ)m?{gdf6=4VduVEaU$ASYxnr%jnRLTLG}`>= zhNr2-+`9IFN3nNysvoXqs;dibe3Qnv<*chC8rSyZO&=1CHE-Tf(~fHoXzVsxp*?`{ zvn|9`ILSL0xB0jx^-u0#{c|`R3l`3*n&+&UVIJJfRhr#W}aI>VUim7QYFz8G)bexJ8^yff=;KD))seC=X)?(&&p{kXY1D${;br=Yd9YZP&#KrB>;d))mWYl#iIW#(C2tx!1! zpJArW=x&P$F+yU=%$gCvSh~4rMhH6i7Eq`81n5HZUC`^y3!vLfpP3=HM?;N>SP%2i z%s|E>%@Z?2IAa+qw`|JHS!-nQ>%x3lHx|mG zSWlM7`e57+U^#3UD_|vT9GlF_*$n6&HCVTovwGHq##zryww2w+3h!k1v4=6l_p+zi zK}?yiup{gp_5nM=K4WLtcUUlgfj&sw#yxpw?!yCl2#@5km=02S2A2Q9(ELVXY8cBW zL8++}2mi}3Nzs=T zeMQk%6@5+7*A;z3(Ibk!spv^XPbvDTqMs@HxuT~PJ)`IkM!i&ie^i;D6uqG6&x-!3 z=wFhOrYI?zplG6^Ns1;b+FQ{SMf)h4s%V;`>5673nyF}C1NH-h+A#U{&&n4m(PBka ztI<-$FH>~6qAL_#spu+2S1YP&k=7_)wKb`>Ce_x|q~y(e?mwZ^O!Je6_tT8F?YlY> zRkl6!NHwFXw!p`B5Y1|Pde5)qG1q%Ua)6&tqhY@JM5u6%vIlQ&Gt9ppe~IR_z4Sy3 z(d@SKd%dWSzxI@dzjv?}#!&%PLw~=Ao};f>X9oKL3;$N;W=Gj~yd9K*8h$T7#7|&8 zZ7^5v46qmWFrt$k%$)aK2-DV^2X-dXF7vycVOSA5-5CmXD(TMdG|4Qy)6YIM*a(27 zE$Sb(`8sr04)1GoO5ZFD-1F|3W6wg0=@rs)OZG4Ks&TAu`(XxuJonmmoM$3CFahTk9sWj z&dZWZuhTsEe1HginR=K{zp|PZnOU#CY-8l7v1M(YhuKMlHtF^b&gI_8vh|w+wB!zE z?J;lhMWG&G9(+d^bJFdeZ7W|3BwE(C_4OudjbuiU=B2S&v=@o|*BH9WJ5Jr6rKQf7 zx3{Id*+{g~eDdgHw4!a!TieKSy~ZkNsdhd3!gAd;*QJ?j-#H6AXZgEd)9SVv$6h9A z|4HxfCfz*s{smYCN$-1$ppMjDwCis7!>btLnQVJIv#8Y&--nTh8Fzd#Yy^}tw;$h5 z)Ry^SPX_VykMAaj5(l5yPImLD6FbOePWt4Y1i6xUX)tALGy%Kq3u;d(G?5zVQ96nB zVFWa}SGdk|`D*?sKZf@lEH>_?9r z+DFA1S<*B;zn4WaIwp>|DXHDUR3odugXYekDUQAbCG?#a{b_+Heu?_ni~AWPvS60I z_I#SXF54I*`NCJT?29suJn*8!%ameYJkThXnPD$erhQ4KF+v)053fz35^>;Vz*7sw zSu{1dh0iM#OYdwxIgr}54LW(oAkVhgFMngyzAf^r?-_M!^ZquMsAJoN?@EX|v^{)w z8&Q|GVdsLmM`!N{*_bd;x}5M6Em`)i=Adu&wrxK?Mbx!z?1jHLd9{uGbvJX2)7T>I zYi%6rDqnYXa`}o{P8;+_yUVBT?8UXfYs|A3{o6MExrn+2YkVda&OEw9`$Y>@{YDbk zSXYqf=}E_QSEQ@kmRWQk^x@7#_jm+&XC=zl=pas_zlwJWSb@L%fo`G<7#BqEGum>g zRmW-CIITh3r+r54V2jUzhJF>Mn|e~Sc+8v9=zuum zjhgB$y858rQbeW?YViXx+lLbAeQ~P~^|HT{VdO|yYjnvE6Haw>Xiw!=w<9Kf){j&7@=Xku7(nmu0Q6_yTj`{(|`&68s!4iDl zm3o&=OVW55dzX!*#oCuz(x&Vn-PPL_E}rQ~PdLK73S|YaGP6I76nAu@a@|$p3KcsX zP@_V`Vh_3=zwnm_RIXsLwjFK1WYU&vd^o$C{-kQH9MxHH_<=e-j3;K#Y;hGz*FL{Ad08AMSL(|m@{Hz zFvZYhu_&0r>|-K~#0cEAJ_$If{-F@Tu;1Pi`-7<$9Ti_8vA-E1>v=)v1m$j!ln8huqz&gIj)l2w9pi9Sz zn<8kT?(%l^6m$GZP^{nq^bN(hzYidtd}W*3F@5nHxgT2#4YykRN~^&$Ci2Cu6tS)c z#ztr~O+|OEk0zJyB3H8Hx`{hNsfv<>M;NtIqSz5eHv+or6%JE2UhD{`1)DeOK+^&B zUB~{S-v|rJdEK?xl`h&P($9JWxzhFmg&~hr@7P3Xvw4cY0?Ai=tpm%==s}~YkNow; zdpncV@9r35Q@Tg1DC>gG)7XVZ0iSuT3)PBAU8#G3(&s02JW!aO8?o(7LnCxlA?^jeQo9r3I zKdb0L*)2O$o<@17l-ubreaSk(PN-lvL7zDV7?sLvO_Q}Mq>e5j2zsJ^IVy3uio?>>5Ubx z40l94eMXzl8Fu!d#&2T}D(u!w8q}b>=DV`Qfh0OleZ`~6RMwh7W2nCvn}ILy=MKoE zZ&-LItytqP@LPE;R5@ZVvQ+@GzN33-3i)auYpq%_x?UX1Nf8Hrq#TylTTJRhL)s^M zre4B!5*^~y3*;>h^`QXtz7OTqM9;iSR|f+5*@USxKNZ6&LCi_T)%dHgo^Qa_59HNe z;&*v9?&_1kX7N)Iq{$q5fi2D$7~x?SKOM#Nc4o-aJ<*#ws+8+pk@fBeH&4v`w1d8OK3?RD*QKq>99Mi0PjGmmb-;?feh(3n=KSN2}}8E2k}*>6|xzdSxGfJq4FfK~2$%12GpoHkN#N zc}-98$XM!Tiw)Ita2cIEz)@b)D@@O`azR)mHjSeI5pp{@M8Y_9|3pzV4h#0iaZ+-^*n$ zTQrL+tEbOjkR_X>2WndTOuL976N6DVlFG1hZN%Drm_DLkw1b*dyy8*legG^^wh(a2 zE$kuY^$dHDod?|2ix&V0S)-0%6Y&lkc>a1hk zm-32o)gZ52ZXzX+?eVgzNojsv?I^{S08}f~W1!XrojapprEhjd%}n(i-^sc~PiXKY{!M23&U2UMh5XIE9F3Ct%hK zmx;fTk}R9J%S6@0d7|S)G;wZ#4((mk!Va)`Td(R`;sYq$IgxxTVlMxW52>2woUZ)PBQAHpOA>tTa8#N&Kasr9<^09ji4y)dW-PU z<2+=WUG3D?*8Q8Sn`v;UU+V$q+WLPJ>)M8YiVf*7H^iHh$d}u+P39Y(zO;F78HH23 zQm?p7=(kI>bg^?5s&!yFmafs_%W`^yO59IOqg7;#_fF0X5S=P9NQ$P@Q#4L^R?;yV z>;ANofRv1JpPzx7pigd{MeoxjQCo!taH4R|rnlQo@Jh+_3kY7J4YZzLIENl<-A*=P ztD|hd1jFiR2RYqe)lnhQRFS!uo}nr3|1Ks6waz8ot-r)(P)BxH=^qOCV$X{wy=a(H zp4d^h&0qo4fy?V$SJV(iHs)8~No6`K+C@7zhNEcT~7gtCZS4bCENEcT~7w;>+wXxFHr2vX5 z-J_OLDtS!zPJ#O?*fmrX)uGmB+=P}{Uq|i4^WT!Q+o-Vxd7+i_7R@cMtD0Y(;7WB> zc&DeMmR)14@-ge7amw=Mv1whz)b%iY-&;;TP`bWbj)kOL)UKcnts6;?>8d@d;qN4M zp}|n;?xuGcXT1USZe-80vpg86>{7r}(pl3e4#nD%uh={GV z#nDPJrq&j3ypU#$juI1UZQaDEspQMFBjTxATR1uPuB0NMb)t9`tmf)1j~jj-R=orXSDa09h?*7#)Q1q1{) zkTz8Pg8RQW$Vbh08#khxGuIL^b{(B&uEk>DO>~gC771EUuQFGicw;?n(OnC@3&fl2 zDNJnW$a;y#H&9UzZyAMfulByO+~?69bd)Zz060l%p=mwKz5tRK!3#u!Lys_v{3nQF zhmJ0ASP!DxB%e&TizCl*AFLo4*M<#j#nGAvS(W zcCm3AohBx3-$VZHjoUGXiDavGlRxed+d}M7qQ~vDj5OKCm!$87*rUbQx08#x>SdE# zV)w>7pskT1hVO&{s=H6^qG*v@xCBY%)y!V6x6x{=66!lkwb(Ifj1*7P0s;60$7!z$(` z-z^f7c$s+OobC&Z^$0J`|mP z)PqyslYv4gKLi0fIe8_{g2LQ9daFAhc(t%}SV`XKVTB`e5to#m3w)vcM?Hkz6s{k2 zALDQ^@6XJQU;7tm>*Re!Ir(|coRYlU{8DFW;fTCZ&eHsXyuvZ1+LJ0MDJS2VU0PUx zKpgd3vwh*P$34!$V@4<8`J+oq@^eaoc0Sv!8yafVTnfUvgT%M{xcuDGVdS{#hUEX< zV2C^BQa4om)A9}`-bdoEUsbmE|H^g|?dPFvClND`f{czqJPWZ~&yrs-b-wC`l>gn( zp&QRc@XsFdwUMV)yp8;9)K2k5kC7kXM{#5x`5FPLX!jQ}zX3Tx*qCq1=%T#5T=JF8 z?W3*I(Bj8od?f;)ZKmDyA+xb$xaykOBkV(M72NH8c)3WL%)&7xBnrnA7D>}Z?JJaS zFO4<&hr#N~o@9hG{*ByyeDoL`pY7ZjpVMgXlfbmlSaL*(+SaCj^M`DK;@p13 z;*>o{J9@~5^3zH*{4Gagy`ud9NB3Zw4O75PCt#KJVx!q|5vjv?-+sc7pE^%6(ZHxx zUgyiiw=!RE zvGa9`aX9$qo<=Hwl=J)bNXDzgCkLQy&X-9nK;cCeqw^IOV{n()@C-^^XXWkuCW~=! zv-Nq*bpBQ~ZF*j|f}d3{AHINA@O9tzB301d*I)@_&OyoFQ+>dJb^UJAy_q zy8o|L-g#5DO0bA{3zZ#osR7=S4G<=VzYAHY`_#L#0Ya=F8vGu>oJe<%_n}4sOr87z zouY8}faCCe=SFHZtgoG&9Aix3QG1vicz0)>OeUX~zAuwZolczwoI z^FZqV<^dl$xGzms{}Vg2M;8^KFU?1cD7qk$%X5|YRgX#g-($kW!D`GuA>t!>M|bfn z693Sv%BKIXY_N!*kFwoF{(Q_;f!5^nHu*(S(52bdnOit+6sFC*>;h*|VM(bI*}M`8 zmn(sIv>xV|_GLI9s(2sKc^Nru+7|&lm5K6X@@Cq8vsXa(`lq|_Xez=AaH(!a4_WQY zldqOss+;APs%vm|N$<OGj>q&BZMtf)FK#z2JL602t zJqA|YDcT0KuJfm~pQ7Bae@f{D0CJ6nzx~<;Om4HF!kOD6!@_-CMkGQZyiM@LBfQenxfdsE_@AaII@fwe{=7Tv4Dc>Ie#BSwOZ%SQh3d2Yw8B*)`+NMx zysu#U?Dm89)#(esN#@t|1jV}ZzmYRcvRL^ojK(C9^&P$Jk?5V3EtPvi>^zIfCH^>h zh@`WK1WE87ku8p{M#U_>F}cX8x$V@Jv|bWukm;J!@QA?;@#NS zh-bMT_)K5Mf!pjta7~u>U+rmBcmAgAZY*_(c=bM@otb%}|2e=sxnk)#>eoKUb0D*# z>oOgpd=#F1{2T?-VDaB`luOy7|9Q03ATj$qJW&J1E$1a(Ck~!R1N0ZaoQLNn5bm93U^`SH|=tq=H6;(3nBR2m?v8_Mh5q(9} zPrzw2#k`+r5^j3=CvxJZ*b9g?OcNU~0Fp`-A76kQq>t$LGvabn#3Mh$itp_n^9z~| z@Abx?n2#U*FQyf|oyvUiD_R=wNWWvU?k5U=$3mGU?)V+E@Gy~f5wq}6vF0Lvb%=QB zB77WqBH<4RQ7eB?G0@RhWNxtV{*xx77HVZO$c-oehp2E%E2{;x=^!=+CgxOPRRBw0 zB6cgl(h9~#11xnjb{D|XNt`{P&!N?tyYowIEJ3viHOp?(#c(?dDO7$9uKXHY`8Bxm zYjEY);L5MTm0yD^zXn%+4SrDB>W36nNCQ_$0|(MzXBN`HkBS*Dv+yF_E=%bSMLiU4 zr>Li*?G^2yXh%gA452F+LRT<^-c`xH6vbeBnbj5!RheOm<|{f}(GiM{RJ1_RQHmBS zTBK;Pq9uxsR53l)pe?bxdTq(eN}7sCRzk=PspC&10xliG*cUszR#!mGRi zTPfb7-&rWjW3yqMK8`@JKRMP7J{R%od-;b@ivIRb6#vY_5dU6pF?ME(Q$O`{c#$w%Uqn#tvWMIeYaAud{cq@CN(%3U6ayUg7QRd&PU=IS%&U2qRYh zKrGyvEI`!8vT(o?@fO1w`lyuXY>dSitjc0+Y?WjpX_LwW=(y*~lL8I-if(x!#CqF< zS9s1|zQXJ5tt-62K2*He*qa;lx#9=lF?RNy)FAz3JulFF zxo6d~<$r6>`*A1yp1b(5P1)XJMI4LjMBzp-5Y#KNpG7x$8D7D7T$0ZX%2gcE ze=*U>1O6{gjYh!n9~m8B&)qzVg;SMqk79B56=6oOv;n4^3k3KWW28rk@_5}(gch<6 zFgE4h21Jjd9lGXR@~~vX6*IH zoB;f=G=S|Ur!WH9Ai#%10@?jEMSLH~ZU7v)tQ+FME5wo@_6kjN4-RJIiOSvEy0c%2 zW{54J>>&Vd* zvrifDq0l6j1$;;#jd0f|GwkV^>)zTM!H!0acYJbyC`)D`?nhFAPePkkrM^jH-5G0G z;6`Nk5TaUlNniE|sqhSM#FgXkW8eoVn5vsFh)w`HNrNkGJ$s6MiN!o0&eiMqE|FBG zkHWNKzd9V#|Q1$@97JGXbdk^;fL;375?D^{9>>YqKIV0GC zy+v#$%t$e-m=y!9d8!zzk6m;wL7%dTLnX{bhR7Ms4z!+Ri|x-R8~L)E-;oDJ`?V?5 zo@sB02Trme`$1_x$pO#`tnuVY1oa;h=W&5<79CF^3~rwobP8KJwg~4b>?BAR%TKXB zu!J8y#d^Raf9w>C5BWUUh{6b~t6DsNZk2OM`QJn9Mu_lFSv>tm6n%;ce^p%fDGLrM z4>p2ham)NVxLp>{fGYv+xXYdueWrNsQ;fm2;>%B2EUglqKSLXw6iJ_J~cDYZleX5WvOAOe@FUyK?&J|8aGij3@4n z7_xHATr?B2);{fX>HzI%CIGM(5!^jOD`!j4fM+o2Pk~MKAb;&|%YkMV`bPqnli?$Znhjm78*TRx&o&!fjgL|2KC$sS zBTx)1vKcLzm zBtJl_8$2QgPH{tZ|t=%J6OK+_WAF6#w9J5ymEvGx_75V|adoZ*Sf#CEX z(eDcRD*h1vK)E#(rex!fh+2FT?XfT>2j43WO~v?pUw)qiW==>Z8mqI)>-=j`CiCa4 zyp8`Xb~{-Q#xE)X0uxv-BRj%FJXWUnV7gtbF4N;tyGY^?p3=!;bluBh3@nK1l1=Ys zF?Kz~VgTvOS5bA`k?{{&OIbgFSp7>`i440eW#3T;v3d+E0RHvb7?!VldPT*F`4d>Q z7&Mmk1^BgMEGw0W)tlp4Au##S32X#FhPe~i485y&YNA*@mL<7u6QNB5>Y6eM&+ROB zPhv%TXEAt00!3~WdqWTK@<|kBlURsIoy~f~j+!-_mBKbVAQNAA*EyK>07PtB2CX7< zE|$0MBDo%KE#|VP0N`v|1^KLbYyeQ4`{uE;)Xm*m&8n%skis-LSn?1gQ4CCG3J{_y zL@_QxsGEzfLr9zngZK_aGCYK?@1_HYqkfr=AnM{nKs%@5Y5b9XrN4lsd142HA2hiL zY#vF3RhGrF*--3W7>)f~PF9J%3$>VcRU70JoGFNnEuISH+hhJr- z$|b75C2UbVvG6%k-MSoOO#rEqL6#uiLzbN`&MSoTFH_;TuBMf^W zPe*+DVDhnPhZH|Q&+ZeVe=EVH?A)>0qjK_c0UeD4`ZGGOv^0Oz(9zm|L}3r^+jWJ6 zR*+zZ_u=J2(Q|p?MJVv zrp@RVA2Gt{8-ZzY3lzDFK<%dUt^75NaHkl)j`hOM-X-f;iv20<2a^F0kE{x@kLY7$ z%h=$erUckDh3i?k?GsCpKe%3+1peYAWYCU!Sqx``BohhaNL?`4EQ_(Rl@?=X8x;eS z;O^eWP#70SH(=rRQ)>+#6lXD<4YU}YjkXwr&9oRBTOpYgIB4q_&~5QZ9s3Fq5?dEx z%!G;S7PEQ4JTEL};|RfAYE)G$#i)uAcP>SVXgL6}i_sc;#&V3kD67=58lZ*@)n&#l=l#9bH5I%)R#OIi%UJfM=MoxWvDH|$dZAe zCu;4{cB5U4kr?k`x?JIm{xaWmL5*jcN;xBy>Wrz>U|gj(rX!6-5W6hxU^X+fF_>D+ z0gX}iR}zhUX=8juEXF}2Lyb6@o6n_wl5alIC^ule+t?F&T-Rx6M@ObnfY>0jV`~bQ zgk2kXPlKhv3n3och#2&98@crPwBN*|>_&=_ElV!H7>s>so$XV57_oBA$eL{rVTRti zl9dC$QuEf*m6*2@thzh45_K0Z>#h{|*q5s?%_6Eu&Te0?MyZ}|%x-`~QZKc^8q{td zapxKoORq4>K*2DA$JS^EN`fdY?Cb_*E*+>F@Qr?92>T4Byw+Y2Etz!2!qgaOc zq8Y79L?1d}Z!p6fMKT)3I_ z5UZ;UKjE{1I`PuR9P#7L=s1JLh%M|6U@+foVatI;&1hwG=E09AP;*PilQJp|< zQns-RFf3xXvmKQ0eq}r2acP+Qz1yTgGt_jhMNE)dRUXy@P!L_H$m zOYeluHA3Xv#SRJmetckwD8HXwL`d7z2cT+Gk$d-psMnre+F*^p$~W=~>;vn>KEh_Q zu~1ik!Zg1b3S&Ciu%YyB?1~*M4cdNpvm|ay950UE%@VkgI8HH8@Q=s~JaLT7Ct-B5 zdsw2Fd=Cb2{ylIym53?#u%19KuD=KBbCG!V9_ZhN;-`BsEsPRj_o7w{#H@Q!-y_9+ z_hNAyA&%b*lX$q`_u;;Lk#HYM4il5^!*V)QwBE;3I?AY0PTm@y%DR$wTbDC7>f~D9 zIL13VR^pF~7NvF&U3anX^@d@MrEcFxu;c+7n2|iPKM@-p9H>-pg7DF&opLWVwjhc;HC@FlA!kJ~j{rZ~Zj$h8gFaquiaonZhVzh|8J10?CaA9Xxw zJk*2o{mhr1lZiLCYlkfc3xvfO+ChuawP!7cYtJagk7)-kM?tAmJ!)nxld)MM;Q;f4 z%K5ZN0z*#;=K=h{<1**Nnf8RmaBZ)}=$hMN3=O+OQ6|o&?L%OghYZb{J9m1GvwE6* z>`HGP81vs{OyEop?>N5tU#{u(KDa@KXkGOXLkxO``Q+L(*S}n}YYqP*b!d%PdK zK+CNY=ke2wEwWO+*h=*!GW8MXK$vZrCA2SBslQ{zmHN8$UDGS3E!CQY^I7Iw-+Vdl z>+<``i(G5@H?gi=_itiDyZ+zAHtmLg6Wg`5SBb^P&oU1*+l{TS0a=+X4jyHp?$=&p zKs2h{Z@kX#2WTRkpP<*=`zEH2d7|t?79^g1pLG_)jgq*TbfzpBC+!$OmA~P0IJYfC+_%wO=67;#l;Wc#%o+4#vcdVQ!5^m zNsVatAuRj(@^;H9>!l6U5HR}_6wi9}0G$oQrq%=O4<5ybY3p!tx(IC#e9O@RtNj5H z-vQ3*Cu5C7xo&*F-WG1?^ZLV~l6@L3iH)Zz(tdupF-7`GimykIxAucL_?$kFz83Wz zFsXbmp6S5y>}UHL{bi9UE-24&zEIlFoknPz_LKC7^fkU6Y~U=ELmdGj+_-^avGY!K$AvhIN7+UnQzL0Z>>kZs-K#wKdKN%f|ChY-f=UdO6;R z9*EqjovcS+dR-20f2~@B&h(7-9YFmNu#6sn1NJ=T`b1X9X0f$uk3Pr7+>yLatL8Uz zw+j496F(V7s5Fe8)e*kMYb=JN$0~`=S6Yn08zhr}9U|(2ov&96c6{CJZ+OLta+~2T zCfkf9#_2HZ+BSD)2fHuWjCL}1aL#lVZhtn)NR|-Gcf~jfKzmutJ*$V)4Xq!sJ6Pjt z+1}$=<0{$IF(Uk91T;6UlOV%%TH^}Y=sm;-AIl!GTsD2QNIAihSmQF;0TAAP z0-xHrRCa@2;`9l&m^ChuJ#uI3=j?7EL#w{Pay8=%Og1F>_W&&^k?(1Y#m0Jf{Ar0d z*(_n@S14y#eE+Y(>lW|x4R~(x-+jXZ65vrff^#31@zFdU8^BM&r?iF5hdJs^Um{?B zE!-dpz!Kip?$MS=zmks_@-2(!dar76^joMKWq)DEH19RSfgDHg*bCX3pglIu7zXP=CGlF(@sgA&HBgChzlqX+x56fVW$jGje z+=6Uag(LHFO7q9&AugdPFS``hAf~ZRpTM&?OYA~vdcoY;&5tKDhe~_1c1Q!Ly~_1r z9aWl&Rw^H23!ttlo6fvdnt{>ss1&~;l84&lL+lpQ8_lF7DQG6e^g%O$3BcE@d>ZRw zG3jU~DXGt3J~F_gq%a3TXoaInOA1Ho)iUltNk-+3FU2Weg{6f#g(GWZB!N6UD?9(v z*;&af_!?PnmVAvYh2>o%>%%5MhEo@=eqbt_cTK@G=DJ3f&bC}5%U}=4Bg4E=AAuIr znh%%6<=^(KZ?Ce7ehftf#mDA8S+PIewbcB|o#wwE(o-wFI=nB|mbyYc*(P0|TAW zAir{EgB^5sgZ$Px4f6BmHptJL*C0Qvy1@suroO=+No_+n&;r>- zptm%JfNpP$0KKg-7W9tBM9>|Lsh~R>W#!-5H~{pnMp@x^Hx7{%Qmwi$^+y+8Kudvp zG|^hO|3w(a_4hW)kGQX~1oVMM`6&-JP6U0ZaT@5ZMp^%lHqHj!-6&uGu}1mEk2lIX zf1*j&`Q9cQ=#x!S;o8^K5%lRMSr=gsx<3%+QUU+`tKtn<^& z@(aFdmS6C7v;2Z@n&lUK+Z+t~U97rD?ZKj7zP*$Tfj z4+8yfa~|lg&GOZMYaRvqd$V*W{LwrP^v~wW^?>xX<}y&$TnWmX(O*b!##@uojJGCx zGrBrCnpc2&wBRmk*MgU(_APj6>d@ieRUfuTEWByg|FRppTPR3qF8+ zTF?aK+Y$=u*MdGy{w+N)3s7JSzJr2W(ABAXOA=^E3x+j?w%}_htOd@c>JeT!u}2#EGbfTAn;%`%8_skH#4ve_1s##UQQ zI@_!mEP(fROHso4iA2#t?VJfS>R+z?Mx8UT8xYld0Wv~Y? z3k$NxUs>IQ1R{F8>yxg%mcnwc74~7{uN9`Uxz`HQ*qUpF>Fnlfg&FMrda2^bs*s0v z=H}%%hh*b~&14q(ukzlk&%er3*sy<<_hFO&Ri4UfF3Icv{=;dk>0fV1XIuYOp1~fz z@>y3-9ZhCo*9v>H)N6$)%s2m9X&*MFwKIPhu+*;3{6)AU>$>nKU~u>B$`6pA`%G7U z6TvmL*qi?cD)ay!evpFPfBA46-qXz;{ zL0A~><{()(Qb4J_iz3`5-T5QbOAgVl+EGl*h=WRi7i%3ojq`p2u)T9WyiHF6OZUO4 zDGSy48exO(5#Ma$@wPd@)8j~-+r;5)=e1XIF?PP>N(P&x`KqgO25-D7XX7_qm9z5= z|I2X)-y)`&ya&GM29t--I`M$XW9(bwjcmE)I&rH3f8~49n=S47k1dAt&n!mgUs;U7 zzqc40zhE(T{(EaE$3}6{Ka}4BKg4^X{A0Kvo(MyQMT?2y{3*B~d?NTat!Eg(&KQ0t zVD$%LQ0Fqbith!Y9@CRQLvilYJ^5M!OunEOe+dYARy;ohaQu&WXq`aiqZ9dwc%YK_ zYejU-TiRJ{fXcychi7pHMl>q73Om(yA=FjJ>^76%#@~d)XQ&u!1n^063J81N&n6A?`(WV*MfBmzIi`5Aj~u_Wbi97-++V-(e&(M8;t>!D8V&%!9}j zD-ZJs8X$HY=Dq1|afjTLb>=V+q`RcZM{NIG9!~mzNP7-p%XeC`)n7{4eX?*O-O<{I zXTb~5uMhtV-iLmv{2n+SK27C6Q;Pe8G=4u(rn@0S)?bErI1>$$?k?`jzm#E|8U6UJ za1^}VkDovQ=brw!HA{>iz@LT#!h0ZgRwZ#g&tJ=j{~hEZ?F~d7_#$*;Dm7@c5FL6H z>q`P~wj0#BBmR5{ui|U@ZvH-c|KIlenf7$4#gG9_=^wWXv(}QI{9U>OwqMzo8tUUD7T=yS&vYvB9 z^icTa%eWCh(>0n7llgvn1*b!Fz*=04-Q8Od5ExoxJC3NWxt4i8|2mlGt}AA{oo%_o zJ7BKC!Vgk`gilMcJYDd4$%N7CR$gbvEXH7;Sd5LGu^2l$Z!r$`o0!K@g@IxdP(2Jl zB;lO1!4{*lu@+-M2T+%6&;b-5AP0BAG#Dk^X{l*;-TDIOk!emBBhJeEI7t^Ig9Tre4v(f5kQ+mq4vio~8Ncut`h zKNWp%l<;=)a|ymU4pMV#pF+QhrJ+#H1wF3K$429yS)jHV&iq>JkpC3h*81}${B|?x z$^N2xH^9(M;`coOn>LEt$5?I1O~HmA2JO80)pfIgtNeX$K0>evW$iURje*j;xJlR| zn7&XH??JHET2Z|R`11{7;~s=c-6VGJ0qnJ2yt9Y(uy05-vaqK~Y-&S9L;p6od{&6! zHkL^{#f@$7DY-uUpo3LLXLw4E%Ch_W z82ND`c{aRrbz9(3p~E76w$aOZKrSV5aJ}GfCyv*B4#&uSq5XoBgSsI`VIZ`=3Is>2 zMM%Ws2!uF6KLVBsMnB6&phG1B9Bx2h!!C9R2O50^JR1-Oj(CuV39R8e_(6UW^J8!E z$X4F5z7L=9_hYhC`Q*O~(zx^Qf^Ad_Ok_ICYA#^sM3i3kMwPQ}*>>wELkYo#fC z+_l0!T&a?Oe`qS7a&5^pUUsc8omX5d%&6xxtas1Dx#&es`I;=^AClfI{U4GPHsT+W zKFs+KNh(|T4@nxk?jMqL7QO8sq73$^gpP87cgYtjDFwil%pwJC<6iwUuDO)LMqVT9 z!^*CarLsCvj7Rjl{+dhaZ2L8`47OVy)1I4C;vAVjq)=_kq4&g&ZO~s{ln3sIz(I6U zCbjDLeVib=#A5pJRcZnsD;}7R2^>M&m6*UwMa&FL;G^BAXUGYBqF68s6Ziy?RfP$B zy!($TIbn@+N6+EdPdiogn~P~~is&~F)6-<}={!txliVLvW11T&$7KW}-L=y=*P{#d zz%e={Gz<2Z++=$Y^VE0nBXxr#BA=D9B`Ej?B6qhV67_u?wBpTs^CDi&*YUgfGyF}F zl!UOCJBzqaBKh+aHadGqp4!Fgys|^q&}65%tle8j@~5$8amvQMeQ&w;S_a!C!tC4& zCP6pJ;BYo8pTcr1rVkruF{x~h#iSwTUfq+9n0v)!u=~W(BD`)g6dc9$hObvKDGVEE zm+e1EkB>HIInOwG^@3BOv~dYzZ{kjZUb^)eD^^f(~OIfY~MN+vi9 zM>+FKN(xIxYtPF*UOIBLv#&wON zVlU#{rS`z&ORxoa(Ur5dLq*!1wm>Li7e#gf;(8qHcTpoHcJ`w<*_-<*b>n~~W9&tX z;p~XT=-mn;*y=O57J83aC_LXE1LjHreeH6D|El3;$ zYrR_16`r$P#apj7UbXomcf7i(JRE?&#OfMB`ESjTT+P0PgF>-fj4 zX{p$Qb9q?P5;1-~e~L9N7Tz29x$Y720QBc^H1?lZsk5-_Y6UjyJq=Xmch*gNP;`G- zzg~2IL=U+1zjp96ex3U7J9s*F(8~YE10gV`pj~Dxt zxn3NS$$D{0CN~RuL=UQeR(5x+c_W;q6N=IIY$k4s`V3#@&DCz9q>6_@Bf~4?@MBY?8uUd1lh3@ zNf0D51hFFa7O`hUN#1l&jlPGf)l#%5Rc@zNhw7lTwAE7GORcuQU#sKi|2_96O8DoK z&ppq5?z!jQ_uMm|@qMg;?RI87yGzal=6>hxiLAw)%p~Tkm@?^U-n?DVo!3)X_?^sD z))o;_yf7*eD~)G{l_szzR+`9KT4@sVv(jW1Y|SrA<*v2tC|v;`pobYOb{5NM7kinm zSY&?h0urHX3&V~V;RB#hE`Jogoyaa5(c3lipN&@gsxYHAtI0-}UAM3sP$75Sir&uU zS6k8BnR)gxwS{YBF5jlc28Z0e9V3uo=0BlEpr$f)Cq|$q^241Nf!yUYyKt+U9P%Va zpvKbkDQw}^LBHz>+(`T{*LG@W0MXM8Hj*332`m-;EyM9gFh=}^L3jex(kHMWOpsri zJP5nkA4+M2QLOBi)#BI%U-sdfbTxfH_l$Wc7J2aA;#vAS7NpO6;(Sh>c z1K9dCSKoXYcI^JL>vQ<1 zezNQH_%gootLO1ieay2jsE-YUh z`ngT$^m~hN81!nmXa_S{k17^m%_Sl7)s-y79c2VbMQkT;{gExU|Kj$AAx^wGCGJmOdz|%%wz_2YUkiv zbP>30FVN3mP#g$+#}e$Kwz3x$P#(N3T+;0zYwELG1qCX~>XmKzsAB=rb3kDhe@b>d z2&vAKGN6$8RqRp%P%BSnR?ni|R?glTnS7_>4;)fbn9(OIv#3AJrh66@6b>ZE+~Iv( zlz}VIkB?U__6=_C*}q@*0KQFm`Zv6i!yi`*np@c(aGpoFqrCKi8GZO;mf`lP?{u#~ zzT++h^eW_=)tXdZJFT}2;2RZvYhfr$g_Po(v-uNhZ)rWLPj)tbIIon$4*}ga4p=}I5f3aNi%4MK*+e4y*(Q?MFE)|P{;-J@ z_CH00D7&0P%+G&=dh8$=9{{x`BfWoyst^^v3D%MO4lz&PT2&QlRhiuzi|uTzAuUvy za@R75+uF;nC(*5AW!F>amof6IQ|Q+1%(EY;ZXIVXKdm}jN4fh9x^)LL|08tk&Z?dH zYbA)J207Yqu&YedmZQZv;mB|TW>=mx#R8nz3=Pe<5Y@J0xmpQ8Cf2GL7o&KDO!<%1 z|Nf^Mau_<|KZ=NebES38=~TIS>TOEGo&HM&kZ_#d8@Hyz7n-B1{){U>IYigNxOfEYDo2^s!Ij5i6 zgrHyBgie1}M5sakbJM%m&+7OA$}tzL(Z=ljMh=V1P`N z&z!}FNPxu`2FQ5R^D_o_&@OV~Ikts#-qGkhgA`OY{+zu8A?RD5vt2Nuo_T>?fjqDD z3s&2xhi60^g{%PEsV`wJKFp6blObQSArKWV_>!F@-ORpUVMz`l>Bz6yHOTw&zF|+0 zO!@maY%9qy*ME!hAt~JO9h3^`viN(p!}T-n?kkIbhLRv#J!G}OMq*_jx$Y8M0i)r- z%j^{CWnQ_=+$bboDDN?32wIt=%G?NY>B{~R<^BV*^U8jz=;sNuN-dPdf1p&DP^(fo zO3jz+uA|gE8Tcnk9bjJhlX;M~s=;|ea*O{%+7}R%Cqi)hApB+i3y+xL&_cXM|AWm} z8XG2KMv2ifAr_vu92+mo1y^9>Wf3}dULc|=HeMFP!G#qzL@hTVTxu|o*OD|(Jif2io$^3wnCHnWs%U!D1&BL>KNb!R@dhe`~!lJyq{@Gatd`>XSAX$ZjvoUolb#y_VrE4wBD9Fyk zR8m+T#`=-ks-uV!BzxTpiSbxD`Cf>Tzm)f@Ny!+s$YC*2aQ^`haou60mYl`-jmy(ReI{!S7^&quN z_xeFB@#TF`t&FW*>K8zMvWARtvbZ@~{aCxz>uB|3`on{wmpwOvuogWIFA_M(V=w$PXKW|Lw z%5u9@1EtQiOEpkxnO&-ZQfFAD#u}>q)M-us2XDyDlB5%Y}AbI#8Dj?7DQIF6Y;M zp(s8C_R2$|`I~fQg$!=P=h2l*<+?Vi)Fm>ottxe~d8I7|J6A_Oj8JoUN4^i!nAs$r z|BA31)&O`>BSW!7IfNa8Wj_n7iRM@YPp4~Pwycyd9bxIYlx=4p;Cs9%n-xQ&4P?D~Z2_ zJ@>IBzJPGEXEIMv7>jdL_}9c?4o&5V%VwDFo%uDu$szAnxw#vU#1TvcN; ztvgR7jT?D(YNs$)8)>q~y%@q{d|+MqbPCUxH+t})q^UVHO%>L}bnmGOYhf3bg~B}S z!Z-?RZl?88g*E&C3+s)-Jk6nfRADVm_rCl$Xw>*W#Mdq`9|ii@1qu}CZKf5d0=@qK z0t-=~zd3ZED$vh#AA|y}coQu(*fw?2Rv=EV3R_eRAeVRGRGCc6=_B+#nEJMc9!a_D zpF>Nj|LZGe%D@RUOg78m;e5rdrw;jKU&zBDu&T(h0Og*_;T;gj<+B_fiy6OBE>D7Z zuSYKL4ByO!xjY%D>ictfqVZf8QK(i5C5^FgYoOFF#5vR0tpANv%VxcUVKobpV-zldhiBQa{41-AB}SO;(@|nw=R5%OF?^RwIBuN6Fc}JW*Ew{v z_BVZ-Uc!d<00zu7>`-@GK>PQ|>AOWVxg_Oo5o~;#D3X*rNS?z0Z2e*7qi#Et13}Snm42D_ggL*>>vB=vbu>u+YVQ$X)1vU@fhxjxx%6Wc+!%> z@y0p<6beqtKQi1y^H^`+X{6+06Z+s3X~2P!t&Oe9)y=m~c{3-JCH#1rjkJ*0ct zjCpnx@TmGvTgSnVj%)^~eCyHnyxk4Z`Bs%$A;0!5kWZ1 z*eZq*=CBO;0p5xEFAE>?sU;py#f)32PN_<~AYOLJ{p!4_eV&MY_Lu71-#$-fA=2Y8 z&Li#fR2C!C4~tfSM;VF4bCy!nDbz=0cbQ+5Rg^_e%TOi$(qwuc(m+IL#$8^i^nlWeSOHty)zMmZC&@W_%CDOh6s zJ%o9fc@JRvWD~18$kPjegV)|nTc`%U*#B?fGjA+Hi-xEqbP1mdQOT+$7@i@sdVDD# zL0l^^ZYP_US7B8s=<<EvmZLJ%*!{Zgz?CMlEkkde&VKxR7q9 zJ*=LeWL3Y&Eh5SYhrr1yim^^M z!C5zpz*05cTB^!8lLV_NP}NjcT}|ouDVcROrBAAY0^X{r4XUR4m?0ZgP4$+Qn^04| z%*&fpP4%;D%7L2dTUQ|lO3ALTsmCFO;VUrO=hj_y;A)PUwo6r4fBRW+4qJ?Y2-YXr zW|$jvW9|@MKS>wBD8UzKDTl~Pg7_}lFTf(+s?E3JSO?4OZ9JOu$VzXyznzHSEV9ze zrf5W^r`)uSM?uf=^L8G~9qlVy*p$(}(!-|o_La?TO0=(RW>Hvm|G1rZxL=_VED8QJHml+%veGFBd<6jn=vf5E>uRKOw>H$;Qk6+n}pKD?LZ#+0(S0e#n-8#(f0rv}l?4 z5mmC!u8Ii5%Ub80j==#tbn64=745om|DUwhnjjbIS#{>I64;cnYRFb^qycBaw#A;qru)|1w>VX(D(k zP9A9^VigR>D|^Ef{uXgrK_U!_c*mMH+;XzSiJG5YQ1*+hq!LDpX*fTr%ou|kDO^QZ z-;mw1EP?q0xa%ogyP)()fmU7)mkLeBRk3iC^A_meq!J_>f+}~T%A0754*Fl$8$27M zu=R;QeghwGwEc;*-vnK%KJXmaepr_a8{@0bs4B5DoIZ*SBkdND{T5mP(5O^9x%3uq zsXQptf(X|j{~8Im@-5^D`3hhO;lRNh4?LBfP&9EY)xV}USW`&46IpMd?@z;my_P+} zo@4K@a|m@6n)a$3`5yPdI@#j{CW%ze>`5XKh*Q?Ik;JarL^AuYO{4&H3YS7K^;-AD zv9mT2&n_q;1SoUXg+zAICX%qUw>ZgI)+?eSh5e({Ou1PD2M;LdXTd)gD&v}-Sq0kR z0H{E6p%KX|$m*2^L6{O!DKKTsnv0a{MjZrpUN7xFHEZ8IRo)0}eM43}+t`qmP{Fn~ z#IM7FH~ zCyDKJ9fJ&ek_ku@+97GirjPx!k@|JLm%*sgp`?UzT?w~9#1O^s%FUc7x+m< zr&djuPkzY{$qpZLfmPScv-~-E>0^GBR?W69=n1T{U)3yi;W(`-mua8!6J(~@>@$9l z(5iV7#AO2_x#cse=GHv|cNA33QIGf_M0I+18l}OaKL<|v8=$DTh~;KiHV$B>&$6>- z+z+}z<^50T5r(e~@h8c0?0*4D@Yz#(xLeDcxPVC(E}+{UM3}|K5LBt8+ z_!rPOr()oJ5KHU}_~r`BZw7_~6Ds(0-_i2BOFW*uB3ECA{sd+jDiW&vYl}kZIU%oH z=1KbdHgbRE6(IN18*-~B1(+uT__ZP!bF&G~JZwTRAW^AHI>tt!+!Mys zn!M_X=|xvbC`xd*3C>#Bgn-@sGB4x^vdXV&`5f&Ky@fc^dRdVAGuz2k+U;cpww#rdvkXF$ciL-N+iL+8w_p>w+ z^Q(eIuEO(|Ia3V3V61at3t(lg(|22?+Q|Nb%E>>npcY&y-uvWXuauo@dE~z$p9Y^C zmM4B>e*7gAAy56tyj(vqKH_DiN57f5u()twR*o_jCaG=*OR0ZRMLtlBfknBwKm*9E58{H%KgiOb;DL2cC29xxm0Y9FEw&dX%**n~ zPgv%#-|P&@>`!@3Wzg*NRIba=i>#I32gsA%0-4__`QSxF zc8H@0NqrGWVV&*s1e$9TiFCA0B+6 z9B6E{`ix}V>hY~eqDC?yv6~B7>P{>NKD}vSG6F#uH^8#wEH>6YXiELrXrK+Qg6{DJ zc9JBr@30W~txYpnGyWThfiF~TDz8s*NqW)10VTOvuo+L~8J0Tfl?+6V0n$?16T}yN z8HqQG=dm`Cz_FQ8oJ5Z8j3Saawlj)I=Ge|CB88{hL@LjcU+y5SSR9YGiFh7k6A8Sd zO(gO}n@HlRHj&J`+C&OZQ$$c~rfLrAWi8X?ob*C0D&lzCyKv)qd%5Kt@v4Zw%f&>V zd>3vK?|c_-GKW9k9S=?6J@3Lz<-OE;2c2_3$-wm9kPzfIF3Lu*Av9Vt4rADRN^ykY z+ek4mgjF}QN0bypjVMjcHB`(Xt{ zOgHg4tij%M7qgT>Sz1$Zf_RzDngPBVqVBdHLPfat@E0x3h!#*`!9uLqOUwoYr+LC# z6jKOEqy5AWq?L(0y%^-pxSUDkqd}r0ti+B7iJ=rGWYM9>6JmO_R(Zne^F$&~Yx6iv z@`%ZO5rP+nWYMw68E$&CS2?5VbH*cQq658bSUdCxOkm5SC@(+I5VhPiVjzj)p>QV6=!Um4P-z!z$sri%l*Guy?qQ$Vz{ULNR;W;l=dG zN?*l@Jmf2)6vSe5C)822>CstSAr^3=51f?n|1o@WeBh5W96x>?IRt=|Uubi9#}z~6dQvHqJr&)r_wz#7T~u4Zq8B3`*NB}K9mnE=TZ8BRw67E@Fe$e3~Ug8FXsW6 z!e3TIAaJCubI#th3BlgB37s9c34@)oh(-=}CQO7Wy~&m^HO4(9pS%Z8IVRt^hbI}| zLk*&?ZH^=%4((YLksD{-dgFzmP;qh~=NyuIIrKg|5@tH%ip9O8i+QzJbR`fz#SRnC5?JQo>Jk{#7}aSiM-?PkovM4NT&a*|RSvA~ zE@Mi>Y1eS^C2V}G%p93B?aUmRGwL#PWbP?rCe&rlwlfQ4?qg>b$lSXwvq0uvGG<0y z<{Ue-j?De-%sMjntIMn-b6*)VPn@<|SAd!`5=jP8;fa=$wSeCF0tOT@Xjk*;Ci(`% zIln*+8v?8GT&#~5?+BS{kTA6g>p5Tm78{T=@`GynvrY@L2ErdABX=O*C-Y~CfY!@y z<{Z>NJ(urQn;9#oI#u)a0l8`xx`&TS!dN_QXA=oPEVVd^w9qD!=meWcri#>ErU+bVIq2_$tC1_Hx#F0!_1tL<*UW%8^7T+C(y4Y!fK}P*s z41B%;b)V0`=gXBbi^S=8wWjnYlQno{JOV`8Gnni>V9SsLk~S!!71?Z`bB0f@9wA@|r#e%SU1tu|*+9F_9H_Ixx;k^9&I-(! z3XJV!h#b63{0D=Nq+bJ<$)C;={Jpi5jLBTY9cnh`QaWqpgtuS0>v&X$K)k2bHbSEG8V z4Ba3u7y=(`E(QhGXAqRYJe&C>(RDRha{-+u@j39gAarH9&GmK{Y^HNMW@C zHyK#1UZ|*|8nQSts9MSH23M!!IHWoY$Kq;ugp;AwIXDil&c|_NwZb(isaC&uRJHo` zrPU*F99=yM$1&BaZpKxQ$8mi1BpfGILpVn!SF2i_QmueordF$ZonAd3$Fk~0IL@rD zP^c&6PF4A{ogBwG&PF)Sb*eg;=TyIbfinolg--SR7CWPHT;f!}Z>h5_julQ-jmw!$?^^0qq3e@FZXDW{OIXhJ#x!>6t$5l>+@Uq&e zYT`ks`f_WWX*fRQRJBs;RG2SootZd3>{K-*o$5=kb1KZ2^-fhc8=MOBWuvnc$4yRE z6I+~+Lz1n|={P>_RCTb;IUC3A&UrXK;asHk*2qq$s)JoMst%s2QFXAV#=voJ4MrET zuST_r{WYpS4%D>7@!1-091qs0HgTv%wFa{$)an!C&1G9upBN_tA48uQYq~wI`oyHV zJ^?_zmKJk%V=niqAHJ+k*kZd$0*kZkmC5;#2;*Ee`*>+`Q056~pW=JCP z%hX)VQSZpb2vtBnkh^m+XPuH?=91PBv6lhU9b-g+O)yqu6PyiEL>PLul|yGEZNgxs z77^-TV*^Df5FjT_E1fW|M1`Axme`6uu3~1BM`ZhjIGDkL(|^EqvP(vWaAq!r>oofga%y2 z6cg{l)F<7AX-vKg(=nytdqOrpRpxIJo-z*y6@?NfEh(R2r=rYG^_g~Rlv`<#V^#p7 z&nxqV@)^_A=bjG5{p?B8#?6>BTRZLAEPUjRO~Sinymq2qZ?7`KqyT}>HVa?|NAf8o-XGt3`=sfUlG^ejtbg;OU{3jtuYpi5Ut67K zs<~{Z>NK!ud=i~zvUGb&{KxgIfZ%DJ@FX+pCzMW@Py~9{s&@?gtAg{+4{lr&1J7*cBR$xWZ-M!XIed1y1g#0`!=TC zG};Y&yj>7XdO<8%$t?JQgK*yo=WUXUX;gG@`}8qlGk19gg;qSU%lC=UIVqX(7gV(RZ9!Z(08r+U1~0S z&w5{&G@elJyV!JlUyW;|zJi-t73|c^>!+++;or zIR^DtIuO}_6VEK~`}%v3CxLBlkSCEn4$h#P1tU`u+tDCXGJC24Cxt!TfRoA&C?TAB z7<4u&D5kbnuD-^-Tdb((*O^3X4@>hJ4-#h;UZ*@VmiX%0CziX==2C)Aby_z2g@*-Q zP$DN48oDGar>MW}ETc-diasy%et|mVBbE5@LA|sy=sy*No6AnCj=^N$N9Y*Tbo*EU z61|Ze{E1isH^(!dhR zA%nrqWl#^`&ZUs~qx==nbz5cg>CP5**=&*1!zx?en5PSPSN8f>9s(&1JpobPL_{2+ zh)eP)fJ?fN#;~v12{_+gYtp@C?l;)p8nQwqy4l%IVk z;$Zn<31A@Uh_@*tvNF!1P}1J-A@dNCl^ql#(sflVfMnmQP<@dz(5_IJk2_o06{@2` z1LT!!s5*a)x~Muo*RQBKUs>_1cn6Xi>kGi3*%@x%;J^)Gc6~agJ0Y=A-^y6z1n7?X zRxl!WhS)g`L8 z8|_8%jO?@*Jw98G+6ybQ=VZlRSZ=>0H>>1T`HD*3kQY>POx{q*douWGBqwDLm7JC( zPm4qnf9MYZT`nM2|9BQg}VkFkQ>Y+bIA^oWJ)Tgl|wYKusuV|bpGv86-xDwKt~;Ig7d^f?)v-6N$#W{>ZpTx z$Y0e_oOv}+)ls}z8=`j=una#Lfy)Wzp-3HTN?+oJkW_#>7(^CW3iWTOK$w^QbT+!& z>u44newoP#=QI%$)FbQw%wE2N^eFs;U%8h!sCHFd4S^jkl0XCF+0Q7@ z&anO$?oO`Bkw+oM{0Rlx+|5Tt6JWlB>nD#M#q9s1JcAtMvMhZ|Ay}|SY$6_E%`Hv> zd(0*h*%ONJg}BYSkc^;I7Lmf9v54eUc1VrAg9-ummo+4>sDGhyRLm^0Jr=bO)yO}1 zK!4cG^@f!j#5pC_NWN;L0vLMxP;>nXB9@p}V^x(Wo3$NPm8Z&+NvQG^^H8$-BAv{u zoz&&dW^Gr!D<@aw$uvD$zY@XwVM*c9!3fZ&mrfg}U6#S=dbob+Uw%;8jPlvq&psTY z#kwWkq*-HTO)42XaZH)^l}zuc2fLMy9b2w_6U7Ihu+UH=lxhf^mW~Jf7{+_62b>4I zw)UNs*?!RXiVoMm4Tdc!CZ#dlk7}RDQ$6)o?qepFmX%Bzt9^l&kZBpZpIqz%!w?PV zBDe*5B$Z1}Yhqxl|7j@Cu=3cYUXa}~^jLnr1I&o5JAd*pS_tj)Xr6DKx0p3&^mN#! zPAi=?Mf>dEAKA+K0T=(>MocT2F=p0S97d1MvzvHVc`_Rn+QmH7S5;^?^Je0Q&*5yIv%mb` za(yo5SHs!Qx=QCd``TAQWxHnR3jhtaaE4yxnyudt8IYA7GE(P2E4!HMEVQ$WdCmg+ zD#WeMeCsNo>&#PE=VJq@Zj?7J3V{GIGc+0vhwLhP5HP0Ustet4t@a0^?j}vdF=Zi*e3JK0R0Wqr4ApN+JE!t&JGZg>EGjP4u(B zNpK+Pl{SokMPSu+Ex z-bPT>tViI7=J4>iS4A3tOMB%&`P#2~chta0(R&!r1);lW?(UfJf&C;*D`$dQggvFy{W?7aaQW5Aj%uMTz?$4 zR%ig^2R-S5KL-R+WJV8a-MMbf9ikZW_bUTTRkn$p%9 zZH*i zvL@3Sn@FJ>Z6cNKw@~g;N^6^lrwGvmBzvgI``Sbz9cdFuwA?0=X_d>VXEvJR8QVdH z3+myzR}Yt6P2NZ@bn26_@%+}QPlZiUL5;p0efEzUeG{2r%6s)xMy8u5AJE-Y=-G3t z(B-DeL96vATdCDWW16eM)3OpVm%qn`CJ}vPCG>V5Tk9o=nW1uwCdxT?kWCo8*diJ^ z`0!8>rS^=+dlG+#hKQzJR3MHS`6SHH-iZ>inBZr&MMbo+*C7Z`C7CTsL^*t5-Eqd$u+beo6t^F%+bu?6I`8nuoQ_j^K}v%SM2 zd{7f^a>K)Vg4~dbs_=K|$x=R|w>D?Hbc0amEV)GL)sYNNr;xLsMAG1|vb}Sj=YlX* zrJ-`eI=zitwE?pNAWPijj?H>8uk?1#m9^`1>DIzI$2&?r@}6-rX}z8#m+aLWna{4* z^Qapq1sa=;A+|NlvF^tZ9r7Nbgje==E|S|G)lX38LOFY*zPqt=foHMxv$Z0_+=MdLIc3phw8p(CoBB3!RUB=nvR`4uLtz zF|1!6lHIEScye_m)&f^=i7R@kz-T1fRf!hlbCo06xYkvaDomA`8}vYVWrNcK!rPb~KPiapt8AK&R#o3pb+uCAJpzfB-&g%lER-k=l$me?FMs*7g zeoXE^ueT#_|9eT^IIlaf!KlyMLcA6wd@@w=L5?Cs!TN%Y9WlY)TU}RNN4R!+Z=zzdu8;3yIpRdY%$9 zy-Q@@I936jtsuonJkO1VQO8jtgY%jT=LS3 z6{?Dbcc_{2!6Uj?#AxM{o}E{sQ0+%~mMMPb9XBMis=MBh!tTE-Kb1XXBdEo(Ns4HNfy+WvOJH+sB9Sd} zy`)coJMP4n^mIbp%_m>hI}ze$esdVvUC-$d@xFl-PjfT<4ZRxy>{G>?dOi@h%u`3P zMpjJ>LfT-B2E!Ajm@cK8>2XL6{Q#OY8By6^FtMJvL2NCk!Jf7W2Rk4)kA?^1TKUFk z5#m114p)rTU`d&rIf1rz-_}-ifGeuaS>s89$qG17iV%F7k})uKc|z8Vfl#AL?i&Mj z>tT6(3B$Lw0u~mcoG0iyN+Rv(9(S3nCdbu%vayW4_uet4%o@R5L*)aXU>XlmNw{2nR(~GdJ^NGrYlx3fz{ep?wfzW>q5XuJ zZYi~Lta@!(jD6W>ay(p0$CvRnf4IrWJD#4qzn{Zc9wLYB+T`N zUfVdrGp-BP3Z+_{Ty`3R@j3_hm#1*W5$>6!u1u55fZQ#eU+O08lhVG@PrJ4D>Y}bx z8d?|orhc!pU~|aV>NB*F^S{x5!4s!^i@7dJ4*O0&4JlK{@AcCmO=(*Vh#6g>cUy)S z#jjy$&NLn?x~}~WQHI6v zYix;T|E|yA=YUb^_4=~_UHbzv4J&7W-24mI$v<+x2~mRfm;A(JkyQJ$_JnU3-WIYG zU$@MxLD>L_&CbMoZ-t!2VLu)}yW%J8K4TO!7_z`4DhYS}tj~s3(43!j9hO5o7GFZr z)?9K~uZA7kZ+brDV{*`cu>puR-~X?kL|VCP`5Jo*xZ*j01Ah%jT%P0z8Ls`RZP)U# z$pe^ghTLDU0@e4+YA@b-idLMZCH2W1>ok1$` zlBK`uQP|sJCzR~^0}tqECjEga7ZR;e*Yz#bwU2UtcN(g}JiQMfs~^QrxQIsI8Q@`6 z7#HfD)xIZQ4M_J}1$B&H>pC7WTv& z0ZO~V46EDUx)buaqkrr7LWZ3G55&On^22}7PUFm-|I-n*&WomN%2gB->jH!X+W@J= z%MgZNfB>^4WD~tvDO*_8?TmQZ z{dPtIEx4VLNXOsKNTLgGXC%{Aw=+`cV-~~x=5tf&AxW6whyIAf2lh_gY$Ac?+e9KA zXA?L@KKXurewBmeR$n7Xe&J!bNz)zKddhB1jD4_)yW9jN zrOA;^4TQgxh0Tn&NN+QsxdD^>Uh)MG<5;6CPoH6`j7fGGYUOJ!S>@lVTb*fPlsC%s z^vQ0R#p+xYEsd3u`xkfIv(}=}BInc`}hA9I^2Vc3`3-if%`L36d2O|jdYm3!Hj_Rp%ndJ?;fw8x6*LoYV z?ql4F>IQ`Yj(?TI@|w5N0g{DKA0ri}LwFsiJFcQmAZ+aD3Napp&}2=BF%LqMMxn-n zMtOC0BV_YXqn$hyY7B-1rD0=RW{k6NIQ+>{*t0;| z{S2z&0{I<5L{vndVHixDfcHHNXYBuAK#2iHRVk40AHas^CH4XPK{@O7Bv!!mcB#yz zM8TG2UuI7WZ;;=kEZlD8l%yBrai@Gbih284>#f@^X7Nv znZkj2e8nAH;GXlfYK3`QA>iV7Jq+QZ@SgP09XA!>ch%m>Ey(8g-7L!5B@`6p4OD&~ ze81X)H6znBG7SQ`qvUUhsdAu@-a*eWjYYB|m<yr8!$4b`gg}Fr-mEpm`C@98~0-#?Gj-;jw$p) zgz-GQch^T68+oCp&tUneuhG8t0k@-FJd8gZXE?L*j|Sm+J2 z#*LX%KCWcqj9Ie>05-zr%_}J#GiKb>apk465mysn4}IjCwuX1x)OuKoS@TL}j2}OB zM(J4Va!PYxfha79*=2yKK>kp9s;%MUd(0c~6iS0JcM@c`N(o@e{NHl5GraJ=TaZv% zWT$M9o$|qUDu!4oq|P(j8Q#+e!bu{J!7=J-Wd_h=fCd4DRqqwC{A?Abt=k7K^IA+?AzUV8S>$O3j)foq2yuE&LQovZ1D) zCf8&et0CnI?Tf}c#eB0bW*1kUF{*LR9M68CO5%vVm~VK>rFq7j#x=9=U^bQk`36jZ zXGv$iv60r4t29OiCmEQN3XF01GGK(syp^zbfTV98zR|yo`wNZPmRP$9B^oA#F;vnQ z=m%&51a5Z|~3@{Qf&8<<%9{J_~qqW~iAK|A&f78lt z7yM<)zNNGS1oO>18{t5APwH&61F%wQXH1ld^1jYSFbuq(>THCOz4HCeM(e=p0O8lp zLB^LWBs43|O4*#zQzwlnnKEuc6W2gv5Up7(hYU0p(war`^gzQ&YZl6pMaE)Uvp}9J zGFCROneUly)m$UH<|+oM`k5zx9%MX3Yv#&jgN+qfOM7XsLhON1PcEzweuhJvT1zis zd+MyGJEont&HfC!$tE218M$Pb5rYxu$zettV{|)(3q|FgcsOI@6PAsl9o(t|g%_BU z%H}3oP;V|d>AVPcyj#bvJ$#Qhk#f~}SQfl051$tbtg7SZ82nyv4aYiw$WFtty3tHA z!YC)Sra~?lX*@`4mP)r0qm0%pkxNR9YJWGlx5I*R81z@WfuE*9v)>n!_7-*w%i#bj zzc|Q4jc@F5G_Ju$80Ejq*h4(Rcr!_4DR=pb9ct-ObBG5Tqk@1zho3Qhx$fiOCCc>^ zXR8O%FiP%~*ADR*@(^}@JQ@Pn-X@R2dT55pQ-a4ThyO+t#;=<84B}Hvf#uT?co9Tn z1X;;m$BQ8F!QV3YHNfa?MxKY{kk@!CaSi0#^8MFYN3j#+XbW@CO|V~JWU9vrjMw$R zc5Z6W*7=9H@Z`U9RdY+~`7xO9MvGWAyKHJqLUnB;IM2z?vC|f?%GKt{yzj7M-L+Cl z0WP^F8oeR*>oXB(;;@pLH_3P!Ru)l{vFc^=)yc*#NHHf*Fi_@% diff --git a/mlxconfig/mlxconfig_dbs/mlxconfig_switch.db b/mlxconfig/mlxconfig_dbs/mlxconfig_switch.db index e9ddebf1801de730f96c52083dee3eebf2fd0d0d..7d681d9f23b707068ee5ce9203a95515e4d67321 100644 GIT binary patch delta 3464 zcmb_eeN0=|6~E^m8(dOI4F+RK@JlI85nnbC;)KxDfZI3$8~njX_;?umfxS33v5m`; zMK3Q>+bwI;pgT2EH7Ti9rRr2I1y}j2s*-h6*J)F$R^6m&(-x_lI!$Z$Rjr$}Y4@3Y zkosAPs#)k~zkBXI_x#Q|zw@{ zzeI+wQW+!YrSH)H(ChRvJ&$i=H(F>lMY^9h(Kwx0Q{DqsUuHDcY}M^BKq4zH&Wqt> zVxgM#m02cCwYskSYI-Ri%ZN+KR3YhQPb(Sw}JItXz$iXti zeq??OLvVqW)-oG?o}Qsk(NpvU&C+9>!6KcfGjxLbsRu4lgmriseoUKb9o-F|!LL@8 zk9u`TAXJW4c%ok%a}5N%zPUnL=(2%-XIRSJWm7;%rc?QB+pb~ z3;0Kd+yQaK>kH)hPuHLw2Hk#V|By>`1_NF(zhSBZcih;jIz6o3x^Z&AIWno9*?95< zhehw>d3XK^HNJ5b##9KZ5KzIdf=~A_$5Hj?hzed6JSq&UFr>mE6>_XD0YpOUz?kJHMi*y$j zF0d|?m^#M^87EotBDqTb0OimFA}H`Z_&NNO*3w7m0zFGF(GTf=u@xuqG`@zvSXHdK z3*8@oCcn=<@FVUaUzoQBFaov5B^Ztlf^z}_#0r6x;loDKC@mS)B z*r6&cq#f|C!YIbr#ocr4H`d0II=#8Y0PMQk#QyA%Si;dzFIx0gu3RqLtQ5{9Q@15N z$DVTtFq`x3vC{Q@I#Z{ae4FsU?~`}QCr}CxgA0zp^Y8||5C7m4oLo-l>D%;E+>QtF zNqiaKUsZx~gWke>BauvmC5-|NZ!&9C#kf%)+X&O_2abnehF$G_OxLJyZeg>dR;bC@M?Zn}fbM>|gftO6 z!pBbuTqIZc!u&vnIJG)hMxcHbF+ejPx-MsF>a5NN;ONm8Ez2s;p(>~qH_w5zt zyE=t7fx|rO3tMV4$s+>Y@KCH!zrDFfZDsd{jxoMrsava{Akwm0=w>12a`2Y*j8>tZb&X0_=i zm|%~lEsv;ec^4`NoAhlhOiu4$$J1wO?jt7&Uc(Oh7dlI=@Emx^o8;uG5|;adRTjI& zVlLm5rVX`f2*$S3Z&Q1%lViTw49eC3Z(GaV+E&w-llQHBm&W}HecR_R#z&G064GX5UyHWw+xx&4J6H@`%PH6mg%i8dKkg0;9I%luN*;F) zxr9O2n0vq_1U>H2peuJidK4@42n655@8CGLBdjT(QQA_&x|6L?%|gjXz{JiZ_dykV zC%K1qRI)wMjs`Ut9jPbuEx1Bn<3DbHl!{pv&7Omq+`qD=fT#7-xoeS9fT`TO(tfB= lPa-)%&;U=96RXNmJZ%W&vR^L)n9C{0W#9!B+0ydo{{yZM;EDhM delta 1199 zcmY*YZA_b06u#%2zOWmHOmMk*BIL*~Qjoq>uy{4V@B6JJ4!Ad+d8WE~#@=Ul z*{`61D(Ht9_z=E@hiJxDr8w8{HvWK*$VO)<$>wQ|KBHe&q#o`&W)Z@6!QtlbHCW}z zh8lz(ezR#a&n8&hSq3v-JJxYB(=Rp_VQiZ{0zK5QxB}jW5S)kWa4XAX#1lA#^Y{^d zkAKr)h3PeVm))i<+F9`xIW2-iX&a?yE=C8F;}`b(CuA2~$_;nS7DFH3@;V{Nm-@=p z0jqE@6T)tniI;k#@~+o`s%Hh4mv5XXSBnEj%Y>48es9XgH&QC-G)eE!C-ie#QiG~ea5XALEtlIuTfikpm9k5@zd4^r zqi=0SR64!DWJc$43G-l($t%(aBzd~|{n$F33nj{E=H@mwJ``0%nb;pvKmT*M;?UV5!Caw% zWOOPyJUSLt#y1v=#*sMysUyFG`(f|Me diff --git a/mlxconfig/mstprivhost.py b/mlxconfig/mstprivhost.py index 40d4e036..f23cd724 100644 --- a/mlxconfig/mstprivhost.py +++ b/mlxconfig/mstprivhost.py @@ -308,8 +308,9 @@ def setRestrictConf(self, host_number): cmd = self.CONFIG_CMD_LINE % (self._device, self._file_name) exit_code, stdout, stderr = self._exec_cmd(cmd) if exit_code != 0: + current_conf = self.queryConf(host_number, True) self.printCmd("Failed") - if self.isHwAccessDisabled(): + if current_conf is None and self.isHwAccessDisabled(): error("Secure host enabled on the device", hide=self._disable_out) else: error("Host is already restricted", hide=self._disable_out) diff --git a/mlxfwupdate/Makefile.am b/mlxfwupdate/Makefile.am index 969805d2..38162fef 100755 --- a/mlxfwupdate/Makefile.am +++ b/mlxfwupdate/Makefile.am @@ -63,7 +63,7 @@ common_INCLUDES = -I$(USER_DIR)/common\ -I$(USER_DIR)/mft_utils\ -I$(USER_DIR)/dev_mgt -AM_CXXFLAGS = -g -MP -MD -Wall -W $(BOOST_CXX_IGNORES) +AM_CXXFLAGS = -g -MP -MD -Wall -W -Werror $(BOOST_CXX_IGNORES) common_SOURCEES = mlxfwmanager_common.cpp mlxfwmanager_common.h\ diff --git a/mlxsign_lib/Makefile.am b/mlxsign_lib/Makefile.am index 9a2139c6..45d554c6 100644 --- a/mlxsign_lib/Makefile.am +++ b/mlxsign_lib/Makefile.am @@ -33,7 +33,7 @@ # Makefile.am -- Process this file with automake to produce Makefile.in USER_DIR = .. INCLUDES = -I$(USER_DIR) -I$(USER_DIR)/common -AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe $(COMPILER_FPIC) +AM_CXXFLAGS = -Wall -W -Werror -g -MP -MD -pipe $(COMPILER_FPIC) AM_CXXFLAGS += -DTOOLS_CRYPTO_KEY='$(TOOLS_CRYPTO_KEY)' -DTOOLS_CRYPTO_IV='$(TOOLS_CRYPTO_IV)' noinst_LIBRARIES = libmlxsign.a diff --git a/mlxsign_lib/mlxsign_openssl_engine.cpp b/mlxsign_lib/mlxsign_openssl_engine.cpp index f2e4cac4..d40826b4 100644 --- a/mlxsign_lib/mlxsign_openssl_engine.cpp +++ b/mlxsign_lib/mlxsign_openssl_engine.cpp @@ -88,10 +88,12 @@ OpensslEngineSigner::~OpensslEngineSigner() ENGINE_finish(engine); ENGINE_free(engine); } - ENGINE_cleanup(); CONF_modules_unload(1); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + ENGINE_cleanup(); EVP_cleanup(); ERR_free_strings(); +#endif CRYPTO_cleanup_all_ex_data(); #if OPENSSL_VERSION_NUMBER >= 0x10100000L OPENSSL_thread_stop(); diff --git a/mstdump/crd_lib/Makefile.am b/mstdump/crd_lib/Makefile.am index 09917500..be1e3c55 100755 --- a/mstdump/crd_lib/Makefile.am +++ b/mstdump/crd_lib/Makefile.am @@ -34,7 +34,7 @@ AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include/mtcr_ul -I$(top_srcdir)/common $(COMPILER_FPIC) -AM_CFLAGS = -Wall -W -g -MP -MD -pipe -Wno-unused-function $(COMPILER_FPIC) -DMTCR_EXPORT -DMST_UL -DDATA_PATH=\"$(pkgdatadir)\" $(COMPILER_FPIC) +AM_CFLAGS = -Wall -W -g -MP -MD -pipe -Werror -Wno-unused-function $(COMPILER_FPIC) -DMTCR_EXPORT -DMST_UL -DDATA_PATH=\"$(pkgdatadir)\" $(COMPILER_FPIC) noinst_LIBRARIES = libcrdump.a diff --git a/mstdump/mstdump_dbs/BlueField3.csv b/mstdump/mstdump_dbs/BlueField3.csv index a1b3503a..6ba1846d 100644 --- a/mstdump/mstdump_dbs/BlueField3.csv +++ b/mstdump/mstdump_dbs/BlueField3.csv @@ -183,7 +183,7 @@ 0x050a00,2, 0x051000,1, 0x051080,1, -0x051088,6, +0x051088,4, 0x0510a4,6, 0x0510c4,5, 0x051100,2, @@ -196,8 +196,7 @@ 0x051524,8, 0x051584,1, 0x0515a8,23, -0x051800,2, -0x051810,3, +0x051800,7, 0x051820,42, 0x0518e4,1, 0x0518f4,6, @@ -603,7 +602,7 @@ 0x06896c,3, 0x068a00,8, 0x068a24,41, -0x068c00,5, +0x068c00,6, 0x069000,204, 0x069400,3, 0x069410,6, @@ -2457,7 +2456,7 @@ 0x0f0000,1, 0x0f000c,4, 0x0f0020,7, -0x0f0040,2, +0x0f0040,4, 0x0f0404,1, 0x0f0410,6, 0x0f0440,5, @@ -2552,8 +2551,8 @@ 0x0f4000,23, 0x0f4080,23, 0x0f4100,23, -0x0f4180,6, -0x0f41a0,1, +0x0f4180,9, +0x0f41c0,1, 0x0f4200,2, 0x0f4210,3, 0x0f4220,3, @@ -2574,7 +2573,7 @@ 0x0f447c,33, 0x0f4504,1, 0x0f450c,1, -0x0f4580,19, +0x0f4580,18, 0x0f4600,5, 0x0f4640,9, 0x0f4680,9, @@ -4118,87 +4117,43 @@ 0x1488e0,2, 0x148900,211, 0x148c50,6, -0x14c000,10, -0x14c040,10, -0x14c080,10, -0x14c0c0,10, -0x14c100,10, -0x14c140,10, -0x14c180,10, -0x14c1c0,10, -0x14c200,10, -0x14c400,10, -0x14c440,10, -0x14c480,10, -0x14c4c0,10, -0x14c500,10, -0x14c540,10, -0x14c580,10, -0x14c5c0,10, -0x14c600,10, -0x14c800,10, -0x14c840,10, -0x14c880,10, -0x14c8c0,10, -0x14c900,10, -0x14c940,10, -0x14c980,10, -0x14c9c0,10, -0x14ca00,10, -0x14cc00,10, -0x14cc40,10, -0x14cc80,10, -0x14ccc0,10, -0x14cd00,10, -0x14cd40,10, -0x14cd80,10, -0x14cdc0,10, -0x14ce00,10, -0x14d000,10, -0x14d040,10, -0x14d080,10, -0x14d0c0,10, -0x14d100,10, -0x14d140,10, -0x14d180,10, -0x14d1c0,10, -0x14d200,10, -0x14d400,10, -0x14d440,10, -0x14d480,10, -0x14d4c0,10, -0x14d500,10, -0x14d540,10, -0x14d580,10, -0x14d5c0,10, -0x14d600,10, -0x14d800,10, -0x14d840,10, -0x14d880,10, -0x14d8c0,10, -0x14d900,10, -0x14d940,10, -0x14d980,10, -0x14d9c0,10, -0x14da00,10, -0x14dc00,10, -0x14dc40,10, -0x14dc80,10, -0x14dcc0,10, -0x14dd00,10, -0x14dd40,10, -0x14dd80,10, -0x14ddc0,10, -0x14de00,10, -0x14e000,10, -0x14e040,10, -0x14e080,10, -0x14e0c0,10, -0x14e100,10, -0x14e140,10, -0x14e180,10, -0x14e1c0,10, -0x14e200,10, +0x14c000,1152, +0x14e000,18, +0x14e080,18, +0x14e100,18, +0x14e180,18, +0x14e200,18, +0x14e280,18, +0x14e300,18, +0x14e380,18, +0x14e400,18, +0x14e480,18, +0x14e500,18, +0x14e580,18, +0x14e600,18, +0x14e680,18, +0x14e700,18, +0x14e780,18, +0x14e800,18, +0x14e880,18, +0x14e900,18, +0x14e980,18, +0x14ea00,18, +0x14ea80,18, +0x14eb00,18, +0x14eb80,18, +0x14ec00,18, +0x14ec80,18, +0x14ed00,18, +0x14ed80,18, +0x14ee00,18, +0x14ee80,18, +0x14ef00,18, +0x14ef80,18, +0x14f000,18, +0x14f080,18, +0x14f100,18, +0x14f180,18, 0x150000,72, 0x150200,72, 0x150400,72, @@ -4815,7 +4770,8 @@ 0x1741b4,7, 0x1741e0,5, 0x174200,1, -0x174208,10, +0x174208,4, +0x174224,3, 0x174404,5, 0x174420,1, 0x174430,10, @@ -7294,7 +7250,8 @@ 0x248500,46, 0x248600,4, 0x248640,14, -0x248700,33, +0x248700,13, +0x248738,22, 0x248800,5, 0x248820,2, 0x24882c,3, @@ -7664,750 +7621,962 @@ 0x269080,23, 0x280000,20, 0x280080,12, -0x2b0000,8192, +0x2b0000,8448, 0x300000,19, -0x300100,1, -0x300200,57, -0x300300,57, -0x300400,57, -0x300500,57, -0x300600,57, -0x300700,57, -0x300800,57, -0x300900,57, -0x300a00,57, -0x300b00,57, -0x300c00,57, -0x300d00,57, -0x300e00,57, -0x300f00,57, -0x301000,57, -0x301100,57, -0x301200,6, -0x302000,27, -0x302070,3, -0x302080,27, -0x3020f0,3, -0x302100,27, -0x302170,3, -0x302180,27, -0x3021f0,3, -0x302200,27, -0x302270,3, -0x302280,27, -0x3022f0,3, -0x302300,27, -0x302370,3, -0x302380,27, -0x3023f0,3, -0x302400,27, -0x302470,3, -0x302480,27, -0x3024f0,3, -0x302500,27, -0x302570,3, -0x302580,27, -0x3025f0,3, -0x302600,27, -0x302670,3, -0x302680,27, -0x3026f0,3, -0x302700,27, -0x302770,3, -0x302780,27, -0x3027f0,3, -0x302800,1, -0x302808,31, -0x302a04,1, -0x302a10,6, -0x302a30,64, -0x302c00,23, -0x302c60,17, -0x302cc0,5, -0x302ce0,3, -0x302cf0,100, -0x303004,1, -0x303010,12, -0x303104,1, -0x303150,44, -0x303204,1, -0x30321c,11, -0x304000,130, -0x304300,36, -0x304400,36, -0x304500,36, -0x304600,36, -0x304700,36, -0x304800,36, -0x304900,36, -0x304a00,36, -0x304b00,36, -0x304c00,36, -0x304d00,36, -0x304e00,36, -0x304f00,36, -0x305000,36, -0x305100,36, -0x305200,36, -0x305300,64, -0x308000,49, -0x308100,49, -0x308204,1, -0x30821c,11, -0x308280,3, -0x3082a0,5, -0x3082c0,9, -0x308300,3, -0x308320,6, -0x308340,74, -0x308480,5, -0x3084a0,1, -0x3084b0,7, -0x3084d0,3, -0x3084e0,22, -0x30a000,58, -0x30a0f0,10, -0x30a200,36, -0x30a300,36, -0x30a400,36, -0x30a500,36, -0x30a600,36, -0x30a700,36, -0x30a800,36, -0x30a900,36, -0x30aa00,36, -0x30ab00,36, -0x30ac00,36, -0x30ad00,36, -0x30ae00,36, -0x30af00,36, -0x30b000,36, -0x30b100,36, -0x30b200,36, -0x30b300,36, -0x30c000,51, -0x30c100,1, -0x30c120,9, -0x30c160,9, -0x30c1a0,9, -0x30c1e0,9, -0x30c220,9, -0x30c260,9, -0x30c2a0,9, -0x30c2e0,9, -0x30c320,9, -0x30c360,9, -0x30c3a0,9, -0x30c3e0,9, -0x30c420,9, -0x30c460,9, -0x30c4a0,9, -0x30c4e0,28, -0x30c580,20, -0x30c600,20, -0x30c680,20, -0x30c700,20, -0x30c780,20, -0x30c800,20, -0x30c880,20, -0x30c900,20, -0x30c980,20, -0x30ca00,20, -0x30ca80,20, -0x30cb00,20, -0x30cb80,20, -0x30cc00,20, -0x30cc80,20, -0x30cd00,20, -0x30cd80,20, -0x30ce00,20, -0x30d000,3, -0x30d010,3, -0x30d020,3, -0x30d030,3, -0x30d040,3, -0x30d050,3, -0x30d060,3, -0x30d070,3, -0x30d080,5, -0x30d100,28, -0x30d180,28, -0x30d200,28, -0x30d280,28, -0x30d300,28, -0x30d380,28, -0x30d400,28, -0x30d480,28, -0x30d500,28, -0x30d580,28, -0x30d600,28, -0x30d680,28, -0x30d700,28, -0x30d780,28, -0x30d800,28, -0x30d880,28, -0x30d900,28, -0x30d980,28, -0x30e000,4, -0x310000,9, -0x310040,9, -0x310080,33, -0x310108,5, -0x310120,3, -0x310130,3, -0x310140,1, -0x310148,1, -0x310150,1, -0x310164,8, -0x3101a0,8, -0x310200,1, -0x310208,7, -0x310280,20, -0x310300,20, -0x310380,20, -0x310400,20, -0x310480,20, -0x310500,20, -0x310580,20, -0x310600,20, -0x310680,20, -0x310700,20, -0x310780,20, -0x310800,20, -0x310880,20, -0x310900,20, -0x310980,20, -0x310a00,20, -0x310b00,36, -0x310c00,92, -0x310e00,4, -0x310e20,1, -0x310e40,1, -0x310e60,7, -0x310e80,7, -0x310ea0,1, -0x310ec0,6, -0x310ee0,6, -0x310f00,3, -0x310f10,5, -0x310f40,6, -0x310f60,6, -0x310f80,3, -0x310f90,5, -0x310fc0,6, -0x310fe0,6, -0x311000,3, -0x311010,7, -0x311030,7, -0x311050,7, -0x311070,7, -0x311090,7, -0x3110b0,7, -0x3110d0,7, -0x3110f0,7, -0x311110,7, -0x311130,7, -0x311150,7, -0x311170,7, -0x311190,7, -0x3111b0,7, -0x3111d0,7, -0x3111f0,7, -0x311210,7, -0x311230,7, -0x311250,7, -0x311270,7, -0x311290,7, -0x3112b0,7, -0x3112d0,7, -0x3112f0,7, -0x311310,7, -0x311330,7, -0x311350,7, -0x311370,7, -0x311390,7, -0x3113b0,7, -0x3113d0,7, -0x3113f0,7, -0x311410,24, -0x311480,15, -0x3114c0,15, -0x311520,2, -0x31152c,3, -0x311540,2, -0x31154c,3, -0x311560,2, -0x31156c,3, -0x311580,2, -0x31158c,3, -0x3115a0,2, -0x3115ac,3, -0x3115c0,2, -0x3115cc,3, -0x3115e0,2, -0x3115ec,3, -0x311600,2, -0x31160c,3, -0x311620,2, -0x31162c,3, -0x311640,2, -0x31164c,3, -0x311660,2, -0x31166c,3, -0x311680,2, -0x31168c,3, -0x3116a0,2, -0x3116ac,3, -0x3116c0,2, -0x3116cc,3, -0x3116e0,2, -0x3116ec,3, -0x311700,2, -0x31170c,3, -0x311780,11, -0x3117c0,6, -0x3117dc,2, -0x311800,27, -0x311880,1, -0x3118a0,6, -0x311a00,27, -0x311a80,4, -0x311ac0,25, -0x311b40,6, -0x311b60,2, -0x311b6c,3, -0x311b80,8, -0x311ba4,22, -0x311c00,27, +0x300050,8, +0x300080,12, +0x3000c0,9, +0x300100,19, +0x300150,8, +0x300180,12, +0x3001c0,9, +0x300200,19, +0x300250,8, +0x300280,12, +0x3002c0,9, +0x300300,19, +0x300350,8, +0x300380,12, +0x3003c0,9, +0x300400,19, +0x300450,8, +0x300480,12, +0x3004c0,9, +0x300500,19, +0x300550,8, +0x300580,12, +0x3005c0,9, +0x300600,19, +0x300650,8, +0x300680,12, +0x3006c0,9, +0x300700,19, +0x300750,8, +0x300780,12, +0x3007c0,9, +0x300800,19, +0x300850,8, +0x300880,12, +0x3008c0,9, +0x300900,19, +0x300950,8, +0x300980,12, +0x3009c0,9, +0x300a00,19, +0x300a50,8, +0x300a80,12, +0x300ac0,9, +0x300b00,19, +0x300b50,8, +0x300b80,12, +0x300bc0,9, +0x300c00,19, +0x300c50,8, +0x300c80,12, +0x300cc0,9, +0x300d00,19, +0x300d50,8, +0x300d80,12, +0x300dc0,9, +0x300e00,19, +0x300e50,8, +0x300e80,12, +0x300ec0,9, +0x300f00,19, +0x300f50,8, +0x300f80,12, +0x300fc0,9, +0x301000,19, +0x301050,8, +0x301080,12, +0x3010c0,9, +0x301100,19, +0x301150,8, +0x301180,12, +0x3011c0,9, +0x301200,19, +0x301250,8, +0x301280,12, +0x3012c0,9, +0x301300,19, +0x301350,8, +0x301380,12, +0x3013c0,9, +0x301400,19, +0x301450,8, +0x301480,12, +0x3014c0,9, +0x301500,19, +0x301550,8, +0x301580,12, +0x3015c0,9, +0x301600,19, +0x301650,8, +0x301680,12, +0x3016c0,9, +0x301700,19, +0x301750,8, +0x301780,12, +0x3017c0,9, +0x301800,19, +0x301850,8, +0x301880,12, +0x3018c0,9, +0x301900,19, +0x301950,8, +0x301980,12, +0x3019c0,9, +0x301a00,19, +0x301a50,8, +0x301a80,12, +0x301ac0,9, +0x301b00,19, +0x301b50,8, +0x301b80,12, +0x301bc0,9, +0x301c00,19, +0x301c50,8, +0x301c80,12, +0x301cc0,9, +0x301d00,19, +0x301d50,8, +0x301d80,12, +0x301dc0,9, +0x301e00,19, +0x301e50,8, +0x301e80,12, +0x301ec0,9, +0x301f00,19, +0x301f50,8, +0x301f80,12, +0x301fc0,9, +0x302000,19, +0x302050,8, +0x302080,12, +0x3020c0,9, +0x302100,19, +0x302150,8, +0x302180,12, +0x3021c0,9, +0x302200,19, +0x302250,8, +0x302280,12, +0x3022c0,9, +0x302300,19, +0x302350,8, +0x302380,12, +0x3023c0,9, +0x302400,19, +0x302450,8, +0x302480,12, +0x3024c0,9, +0x302500,19, +0x302550,8, +0x302580,12, +0x3025c0,9, +0x302600,19, +0x302650,8, +0x302680,12, +0x3026c0,9, +0x302700,19, +0x302750,8, +0x302780,12, +0x3027c0,9, +0x302800,24, +0x302880,12, +0x3028c0,17, +0x302a00,24, +0x302a80,12, +0x302ac0,17, +0x302c00,24, +0x302c80,12, +0x302cc0,17, +0x302e00,24, +0x302e80,12, +0x302ec0,17, +0x303000,24, +0x303080,12, +0x3030c0,17, +0x303200,24, +0x303280,12, +0x3032c0,17, +0x303400,24, +0x303480,12, +0x3034c0,17, +0x303600,24, +0x303680,12, +0x3036c0,17, +0x303800,24, +0x303880,12, +0x3038c0,17, +0x303c00,13, +0x303c40,5, +0x303c80,5, +0x303d00,6, +0x303d20,6, +0x303d40,6, +0x303d60,6, +0x303d80,6, +0x303da0,6, +0x303dc0,6, +0x303de0,6, +0x303e00,6, +0x303e20,6, +0x303e40,5, +0x303e60,9, +0x304000,19, +0x304050,6, +0x304080,7, +0x3040a0,2, +0x3040c0,12, +0x304100,9, +0x304200,27, +0x304280,27, +0x304300,15, +0x304340,5, +0x304360,12, +0x304400,20, +0x308000,3, +0x308010,3, +0x308020,3, +0x308030,3, +0x308040,3, +0x308050,3, +0x308060,3, +0x308070,3, +0x308080,28, +0x308100,28, +0x308180,28, +0x308200,28, +0x308280,28, +0x308300,28, +0x308380,28, +0x308400,28, +0x308480,4, +0x3084c0,3, +0x3084e0,18, +0x308540,2, +0x308550,3, +0x308580,2, +0x3085a0,7, +0x3085c0,1, +0x308600,2, +0x308620,7, +0x308640,1, +0x308680,2, +0x3086a0,7, +0x3086c0,1, +0x308700,2, +0x308720,7, +0x308740,1, +0x308780,2, +0x3087a0,7, +0x3087c0,1, +0x308800,2, +0x308820,7, +0x308840,1, +0x308880,2, +0x3088a0,7, +0x3088c0,1, +0x308900,2, +0x308920,7, +0x308940,1, +0x308980,9, +0x309000,5, +0x309020,5, +0x309040,5, +0x309060,5, +0x309080,5, +0x3090a0,5, +0x3090c0,5, +0x3090e0,5, +0x309100,44, +0x309200,44, +0x309300,44, +0x309400,44, +0x309500,44, +0x309600,44, +0x309700,44, +0x309800,44, +0x309900,5, +0x309920,10, +0x309950,3, +0x309960,5, +0x309980,5, +0x3099a0,5, +0x3099b8,5, +0x3099d0,20, +0x30a000,3, +0x30a010,3, +0x30a020,3, +0x30a030,3, +0x30a040,3, +0x30a050,3, +0x30a060,3, +0x30a070,3, +0x30a080,28, +0x30a100,28, +0x30a180,28, +0x30a200,28, +0x30a280,28, +0x30a300,28, +0x30a380,28, +0x30a400,28, +0x30a480,9, +0x30a4b0,3, +0x30a4c0,9, +0x30a4f0,3, +0x30a500,3, +0x30a510,1, +0x30a520,17, +0x30a800,22, +0x310000,1, +0x310200,2, +0x310240,8, +0x310280,9, +0x3102c0,9, +0x310300,9, +0x310340,9, +0x310380,24, +0x310400,2, +0x310440,8, +0x310480,9, +0x3104c0,9, +0x310500,9, +0x310540,9, +0x310580,24, +0x310600,9, +0x310640,9, +0x310680,9, +0x3106c0,9, +0x310700,9, +0x310740,9, +0x310780,9, +0x3107c0,9, +0x310800,9, +0x310840,9, +0x310880,9, +0x3108c0,9, +0x310900,9, +0x310940,9, +0x310980,9, +0x3109c0,9, +0x310a00,9, +0x310a40,9, +0x310a80,9, +0x310ac0,9, +0x310b00,9, +0x310b40,9, +0x310b80,9, +0x310bc0,9, +0x310c00,3, +0x310c20,25, +0x310ca0,5, +0x310cc0,1, +0x310cc8,5, +0x310ce0,5, +0x310d00,1, +0x310d08,5, +0x310d20,16, +0x311000,74, +0x311200,74, +0x311404,1, +0x311418,10, +0x311444,3, +0x311464,7, +0x311484,7, +0x3114a4,1, +0x3114ac,1, +0x3114b4,1, +0x3114bc,3, +0x311500,8, +0x311600,17, +0x311660,1, +0x311680,66, +0x311790,3, +0x3117a4,1, +0x3117ac,4, +0x3117c0,14, +0x311800,17, +0x311860,1, +0x311880,66, +0x311990,3, +0x311a00,1, +0x311a40,10, +0x311a80,2, +0x311aa0,6, +0x311ac0,6, +0x311ae0,17, +0x311b28,19, +0x311b78,4, +0x311b90,3, +0x311ba0,2, +0x311bb0,3, +0x311c00,21, 0x311c80,1, -0x311ca0,6, -0x311d00,27, -0x311d80,27, -0x311e00,27, -0x311e80,27, -0x311f00,27, -0x311f80,27, -0x312000,27, -0x312080,27, -0x312100,27, -0x312180,27, -0x312200,27, -0x312280,27, -0x312300,27, -0x312380,27, -0x312400,27, -0x312480,27, -0x312500,2, -0x312510,3, -0x312520,1, -0x312800,2, -0x312820,64, -0x312a00,2, -0x312a20,64, -0x312c00,195, -0x313000,33, -0x314000,6, -0x314020,6, -0x314040,6, -0x314060,6, -0x314080,6, -0x3140a0,6, -0x3140c0,6, -0x3140e0,6, -0x314100,6, -0x314120,6, -0x314140,6, -0x314160,6, -0x314180,6, -0x3141a0,6, -0x3141c0,6, -0x3141e0,6, -0x314200,4, -0x318000,9, -0x318028,8, -0x318080,3, -0x3180a0,5, -0x318100,9, -0x318128,8, -0x318180,3, -0x3181a0,5, -0x318200,9, -0x318228,8, -0x318280,3, -0x3182a0,5, -0x318300,9, -0x318328,8, -0x318380,3, -0x3183a0,5, -0x318400,9, -0x318428,8, -0x318480,3, -0x3184a0,5, -0x318500,9, -0x318528,8, -0x318580,6, -0x3185a0,5, -0x318600,9, -0x318628,8, -0x318680,3, -0x3186a0,5, -0x318700,9, -0x318728,8, -0x318780,3, -0x3187a0,5, -0x318800,9, -0x318828,8, -0x318880,3, -0x3188a0,5, -0x319000,9, -0x319028,8, -0x319080,3, -0x3190a0,5, -0x319100,9, -0x319128,8, -0x319180,3, -0x3191a0,5, -0x319200,9, -0x319228,8, -0x319280,3, -0x3192a0,5, -0x319300,9, -0x319328,8, -0x319380,3, -0x3193a0,5, -0x319400,9, -0x319428,8, -0x319480,3, -0x3194a0,5, -0x319500,9, -0x319528,8, -0x319580,6, -0x3195a0,5, -0x319600,9, -0x319628,8, -0x319680,3, -0x3196a0,5, -0x319700,9, -0x319728,8, -0x319780,3, -0x3197a0,5, -0x319800,9, -0x319828,8, -0x319880,3, -0x3198a0,5, -0x31a000,9, -0x31a028,8, -0x31a080,6, -0x31a0a0,5, -0x31a100,9, -0x31a128,8, -0x31a180,6, -0x31a1a0,5, -0x31a200,9, -0x31a228,8, -0x31a280,6, -0x31a2a0,5, -0x31a300,9, -0x31a328,8, -0x31a380,6, -0x31a3a0,5, -0x31a400,9, -0x31a428,8, -0x31a480,6, -0x31a4a0,5, -0x31a500,9, -0x31a528,8, -0x31a580,6, -0x31a5a0,5, -0x31a600,9, -0x31a628,8, -0x31a680,6, -0x31a6a0,5, -0x31a700,9, -0x31a728,8, -0x31a780,6, -0x31a7a0,5, -0x31a800,9, -0x31a828,8, -0x31a880,6, -0x31a8a0,5, -0x31a900,9, -0x31a928,8, -0x31a980,6, -0x31a9a0,5, -0x31aa00,9, -0x31aa28,8, -0x31aa80,6, -0x31aaa0,5, -0x31ab00,9, -0x31ab28,8, -0x31ab80,6, -0x31aba0,5, -0x31ac00,9, -0x31ac28,8, -0x31ac80,6, -0x31aca0,5, -0x31ad00,9, -0x31ad28,8, -0x31ad80,6, -0x31ada0,5, -0x31ae00,9, -0x31ae28,8, -0x31ae80,6, -0x31aea0,5, -0x31af00,9, -0x31af28,8, -0x31af80,6, -0x31afa0,5, -0x31b000,9, -0x31b028,8, -0x31b080,6, -0x31b0a0,5, -0x31b100,9, -0x31b128,8, -0x31b180,6, -0x31b1a0,5, -0x31b200,9, -0x31b228,8, -0x31b280,6, -0x31b2a0,5, -0x31b300,9, -0x31b328,8, -0x31b380,6, -0x31b3a0,5, -0x31b400,9, -0x31b428,8, -0x31b480,6, -0x31b4a0,5, -0x31b500,9, -0x31b528,8, -0x31b580,6, -0x31b5a0,5, -0x31b600,9, -0x31b628,8, -0x31b680,6, -0x31b6a0,5, -0x31b700,9, -0x31b728,8, -0x31b780,6, -0x31b7a0,5, -0x31b800,9, -0x31b828,8, -0x31b880,4, -0x31b8c0,13, -0x31b900,6, -0x31b920,5, -0x31c000,3, -0x31c010,3, -0x31c020,3, -0x31c030,3, -0x31c040,3, -0x31c050,3, -0x31c060,3, -0x31c070,3, -0x31c080,3, -0x31c090,3, -0x31c0a0,3, -0x31c0b0,3, -0x31c0c0,3, -0x31c0d0,3, -0x31c0e0,3, -0x31c0f0,3, -0x31c100,2, -0x31c200,3, -0x31c210,3, -0x31c220,3, -0x31c230,3, -0x31c240,3, -0x31c250,3, -0x31c260,3, -0x31c270,3, -0x31c280,3, -0x31c290,3, -0x31c2a0,3, -0x31c2b0,3, -0x31c2c0,3, -0x31c2d0,3, -0x31c2e0,3, -0x31c2f0,3, -0x31c300,2, -0x31c400,3, -0x31c410,3, -0x31c420,3, -0x31c430,3, -0x31c440,3, -0x31c450,3, -0x31c460,3, -0x31c470,3, -0x31c480,3, -0x31c490,3, -0x31c4a0,3, -0x31c4b0,3, -0x31c4c0,3, -0x31c4d0,3, -0x31c4e0,3, -0x31c4f0,3, -0x31c500,2, -0x31c600,18, -0x31c680,18, -0x31c700,4, -0x31d000,5, -0x31d020,5, -0x31d040,5, -0x31d060,5, -0x31d080,5, -0x31d0a0,5, -0x31d0c0,5, -0x31d0e0,5, -0x31d100,5, -0x31d120,5, -0x31d140,5, -0x31d160,5, -0x31d180,5, -0x31d1a0,5, -0x31d1c0,5, -0x31d1e0,5, -0x31d200,5, -0x31d220,5, -0x31d240,5, -0x31d260,5, -0x31d280,5, -0x31d2a0,5, -0x31d2c0,5, -0x31d2e0,5, -0x31d300,5, -0x31d320,5, -0x31d340,5, -0x31d360,5, -0x31d380,5, -0x31d3a0,5, -0x31d3c0,5, -0x31d3e0,5, -0x31d400,5, -0x31d420,5, -0x31d440,5, -0x31d460,5, -0x31d480,5, -0x31d4a0,5, -0x31d4c0,5, -0x31d4e0,5, -0x31d500,5, -0x31d520,5, -0x31d540,5, -0x31d560,5, -0x31d580,5, -0x31d5a0,5, -0x31d5c0,5, -0x31d5e0,5, -0x31d600,5, -0x31d620,5, -0x31d640,5, -0x31d660,5, -0x31d680,5, -0x31d6a0,5, -0x31d6c0,5, -0x31d6e0,5, -0x31d700,5, -0x31d720,5, -0x31d740,5, -0x31d760,5, -0x31d780,5, -0x31d7a0,5, -0x31d7c0,5, -0x31d7e0,5, -0x31d800,24, -0x31d868,16, -0x31d8b0,3, -0x31e000,5, -0x31e020,5, -0x31e040,5, -0x31e060,5, -0x31e080,5, -0x31e0a0,5, -0x31e0c0,5, -0x31e0e0,5, -0x31e100,5, -0x31e120,5, -0x31e140,5, -0x31e160,5, -0x31e180,5, -0x31e1a0,5, -0x31e1c0,5, -0x31e1e0,5, -0x31e200,5, -0x31e220,5, -0x31e240,5, -0x31e260,5, -0x31e280,5, -0x31e2a0,5, -0x31e2c0,5, -0x31e2e0,5, -0x31e300,5, -0x31e320,5, -0x31e340,5, -0x31e360,5, -0x31e380,5, -0x31e3a0,5, -0x31e3c0,5, -0x31e3e0,5, -0x31e400,5, -0x31e420,5, -0x31e440,5, -0x31e460,5, -0x31e480,5, -0x31e4a0,5, -0x31e4c0,5, -0x31e4e0,5, -0x31e500,5, -0x31e520,5, -0x31e540,5, -0x31e560,5, -0x31e580,5, -0x31e5a0,5, -0x31e5c0,5, -0x31e5e0,5, -0x31e600,5, -0x31e620,5, -0x31e640,5, -0x31e660,5, -0x31e680,5, -0x31e6a0,5, -0x31e6c0,5, -0x31e6e0,5, -0x31e700,5, -0x31e720,5, -0x31e740,5, -0x31e760,5, -0x31e780,5, -0x31e7a0,5, -0x31e7c0,5, -0x31e7e0,5, -0x31e800,24, -0x31e868,10, -0x31f000,11, -0x31f030,7, -0x31f080,11, -0x31f0b0,7, -0x31f100,1, -0x340000,7, -0x340020,7, -0x340040,7, -0x340060,7, -0x340080,7, -0x3400a0,7, -0x3400c0,7, -0x3400e0,7, -0x340100,7, -0x340120,7, -0x340140,7, -0x340160,7, -0x340180,7, -0x3401a0,7, -0x3401c0,7, -0x3401e0,7, -0x340200,47, -0x3402c0,118, -0x3404a0,6, +0x311c88,7, +0x311cc0,1, +0x311ce0,26, +0x311d80,1, +0x311e00,5, +0x311e20,5, +0x311e40,5, +0x311e60,5, +0x311e80,9, +0x312000,108, +0x312200,8, +0x320000,31, +0x320080,31, +0x320100,31, +0x320180,31, +0x320200,31, +0x320280,31, +0x320300,31, +0x320380,31, +0x320400,31, +0x320480,31, +0x320500,31, +0x320580,31, +0x320600,31, +0x320680,31, +0x320700,31, +0x320780,31, +0x320800,9, +0x320880,1, +0x320900,21, +0x320980,21, +0x320a00,21, +0x320a80,1, +0x320c04,1, +0x320c10,6, +0x320c30,64, +0x320e00,12, +0x320e40,10, +0x320e80,13, +0x320ec0,13, +0x320f00,9, +0x320f40,5, +0x320f60,5, +0x320f80,6, +0x320fa0,1, +0x320fa8,100, +0x321404,1, +0x321428,22, +0x321504,1, +0x321544,47, +0x321604,1, +0x32161c,9, +0x321644,1, +0x32164c,1, +0x321654,1, +0x32165c,1, +0x321664,1, +0x32166c,3, +0x322000,96, +0x322200,96, +0x322400,6, +0x322424,1, +0x32242c,14, +0x322800,40, +0x3228c0,3, +0x3228d0,3, +0x3228e0,3, +0x3228f0,3, +0x322904,1, +0x32291c,11, +0x322a04,1, +0x322a0c,7, +0x322a40,1, +0x322a54,4, +0x323000,3, +0x324000,3, +0x324010,3, +0x324020,3, +0x324030,3, +0x324040,3, +0x324050,3, +0x324060,3, +0x324070,3, +0x324080,3, +0x324090,3, +0x3240a0,3, +0x3240b0,3, +0x3240c0,3, +0x3240d0,3, +0x3240e0,3, +0x3240f0,3, +0x324100,3, +0x324110,3, +0x324120,3, +0x324130,3, +0x324140,3, +0x324150,3, +0x324160,3, +0x324170,3, +0x324180,3, +0x324190,3, +0x3241a0,3, +0x3241b0,3, +0x3241c0,3, +0x3241d0,3, +0x3241e0,3, +0x3241f0,3, +0x324200,3, +0x324210,3, +0x324220,3, +0x324230,3, +0x324240,3, +0x324250,3, +0x324260,3, +0x324270,3, +0x324280,3, +0x324290,3, +0x3242a0,3, +0x3242b0,3, +0x3242c0,3, +0x3242d0,3, +0x3242e0,3, +0x3242f0,3, +0x324300,3, +0x324310,3, +0x324320,3, +0x324330,3, +0x324340,3, +0x324350,3, +0x324360,3, +0x324370,3, +0x324380,3, +0x324390,3, +0x3243a0,3, +0x3243b0,3, +0x3243c0,3, +0x3243d0,3, +0x3243e0,3, +0x3243f0,3, +0x324400,3, +0x324410,3, +0x324420,3, +0x324430,3, +0x324440,3, +0x324450,3, +0x324460,3, +0x324470,3, +0x324480,3, +0x324490,3, +0x3244a0,3, +0x3244b0,3, +0x3244c0,3, +0x3244d0,3, +0x3244e0,3, +0x3244f0,3, +0x324500,3, +0x324510,3, +0x324520,3, +0x324530,3, +0x324540,3, +0x324550,3, +0x324560,3, +0x324570,3, +0x324580,3, +0x324590,3, +0x3245a0,3, +0x3245b0,3, +0x3245c0,3, +0x3245d0,3, +0x3245e0,3, +0x3245f0,3, +0x324600,32, +0x324800,128, +0x324a04,1, +0x324a20,8, +0x324a44,1, +0x324a60,8, +0x324a84,1, +0x324a94,3, +0x324aa4,1, +0x324ab4,6, +0x324b00,41, +0x324bc4,1, +0x324bd0,4, +0x324be4,6, +0x324c00,3, +0x324c10,14, +0x324c60,9, +0x325000,5, +0x325020,5, +0x325040,5, +0x325060,5, +0x325080,5, +0x3250a0,5, +0x3250c0,5, +0x3250e0,5, +0x325100,5, +0x325120,5, +0x325140,5, +0x325160,5, +0x325180,5, +0x3251a0,5, +0x3251c0,5, +0x3251e0,5, +0x325200,5, +0x325220,5, +0x325240,5, +0x325260,5, +0x325280,5, +0x3252a0,5, +0x3252c0,5, +0x3252e0,5, +0x325300,5, +0x325320,5, +0x325340,5, +0x325360,5, +0x325380,5, +0x3253a0,5, +0x3253c0,5, +0x3253e0,5, +0x325400,5, +0x325420,5, +0x325440,5, +0x325460,5, +0x325480,5, +0x3254a0,5, +0x3254c0,5, +0x3254e0,5, +0x325500,5, +0x325520,5, +0x325540,5, +0x325560,5, +0x325580,5, +0x3255a0,5, +0x3255c0,5, +0x3255e0,5, +0x325600,5, +0x325620,5, +0x325640,5, +0x325660,5, +0x325680,5, +0x3256a0,5, +0x3256c0,5, +0x3256e0,5, +0x325700,5, +0x325720,5, +0x325740,5, +0x325760,5, +0x325780,5, +0x3257a0,5, +0x3257c0,5, +0x3257e0,5, +0x325800,27, +0x325874,10, +0x325904,1, +0x32590c,5, +0x325924,1, +0x32592c,7, +0x325980,8, +0x326000,5, +0x326020,5, +0x326040,5, +0x326060,5, +0x326080,5, +0x3260a0,5, +0x3260c0,5, +0x3260e0,5, +0x326100,5, +0x326120,5, +0x326140,5, +0x326160,5, +0x326180,5, +0x3261a0,5, +0x3261c0,5, +0x3261e0,5, +0x326200,5, +0x326220,5, +0x326240,5, +0x326260,5, +0x326280,5, +0x3262a0,5, +0x3262c0,5, +0x3262e0,5, +0x326300,5, +0x326320,5, +0x326340,5, +0x326360,5, +0x326380,5, +0x3263a0,5, +0x3263c0,5, +0x3263e0,5, +0x326400,5, +0x326420,5, +0x326440,5, +0x326460,5, +0x326480,5, +0x3264a0,5, +0x3264c0,5, +0x3264e0,5, +0x326500,5, +0x326520,5, +0x326540,5, +0x326560,5, +0x326580,5, +0x3265a0,5, +0x3265c0,5, +0x3265e0,5, +0x326600,5, +0x326620,5, +0x326640,5, +0x326660,5, +0x326680,5, +0x3266a0,5, +0x3266c0,5, +0x3266e0,5, +0x326700,5, +0x326720,5, +0x326740,5, +0x326760,5, +0x326780,5, +0x3267a0,5, +0x3267c0,5, +0x3267e0,5, +0x326800,27, +0x326874,10, +0x326904,1, +0x32690c,5, +0x326924,1, +0x32692c,7, +0x326980,8, +0x327000,20, +0x327080,20, +0x327100,20, +0x327180,20, +0x327200,20, +0x327280,20, +0x327300,20, +0x327380,20, +0x327400,20, +0x327480,20, +0x327500,20, +0x327580,20, +0x327600,20, +0x327680,20, +0x327700,20, +0x327780,20, +0x327800,11, +0x327830,1, +0x327840,9, +0x327880,11, +0x3278b0,1, +0x3278c0,9, +0x327900,11, +0x327930,1, +0x327940,9, +0x327980,11, +0x3279b0,1, +0x3279c0,9, +0x327a00,11, +0x327a30,1, +0x327a40,9, +0x327a80,11, +0x327ab0,1, +0x327ac0,9, +0x327b00,11, +0x327b30,1, +0x327b40,9, +0x327b80,11, +0x327bb0,1, +0x327bc0,9, +0x327c00,8, +0x328000,1, +0x328100,57, +0x328200,57, +0x328300,57, +0x328400,57, +0x328500,57, +0x328600,57, +0x328700,57, +0x328800,57, +0x328900,57, +0x328a00,57, +0x328b00,57, +0x328c00,57, +0x328d00,57, +0x328e00,57, +0x328f00,57, +0x329000,57, +0x329100,28, +0x329180,17, +0x329200,11, +0x329240,9, +0x329280,33, +0x329308,4, +0x329320,1, +0x329340,1, +0x329360,7, +0x329380,7, +0x3293a0,1, +0x3293c0,6, +0x3293e0,6, +0x329400,6, +0x329420,1, +0x329440,6, +0x329460,6, +0x329480,6, +0x3294a0,1, +0x3294c0,6, +0x3294e0,6, +0x329500,6, +0x329520,3, +0x329530,7, +0x329550,7, +0x329570,7, +0x329590,7, +0x3295b0,7, +0x3295d0,7, +0x3295f0,7, +0x329610,7, +0x329630,7, +0x329650,7, +0x329670,7, +0x329690,7, +0x3296b0,7, +0x3296d0,7, +0x3296f0,7, +0x329710,7, +0x329730,7, +0x329750,7, +0x329770,7, +0x329790,7, +0x3297b0,7, +0x3297d0,7, +0x3297f0,7, +0x329810,15, +0x329860,39, +0x329920,7, +0x329960,2, +0x32996c,3, +0x329980,2, +0x32998c,3, +0x3299a0,2, +0x3299ac,3, +0x3299c0,2, +0x3299cc,3, +0x3299e0,2, +0x3299ec,3, +0x329a00,2, +0x329a0c,3, +0x329a20,2, +0x329a2c,3, +0x329a40,2, +0x329a4c,3, +0x329a60,2, +0x329a6c,3, +0x329a80,2, +0x329a8c,3, +0x329aa0,2, +0x329aac,3, +0x329ac0,2, +0x329acc,3, +0x329ae0,2, +0x329aec,3, +0x329b00,2, +0x329b0c,3, +0x329b20,2, +0x329b2c,3, +0x329b40,2, +0x329b4c,3, +0x329c00,27, +0x329c80,1, +0x329ca0,6, +0x32a000,27, +0x32a080,4, +0x32a0c0,25, +0x32a140,6, +0x32a160,2, +0x32a16c,3, +0x32a200,8, +0x32a224,25, +0x32a400,27, +0x32a480,1, +0x32a4a0,6, +0x32a500,27, +0x32a580,27, +0x32a600,27, +0x32a680,27, +0x32a700,27, +0x32a780,27, +0x32a800,27, +0x32a880,27, +0x32a900,27, +0x32a980,27, +0x32aa00,27, +0x32aa80,27, +0x32ab00,27, +0x32ab80,27, +0x32ac00,27, +0x32ac80,27, +0x32ad00,2, +0x32ad10,3, +0x32ad20,1, +0x32ad30,65, +0x32b000,3, +0x32b010,3, +0x32b020,3, +0x32b030,3, +0x32b040,3, +0x32b050,3, +0x32b060,3, +0x32b070,3, +0x32b080,3, +0x32b090,3, +0x32b0a0,3, +0x32b0b0,3, +0x32b0c0,3, +0x32b0d0,3, +0x32b0e0,3, +0x32b0f0,3, +0x32b100,2, +0x32b200,3, +0x32b210,3, +0x32b220,3, +0x32b230,3, +0x32b240,3, +0x32b250,3, +0x32b260,3, +0x32b270,3, +0x32b280,3, +0x32b290,3, +0x32b2a0,3, +0x32b2b0,3, +0x32b2c0,3, +0x32b2d0,3, +0x32b2e0,3, +0x32b2f0,3, +0x32b300,2, +0x32b400,3, +0x32b410,3, +0x32b420,3, +0x32b430,3, +0x32b440,3, +0x32b450,3, +0x32b460,3, +0x32b470,3, +0x32b480,3, +0x32b490,3, +0x32b4a0,3, +0x32b4b0,3, +0x32b4c0,3, +0x32b4d0,3, +0x32b4e0,3, +0x32b4f0,3, +0x32b500,2, +0x32b680,11, +0x32b6b0,8, +0x32b700,11, +0x32b730,8, +0x32b780,1, +0x340000,167, +0x3402a0,7, +0x3402c0,7, +0x3402e0,118, 0x3404c0,6, 0x3404e0,6, 0x340500,6, @@ -8422,7 +8591,7 @@ 0x340620,6, 0x340640,6, 0x340660,6, -0x340680,5, +0x340680,6, 0x3406a0,5, 0x3406c0,5, 0x3406e0,5, @@ -8438,7 +8607,8 @@ 0x340820,5, 0x340840,5, 0x340860,5, -0x340880,29, +0x340880,5, +0x3408a0,16, 0x340900,13, 0x340940,13, 0x340980,13, @@ -8454,8 +8624,7 @@ 0x340c00,13, 0x340c40,13, 0x340c80,13, -0x340cc0,5, -0x340ce0,5, +0x340cc0,13, 0x340d00,5, 0x340d20,5, 0x340d40,5, @@ -8470,7 +8639,9 @@ 0x340e60,5, 0x340e80,5, 0x340ea0,5, -0x340ec0,1, +0x340ec0,5, +0x340ee0,5, +0x340f00,17, 0x341000,179, 0x341400,5, 0x341800,3, @@ -8508,7 +8679,7 @@ 0x341a00,2, 0x341a0c,12, 0x341a40,20, -0x341c00,20, +0x341c00,1, 0x341c80,20, 0x341d00,20, 0x341d80,20, @@ -8524,7 +8695,8 @@ 0x342280,20, 0x342300,20, 0x342380,20, -0x342400,5, +0x342400,20, +0x342480,5, 0x344000,27, 0x344080,27, 0x344100,27, @@ -8565,83 +8737,83 @@ 0x352000,46, 0x352100,2, 0x352110,21, -0x352180,19, -0x3521d0,1, +0x352180,23, +0x3521e0,3, 0x352200,46, 0x352300,2, 0x352310,21, -0x352380,19, -0x3523d0,1, +0x352380,23, +0x3523e0,3, 0x352400,46, 0x352500,2, 0x352510,21, -0x352580,19, -0x3525d0,1, +0x352580,23, +0x3525e0,3, 0x352600,46, 0x352700,2, 0x352710,21, -0x352780,19, -0x3527d0,1, +0x352780,23, +0x3527e0,3, 0x352800,46, 0x352900,2, 0x352910,21, -0x352980,19, -0x3529d0,1, +0x352980,23, +0x3529e0,3, 0x352a00,46, 0x352b00,2, 0x352b10,21, -0x352b80,19, -0x352bd0,1, +0x352b80,23, +0x352be0,3, 0x352c00,46, 0x352d00,2, 0x352d10,21, -0x352d80,19, -0x352dd0,1, +0x352d80,23, +0x352de0,3, 0x352e00,46, 0x352f00,2, 0x352f10,21, -0x352f80,19, -0x352fd0,1, +0x352f80,23, +0x352fe0,3, 0x353000,46, 0x353100,2, 0x353110,21, -0x353180,19, -0x3531d0,1, +0x353180,23, +0x3531e0,3, 0x353200,46, 0x353300,2, 0x353310,21, -0x353380,19, -0x3533d0,1, +0x353380,23, +0x3533e0,3, 0x353400,46, 0x353500,2, 0x353510,21, -0x353580,19, -0x3535d0,1, +0x353580,23, +0x3535e0,3, 0x353600,46, 0x353700,2, 0x353710,21, -0x353780,19, -0x3537d0,1, +0x353780,23, +0x3537e0,3, 0x353800,46, 0x353900,2, 0x353910,21, -0x353980,19, -0x3539d0,1, +0x353980,23, +0x3539e0,3, 0x353a00,46, 0x353b00,2, 0x353b10,21, -0x353b80,19, -0x353bd0,1, +0x353b80,23, +0x353be0,3, 0x353c00,46, 0x353d00,2, 0x353d10,21, -0x353d80,19, -0x353dd0,1, +0x353d80,23, +0x353de0,3, 0x353e00,46, 0x353f00,2, 0x353f10,21, -0x353f80,19, -0x353fd0,1, +0x353f80,23, +0x353fe0,3, 0x354000,21, 0x354060,29, 0x3540e0,29, @@ -8658,22 +8830,22 @@ 0x354660,29, 0x3546e0,29, 0x354760,29, -0x3547e0,37, -0x354880,29, -0x354900,29, -0x354980,29, -0x354a00,29, -0x354a80,29, -0x354b00,29, -0x354b80,29, -0x354c00,29, -0x354c80,29, -0x354d00,29, -0x354d80,29, -0x354e00,29, -0x354e80,29, -0x354f00,29, -0x354f80,29, +0x3547e0,38, +0x354880,30, +0x354900,30, +0x354980,30, +0x354a00,30, +0x354a80,30, +0x354b00,30, +0x354b80,30, +0x354c00,30, +0x354c80,30, +0x354d00,30, +0x354d80,30, +0x354e00,30, +0x354e80,30, +0x354f00,30, +0x354f80,30, 0x355000,58, 0x3550ec,1, 0x3550f4,2, @@ -9063,750 +9235,1099 @@ 0x35f800,34, 0x35f8a0,8, 0x360000,1, -0x361000,22528, +0x361000,977, +0x362000,161, +0x363000,977, +0x364000,977, +0x365000,977, +0x366000,64, +0x366104,127, +0x366304,127, +0x366504,195, +0x366814,31, +0x366894,428, +0x367000,977, +0x368000,977, +0x369000,977, +0x36a000,977, +0x36b000,977, +0x36c000,977, +0x36d000,977, +0x36e000,977, +0x36f000,977, +0x370000,977, +0x371000,977, +0x372000,977, +0x373000,161, +0x374000,161, +0x375000,161, +0x376000,161, +0x378000,13, +0x378040,14, +0x378080,20, +0x378104,1, +0x37810c,3, +0x378200,13, +0x378240,14, +0x378280,20, +0x378304,1, +0x37830c,3, +0x378400,13, +0x378440,14, +0x378480,20, +0x378504,1, +0x37850c,3, +0x378600,13, +0x378640,14, +0x378680,20, +0x378704,1, +0x37870c,3, +0x378800,13, +0x378840,14, +0x378880,20, +0x378904,1, +0x37890c,3, +0x378a00,13, +0x378a40,14, +0x378a80,20, +0x378b04,1, +0x378b0c,3, +0x378c00,13, +0x378c40,14, +0x378c80,20, +0x378d04,1, +0x378d0c,3, +0x378e00,13, +0x378e40,14, +0x378e80,20, +0x378f04,1, +0x378f0c,3, +0x379000,13, +0x379040,14, +0x379080,20, +0x379104,1, +0x37910c,3, +0x379200,13, +0x379240,14, +0x379280,20, +0x379304,1, +0x37930c,3, +0x379400,13, +0x379440,14, +0x379480,20, +0x379504,1, +0x37950c,3, +0x379600,13, +0x379640,14, +0x379680,20, +0x379704,1, +0x37970c,3, +0x379800,13, +0x379840,14, +0x379880,20, +0x379904,1, +0x37990c,3, +0x379a00,13, +0x379a40,14, +0x379a80,20, +0x379b04,1, +0x379b0c,3, +0x379c00,13, +0x379c40,14, +0x379c80,20, +0x379d04,1, +0x379d0c,3, +0x379e00,13, +0x379e40,14, +0x379e80,20, +0x379f04,1, +0x379f0c,3, +0x37a000,13, +0x37a040,14, +0x37a080,20, +0x37a104,1, +0x37a10c,3, +0x37a200,17, +0x37a250,2, +0x37a260,5, +0x37a280,2, +0x37c000,1, +0x37c014,1, +0x37c01c,10, +0x37c060,9, +0x37c094,1, +0x37c09c,10, +0x37c0e0,9, +0x37c114,1, +0x37c11c,10, +0x37c160,9, +0x37c194,1, +0x37c19c,10, +0x37c1e0,9, +0x37c214,1, +0x37c21c,10, +0x37c260,15, +0x37c400,30, +0x37c480,9, +0x37c4c0,12, +0x37c500,1, +0x37c520,5, +0x37c540,1, 0x380000,19, -0x380100,1, -0x380200,57, -0x380300,57, -0x380400,57, -0x380500,57, -0x380600,57, -0x380700,57, -0x380800,57, -0x380900,57, -0x380a00,57, -0x380b00,57, -0x380c00,57, -0x380d00,57, -0x380e00,57, -0x380f00,57, -0x381000,57, -0x381100,57, -0x381200,6, -0x382000,27, -0x382070,3, -0x382080,27, -0x3820f0,3, -0x382100,27, -0x382170,3, -0x382180,27, -0x3821f0,3, -0x382200,27, -0x382270,3, -0x382280,27, -0x3822f0,3, -0x382300,27, -0x382370,3, -0x382380,27, -0x3823f0,3, -0x382400,27, -0x382470,3, -0x382480,27, -0x3824f0,3, -0x382500,27, -0x382570,3, -0x382580,27, -0x3825f0,3, -0x382600,27, -0x382670,3, -0x382680,27, -0x3826f0,3, -0x382700,27, -0x382770,3, -0x382780,27, -0x3827f0,3, -0x382800,1, -0x382808,31, -0x382a04,1, -0x382a10,6, -0x382a30,64, -0x382c00,23, -0x382c60,17, -0x382cc0,5, -0x382ce0,3, -0x382cf0,100, -0x383004,1, -0x383010,12, -0x383104,1, -0x383150,44, -0x383204,1, -0x38321c,11, -0x384000,130, -0x384300,36, -0x384400,36, -0x384500,36, -0x384600,36, -0x384700,36, -0x384800,36, -0x384900,36, -0x384a00,36, -0x384b00,36, -0x384c00,36, -0x384d00,36, -0x384e00,36, -0x384f00,36, -0x385000,36, -0x385100,36, -0x385200,36, -0x385300,64, -0x388000,49, -0x388100,49, -0x388204,1, -0x38821c,11, -0x388280,3, -0x3882a0,5, -0x3882c0,9, -0x388300,3, -0x388320,6, -0x388340,74, -0x388480,5, -0x3884a0,1, -0x3884b0,7, -0x3884d0,3, -0x3884e0,22, -0x38a000,58, -0x38a0f0,10, -0x38a200,36, -0x38a300,36, -0x38a400,36, -0x38a500,36, -0x38a600,36, -0x38a700,36, -0x38a800,36, -0x38a900,36, -0x38aa00,36, -0x38ab00,36, -0x38ac00,36, -0x38ad00,36, -0x38ae00,36, -0x38af00,36, -0x38b000,36, -0x38b100,36, -0x38b200,36, -0x38b300,36, -0x38c000,51, -0x38c100,1, -0x38c120,9, -0x38c160,9, -0x38c1a0,9, -0x38c1e0,9, -0x38c220,9, -0x38c260,9, -0x38c2a0,9, -0x38c2e0,9, -0x38c320,9, -0x38c360,9, -0x38c3a0,9, -0x38c3e0,9, -0x38c420,9, -0x38c460,9, -0x38c4a0,9, -0x38c4e0,28, -0x38c580,20, -0x38c600,20, -0x38c680,20, -0x38c700,20, -0x38c780,20, -0x38c800,20, -0x38c880,20, -0x38c900,20, -0x38c980,20, -0x38ca00,20, -0x38ca80,20, -0x38cb00,20, -0x38cb80,20, -0x38cc00,20, -0x38cc80,20, -0x38cd00,20, -0x38cd80,20, -0x38ce00,20, -0x38d000,3, -0x38d010,3, -0x38d020,3, -0x38d030,3, -0x38d040,3, -0x38d050,3, -0x38d060,3, -0x38d070,3, -0x38d080,5, -0x38d100,28, -0x38d180,28, -0x38d200,28, -0x38d280,28, -0x38d300,28, -0x38d380,28, -0x38d400,28, -0x38d480,28, -0x38d500,28, -0x38d580,28, -0x38d600,28, -0x38d680,28, -0x38d700,28, -0x38d780,28, -0x38d800,28, -0x38d880,28, -0x38d900,28, -0x38d980,28, -0x38e000,4, -0x390000,9, -0x390040,9, -0x390080,33, -0x390108,5, -0x390120,3, -0x390130,3, -0x390140,1, -0x390148,1, -0x390150,1, -0x390164,8, -0x3901a0,8, -0x390200,1, -0x390208,7, -0x390280,20, -0x390300,20, -0x390380,20, -0x390400,20, -0x390480,20, -0x390500,20, -0x390580,20, -0x390600,20, -0x390680,20, -0x390700,20, -0x390780,20, -0x390800,20, -0x390880,20, -0x390900,20, -0x390980,20, -0x390a00,20, -0x390b00,36, -0x390c00,92, -0x390e00,4, -0x390e20,1, -0x390e40,1, -0x390e60,7, -0x390e80,7, -0x390ea0,1, -0x390ec0,6, -0x390ee0,6, -0x390f00,3, -0x390f10,5, -0x390f40,6, -0x390f60,6, -0x390f80,3, -0x390f90,5, -0x390fc0,6, -0x390fe0,6, -0x391000,3, -0x391010,7, -0x391030,7, -0x391050,7, -0x391070,7, -0x391090,7, -0x3910b0,7, -0x3910d0,7, -0x3910f0,7, -0x391110,7, -0x391130,7, -0x391150,7, -0x391170,7, -0x391190,7, -0x3911b0,7, -0x3911d0,7, -0x3911f0,7, -0x391210,7, -0x391230,7, -0x391250,7, -0x391270,7, -0x391290,7, -0x3912b0,7, -0x3912d0,7, -0x3912f0,7, -0x391310,7, -0x391330,7, -0x391350,7, -0x391370,7, -0x391390,7, -0x3913b0,7, -0x3913d0,7, -0x3913f0,7, -0x391410,24, -0x391480,15, -0x3914c0,15, -0x391520,2, -0x39152c,3, -0x391540,2, -0x39154c,3, -0x391560,2, -0x39156c,3, -0x391580,2, -0x39158c,3, -0x3915a0,2, -0x3915ac,3, -0x3915c0,2, -0x3915cc,3, -0x3915e0,2, -0x3915ec,3, -0x391600,2, -0x39160c,3, -0x391620,2, -0x39162c,3, -0x391640,2, -0x39164c,3, -0x391660,2, -0x39166c,3, -0x391680,2, -0x39168c,3, -0x3916a0,2, -0x3916ac,3, -0x3916c0,2, -0x3916cc,3, -0x3916e0,2, -0x3916ec,3, -0x391700,2, -0x39170c,3, -0x391780,11, -0x3917c0,6, -0x3917dc,2, -0x391800,27, -0x391880,1, -0x3918a0,6, -0x391a00,27, -0x391a80,4, -0x391ac0,25, -0x391b40,6, -0x391b60,2, -0x391b6c,3, -0x391b80,8, -0x391ba4,22, -0x391c00,27, +0x380050,8, +0x380080,12, +0x3800c0,9, +0x380100,19, +0x380150,8, +0x380180,12, +0x3801c0,9, +0x380200,19, +0x380250,8, +0x380280,12, +0x3802c0,9, +0x380300,19, +0x380350,8, +0x380380,12, +0x3803c0,9, +0x380400,19, +0x380450,8, +0x380480,12, +0x3804c0,9, +0x380500,19, +0x380550,8, +0x380580,12, +0x3805c0,9, +0x380600,19, +0x380650,8, +0x380680,12, +0x3806c0,9, +0x380700,19, +0x380750,8, +0x380780,12, +0x3807c0,9, +0x380800,19, +0x380850,8, +0x380880,12, +0x3808c0,9, +0x380900,19, +0x380950,8, +0x380980,12, +0x3809c0,9, +0x380a00,19, +0x380a50,8, +0x380a80,12, +0x380ac0,9, +0x380b00,19, +0x380b50,8, +0x380b80,12, +0x380bc0,9, +0x380c00,19, +0x380c50,8, +0x380c80,12, +0x380cc0,9, +0x380d00,19, +0x380d50,8, +0x380d80,12, +0x380dc0,9, +0x380e00,19, +0x380e50,8, +0x380e80,12, +0x380ec0,9, +0x380f00,19, +0x380f50,8, +0x380f80,12, +0x380fc0,9, +0x381000,19, +0x381050,8, +0x381080,12, +0x3810c0,9, +0x381100,19, +0x381150,8, +0x381180,12, +0x3811c0,9, +0x381200,19, +0x381250,8, +0x381280,12, +0x3812c0,9, +0x381300,19, +0x381350,8, +0x381380,12, +0x3813c0,9, +0x381400,19, +0x381450,8, +0x381480,12, +0x3814c0,9, +0x381500,19, +0x381550,8, +0x381580,12, +0x3815c0,9, +0x381600,19, +0x381650,8, +0x381680,12, +0x3816c0,9, +0x381700,19, +0x381750,8, +0x381780,12, +0x3817c0,9, +0x381800,19, +0x381850,8, +0x381880,12, +0x3818c0,9, +0x381900,19, +0x381950,8, +0x381980,12, +0x3819c0,9, +0x381a00,19, +0x381a50,8, +0x381a80,12, +0x381ac0,9, +0x381b00,19, +0x381b50,8, +0x381b80,12, +0x381bc0,9, +0x381c00,19, +0x381c50,8, +0x381c80,12, +0x381cc0,9, +0x381d00,19, +0x381d50,8, +0x381d80,12, +0x381dc0,9, +0x381e00,19, +0x381e50,8, +0x381e80,12, +0x381ec0,9, +0x381f00,19, +0x381f50,8, +0x381f80,12, +0x381fc0,9, +0x382000,19, +0x382050,8, +0x382080,12, +0x3820c0,9, +0x382100,19, +0x382150,8, +0x382180,12, +0x3821c0,9, +0x382200,19, +0x382250,8, +0x382280,12, +0x3822c0,9, +0x382300,19, +0x382350,8, +0x382380,12, +0x3823c0,9, +0x382400,19, +0x382450,8, +0x382480,12, +0x3824c0,9, +0x382500,19, +0x382550,8, +0x382580,12, +0x3825c0,9, +0x382600,19, +0x382650,8, +0x382680,12, +0x3826c0,9, +0x382700,19, +0x382750,8, +0x382780,12, +0x3827c0,9, +0x382800,24, +0x382880,12, +0x3828c0,17, +0x382a00,24, +0x382a80,12, +0x382ac0,17, +0x382c00,24, +0x382c80,12, +0x382cc0,17, +0x382e00,24, +0x382e80,12, +0x382ec0,17, +0x383000,24, +0x383080,12, +0x3830c0,17, +0x383200,24, +0x383280,12, +0x3832c0,17, +0x383400,24, +0x383480,12, +0x3834c0,17, +0x383600,24, +0x383680,12, +0x3836c0,17, +0x383800,24, +0x383880,12, +0x3838c0,17, +0x383c00,13, +0x383c40,5, +0x383c80,5, +0x383d00,6, +0x383d20,6, +0x383d40,6, +0x383d60,6, +0x383d80,6, +0x383da0,6, +0x383dc0,6, +0x383de0,6, +0x383e00,6, +0x383e20,6, +0x383e40,5, +0x383e60,9, +0x384000,19, +0x384050,6, +0x384080,7, +0x3840a0,2, +0x3840c0,12, +0x384100,9, +0x384200,27, +0x384280,27, +0x384300,15, +0x384340,5, +0x384360,12, +0x384400,20, +0x388000,3, +0x388010,3, +0x388020,3, +0x388030,3, +0x388040,3, +0x388050,3, +0x388060,3, +0x388070,3, +0x388080,28, +0x388100,28, +0x388180,28, +0x388200,28, +0x388280,28, +0x388300,28, +0x388380,28, +0x388400,28, +0x388480,4, +0x3884c0,3, +0x3884e0,18, +0x388540,2, +0x388550,3, +0x388580,2, +0x3885a0,7, +0x3885c0,1, +0x388600,2, +0x388620,7, +0x388640,1, +0x388680,2, +0x3886a0,7, +0x3886c0,1, +0x388700,2, +0x388720,7, +0x388740,1, +0x388780,2, +0x3887a0,7, +0x3887c0,1, +0x388800,2, +0x388820,7, +0x388840,1, +0x388880,2, +0x3888a0,7, +0x3888c0,1, +0x388900,2, +0x388920,7, +0x388940,1, +0x388980,9, +0x389000,5, +0x389020,5, +0x389040,5, +0x389060,5, +0x389080,5, +0x3890a0,5, +0x3890c0,5, +0x3890e0,5, +0x389100,44, +0x389200,44, +0x389300,44, +0x389400,44, +0x389500,44, +0x389600,44, +0x389700,44, +0x389800,44, +0x389900,5, +0x389920,10, +0x389950,3, +0x389960,5, +0x389980,5, +0x3899a0,5, +0x3899b8,5, +0x3899d0,20, +0x38a000,3, +0x38a010,3, +0x38a020,3, +0x38a030,3, +0x38a040,3, +0x38a050,3, +0x38a060,3, +0x38a070,3, +0x38a080,28, +0x38a100,28, +0x38a180,28, +0x38a200,28, +0x38a280,28, +0x38a300,28, +0x38a380,28, +0x38a400,28, +0x38a480,9, +0x38a4b0,3, +0x38a4c0,9, +0x38a4f0,3, +0x38a500,3, +0x38a510,1, +0x38a520,17, +0x38a800,22, +0x390000,1, +0x390200,2, +0x390240,8, +0x390280,9, +0x3902c0,9, +0x390300,9, +0x390340,9, +0x390380,24, +0x390400,2, +0x390440,8, +0x390480,9, +0x3904c0,9, +0x390500,9, +0x390540,9, +0x390580,24, +0x390600,9, +0x390640,9, +0x390680,9, +0x3906c0,9, +0x390700,9, +0x390740,9, +0x390780,9, +0x3907c0,9, +0x390800,9, +0x390840,9, +0x390880,9, +0x3908c0,9, +0x390900,9, +0x390940,9, +0x390980,9, +0x3909c0,9, +0x390a00,9, +0x390a40,9, +0x390a80,9, +0x390ac0,9, +0x390b00,9, +0x390b40,9, +0x390b80,9, +0x390bc0,9, +0x390c00,3, +0x390c20,25, +0x390ca0,5, +0x390cc0,1, +0x390cc8,5, +0x390ce0,5, +0x390d00,1, +0x390d08,5, +0x390d20,16, +0x391000,74, +0x391200,74, +0x391404,1, +0x391418,10, +0x391444,3, +0x391464,7, +0x391484,7, +0x3914a4,1, +0x3914ac,1, +0x3914b4,1, +0x3914bc,3, +0x391500,8, +0x391600,17, +0x391660,1, +0x391680,66, +0x391790,3, +0x3917a4,1, +0x3917ac,4, +0x3917c0,14, +0x391800,17, +0x391860,1, +0x391880,66, +0x391990,3, +0x391a00,1, +0x391a40,10, +0x391a80,2, +0x391aa0,6, +0x391ac0,6, +0x391ae0,17, +0x391b28,19, +0x391b78,4, +0x391b90,3, +0x391ba0,2, +0x391bb0,3, +0x391c00,21, 0x391c80,1, -0x391ca0,6, -0x391d00,27, -0x391d80,27, -0x391e00,27, -0x391e80,27, -0x391f00,27, -0x391f80,27, -0x392000,27, -0x392080,27, -0x392100,27, -0x392180,27, -0x392200,27, -0x392280,27, -0x392300,27, -0x392380,27, -0x392400,27, -0x392480,27, -0x392500,2, -0x392510,3, -0x392520,1, -0x392800,2, -0x392820,64, -0x392a00,2, -0x392a20,64, -0x392c00,195, -0x393000,33, -0x394000,6, -0x394020,6, -0x394040,6, -0x394060,6, -0x394080,6, -0x3940a0,6, -0x3940c0,6, -0x3940e0,6, -0x394100,6, -0x394120,6, -0x394140,6, -0x394160,6, -0x394180,6, -0x3941a0,6, -0x3941c0,6, -0x3941e0,6, -0x394200,4, -0x398000,9, -0x398028,8, -0x398080,3, -0x3980a0,5, -0x398100,9, -0x398128,8, -0x398180,3, -0x3981a0,5, -0x398200,9, -0x398228,8, -0x398280,3, -0x3982a0,5, -0x398300,9, -0x398328,8, -0x398380,3, -0x3983a0,5, -0x398400,9, -0x398428,8, -0x398480,3, -0x3984a0,5, -0x398500,9, -0x398528,8, -0x398580,6, -0x3985a0,5, -0x398600,9, -0x398628,8, -0x398680,3, -0x3986a0,5, -0x398700,9, -0x398728,8, -0x398780,3, -0x3987a0,5, -0x398800,9, -0x398828,8, -0x398880,3, -0x3988a0,5, -0x399000,9, -0x399028,8, -0x399080,3, -0x3990a0,5, -0x399100,9, -0x399128,8, -0x399180,3, -0x3991a0,5, -0x399200,9, -0x399228,8, -0x399280,3, -0x3992a0,5, -0x399300,9, -0x399328,8, -0x399380,3, -0x3993a0,5, -0x399400,9, -0x399428,8, -0x399480,3, -0x3994a0,5, -0x399500,9, -0x399528,8, -0x399580,6, -0x3995a0,5, -0x399600,9, -0x399628,8, -0x399680,3, -0x3996a0,5, -0x399700,9, -0x399728,8, -0x399780,3, -0x3997a0,5, -0x399800,9, -0x399828,8, -0x399880,3, -0x3998a0,5, -0x39a000,9, -0x39a028,8, -0x39a080,6, -0x39a0a0,5, -0x39a100,9, -0x39a128,8, -0x39a180,6, -0x39a1a0,5, -0x39a200,9, -0x39a228,8, -0x39a280,6, -0x39a2a0,5, -0x39a300,9, -0x39a328,8, -0x39a380,6, -0x39a3a0,5, -0x39a400,9, -0x39a428,8, -0x39a480,6, -0x39a4a0,5, -0x39a500,9, -0x39a528,8, -0x39a580,6, -0x39a5a0,5, -0x39a600,9, -0x39a628,8, -0x39a680,6, -0x39a6a0,5, -0x39a700,9, -0x39a728,8, -0x39a780,6, -0x39a7a0,5, -0x39a800,9, -0x39a828,8, -0x39a880,6, -0x39a8a0,5, -0x39a900,9, -0x39a928,8, -0x39a980,6, -0x39a9a0,5, -0x39aa00,9, -0x39aa28,8, -0x39aa80,6, -0x39aaa0,5, -0x39ab00,9, -0x39ab28,8, -0x39ab80,6, -0x39aba0,5, -0x39ac00,9, -0x39ac28,8, -0x39ac80,6, -0x39aca0,5, -0x39ad00,9, -0x39ad28,8, -0x39ad80,6, -0x39ada0,5, -0x39ae00,9, -0x39ae28,8, -0x39ae80,6, -0x39aea0,5, -0x39af00,9, -0x39af28,8, -0x39af80,6, -0x39afa0,5, -0x39b000,9, -0x39b028,8, -0x39b080,6, -0x39b0a0,5, -0x39b100,9, -0x39b128,8, -0x39b180,6, -0x39b1a0,5, -0x39b200,9, -0x39b228,8, -0x39b280,6, -0x39b2a0,5, -0x39b300,9, -0x39b328,8, -0x39b380,6, -0x39b3a0,5, -0x39b400,9, -0x39b428,8, -0x39b480,6, -0x39b4a0,5, -0x39b500,9, -0x39b528,8, -0x39b580,6, -0x39b5a0,5, -0x39b600,9, -0x39b628,8, -0x39b680,6, -0x39b6a0,5, -0x39b700,9, -0x39b728,8, -0x39b780,6, -0x39b7a0,5, -0x39b800,9, -0x39b828,8, -0x39b880,4, -0x39b8c0,13, -0x39b900,6, -0x39b920,5, -0x39c000,3, -0x39c010,3, -0x39c020,3, -0x39c030,3, -0x39c040,3, -0x39c050,3, -0x39c060,3, -0x39c070,3, -0x39c080,3, -0x39c090,3, -0x39c0a0,3, -0x39c0b0,3, -0x39c0c0,3, -0x39c0d0,3, -0x39c0e0,3, -0x39c0f0,3, -0x39c100,2, -0x39c200,3, -0x39c210,3, -0x39c220,3, -0x39c230,3, -0x39c240,3, -0x39c250,3, -0x39c260,3, -0x39c270,3, -0x39c280,3, -0x39c290,3, -0x39c2a0,3, -0x39c2b0,3, -0x39c2c0,3, -0x39c2d0,3, -0x39c2e0,3, -0x39c2f0,3, -0x39c300,2, -0x39c400,3, -0x39c410,3, -0x39c420,3, -0x39c430,3, -0x39c440,3, -0x39c450,3, -0x39c460,3, -0x39c470,3, -0x39c480,3, -0x39c490,3, -0x39c4a0,3, -0x39c4b0,3, -0x39c4c0,3, -0x39c4d0,3, -0x39c4e0,3, -0x39c4f0,3, -0x39c500,2, -0x39c600,18, -0x39c680,18, -0x39c700,4, -0x39d000,5, -0x39d020,5, -0x39d040,5, -0x39d060,5, -0x39d080,5, -0x39d0a0,5, -0x39d0c0,5, -0x39d0e0,5, -0x39d100,5, -0x39d120,5, -0x39d140,5, -0x39d160,5, -0x39d180,5, -0x39d1a0,5, -0x39d1c0,5, -0x39d1e0,5, -0x39d200,5, -0x39d220,5, -0x39d240,5, -0x39d260,5, -0x39d280,5, -0x39d2a0,5, -0x39d2c0,5, -0x39d2e0,5, -0x39d300,5, -0x39d320,5, -0x39d340,5, -0x39d360,5, -0x39d380,5, -0x39d3a0,5, -0x39d3c0,5, -0x39d3e0,5, -0x39d400,5, -0x39d420,5, -0x39d440,5, -0x39d460,5, -0x39d480,5, -0x39d4a0,5, -0x39d4c0,5, -0x39d4e0,5, -0x39d500,5, -0x39d520,5, -0x39d540,5, -0x39d560,5, -0x39d580,5, -0x39d5a0,5, -0x39d5c0,5, -0x39d5e0,5, -0x39d600,5, -0x39d620,5, -0x39d640,5, -0x39d660,5, -0x39d680,5, -0x39d6a0,5, -0x39d6c0,5, -0x39d6e0,5, -0x39d700,5, -0x39d720,5, -0x39d740,5, -0x39d760,5, -0x39d780,5, -0x39d7a0,5, -0x39d7c0,5, -0x39d7e0,5, -0x39d800,24, -0x39d868,16, -0x39d8b0,3, -0x39e000,5, -0x39e020,5, -0x39e040,5, -0x39e060,5, -0x39e080,5, -0x39e0a0,5, -0x39e0c0,5, -0x39e0e0,5, -0x39e100,5, -0x39e120,5, -0x39e140,5, -0x39e160,5, -0x39e180,5, -0x39e1a0,5, -0x39e1c0,5, -0x39e1e0,5, -0x39e200,5, -0x39e220,5, -0x39e240,5, -0x39e260,5, -0x39e280,5, -0x39e2a0,5, -0x39e2c0,5, -0x39e2e0,5, -0x39e300,5, -0x39e320,5, -0x39e340,5, -0x39e360,5, -0x39e380,5, -0x39e3a0,5, -0x39e3c0,5, -0x39e3e0,5, -0x39e400,5, -0x39e420,5, -0x39e440,5, -0x39e460,5, -0x39e480,5, -0x39e4a0,5, -0x39e4c0,5, -0x39e4e0,5, -0x39e500,5, -0x39e520,5, -0x39e540,5, -0x39e560,5, -0x39e580,5, -0x39e5a0,5, -0x39e5c0,5, -0x39e5e0,5, -0x39e600,5, -0x39e620,5, -0x39e640,5, -0x39e660,5, -0x39e680,5, -0x39e6a0,5, -0x39e6c0,5, -0x39e6e0,5, -0x39e700,5, -0x39e720,5, -0x39e740,5, -0x39e760,5, -0x39e780,5, -0x39e7a0,5, -0x39e7c0,5, -0x39e7e0,5, -0x39e800,24, -0x39e868,10, -0x39f000,11, -0x39f030,7, -0x39f080,11, -0x39f0b0,7, -0x39f100,1, -0x3c0000,7, -0x3c0020,7, -0x3c0040,7, -0x3c0060,7, -0x3c0080,7, -0x3c00a0,7, -0x3c00c0,7, -0x3c00e0,7, -0x3c0100,7, -0x3c0120,7, -0x3c0140,7, -0x3c0160,7, -0x3c0180,7, -0x3c01a0,7, -0x3c01c0,7, -0x3c01e0,7, -0x3c0200,47, -0x3c02c0,118, -0x3c04a0,6, +0x391c88,7, +0x391cc0,1, +0x391ce0,26, +0x391d80,1, +0x391e00,5, +0x391e20,5, +0x391e40,5, +0x391e60,5, +0x391e80,9, +0x392000,108, +0x392200,8, +0x3a0000,31, +0x3a0080,31, +0x3a0100,31, +0x3a0180,31, +0x3a0200,31, +0x3a0280,31, +0x3a0300,31, +0x3a0380,31, +0x3a0400,31, +0x3a0480,31, +0x3a0500,31, +0x3a0580,31, +0x3a0600,31, +0x3a0680,31, +0x3a0700,31, +0x3a0780,31, +0x3a0800,9, +0x3a0880,1, +0x3a0900,21, +0x3a0980,21, +0x3a0a00,21, +0x3a0a80,1, +0x3a0c04,1, +0x3a0c10,6, +0x3a0c30,64, +0x3a0e00,12, +0x3a0e40,10, +0x3a0e80,13, +0x3a0ec0,13, +0x3a0f00,9, +0x3a0f40,5, +0x3a0f60,5, +0x3a0f80,6, +0x3a0fa0,1, +0x3a0fa8,100, +0x3a1404,1, +0x3a1428,22, +0x3a1504,1, +0x3a1544,47, +0x3a1604,1, +0x3a161c,9, +0x3a1644,1, +0x3a164c,1, +0x3a1654,1, +0x3a165c,1, +0x3a1664,1, +0x3a166c,3, +0x3a2000,96, +0x3a2200,96, +0x3a2400,6, +0x3a2424,1, +0x3a242c,14, +0x3a2800,40, +0x3a28c0,3, +0x3a28d0,3, +0x3a28e0,3, +0x3a28f0,3, +0x3a2904,1, +0x3a291c,11, +0x3a2a04,1, +0x3a2a0c,7, +0x3a2a40,1, +0x3a2a54,4, +0x3a3000,3, +0x3a4000,3, +0x3a4010,3, +0x3a4020,3, +0x3a4030,3, +0x3a4040,3, +0x3a4050,3, +0x3a4060,3, +0x3a4070,3, +0x3a4080,3, +0x3a4090,3, +0x3a40a0,3, +0x3a40b0,3, +0x3a40c0,3, +0x3a40d0,3, +0x3a40e0,3, +0x3a40f0,3, +0x3a4100,3, +0x3a4110,3, +0x3a4120,3, +0x3a4130,3, +0x3a4140,3, +0x3a4150,3, +0x3a4160,3, +0x3a4170,3, +0x3a4180,3, +0x3a4190,3, +0x3a41a0,3, +0x3a41b0,3, +0x3a41c0,3, +0x3a41d0,3, +0x3a41e0,3, +0x3a41f0,3, +0x3a4200,3, +0x3a4210,3, +0x3a4220,3, +0x3a4230,3, +0x3a4240,3, +0x3a4250,3, +0x3a4260,3, +0x3a4270,3, +0x3a4280,3, +0x3a4290,3, +0x3a42a0,3, +0x3a42b0,3, +0x3a42c0,3, +0x3a42d0,3, +0x3a42e0,3, +0x3a42f0,3, +0x3a4300,3, +0x3a4310,3, +0x3a4320,3, +0x3a4330,3, +0x3a4340,3, +0x3a4350,3, +0x3a4360,3, +0x3a4370,3, +0x3a4380,3, +0x3a4390,3, +0x3a43a0,3, +0x3a43b0,3, +0x3a43c0,3, +0x3a43d0,3, +0x3a43e0,3, +0x3a43f0,3, +0x3a4400,3, +0x3a4410,3, +0x3a4420,3, +0x3a4430,3, +0x3a4440,3, +0x3a4450,3, +0x3a4460,3, +0x3a4470,3, +0x3a4480,3, +0x3a4490,3, +0x3a44a0,3, +0x3a44b0,3, +0x3a44c0,3, +0x3a44d0,3, +0x3a44e0,3, +0x3a44f0,3, +0x3a4500,3, +0x3a4510,3, +0x3a4520,3, +0x3a4530,3, +0x3a4540,3, +0x3a4550,3, +0x3a4560,3, +0x3a4570,3, +0x3a4580,3, +0x3a4590,3, +0x3a45a0,3, +0x3a45b0,3, +0x3a45c0,3, +0x3a45d0,3, +0x3a45e0,3, +0x3a45f0,3, +0x3a4600,32, +0x3a4800,128, +0x3a4a04,1, +0x3a4a20,8, +0x3a4a44,1, +0x3a4a60,8, +0x3a4a84,1, +0x3a4a94,3, +0x3a4aa4,1, +0x3a4ab4,6, +0x3a4b00,41, +0x3a4bc4,1, +0x3a4bd0,4, +0x3a4be4,6, +0x3a4c00,3, +0x3a4c10,14, +0x3a4c60,9, +0x3a5000,5, +0x3a5020,5, +0x3a5040,5, +0x3a5060,5, +0x3a5080,5, +0x3a50a0,5, +0x3a50c0,5, +0x3a50e0,5, +0x3a5100,5, +0x3a5120,5, +0x3a5140,5, +0x3a5160,5, +0x3a5180,5, +0x3a51a0,5, +0x3a51c0,5, +0x3a51e0,5, +0x3a5200,5, +0x3a5220,5, +0x3a5240,5, +0x3a5260,5, +0x3a5280,5, +0x3a52a0,5, +0x3a52c0,5, +0x3a52e0,5, +0x3a5300,5, +0x3a5320,5, +0x3a5340,5, +0x3a5360,5, +0x3a5380,5, +0x3a53a0,5, +0x3a53c0,5, +0x3a53e0,5, +0x3a5400,5, +0x3a5420,5, +0x3a5440,5, +0x3a5460,5, +0x3a5480,5, +0x3a54a0,5, +0x3a54c0,5, +0x3a54e0,5, +0x3a5500,5, +0x3a5520,5, +0x3a5540,5, +0x3a5560,5, +0x3a5580,5, +0x3a55a0,5, +0x3a55c0,5, +0x3a55e0,5, +0x3a5600,5, +0x3a5620,5, +0x3a5640,5, +0x3a5660,5, +0x3a5680,5, +0x3a56a0,5, +0x3a56c0,5, +0x3a56e0,5, +0x3a5700,5, +0x3a5720,5, +0x3a5740,5, +0x3a5760,5, +0x3a5780,5, +0x3a57a0,5, +0x3a57c0,5, +0x3a57e0,5, +0x3a5800,27, +0x3a5874,10, +0x3a5904,1, +0x3a590c,5, +0x3a5924,1, +0x3a592c,7, +0x3a5980,8, +0x3a6000,5, +0x3a6020,5, +0x3a6040,5, +0x3a6060,5, +0x3a6080,5, +0x3a60a0,5, +0x3a60c0,5, +0x3a60e0,5, +0x3a6100,5, +0x3a6120,5, +0x3a6140,5, +0x3a6160,5, +0x3a6180,5, +0x3a61a0,5, +0x3a61c0,5, +0x3a61e0,5, +0x3a6200,5, +0x3a6220,5, +0x3a6240,5, +0x3a6260,5, +0x3a6280,5, +0x3a62a0,5, +0x3a62c0,5, +0x3a62e0,5, +0x3a6300,5, +0x3a6320,5, +0x3a6340,5, +0x3a6360,5, +0x3a6380,5, +0x3a63a0,5, +0x3a63c0,5, +0x3a63e0,5, +0x3a6400,5, +0x3a6420,5, +0x3a6440,5, +0x3a6460,5, +0x3a6480,5, +0x3a64a0,5, +0x3a64c0,5, +0x3a64e0,5, +0x3a6500,5, +0x3a6520,5, +0x3a6540,5, +0x3a6560,5, +0x3a6580,5, +0x3a65a0,5, +0x3a65c0,5, +0x3a65e0,5, +0x3a6600,5, +0x3a6620,5, +0x3a6640,5, +0x3a6660,5, +0x3a6680,5, +0x3a66a0,5, +0x3a66c0,5, +0x3a66e0,5, +0x3a6700,5, +0x3a6720,5, +0x3a6740,5, +0x3a6760,5, +0x3a6780,5, +0x3a67a0,5, +0x3a67c0,5, +0x3a67e0,5, +0x3a6800,27, +0x3a6874,10, +0x3a6904,1, +0x3a690c,5, +0x3a6924,1, +0x3a692c,7, +0x3a6980,8, +0x3a7000,20, +0x3a7080,20, +0x3a7100,20, +0x3a7180,20, +0x3a7200,20, +0x3a7280,20, +0x3a7300,20, +0x3a7380,20, +0x3a7400,20, +0x3a7480,20, +0x3a7500,20, +0x3a7580,20, +0x3a7600,20, +0x3a7680,20, +0x3a7700,20, +0x3a7780,20, +0x3a7800,11, +0x3a7830,1, +0x3a7840,9, +0x3a7880,11, +0x3a78b0,1, +0x3a78c0,9, +0x3a7900,11, +0x3a7930,1, +0x3a7940,9, +0x3a7980,11, +0x3a79b0,1, +0x3a79c0,9, +0x3a7a00,11, +0x3a7a30,1, +0x3a7a40,9, +0x3a7a80,11, +0x3a7ab0,1, +0x3a7ac0,9, +0x3a7b00,11, +0x3a7b30,1, +0x3a7b40,9, +0x3a7b80,11, +0x3a7bb0,1, +0x3a7bc0,9, +0x3a7c00,8, +0x3a8000,1, +0x3a8100,57, +0x3a8200,57, +0x3a8300,57, +0x3a8400,57, +0x3a8500,57, +0x3a8600,57, +0x3a8700,57, +0x3a8800,57, +0x3a8900,57, +0x3a8a00,57, +0x3a8b00,57, +0x3a8c00,57, +0x3a8d00,57, +0x3a8e00,57, +0x3a8f00,57, +0x3a9000,57, +0x3a9100,28, +0x3a9180,17, +0x3a9200,11, +0x3a9240,9, +0x3a9280,33, +0x3a9308,4, +0x3a9320,1, +0x3a9340,1, +0x3a9360,7, +0x3a9380,7, +0x3a93a0,1, +0x3a93c0,6, +0x3a93e0,6, +0x3a9400,6, +0x3a9420,1, +0x3a9440,6, +0x3a9460,6, +0x3a9480,6, +0x3a94a0,1, +0x3a94c0,6, +0x3a94e0,6, +0x3a9500,6, +0x3a9520,3, +0x3a9530,7, +0x3a9550,7, +0x3a9570,7, +0x3a9590,7, +0x3a95b0,7, +0x3a95d0,7, +0x3a95f0,7, +0x3a9610,7, +0x3a9630,7, +0x3a9650,7, +0x3a9670,7, +0x3a9690,7, +0x3a96b0,7, +0x3a96d0,7, +0x3a96f0,7, +0x3a9710,7, +0x3a9730,7, +0x3a9750,7, +0x3a9770,7, +0x3a9790,7, +0x3a97b0,7, +0x3a97d0,7, +0x3a97f0,7, +0x3a9810,15, +0x3a9860,39, +0x3a9920,7, +0x3a9960,2, +0x3a996c,3, +0x3a9980,2, +0x3a998c,3, +0x3a99a0,2, +0x3a99ac,3, +0x3a99c0,2, +0x3a99cc,3, +0x3a99e0,2, +0x3a99ec,3, +0x3a9a00,2, +0x3a9a0c,3, +0x3a9a20,2, +0x3a9a2c,3, +0x3a9a40,2, +0x3a9a4c,3, +0x3a9a60,2, +0x3a9a6c,3, +0x3a9a80,2, +0x3a9a8c,3, +0x3a9aa0,2, +0x3a9aac,3, +0x3a9ac0,2, +0x3a9acc,3, +0x3a9ae0,2, +0x3a9aec,3, +0x3a9b00,2, +0x3a9b0c,3, +0x3a9b20,2, +0x3a9b2c,3, +0x3a9b40,2, +0x3a9b4c,3, +0x3a9c00,27, +0x3a9c80,1, +0x3a9ca0,6, +0x3aa000,27, +0x3aa080,4, +0x3aa0c0,25, +0x3aa140,6, +0x3aa160,2, +0x3aa16c,3, +0x3aa200,8, +0x3aa224,25, +0x3aa400,27, +0x3aa480,1, +0x3aa4a0,6, +0x3aa500,27, +0x3aa580,27, +0x3aa600,27, +0x3aa680,27, +0x3aa700,27, +0x3aa780,27, +0x3aa800,27, +0x3aa880,27, +0x3aa900,27, +0x3aa980,27, +0x3aaa00,27, +0x3aaa80,27, +0x3aab00,27, +0x3aab80,27, +0x3aac00,27, +0x3aac80,27, +0x3aad00,2, +0x3aad10,3, +0x3aad20,1, +0x3aad30,65, +0x3ab000,3, +0x3ab010,3, +0x3ab020,3, +0x3ab030,3, +0x3ab040,3, +0x3ab050,3, +0x3ab060,3, +0x3ab070,3, +0x3ab080,3, +0x3ab090,3, +0x3ab0a0,3, +0x3ab0b0,3, +0x3ab0c0,3, +0x3ab0d0,3, +0x3ab0e0,3, +0x3ab0f0,3, +0x3ab100,2, +0x3ab200,3, +0x3ab210,3, +0x3ab220,3, +0x3ab230,3, +0x3ab240,3, +0x3ab250,3, +0x3ab260,3, +0x3ab270,3, +0x3ab280,3, +0x3ab290,3, +0x3ab2a0,3, +0x3ab2b0,3, +0x3ab2c0,3, +0x3ab2d0,3, +0x3ab2e0,3, +0x3ab2f0,3, +0x3ab300,2, +0x3ab400,3, +0x3ab410,3, +0x3ab420,3, +0x3ab430,3, +0x3ab440,3, +0x3ab450,3, +0x3ab460,3, +0x3ab470,3, +0x3ab480,3, +0x3ab490,3, +0x3ab4a0,3, +0x3ab4b0,3, +0x3ab4c0,3, +0x3ab4d0,3, +0x3ab4e0,3, +0x3ab4f0,3, +0x3ab500,2, +0x3ab680,11, +0x3ab6b0,8, +0x3ab700,11, +0x3ab730,8, +0x3ab780,1, +0x3c0000,167, +0x3c02a0,7, +0x3c02c0,7, +0x3c02e0,118, 0x3c04c0,6, 0x3c04e0,6, 0x3c0500,6, @@ -9821,7 +10342,7 @@ 0x3c0620,6, 0x3c0640,6, 0x3c0660,6, -0x3c0680,5, +0x3c0680,6, 0x3c06a0,5, 0x3c06c0,5, 0x3c06e0,5, @@ -9837,7 +10358,8 @@ 0x3c0820,5, 0x3c0840,5, 0x3c0860,5, -0x3c0880,29, +0x3c0880,5, +0x3c08a0,16, 0x3c0900,13, 0x3c0940,13, 0x3c0980,13, @@ -9853,8 +10375,7 @@ 0x3c0c00,13, 0x3c0c40,13, 0x3c0c80,13, -0x3c0cc0,5, -0x3c0ce0,5, +0x3c0cc0,13, 0x3c0d00,5, 0x3c0d20,5, 0x3c0d40,5, @@ -9869,7 +10390,9 @@ 0x3c0e60,5, 0x3c0e80,5, 0x3c0ea0,5, -0x3c0ec0,1, +0x3c0ec0,5, +0x3c0ee0,5, +0x3c0f00,17, 0x3c1000,179, 0x3c1400,5, 0x3c1800,3, @@ -9907,7 +10430,7 @@ 0x3c1a00,2, 0x3c1a0c,12, 0x3c1a40,20, -0x3c1c00,20, +0x3c1c00,1, 0x3c1c80,20, 0x3c1d00,20, 0x3c1d80,20, @@ -9923,7 +10446,8 @@ 0x3c2280,20, 0x3c2300,20, 0x3c2380,20, -0x3c2400,5, +0x3c2400,20, +0x3c2480,5, 0x3c4000,27, 0x3c4080,27, 0x3c4100,27, @@ -9964,83 +10488,83 @@ 0x3d2000,46, 0x3d2100,2, 0x3d2110,21, -0x3d2180,19, -0x3d21d0,1, +0x3d2180,23, +0x3d21e0,3, 0x3d2200,46, 0x3d2300,2, 0x3d2310,21, -0x3d2380,19, -0x3d23d0,1, +0x3d2380,23, +0x3d23e0,3, 0x3d2400,46, 0x3d2500,2, 0x3d2510,21, -0x3d2580,19, -0x3d25d0,1, +0x3d2580,23, +0x3d25e0,3, 0x3d2600,46, 0x3d2700,2, 0x3d2710,21, -0x3d2780,19, -0x3d27d0,1, +0x3d2780,23, +0x3d27e0,3, 0x3d2800,46, 0x3d2900,2, 0x3d2910,21, -0x3d2980,19, -0x3d29d0,1, +0x3d2980,23, +0x3d29e0,3, 0x3d2a00,46, 0x3d2b00,2, 0x3d2b10,21, -0x3d2b80,19, -0x3d2bd0,1, +0x3d2b80,23, +0x3d2be0,3, 0x3d2c00,46, 0x3d2d00,2, 0x3d2d10,21, -0x3d2d80,19, -0x3d2dd0,1, +0x3d2d80,23, +0x3d2de0,3, 0x3d2e00,46, 0x3d2f00,2, 0x3d2f10,21, -0x3d2f80,19, -0x3d2fd0,1, +0x3d2f80,23, +0x3d2fe0,3, 0x3d3000,46, 0x3d3100,2, 0x3d3110,21, -0x3d3180,19, -0x3d31d0,1, +0x3d3180,23, +0x3d31e0,3, 0x3d3200,46, 0x3d3300,2, 0x3d3310,21, -0x3d3380,19, -0x3d33d0,1, +0x3d3380,23, +0x3d33e0,3, 0x3d3400,46, 0x3d3500,2, 0x3d3510,21, -0x3d3580,19, -0x3d35d0,1, +0x3d3580,23, +0x3d35e0,3, 0x3d3600,46, 0x3d3700,2, 0x3d3710,21, -0x3d3780,19, -0x3d37d0,1, +0x3d3780,23, +0x3d37e0,3, 0x3d3800,46, 0x3d3900,2, 0x3d3910,21, -0x3d3980,19, -0x3d39d0,1, +0x3d3980,23, +0x3d39e0,3, 0x3d3a00,46, 0x3d3b00,2, 0x3d3b10,21, -0x3d3b80,19, -0x3d3bd0,1, +0x3d3b80,23, +0x3d3be0,3, 0x3d3c00,46, 0x3d3d00,2, 0x3d3d10,21, -0x3d3d80,19, -0x3d3dd0,1, +0x3d3d80,23, +0x3d3de0,3, 0x3d3e00,46, 0x3d3f00,2, 0x3d3f10,21, -0x3d3f80,19, -0x3d3fd0,1, +0x3d3f80,23, +0x3d3fe0,3, 0x3d4000,21, 0x3d4060,29, 0x3d40e0,29, @@ -10057,22 +10581,22 @@ 0x3d4660,29, 0x3d46e0,29, 0x3d4760,29, -0x3d47e0,37, -0x3d4880,29, -0x3d4900,29, -0x3d4980,29, -0x3d4a00,29, -0x3d4a80,29, -0x3d4b00,29, -0x3d4b80,29, -0x3d4c00,29, -0x3d4c80,29, -0x3d4d00,29, -0x3d4d80,29, -0x3d4e00,29, -0x3d4e80,29, -0x3d4f00,29, -0x3d4f80,29, +0x3d47e0,38, +0x3d4880,30, +0x3d4900,30, +0x3d4980,30, +0x3d4a00,30, +0x3d4a80,30, +0x3d4b00,30, +0x3d4b80,30, +0x3d4c00,30, +0x3d4c80,30, +0x3d4d00,30, +0x3d4d80,30, +0x3d4e00,30, +0x3d4e80,30, +0x3d4f00,30, +0x3d4f80,30, 0x3d5000,58, 0x3d50ec,1, 0x3d50f4,2, @@ -10462,750 +10986,1099 @@ 0x3df800,34, 0x3df8a0,8, 0x3e0000,1, -0x3e1000,22528, +0x3e1000,977, +0x3e2000,161, +0x3e3000,977, +0x3e4000,977, +0x3e5000,977, +0x3e6000,64, +0x3e6104,127, +0x3e6304,127, +0x3e6504,195, +0x3e6814,31, +0x3e6894,428, +0x3e7000,977, +0x3e8000,977, +0x3e9000,977, +0x3ea000,977, +0x3eb000,977, +0x3ec000,977, +0x3ed000,977, +0x3ee000,977, +0x3ef000,977, +0x3f0000,977, +0x3f1000,977, +0x3f2000,977, +0x3f3000,161, +0x3f4000,161, +0x3f5000,161, +0x3f6000,161, +0x3f8000,13, +0x3f8040,14, +0x3f8080,20, +0x3f8104,1, +0x3f810c,3, +0x3f8200,13, +0x3f8240,14, +0x3f8280,20, +0x3f8304,1, +0x3f830c,3, +0x3f8400,13, +0x3f8440,14, +0x3f8480,20, +0x3f8504,1, +0x3f850c,3, +0x3f8600,13, +0x3f8640,14, +0x3f8680,20, +0x3f8704,1, +0x3f870c,3, +0x3f8800,13, +0x3f8840,14, +0x3f8880,20, +0x3f8904,1, +0x3f890c,3, +0x3f8a00,13, +0x3f8a40,14, +0x3f8a80,20, +0x3f8b04,1, +0x3f8b0c,3, +0x3f8c00,13, +0x3f8c40,14, +0x3f8c80,20, +0x3f8d04,1, +0x3f8d0c,3, +0x3f8e00,13, +0x3f8e40,14, +0x3f8e80,20, +0x3f8f04,1, +0x3f8f0c,3, +0x3f9000,13, +0x3f9040,14, +0x3f9080,20, +0x3f9104,1, +0x3f910c,3, +0x3f9200,13, +0x3f9240,14, +0x3f9280,20, +0x3f9304,1, +0x3f930c,3, +0x3f9400,13, +0x3f9440,14, +0x3f9480,20, +0x3f9504,1, +0x3f950c,3, +0x3f9600,13, +0x3f9640,14, +0x3f9680,20, +0x3f9704,1, +0x3f970c,3, +0x3f9800,13, +0x3f9840,14, +0x3f9880,20, +0x3f9904,1, +0x3f990c,3, +0x3f9a00,13, +0x3f9a40,14, +0x3f9a80,20, +0x3f9b04,1, +0x3f9b0c,3, +0x3f9c00,13, +0x3f9c40,14, +0x3f9c80,20, +0x3f9d04,1, +0x3f9d0c,3, +0x3f9e00,13, +0x3f9e40,14, +0x3f9e80,20, +0x3f9f04,1, +0x3f9f0c,3, +0x3fa000,13, +0x3fa040,14, +0x3fa080,20, +0x3fa104,1, +0x3fa10c,3, +0x3fa200,17, +0x3fa250,2, +0x3fa260,5, +0x3fa280,2, +0x3fc000,1, +0x3fc014,1, +0x3fc01c,10, +0x3fc060,9, +0x3fc094,1, +0x3fc09c,10, +0x3fc0e0,9, +0x3fc114,1, +0x3fc11c,10, +0x3fc160,9, +0x3fc194,1, +0x3fc19c,10, +0x3fc1e0,9, +0x3fc214,1, +0x3fc21c,10, +0x3fc260,15, +0x3fc400,30, +0x3fc480,9, +0x3fc4c0,12, +0x3fc500,1, +0x3fc520,5, +0x3fc540,1, 0x400000,19, -0x400100,1, -0x400200,57, -0x400300,57, -0x400400,57, -0x400500,57, -0x400600,57, -0x400700,57, -0x400800,57, -0x400900,57, -0x400a00,57, -0x400b00,57, -0x400c00,57, -0x400d00,57, -0x400e00,57, -0x400f00,57, -0x401000,57, -0x401100,57, -0x401200,6, -0x402000,27, -0x402070,3, -0x402080,27, -0x4020f0,3, -0x402100,27, -0x402170,3, -0x402180,27, -0x4021f0,3, -0x402200,27, -0x402270,3, -0x402280,27, -0x4022f0,3, -0x402300,27, -0x402370,3, -0x402380,27, -0x4023f0,3, -0x402400,27, -0x402470,3, -0x402480,27, -0x4024f0,3, -0x402500,27, -0x402570,3, -0x402580,27, -0x4025f0,3, -0x402600,27, -0x402670,3, -0x402680,27, -0x4026f0,3, -0x402700,27, -0x402770,3, -0x402780,27, -0x4027f0,3, -0x402800,1, -0x402808,31, -0x402a04,1, -0x402a10,6, -0x402a30,64, -0x402c00,23, -0x402c60,17, -0x402cc0,5, -0x402ce0,3, -0x402cf0,100, -0x403004,1, -0x403010,12, -0x403104,1, -0x403150,44, -0x403204,1, -0x40321c,11, -0x404000,130, -0x404300,36, -0x404400,36, -0x404500,36, -0x404600,36, -0x404700,36, -0x404800,36, -0x404900,36, -0x404a00,36, -0x404b00,36, -0x404c00,36, -0x404d00,36, -0x404e00,36, -0x404f00,36, -0x405000,36, -0x405100,36, -0x405200,36, -0x405300,64, -0x408000,49, -0x408100,49, -0x408204,1, -0x40821c,11, -0x408280,3, -0x4082a0,5, -0x4082c0,9, -0x408300,3, -0x408320,6, -0x408340,74, -0x408480,5, -0x4084a0,1, -0x4084b0,7, -0x4084d0,3, -0x4084e0,22, -0x40a000,58, -0x40a0f0,10, -0x40a200,36, -0x40a300,36, -0x40a400,36, -0x40a500,36, -0x40a600,36, -0x40a700,36, -0x40a800,36, -0x40a900,36, -0x40aa00,36, -0x40ab00,36, -0x40ac00,36, -0x40ad00,36, -0x40ae00,36, -0x40af00,36, -0x40b000,36, -0x40b100,36, -0x40b200,36, -0x40b300,36, -0x40c000,51, -0x40c100,1, -0x40c120,9, -0x40c160,9, -0x40c1a0,9, -0x40c1e0,9, -0x40c220,9, -0x40c260,9, -0x40c2a0,9, -0x40c2e0,9, -0x40c320,9, -0x40c360,9, -0x40c3a0,9, -0x40c3e0,9, -0x40c420,9, -0x40c460,9, -0x40c4a0,9, -0x40c4e0,28, -0x40c580,20, -0x40c600,20, -0x40c680,20, -0x40c700,20, -0x40c780,20, -0x40c800,20, -0x40c880,20, -0x40c900,20, -0x40c980,20, -0x40ca00,20, -0x40ca80,20, -0x40cb00,20, -0x40cb80,20, -0x40cc00,20, -0x40cc80,20, -0x40cd00,20, -0x40cd80,20, -0x40ce00,20, -0x40d000,3, -0x40d010,3, -0x40d020,3, -0x40d030,3, -0x40d040,3, -0x40d050,3, -0x40d060,3, -0x40d070,3, -0x40d080,5, -0x40d100,28, -0x40d180,28, -0x40d200,28, -0x40d280,28, -0x40d300,28, -0x40d380,28, -0x40d400,28, -0x40d480,28, -0x40d500,28, -0x40d580,28, -0x40d600,28, -0x40d680,28, -0x40d700,28, -0x40d780,28, -0x40d800,28, -0x40d880,28, -0x40d900,28, -0x40d980,28, -0x40e000,4, -0x410000,9, -0x410040,9, -0x410080,33, -0x410108,5, -0x410120,3, -0x410130,3, -0x410140,1, -0x410148,1, -0x410150,1, -0x410164,8, -0x4101a0,8, -0x410200,1, -0x410208,7, -0x410280,20, -0x410300,20, -0x410380,20, -0x410400,20, -0x410480,20, -0x410500,20, -0x410580,20, -0x410600,20, -0x410680,20, -0x410700,20, -0x410780,20, -0x410800,20, -0x410880,20, -0x410900,20, -0x410980,20, -0x410a00,20, -0x410b00,36, -0x410c00,92, -0x410e00,4, -0x410e20,1, -0x410e40,1, -0x410e60,7, -0x410e80,7, -0x410ea0,1, -0x410ec0,6, -0x410ee0,6, -0x410f00,3, -0x410f10,5, -0x410f40,6, -0x410f60,6, -0x410f80,3, -0x410f90,5, -0x410fc0,6, -0x410fe0,6, -0x411000,3, -0x411010,7, -0x411030,7, -0x411050,7, -0x411070,7, -0x411090,7, -0x4110b0,7, -0x4110d0,7, -0x4110f0,7, -0x411110,7, -0x411130,7, -0x411150,7, -0x411170,7, -0x411190,7, -0x4111b0,7, -0x4111d0,7, -0x4111f0,7, -0x411210,7, -0x411230,7, -0x411250,7, -0x411270,7, -0x411290,7, -0x4112b0,7, -0x4112d0,7, -0x4112f0,7, -0x411310,7, -0x411330,7, -0x411350,7, -0x411370,7, -0x411390,7, -0x4113b0,7, -0x4113d0,7, -0x4113f0,7, -0x411410,24, -0x411480,15, -0x4114c0,15, -0x411520,2, -0x41152c,3, -0x411540,2, -0x41154c,3, -0x411560,2, -0x41156c,3, -0x411580,2, -0x41158c,3, -0x4115a0,2, -0x4115ac,3, -0x4115c0,2, -0x4115cc,3, -0x4115e0,2, -0x4115ec,3, -0x411600,2, -0x41160c,3, -0x411620,2, -0x41162c,3, -0x411640,2, -0x41164c,3, -0x411660,2, -0x41166c,3, -0x411680,2, -0x41168c,3, -0x4116a0,2, -0x4116ac,3, -0x4116c0,2, -0x4116cc,3, -0x4116e0,2, -0x4116ec,3, -0x411700,2, -0x41170c,3, -0x411780,11, -0x4117c0,6, -0x4117dc,2, -0x411800,27, -0x411880,1, -0x4118a0,6, -0x411a00,27, -0x411a80,4, -0x411ac0,25, -0x411b40,6, -0x411b60,2, -0x411b6c,3, -0x411b80,8, -0x411ba4,22, -0x411c00,27, +0x400050,8, +0x400080,12, +0x4000c0,9, +0x400100,19, +0x400150,8, +0x400180,12, +0x4001c0,9, +0x400200,19, +0x400250,8, +0x400280,12, +0x4002c0,9, +0x400300,19, +0x400350,8, +0x400380,12, +0x4003c0,9, +0x400400,19, +0x400450,8, +0x400480,12, +0x4004c0,9, +0x400500,19, +0x400550,8, +0x400580,12, +0x4005c0,9, +0x400600,19, +0x400650,8, +0x400680,12, +0x4006c0,9, +0x400700,19, +0x400750,8, +0x400780,12, +0x4007c0,9, +0x400800,19, +0x400850,8, +0x400880,12, +0x4008c0,9, +0x400900,19, +0x400950,8, +0x400980,12, +0x4009c0,9, +0x400a00,19, +0x400a50,8, +0x400a80,12, +0x400ac0,9, +0x400b00,19, +0x400b50,8, +0x400b80,12, +0x400bc0,9, +0x400c00,19, +0x400c50,8, +0x400c80,12, +0x400cc0,9, +0x400d00,19, +0x400d50,8, +0x400d80,12, +0x400dc0,9, +0x400e00,19, +0x400e50,8, +0x400e80,12, +0x400ec0,9, +0x400f00,19, +0x400f50,8, +0x400f80,12, +0x400fc0,9, +0x401000,19, +0x401050,8, +0x401080,12, +0x4010c0,9, +0x401100,19, +0x401150,8, +0x401180,12, +0x4011c0,9, +0x401200,19, +0x401250,8, +0x401280,12, +0x4012c0,9, +0x401300,19, +0x401350,8, +0x401380,12, +0x4013c0,9, +0x401400,19, +0x401450,8, +0x401480,12, +0x4014c0,9, +0x401500,19, +0x401550,8, +0x401580,12, +0x4015c0,9, +0x401600,19, +0x401650,8, +0x401680,12, +0x4016c0,9, +0x401700,19, +0x401750,8, +0x401780,12, +0x4017c0,9, +0x401800,19, +0x401850,8, +0x401880,12, +0x4018c0,9, +0x401900,19, +0x401950,8, +0x401980,12, +0x4019c0,9, +0x401a00,19, +0x401a50,8, +0x401a80,12, +0x401ac0,9, +0x401b00,19, +0x401b50,8, +0x401b80,12, +0x401bc0,9, +0x401c00,19, +0x401c50,8, +0x401c80,12, +0x401cc0,9, +0x401d00,19, +0x401d50,8, +0x401d80,12, +0x401dc0,9, +0x401e00,19, +0x401e50,8, +0x401e80,12, +0x401ec0,9, +0x401f00,19, +0x401f50,8, +0x401f80,12, +0x401fc0,9, +0x402000,19, +0x402050,8, +0x402080,12, +0x4020c0,9, +0x402100,19, +0x402150,8, +0x402180,12, +0x4021c0,9, +0x402200,19, +0x402250,8, +0x402280,12, +0x4022c0,9, +0x402300,19, +0x402350,8, +0x402380,12, +0x4023c0,9, +0x402400,19, +0x402450,8, +0x402480,12, +0x4024c0,9, +0x402500,19, +0x402550,8, +0x402580,12, +0x4025c0,9, +0x402600,19, +0x402650,8, +0x402680,12, +0x4026c0,9, +0x402700,19, +0x402750,8, +0x402780,12, +0x4027c0,9, +0x402800,24, +0x402880,12, +0x4028c0,17, +0x402a00,24, +0x402a80,12, +0x402ac0,17, +0x402c00,24, +0x402c80,12, +0x402cc0,17, +0x402e00,24, +0x402e80,12, +0x402ec0,17, +0x403000,24, +0x403080,12, +0x4030c0,17, +0x403200,24, +0x403280,12, +0x4032c0,17, +0x403400,24, +0x403480,12, +0x4034c0,17, +0x403600,24, +0x403680,12, +0x4036c0,17, +0x403800,24, +0x403880,12, +0x4038c0,17, +0x403c00,13, +0x403c40,5, +0x403c80,5, +0x403d00,6, +0x403d20,6, +0x403d40,6, +0x403d60,6, +0x403d80,6, +0x403da0,6, +0x403dc0,6, +0x403de0,6, +0x403e00,6, +0x403e20,6, +0x403e40,5, +0x403e60,9, +0x404000,19, +0x404050,6, +0x404080,7, +0x4040a0,2, +0x4040c0,12, +0x404100,9, +0x404200,27, +0x404280,27, +0x404300,15, +0x404340,5, +0x404360,12, +0x404400,20, +0x408000,3, +0x408010,3, +0x408020,3, +0x408030,3, +0x408040,3, +0x408050,3, +0x408060,3, +0x408070,3, +0x408080,28, +0x408100,28, +0x408180,28, +0x408200,28, +0x408280,28, +0x408300,28, +0x408380,28, +0x408400,28, +0x408480,4, +0x4084c0,3, +0x4084e0,18, +0x408540,2, +0x408550,3, +0x408580,2, +0x4085a0,7, +0x4085c0,1, +0x408600,2, +0x408620,7, +0x408640,1, +0x408680,2, +0x4086a0,7, +0x4086c0,1, +0x408700,2, +0x408720,7, +0x408740,1, +0x408780,2, +0x4087a0,7, +0x4087c0,1, +0x408800,2, +0x408820,7, +0x408840,1, +0x408880,2, +0x4088a0,7, +0x4088c0,1, +0x408900,2, +0x408920,7, +0x408940,1, +0x408980,9, +0x409000,5, +0x409020,5, +0x409040,5, +0x409060,5, +0x409080,5, +0x4090a0,5, +0x4090c0,5, +0x4090e0,5, +0x409100,44, +0x409200,44, +0x409300,44, +0x409400,44, +0x409500,44, +0x409600,44, +0x409700,44, +0x409800,44, +0x409900,5, +0x409920,10, +0x409950,3, +0x409960,5, +0x409980,5, +0x4099a0,5, +0x4099b8,5, +0x4099d0,20, +0x40a000,3, +0x40a010,3, +0x40a020,3, +0x40a030,3, +0x40a040,3, +0x40a050,3, +0x40a060,3, +0x40a070,3, +0x40a080,28, +0x40a100,28, +0x40a180,28, +0x40a200,28, +0x40a280,28, +0x40a300,28, +0x40a380,28, +0x40a400,28, +0x40a480,9, +0x40a4b0,3, +0x40a4c0,9, +0x40a4f0,3, +0x40a500,3, +0x40a510,1, +0x40a520,17, +0x40a800,22, +0x410000,1, +0x410200,2, +0x410240,8, +0x410280,9, +0x4102c0,9, +0x410300,9, +0x410340,9, +0x410380,24, +0x410400,2, +0x410440,8, +0x410480,9, +0x4104c0,9, +0x410500,9, +0x410540,9, +0x410580,24, +0x410600,9, +0x410640,9, +0x410680,9, +0x4106c0,9, +0x410700,9, +0x410740,9, +0x410780,9, +0x4107c0,9, +0x410800,9, +0x410840,9, +0x410880,9, +0x4108c0,9, +0x410900,9, +0x410940,9, +0x410980,9, +0x4109c0,9, +0x410a00,9, +0x410a40,9, +0x410a80,9, +0x410ac0,9, +0x410b00,9, +0x410b40,9, +0x410b80,9, +0x410bc0,9, +0x410c00,3, +0x410c20,25, +0x410ca0,5, +0x410cc0,1, +0x410cc8,5, +0x410ce0,5, +0x410d00,1, +0x410d08,5, +0x410d20,16, +0x411000,74, +0x411200,74, +0x411404,1, +0x411418,10, +0x411444,3, +0x411464,7, +0x411484,7, +0x4114a4,1, +0x4114ac,1, +0x4114b4,1, +0x4114bc,3, +0x411500,8, +0x411600,17, +0x411660,1, +0x411680,66, +0x411790,3, +0x4117a4,1, +0x4117ac,4, +0x4117c0,14, +0x411800,17, +0x411860,1, +0x411880,66, +0x411990,3, +0x411a00,1, +0x411a40,10, +0x411a80,2, +0x411aa0,6, +0x411ac0,6, +0x411ae0,17, +0x411b28,19, +0x411b78,4, +0x411b90,3, +0x411ba0,2, +0x411bb0,3, +0x411c00,21, 0x411c80,1, -0x411ca0,6, -0x411d00,27, -0x411d80,27, -0x411e00,27, -0x411e80,27, -0x411f00,27, -0x411f80,27, -0x412000,27, -0x412080,27, -0x412100,27, -0x412180,27, -0x412200,27, -0x412280,27, -0x412300,27, -0x412380,27, -0x412400,27, -0x412480,27, -0x412500,2, -0x412510,3, -0x412520,1, -0x412800,2, -0x412820,64, -0x412a00,2, -0x412a20,64, -0x412c00,195, -0x413000,33, -0x414000,6, -0x414020,6, -0x414040,6, -0x414060,6, -0x414080,6, -0x4140a0,6, -0x4140c0,6, -0x4140e0,6, -0x414100,6, -0x414120,6, -0x414140,6, -0x414160,6, -0x414180,6, -0x4141a0,6, -0x4141c0,6, -0x4141e0,6, -0x414200,4, -0x418000,9, -0x418028,8, -0x418080,3, -0x4180a0,5, -0x418100,9, -0x418128,8, -0x418180,3, -0x4181a0,5, -0x418200,9, -0x418228,8, -0x418280,3, -0x4182a0,5, -0x418300,9, -0x418328,8, -0x418380,3, -0x4183a0,5, -0x418400,9, -0x418428,8, -0x418480,3, -0x4184a0,5, -0x418500,9, -0x418528,8, -0x418580,6, -0x4185a0,5, -0x418600,9, -0x418628,8, -0x418680,3, -0x4186a0,5, -0x418700,9, -0x418728,8, -0x418780,3, -0x4187a0,5, -0x418800,9, -0x418828,8, -0x418880,3, -0x4188a0,5, -0x419000,9, -0x419028,8, -0x419080,3, -0x4190a0,5, -0x419100,9, -0x419128,8, -0x419180,3, -0x4191a0,5, -0x419200,9, -0x419228,8, -0x419280,3, -0x4192a0,5, -0x419300,9, -0x419328,8, -0x419380,3, -0x4193a0,5, -0x419400,9, -0x419428,8, -0x419480,3, -0x4194a0,5, -0x419500,9, -0x419528,8, -0x419580,6, -0x4195a0,5, -0x419600,9, -0x419628,8, -0x419680,3, -0x4196a0,5, -0x419700,9, -0x419728,8, -0x419780,3, -0x4197a0,5, -0x419800,9, -0x419828,8, -0x419880,3, -0x4198a0,5, -0x41a000,9, -0x41a028,8, -0x41a080,6, -0x41a0a0,5, -0x41a100,9, -0x41a128,8, -0x41a180,6, -0x41a1a0,5, -0x41a200,9, -0x41a228,8, -0x41a280,6, -0x41a2a0,5, -0x41a300,9, -0x41a328,8, -0x41a380,6, -0x41a3a0,5, -0x41a400,9, -0x41a428,8, -0x41a480,6, -0x41a4a0,5, -0x41a500,9, -0x41a528,8, -0x41a580,6, -0x41a5a0,5, -0x41a600,9, -0x41a628,8, -0x41a680,6, -0x41a6a0,5, -0x41a700,9, -0x41a728,8, -0x41a780,6, -0x41a7a0,5, -0x41a800,9, -0x41a828,8, -0x41a880,6, -0x41a8a0,5, -0x41a900,9, -0x41a928,8, -0x41a980,6, -0x41a9a0,5, -0x41aa00,9, -0x41aa28,8, -0x41aa80,6, -0x41aaa0,5, -0x41ab00,9, -0x41ab28,8, -0x41ab80,6, -0x41aba0,5, -0x41ac00,9, -0x41ac28,8, -0x41ac80,6, -0x41aca0,5, -0x41ad00,9, -0x41ad28,8, -0x41ad80,6, -0x41ada0,5, -0x41ae00,9, -0x41ae28,8, -0x41ae80,6, -0x41aea0,5, -0x41af00,9, -0x41af28,8, -0x41af80,6, -0x41afa0,5, -0x41b000,9, -0x41b028,8, -0x41b080,6, -0x41b0a0,5, -0x41b100,9, -0x41b128,8, -0x41b180,6, -0x41b1a0,5, -0x41b200,9, -0x41b228,8, -0x41b280,6, -0x41b2a0,5, -0x41b300,9, -0x41b328,8, -0x41b380,6, -0x41b3a0,5, -0x41b400,9, -0x41b428,8, -0x41b480,6, -0x41b4a0,5, -0x41b500,9, -0x41b528,8, -0x41b580,6, -0x41b5a0,5, -0x41b600,9, -0x41b628,8, -0x41b680,6, -0x41b6a0,5, -0x41b700,9, -0x41b728,8, -0x41b780,6, -0x41b7a0,5, -0x41b800,9, -0x41b828,8, -0x41b880,4, -0x41b8c0,13, -0x41b900,6, -0x41b920,5, -0x41c000,3, -0x41c010,3, -0x41c020,3, -0x41c030,3, -0x41c040,3, -0x41c050,3, -0x41c060,3, -0x41c070,3, -0x41c080,3, -0x41c090,3, -0x41c0a0,3, -0x41c0b0,3, -0x41c0c0,3, -0x41c0d0,3, -0x41c0e0,3, -0x41c0f0,3, -0x41c100,2, -0x41c200,3, -0x41c210,3, -0x41c220,3, -0x41c230,3, -0x41c240,3, -0x41c250,3, -0x41c260,3, -0x41c270,3, -0x41c280,3, -0x41c290,3, -0x41c2a0,3, -0x41c2b0,3, -0x41c2c0,3, -0x41c2d0,3, -0x41c2e0,3, -0x41c2f0,3, -0x41c300,2, -0x41c400,3, -0x41c410,3, -0x41c420,3, -0x41c430,3, -0x41c440,3, -0x41c450,3, -0x41c460,3, -0x41c470,3, -0x41c480,3, -0x41c490,3, -0x41c4a0,3, -0x41c4b0,3, -0x41c4c0,3, -0x41c4d0,3, -0x41c4e0,3, -0x41c4f0,3, -0x41c500,2, -0x41c600,18, -0x41c680,18, -0x41c700,4, -0x41d000,5, -0x41d020,5, -0x41d040,5, -0x41d060,5, -0x41d080,5, -0x41d0a0,5, -0x41d0c0,5, -0x41d0e0,5, -0x41d100,5, -0x41d120,5, -0x41d140,5, -0x41d160,5, -0x41d180,5, -0x41d1a0,5, -0x41d1c0,5, -0x41d1e0,5, -0x41d200,5, -0x41d220,5, -0x41d240,5, -0x41d260,5, -0x41d280,5, -0x41d2a0,5, -0x41d2c0,5, -0x41d2e0,5, -0x41d300,5, -0x41d320,5, -0x41d340,5, -0x41d360,5, -0x41d380,5, -0x41d3a0,5, -0x41d3c0,5, -0x41d3e0,5, -0x41d400,5, -0x41d420,5, -0x41d440,5, -0x41d460,5, -0x41d480,5, -0x41d4a0,5, -0x41d4c0,5, -0x41d4e0,5, -0x41d500,5, -0x41d520,5, -0x41d540,5, -0x41d560,5, -0x41d580,5, -0x41d5a0,5, -0x41d5c0,5, -0x41d5e0,5, -0x41d600,5, -0x41d620,5, -0x41d640,5, -0x41d660,5, -0x41d680,5, -0x41d6a0,5, -0x41d6c0,5, -0x41d6e0,5, -0x41d700,5, -0x41d720,5, -0x41d740,5, -0x41d760,5, -0x41d780,5, -0x41d7a0,5, -0x41d7c0,5, -0x41d7e0,5, -0x41d800,24, -0x41d868,16, -0x41d8b0,3, -0x41e000,5, -0x41e020,5, -0x41e040,5, -0x41e060,5, -0x41e080,5, -0x41e0a0,5, -0x41e0c0,5, -0x41e0e0,5, -0x41e100,5, -0x41e120,5, -0x41e140,5, -0x41e160,5, -0x41e180,5, -0x41e1a0,5, -0x41e1c0,5, -0x41e1e0,5, -0x41e200,5, -0x41e220,5, -0x41e240,5, -0x41e260,5, -0x41e280,5, -0x41e2a0,5, -0x41e2c0,5, -0x41e2e0,5, -0x41e300,5, -0x41e320,5, -0x41e340,5, -0x41e360,5, -0x41e380,5, -0x41e3a0,5, -0x41e3c0,5, -0x41e3e0,5, -0x41e400,5, -0x41e420,5, -0x41e440,5, -0x41e460,5, -0x41e480,5, -0x41e4a0,5, -0x41e4c0,5, -0x41e4e0,5, -0x41e500,5, -0x41e520,5, -0x41e540,5, -0x41e560,5, -0x41e580,5, -0x41e5a0,5, -0x41e5c0,5, -0x41e5e0,5, -0x41e600,5, -0x41e620,5, -0x41e640,5, -0x41e660,5, -0x41e680,5, -0x41e6a0,5, -0x41e6c0,5, -0x41e6e0,5, -0x41e700,5, -0x41e720,5, -0x41e740,5, -0x41e760,5, -0x41e780,5, -0x41e7a0,5, -0x41e7c0,5, -0x41e7e0,5, -0x41e800,24, -0x41e868,10, -0x41f000,11, -0x41f030,7, -0x41f080,11, -0x41f0b0,7, -0x41f100,1, -0x440000,7, -0x440020,7, -0x440040,7, -0x440060,7, -0x440080,7, -0x4400a0,7, -0x4400c0,7, -0x4400e0,7, -0x440100,7, -0x440120,7, -0x440140,7, -0x440160,7, -0x440180,7, -0x4401a0,7, -0x4401c0,7, -0x4401e0,7, -0x440200,47, -0x4402c0,118, -0x4404a0,6, +0x411c88,7, +0x411cc0,1, +0x411ce0,26, +0x411d80,1, +0x411e00,5, +0x411e20,5, +0x411e40,5, +0x411e60,5, +0x411e80,9, +0x412000,108, +0x412200,8, +0x420000,31, +0x420080,31, +0x420100,31, +0x420180,31, +0x420200,31, +0x420280,31, +0x420300,31, +0x420380,31, +0x420400,31, +0x420480,31, +0x420500,31, +0x420580,31, +0x420600,31, +0x420680,31, +0x420700,31, +0x420780,31, +0x420800,9, +0x420880,1, +0x420900,21, +0x420980,21, +0x420a00,21, +0x420a80,1, +0x420c04,1, +0x420c10,6, +0x420c30,64, +0x420e00,12, +0x420e40,10, +0x420e80,13, +0x420ec0,13, +0x420f00,9, +0x420f40,5, +0x420f60,5, +0x420f80,6, +0x420fa0,1, +0x420fa8,100, +0x421404,1, +0x421428,22, +0x421504,1, +0x421544,47, +0x421604,1, +0x42161c,9, +0x421644,1, +0x42164c,1, +0x421654,1, +0x42165c,1, +0x421664,1, +0x42166c,3, +0x422000,96, +0x422200,96, +0x422400,6, +0x422424,1, +0x42242c,14, +0x422800,40, +0x4228c0,3, +0x4228d0,3, +0x4228e0,3, +0x4228f0,3, +0x422904,1, +0x42291c,11, +0x422a04,1, +0x422a0c,7, +0x422a40,1, +0x422a54,4, +0x423000,3, +0x424000,3, +0x424010,3, +0x424020,3, +0x424030,3, +0x424040,3, +0x424050,3, +0x424060,3, +0x424070,3, +0x424080,3, +0x424090,3, +0x4240a0,3, +0x4240b0,3, +0x4240c0,3, +0x4240d0,3, +0x4240e0,3, +0x4240f0,3, +0x424100,3, +0x424110,3, +0x424120,3, +0x424130,3, +0x424140,3, +0x424150,3, +0x424160,3, +0x424170,3, +0x424180,3, +0x424190,3, +0x4241a0,3, +0x4241b0,3, +0x4241c0,3, +0x4241d0,3, +0x4241e0,3, +0x4241f0,3, +0x424200,3, +0x424210,3, +0x424220,3, +0x424230,3, +0x424240,3, +0x424250,3, +0x424260,3, +0x424270,3, +0x424280,3, +0x424290,3, +0x4242a0,3, +0x4242b0,3, +0x4242c0,3, +0x4242d0,3, +0x4242e0,3, +0x4242f0,3, +0x424300,3, +0x424310,3, +0x424320,3, +0x424330,3, +0x424340,3, +0x424350,3, +0x424360,3, +0x424370,3, +0x424380,3, +0x424390,3, +0x4243a0,3, +0x4243b0,3, +0x4243c0,3, +0x4243d0,3, +0x4243e0,3, +0x4243f0,3, +0x424400,3, +0x424410,3, +0x424420,3, +0x424430,3, +0x424440,3, +0x424450,3, +0x424460,3, +0x424470,3, +0x424480,3, +0x424490,3, +0x4244a0,3, +0x4244b0,3, +0x4244c0,3, +0x4244d0,3, +0x4244e0,3, +0x4244f0,3, +0x424500,3, +0x424510,3, +0x424520,3, +0x424530,3, +0x424540,3, +0x424550,3, +0x424560,3, +0x424570,3, +0x424580,3, +0x424590,3, +0x4245a0,3, +0x4245b0,3, +0x4245c0,3, +0x4245d0,3, +0x4245e0,3, +0x4245f0,3, +0x424600,32, +0x424800,128, +0x424a04,1, +0x424a20,8, +0x424a44,1, +0x424a60,8, +0x424a84,1, +0x424a94,3, +0x424aa4,1, +0x424ab4,6, +0x424b00,41, +0x424bc4,1, +0x424bd0,4, +0x424be4,6, +0x424c00,3, +0x424c10,14, +0x424c60,9, +0x425000,5, +0x425020,5, +0x425040,5, +0x425060,5, +0x425080,5, +0x4250a0,5, +0x4250c0,5, +0x4250e0,5, +0x425100,5, +0x425120,5, +0x425140,5, +0x425160,5, +0x425180,5, +0x4251a0,5, +0x4251c0,5, +0x4251e0,5, +0x425200,5, +0x425220,5, +0x425240,5, +0x425260,5, +0x425280,5, +0x4252a0,5, +0x4252c0,5, +0x4252e0,5, +0x425300,5, +0x425320,5, +0x425340,5, +0x425360,5, +0x425380,5, +0x4253a0,5, +0x4253c0,5, +0x4253e0,5, +0x425400,5, +0x425420,5, +0x425440,5, +0x425460,5, +0x425480,5, +0x4254a0,5, +0x4254c0,5, +0x4254e0,5, +0x425500,5, +0x425520,5, +0x425540,5, +0x425560,5, +0x425580,5, +0x4255a0,5, +0x4255c0,5, +0x4255e0,5, +0x425600,5, +0x425620,5, +0x425640,5, +0x425660,5, +0x425680,5, +0x4256a0,5, +0x4256c0,5, +0x4256e0,5, +0x425700,5, +0x425720,5, +0x425740,5, +0x425760,5, +0x425780,5, +0x4257a0,5, +0x4257c0,5, +0x4257e0,5, +0x425800,27, +0x425874,10, +0x425904,1, +0x42590c,5, +0x425924,1, +0x42592c,7, +0x425980,8, +0x426000,5, +0x426020,5, +0x426040,5, +0x426060,5, +0x426080,5, +0x4260a0,5, +0x4260c0,5, +0x4260e0,5, +0x426100,5, +0x426120,5, +0x426140,5, +0x426160,5, +0x426180,5, +0x4261a0,5, +0x4261c0,5, +0x4261e0,5, +0x426200,5, +0x426220,5, +0x426240,5, +0x426260,5, +0x426280,5, +0x4262a0,5, +0x4262c0,5, +0x4262e0,5, +0x426300,5, +0x426320,5, +0x426340,5, +0x426360,5, +0x426380,5, +0x4263a0,5, +0x4263c0,5, +0x4263e0,5, +0x426400,5, +0x426420,5, +0x426440,5, +0x426460,5, +0x426480,5, +0x4264a0,5, +0x4264c0,5, +0x4264e0,5, +0x426500,5, +0x426520,5, +0x426540,5, +0x426560,5, +0x426580,5, +0x4265a0,5, +0x4265c0,5, +0x4265e0,5, +0x426600,5, +0x426620,5, +0x426640,5, +0x426660,5, +0x426680,5, +0x4266a0,5, +0x4266c0,5, +0x4266e0,5, +0x426700,5, +0x426720,5, +0x426740,5, +0x426760,5, +0x426780,5, +0x4267a0,5, +0x4267c0,5, +0x4267e0,5, +0x426800,27, +0x426874,10, +0x426904,1, +0x42690c,5, +0x426924,1, +0x42692c,7, +0x426980,8, +0x427000,20, +0x427080,20, +0x427100,20, +0x427180,20, +0x427200,20, +0x427280,20, +0x427300,20, +0x427380,20, +0x427400,20, +0x427480,20, +0x427500,20, +0x427580,20, +0x427600,20, +0x427680,20, +0x427700,20, +0x427780,20, +0x427800,11, +0x427830,1, +0x427840,9, +0x427880,11, +0x4278b0,1, +0x4278c0,9, +0x427900,11, +0x427930,1, +0x427940,9, +0x427980,11, +0x4279b0,1, +0x4279c0,9, +0x427a00,11, +0x427a30,1, +0x427a40,9, +0x427a80,11, +0x427ab0,1, +0x427ac0,9, +0x427b00,11, +0x427b30,1, +0x427b40,9, +0x427b80,11, +0x427bb0,1, +0x427bc0,9, +0x427c00,8, +0x428000,1, +0x428100,57, +0x428200,57, +0x428300,57, +0x428400,57, +0x428500,57, +0x428600,57, +0x428700,57, +0x428800,57, +0x428900,57, +0x428a00,57, +0x428b00,57, +0x428c00,57, +0x428d00,57, +0x428e00,57, +0x428f00,57, +0x429000,57, +0x429100,28, +0x429180,17, +0x429200,11, +0x429240,9, +0x429280,33, +0x429308,4, +0x429320,1, +0x429340,1, +0x429360,7, +0x429380,7, +0x4293a0,1, +0x4293c0,6, +0x4293e0,6, +0x429400,6, +0x429420,1, +0x429440,6, +0x429460,6, +0x429480,6, +0x4294a0,1, +0x4294c0,6, +0x4294e0,6, +0x429500,6, +0x429520,3, +0x429530,7, +0x429550,7, +0x429570,7, +0x429590,7, +0x4295b0,7, +0x4295d0,7, +0x4295f0,7, +0x429610,7, +0x429630,7, +0x429650,7, +0x429670,7, +0x429690,7, +0x4296b0,7, +0x4296d0,7, +0x4296f0,7, +0x429710,7, +0x429730,7, +0x429750,7, +0x429770,7, +0x429790,7, +0x4297b0,7, +0x4297d0,7, +0x4297f0,7, +0x429810,15, +0x429860,39, +0x429920,7, +0x429960,2, +0x42996c,3, +0x429980,2, +0x42998c,3, +0x4299a0,2, +0x4299ac,3, +0x4299c0,2, +0x4299cc,3, +0x4299e0,2, +0x4299ec,3, +0x429a00,2, +0x429a0c,3, +0x429a20,2, +0x429a2c,3, +0x429a40,2, +0x429a4c,3, +0x429a60,2, +0x429a6c,3, +0x429a80,2, +0x429a8c,3, +0x429aa0,2, +0x429aac,3, +0x429ac0,2, +0x429acc,3, +0x429ae0,2, +0x429aec,3, +0x429b00,2, +0x429b0c,3, +0x429b20,2, +0x429b2c,3, +0x429b40,2, +0x429b4c,3, +0x429c00,27, +0x429c80,1, +0x429ca0,6, +0x42a000,27, +0x42a080,4, +0x42a0c0,25, +0x42a140,6, +0x42a160,2, +0x42a16c,3, +0x42a200,8, +0x42a224,25, +0x42a400,27, +0x42a480,1, +0x42a4a0,6, +0x42a500,27, +0x42a580,27, +0x42a600,27, +0x42a680,27, +0x42a700,27, +0x42a780,27, +0x42a800,27, +0x42a880,27, +0x42a900,27, +0x42a980,27, +0x42aa00,27, +0x42aa80,27, +0x42ab00,27, +0x42ab80,27, +0x42ac00,27, +0x42ac80,27, +0x42ad00,2, +0x42ad10,3, +0x42ad20,1, +0x42ad30,65, +0x42b000,3, +0x42b010,3, +0x42b020,3, +0x42b030,3, +0x42b040,3, +0x42b050,3, +0x42b060,3, +0x42b070,3, +0x42b080,3, +0x42b090,3, +0x42b0a0,3, +0x42b0b0,3, +0x42b0c0,3, +0x42b0d0,3, +0x42b0e0,3, +0x42b0f0,3, +0x42b100,2, +0x42b200,3, +0x42b210,3, +0x42b220,3, +0x42b230,3, +0x42b240,3, +0x42b250,3, +0x42b260,3, +0x42b270,3, +0x42b280,3, +0x42b290,3, +0x42b2a0,3, +0x42b2b0,3, +0x42b2c0,3, +0x42b2d0,3, +0x42b2e0,3, +0x42b2f0,3, +0x42b300,2, +0x42b400,3, +0x42b410,3, +0x42b420,3, +0x42b430,3, +0x42b440,3, +0x42b450,3, +0x42b460,3, +0x42b470,3, +0x42b480,3, +0x42b490,3, +0x42b4a0,3, +0x42b4b0,3, +0x42b4c0,3, +0x42b4d0,3, +0x42b4e0,3, +0x42b4f0,3, +0x42b500,2, +0x42b680,11, +0x42b6b0,8, +0x42b700,11, +0x42b730,8, +0x42b780,1, +0x440000,167, +0x4402a0,7, +0x4402c0,7, +0x4402e0,118, 0x4404c0,6, 0x4404e0,6, 0x440500,6, @@ -11220,7 +12093,7 @@ 0x440620,6, 0x440640,6, 0x440660,6, -0x440680,5, +0x440680,6, 0x4406a0,5, 0x4406c0,5, 0x4406e0,5, @@ -11236,7 +12109,8 @@ 0x440820,5, 0x440840,5, 0x440860,5, -0x440880,29, +0x440880,5, +0x4408a0,16, 0x440900,13, 0x440940,13, 0x440980,13, @@ -11252,8 +12126,7 @@ 0x440c00,13, 0x440c40,13, 0x440c80,13, -0x440cc0,5, -0x440ce0,5, +0x440cc0,13, 0x440d00,5, 0x440d20,5, 0x440d40,5, @@ -11268,7 +12141,9 @@ 0x440e60,5, 0x440e80,5, 0x440ea0,5, -0x440ec0,1, +0x440ec0,5, +0x440ee0,5, +0x440f00,17, 0x441000,179, 0x441400,5, 0x441800,3, @@ -11306,7 +12181,7 @@ 0x441a00,2, 0x441a0c,12, 0x441a40,20, -0x441c00,20, +0x441c00,1, 0x441c80,20, 0x441d00,20, 0x441d80,20, @@ -11322,7 +12197,8 @@ 0x442280,20, 0x442300,20, 0x442380,20, -0x442400,5, +0x442400,20, +0x442480,5, 0x444000,27, 0x444080,27, 0x444100,27, @@ -11363,83 +12239,83 @@ 0x452000,46, 0x452100,2, 0x452110,21, -0x452180,19, -0x4521d0,1, +0x452180,23, +0x4521e0,3, 0x452200,46, 0x452300,2, 0x452310,21, -0x452380,19, -0x4523d0,1, +0x452380,23, +0x4523e0,3, 0x452400,46, 0x452500,2, 0x452510,21, -0x452580,19, -0x4525d0,1, +0x452580,23, +0x4525e0,3, 0x452600,46, 0x452700,2, 0x452710,21, -0x452780,19, -0x4527d0,1, +0x452780,23, +0x4527e0,3, 0x452800,46, 0x452900,2, 0x452910,21, -0x452980,19, -0x4529d0,1, +0x452980,23, +0x4529e0,3, 0x452a00,46, 0x452b00,2, 0x452b10,21, -0x452b80,19, -0x452bd0,1, +0x452b80,23, +0x452be0,3, 0x452c00,46, 0x452d00,2, 0x452d10,21, -0x452d80,19, -0x452dd0,1, +0x452d80,23, +0x452de0,3, 0x452e00,46, 0x452f00,2, 0x452f10,21, -0x452f80,19, -0x452fd0,1, +0x452f80,23, +0x452fe0,3, 0x453000,46, 0x453100,2, 0x453110,21, -0x453180,19, -0x4531d0,1, +0x453180,23, +0x4531e0,3, 0x453200,46, 0x453300,2, 0x453310,21, -0x453380,19, -0x4533d0,1, +0x453380,23, +0x4533e0,3, 0x453400,46, 0x453500,2, 0x453510,21, -0x453580,19, -0x4535d0,1, +0x453580,23, +0x4535e0,3, 0x453600,46, 0x453700,2, 0x453710,21, -0x453780,19, -0x4537d0,1, +0x453780,23, +0x4537e0,3, 0x453800,46, 0x453900,2, 0x453910,21, -0x453980,19, -0x4539d0,1, +0x453980,23, +0x4539e0,3, 0x453a00,46, 0x453b00,2, 0x453b10,21, -0x453b80,19, -0x453bd0,1, +0x453b80,23, +0x453be0,3, 0x453c00,46, 0x453d00,2, 0x453d10,21, -0x453d80,19, -0x453dd0,1, +0x453d80,23, +0x453de0,3, 0x453e00,46, 0x453f00,2, 0x453f10,21, -0x453f80,19, -0x453fd0,1, +0x453f80,23, +0x453fe0,3, 0x454000,21, 0x454060,29, 0x4540e0,29, @@ -11456,22 +12332,22 @@ 0x454660,29, 0x4546e0,29, 0x454760,29, -0x4547e0,37, -0x454880,29, -0x454900,29, -0x454980,29, -0x454a00,29, -0x454a80,29, -0x454b00,29, -0x454b80,29, -0x454c00,29, -0x454c80,29, -0x454d00,29, -0x454d80,29, -0x454e00,29, -0x454e80,29, -0x454f00,29, -0x454f80,29, +0x4547e0,38, +0x454880,30, +0x454900,30, +0x454980,30, +0x454a00,30, +0x454a80,30, +0x454b00,30, +0x454b80,30, +0x454c00,30, +0x454c80,30, +0x454d00,30, +0x454d80,30, +0x454e00,30, +0x454e80,30, +0x454f00,30, +0x454f80,30, 0x455000,58, 0x4550ec,1, 0x4550f4,2, @@ -11861,7 +12737,144 @@ 0x45f800,34, 0x45f8a0,8, 0x460000,1, -0x461000,22528, +0x461000,977, +0x462000,161, +0x463000,977, +0x464000,977, +0x465000,977, +0x466000,64, +0x466104,127, +0x466304,127, +0x466504,195, +0x466814,31, +0x466894,428, +0x467000,977, +0x468000,977, +0x469000,977, +0x46a000,977, +0x46b000,977, +0x46c000,977, +0x46d000,977, +0x46e000,977, +0x46f000,977, +0x470000,977, +0x471000,977, +0x472000,977, +0x473000,161, +0x474000,161, +0x475000,161, +0x476000,161, +0x478000,13, +0x478040,14, +0x478080,20, +0x478104,1, +0x47810c,3, +0x478200,13, +0x478240,14, +0x478280,20, +0x478304,1, +0x47830c,3, +0x478400,13, +0x478440,14, +0x478480,20, +0x478504,1, +0x47850c,3, +0x478600,13, +0x478640,14, +0x478680,20, +0x478704,1, +0x47870c,3, +0x478800,13, +0x478840,14, +0x478880,20, +0x478904,1, +0x47890c,3, +0x478a00,13, +0x478a40,14, +0x478a80,20, +0x478b04,1, +0x478b0c,3, +0x478c00,13, +0x478c40,14, +0x478c80,20, +0x478d04,1, +0x478d0c,3, +0x478e00,13, +0x478e40,14, +0x478e80,20, +0x478f04,1, +0x478f0c,3, +0x479000,13, +0x479040,14, +0x479080,20, +0x479104,1, +0x47910c,3, +0x479200,13, +0x479240,14, +0x479280,20, +0x479304,1, +0x47930c,3, +0x479400,13, +0x479440,14, +0x479480,20, +0x479504,1, +0x47950c,3, +0x479600,13, +0x479640,14, +0x479680,20, +0x479704,1, +0x47970c,3, +0x479800,13, +0x479840,14, +0x479880,20, +0x479904,1, +0x47990c,3, +0x479a00,13, +0x479a40,14, +0x479a80,20, +0x479b04,1, +0x479b0c,3, +0x479c00,13, +0x479c40,14, +0x479c80,20, +0x479d04,1, +0x479d0c,3, +0x479e00,13, +0x479e40,14, +0x479e80,20, +0x479f04,1, +0x479f0c,3, +0x47a000,13, +0x47a040,14, +0x47a080,20, +0x47a104,1, +0x47a10c,3, +0x47a200,17, +0x47a250,2, +0x47a260,5, +0x47a280,2, +0x47c000,1, +0x47c014,1, +0x47c01c,10, +0x47c060,9, +0x47c094,1, +0x47c09c,10, +0x47c0e0,9, +0x47c114,1, +0x47c11c,10, +0x47c160,9, +0x47c194,1, +0x47c19c,10, +0x47c1e0,9, +0x47c214,1, +0x47c21c,10, +0x47c260,15, +0x47c400,30, +0x47c480,9, +0x47c4c0,12, +0x47c500,1, +0x47c520,5, +0x47c540,1, 0x580000,3, 0x580080,3, 0x580090,3, @@ -11879,20 +12892,36 @@ 0x580150,3, 0x580160,3, 0x580170,3, -0x580180,1, -0x580188,10, +0x580180,3, +0x580190,3, +0x5801a0,3, +0x5801b0,3, +0x5801c0,3, +0x5801d0,3, +0x5801e0,3, +0x5801f0,3, +0x580200,1, +0x580208,10, +0x580800,3, +0x580900,38, +0x580a00,38, +0x580b00,38, +0x580c00,38, +0x580d00,52, +0x580e00,4, +0x580e20,6, +0x580e40,8, 0x581000,2, -0x581040,38, -0x581100,9, -0x581140,2, -0x581180,9, -0x5811c0,12, -0x581200,11, +0x581040,54, +0x581140,9, +0x581180,2, +0x5811c0,9, +0x581200,12, 0x581240,11, 0x581280,11, 0x5812c0,11, -0x581300,12, -0x581340,11, +0x581300,11, +0x581340,12, 0x581380,11, 0x5813c0,11, 0x581400,11, @@ -11907,73 +12936,75 @@ 0x581640,11, 0x581680,11, 0x5816c0,11, -0x581700,1, -0x581744,1, -0x58175c,14, -0x5817a0,1, -0x5817c0,40, +0x581700,11, +0x581740,3, +0x581784,1, +0x58179c,14, +0x5817e0,9, +0x581844,1, +0x581854,6, +0x581880,2, +0x5818c0,11, +0x581900,11, +0x581940,11, +0x581980,1, +0x5819c0,10, +0x581a00,1, 0x582000,4, -0x582080,71, -0x5821a0,7, -0x5821c0,54, -0x5822a4,1, -0x5822b0,9, -0x5822e0,9, -0x582310,65, -0x582800,1, -0x582808,108, -0x5829c0,1, -0x5829d0,5, -0x5829f0,5, -0x582a10,5, -0x582a30,4, -0x582c04,56, -0x582ce8,2, -0x582d00,3, -0x582d10,1, -0x582d24,3, -0x582d40,1, -0x582d48,4, -0x582d80,48, -0x583000,2, -0x583100,38, +0x582080,103, +0x582220,9, +0x582248,49, +0x582324,1, +0x582330,9, +0x582360,109, +0x582540,1, +0x582584,1, +0x582594,6, +0x5825c0,1, +0x5825e0,9, +0x583000,1, +0x583008,110, 0x583200,38, 0x583300,38, -0x583400,24, -0x583480,20, -0x583500,11, -0x583800,21, -0x583880,3, -0x583890,2, -0x5838a0,6, -0x5838c0,6, -0x583900,34, -0x583a00,1, -0x583a40,13, -0x583b00,2, -0x583b84,1, -0x583b9c,27, -0x583c44,1, -0x583c50,12, -0x583e00,4, -0x583f04,1, -0x583f6c,37, -0x584004,1, -0x5840e4,79, -0x584300,1, -0x584308,2, +0x583400,52, +0x583500,4, +0x583600,52, +0x583700,38, +0x583800,52, +0x583900,38, +0x583a00,38, +0x583b00,38, +0x583c00,1, +0x583c10,5, +0x583c30,5, +0x583c50,5, +0x583c70,4, +0x584004,56, +0x5840e8,2, +0x584100,3, +0x584110,1, +0x584124,3, +0x584140,49, +0x584208,4, 0x584400,37, -0x584500,9, -0x584540,1, -0x584548,2, -0x584560,2, -0x584580,5, -0x5845a0,5, -0x584600,6, -0x584640,11, -0x584680,11, -0x5846c0,1, -0x5846e0,16, +0x584500,6, +0x584520,6, +0x584540,6, +0x584560,6, +0x584600,34, +0x584700,13, +0x584740,5, +0x584780,5, +0x584800,2, +0x584884,1, +0x584898,28, +0x584944,1, +0x58494c,13, +0x584a00,4, +0x584b04,1, +0x584b6c,37, +0x584c04,1, +0x584ce4,73, 0x588004,1, 0x58801c,12, 0x588404,1, @@ -12008,622 +13039,795 @@ 0x588b1c,12, 0x588b84,1, 0x588b9c,12, -0x588c00,13, -0x588c40,11, -0x588c80,17, -0x588d00,11, -0x588d40,1, -0x588d80,11, -0x588dc0,1, -0x588e00,11, -0x588e40,1, -0x588e80,6, -0x588f00,38, -0x589000,38, -0x589100,38, -0x589200,7, -0x589220,7, -0x589304,1, -0x58936c,44, -0x589420,7, -0x589504,1, -0x58956c,44, -0x589620,7, -0x589704,1, -0x58976c,44, -0x589820,7, -0x589904,1, -0x58996c,44, -0x589a20,7, -0x589b04,1, -0x589b6c,44, +0x588c04,1, +0x588c1c,12, +0x588c84,1, +0x588c9c,12, +0x588d04,1, +0x588d1c,12, +0x588d84,1, +0x588d9c,12, +0x588e04,1, +0x588e1c,12, +0x588e84,1, +0x588e9c,12, +0x588f04,1, +0x588f1c,12, +0x588f84,1, +0x588f9c,12, +0x589000,13, +0x589040,12, +0x589080,12, +0x5890c0,5, +0x5890d8,5, +0x5890f0,5, +0x589108,7, +0x589200,12, +0x589240,1, +0x589300,12, +0x589340,12, +0x589380,2, +0x589400,12, +0x589440,12, +0x589480,2, +0x589500,12, +0x589540,12, +0x589580,2, +0x589600,8, +0x589700,54, +0x589800,54, +0x589900,54, +0x589c00,7, 0x589c20,7, 0x589d04,1, -0x589d6c,44, -0x589e20,7, -0x589f04,1, -0x589f6c,44, +0x589d6c,38, +0x58a000,7, 0x58a020,7, 0x58a104,1, -0x58a16c,37, +0x58a16c,38, +0x58a400,7, +0x58a420,7, +0x58a504,1, +0x58a56c,38, +0x58a800,7, +0x58a820,7, +0x58a904,1, +0x58a96c,38, +0x58ac00,7, +0x58ac20,7, +0x58ad04,1, +0x58ad6c,38, +0x58b000,7, +0x58b020,7, +0x58b104,1, +0x58b16c,38, +0x58b400,7, +0x58b420,7, +0x58b504,1, +0x58b56c,38, +0x58b800,7, +0x58b820,7, +0x58b904,1, +0x58b96c,38, +0x58bc00,1, 0x58c000,1, -0x58c020,16, +0x58c020,24, 0x58c084,1, -0x58c09c,10, +0x58c098,11, 0x58c100,1, -0x58c120,16, +0x58c120,24, 0x58c184,1, 0x58c1a4,9, 0x58c200,8, 0x58c224,35, 0x58c304,2, -0x58c310,12, +0x58c310,13, 0x58c400,7, -0x58c420,6, +0x58c420,7, 0x58c440,1, 0x58c448,6, 0x58c800,7, -0x58c820,6, +0x58c820,7, 0x58c840,1, 0x58c848,6, 0x58c880,7, -0x58c8a0,6, +0x58c8a0,7, 0x58c8c0,1, 0x58c8c8,6, 0x58c900,7, -0x58c920,6, +0x58c920,7, 0x58c940,1, 0x58c948,6, 0x58c980,7, -0x58c9a0,6, +0x58c9a0,7, 0x58c9c0,1, 0x58c9c8,6, 0x58ca00,7, -0x58ca20,6, +0x58ca20,7, 0x58ca40,1, 0x58ca48,6, 0x58ca80,7, -0x58caa0,6, +0x58caa0,7, 0x58cac0,1, 0x58cac8,6, 0x58cb00,7, -0x58cb20,6, +0x58cb20,7, 0x58cb40,1, 0x58cb48,6, 0x58cb80,7, -0x58cba0,6, +0x58cba0,7, 0x58cbc0,1, 0x58cbc8,6, 0x58cc00,7, -0x58cc20,6, +0x58cc20,7, 0x58cc40,1, 0x58cc48,6, 0x58cc80,7, -0x58cca0,6, +0x58cca0,7, 0x58ccc0,1, 0x58ccc8,6, 0x58cd00,7, -0x58cd20,6, +0x58cd20,7, 0x58cd40,1, 0x58cd48,6, 0x58cd80,7, -0x58cda0,6, +0x58cda0,7, 0x58cdc0,1, 0x58cdc8,6, 0x58ce00,7, -0x58ce20,6, +0x58ce20,7, 0x58ce40,1, 0x58ce48,6, 0x58ce80,7, -0x58cea0,6, +0x58cea0,7, 0x58cec0,1, 0x58cec8,6, 0x58cf00,7, -0x58cf20,6, +0x58cf20,7, 0x58cf40,1, 0x58cf48,6, 0x58cf80,7, -0x58cfa0,6, +0x58cfa0,7, 0x58cfc0,1, 0x58cfc8,6, -0x58e000,15, -0x58e040,3, -0x58e050,5, -0x58e080,16, -0x58e100,20, -0x58e180,20, -0x58e200,20, -0x58e400,15, -0x58e480,20, -0x58e500,20, -0x58e580,20, +0x58d000,7, +0x58d020,7, +0x58d040,1, +0x58d048,6, +0x58d080,7, +0x58d0a0,7, +0x58d0c0,1, +0x58d0c8,6, +0x58d100,7, +0x58d120,7, +0x58d140,1, +0x58d148,6, +0x58d180,7, +0x58d1a0,7, +0x58d1c0,1, +0x58d1c8,6, +0x58d200,7, +0x58d220,7, +0x58d240,1, +0x58d248,6, +0x58d280,7, +0x58d2a0,7, +0x58d2c0,1, +0x58d2c8,6, +0x58d300,7, +0x58d320,7, +0x58d340,1, +0x58d348,6, +0x58d380,7, +0x58d3a0,7, +0x58d3c0,1, +0x58d3c8,6, +0x58e000,5, +0x58e020,5, +0x58e040,5, +0x58e060,5, +0x58e080,5, +0x58e0a0,5, +0x58e0c0,5, +0x58e0e0,5, +0x58e100,5, +0x58e120,5, +0x58e140,5, +0x58e160,5, +0x58e180,5, +0x58e1a0,5, +0x58e1c0,5, +0x58e1e0,5, +0x58e200,5, +0x58e220,5, +0x58e240,5, +0x58e260,5, +0x58e280,5, +0x58e2a0,5, +0x58e2c0,5, +0x58e2e0,5, +0x58e300,5, +0x58e320,5, +0x58e340,5, +0x58e360,5, +0x58e380,5, +0x58e3a0,5, +0x58e3c0,5, +0x58e3e0,5, +0x58e400,5, +0x58e420,5, +0x58e440,5, +0x58e460,5, +0x58e480,5, +0x58e4a0,5, +0x58e4c0,5, +0x58e4e0,5, +0x58e500,5, +0x58e520,5, +0x58e540,5, +0x58e560,5, +0x58e580,5, +0x58e5a0,5, +0x58e5c0,5, +0x58e5e0,5, 0x58e600,5, -0x58e620,1, -0x58e640,7, -0x58e660,24, -0x58e800,276, -0x58f004,9, -0x58f040,1, -0x58f060,7, -0x58f080,8, -0x58f100,53, -0x58f200,10, -0x58f240,9, -0x58f280,10, -0x58f400,2, -0x58f504,1, -0x58f568,43, -0x590000,3, -0x590010,3, -0x590020,3, -0x590030,3, +0x58e620,5, +0x58e640,5, +0x58e660,5, +0x58e680,5, +0x58e6a0,5, +0x58e6c0,5, +0x58e6e0,5, +0x58e700,5, +0x58e720,5, +0x58e740,5, +0x58e760,5, +0x58e780,5, +0x58e7a0,5, +0x58e7c0,5, +0x58e7e0,5, +0x58e800,27, +0x58e874,10, +0x58e904,1, +0x58e90c,5, +0x58e924,1, +0x58e92c,7, +0x58e980,8, +0x58f000,5, +0x58f020,5, +0x58f040,5, +0x58f060,5, +0x58f080,5, +0x58f0a0,5, +0x58f0c0,5, +0x58f0e0,5, +0x58f100,5, +0x58f120,5, +0x58f140,5, +0x58f160,5, +0x58f180,5, +0x58f1a0,5, +0x58f1c0,5, +0x58f1e0,5, +0x58f200,5, +0x58f220,5, +0x58f240,5, +0x58f260,5, +0x58f280,5, +0x58f2a0,5, +0x58f2c0,5, +0x58f2e0,5, +0x58f300,5, +0x58f320,5, +0x58f340,5, +0x58f360,5, +0x58f380,5, +0x58f3a0,5, +0x58f3c0,5, +0x58f3e0,5, +0x58f400,5, +0x58f420,5, +0x58f440,5, +0x58f460,5, +0x58f480,5, +0x58f4a0,5, +0x58f4c0,5, +0x58f4e0,5, +0x58f500,5, +0x58f520,5, +0x58f540,5, +0x58f560,5, +0x58f580,5, +0x58f5a0,5, +0x58f5c0,5, +0x58f5e0,5, +0x58f600,5, +0x58f620,5, +0x58f640,5, +0x58f660,5, +0x58f680,5, +0x58f6a0,5, +0x58f6c0,5, +0x58f6e0,5, +0x58f700,5, +0x58f720,5, +0x58f740,5, +0x58f760,5, +0x58f780,5, +0x58f7a0,5, +0x58f7c0,5, +0x58f7e0,5, +0x58f800,27, +0x58f874,10, +0x58f904,1, +0x58f90c,5, +0x58f924,1, +0x58f92c,7, +0x58f980,8, +0x590000,15, 0x590040,3, -0x590050,3, -0x590060,3, -0x590070,3, -0x590080,3, -0x590090,3, -0x5900a0,3, -0x5900b0,3, -0x5900c0,3, -0x5900d0,3, -0x5900e0,3, -0x5900f0,3, -0x590100,3, -0x590110,3, -0x590120,3, -0x590130,3, -0x590140,3, -0x590150,3, -0x590160,3, -0x590170,3, -0x590180,3, -0x590190,3, -0x5901a0,3, -0x5901b0,3, -0x5901c0,3, -0x5901d0,3, -0x5901e0,3, -0x5901f0,3, -0x590200,3, -0x590210,3, -0x590220,3, -0x590230,3, -0x590240,3, -0x590250,3, -0x590260,3, -0x590270,3, -0x590280,3, -0x590290,3, -0x5902a0,3, -0x5902b0,3, -0x5902c0,3, -0x5902d0,3, -0x5902e0,3, -0x5902f0,3, -0x590300,3, -0x590310,3, -0x590320,3, -0x590330,3, -0x590340,3, -0x590350,3, -0x590360,3, -0x590370,3, -0x590380,3, -0x590390,3, -0x5903a0,3, -0x5903b0,3, -0x5903c0,3, -0x5903d0,3, -0x5903e0,3, -0x5903f0,3, -0x590400,3, -0x590410,3, -0x590420,3, -0x590430,3, -0x590440,3, -0x590450,3, -0x590460,3, -0x590470,3, -0x590480,3, -0x590490,3, -0x5904a0,3, -0x5904b0,3, -0x5904c0,3, -0x5904d0,3, -0x5904e0,3, -0x5904f0,3, -0x590500,3, -0x590510,3, -0x590520,3, -0x590530,3, -0x590540,3, -0x590550,3, -0x590560,3, -0x590570,3, -0x590580,3, -0x590590,3, -0x5905a0,3, -0x5905b0,3, -0x5905c0,3, -0x5905d0,3, -0x5905e0,3, -0x5905f0,3, -0x590600,3, -0x590610,3, -0x590620,3, -0x590630,3, -0x590640,3, -0x590650,3, -0x590660,3, -0x590670,3, -0x590680,3, -0x590690,3, -0x5906a0,3, -0x5906b0,3, -0x5906c0,3, -0x5906d0,3, -0x5906e0,3, -0x5906f0,3, -0x590700,3, -0x590710,3, -0x590720,3, -0x590730,3, -0x590740,1, -0x590800,2, -0x590880,5, -0x5908a0,5, -0x5908c0,5, -0x5908e0,5, -0x590900,5, -0x590920,5, -0x590940,5, -0x590960,5, -0x590a00,5, -0x590a20,5, -0x590a40,5, -0x590a60,5, -0x590a80,5, -0x590aa0,5, -0x590ac0,5, -0x590ae0,5, -0x590b00,5, -0x590b20,5, -0x590c00,5, -0x590c20,5, -0x590c40,5, -0x590c60,5, -0x590c80,5, -0x590ca0,5, -0x590cc0,5, -0x590ce0,5, -0x590d00,5, -0x590d20,5, -0x591000,5, -0x591020,17, -0x591104,47, -0x592000,6, -0x592020,6, -0x592040,6, -0x592060,6, -0x592080,6, -0x5920a0,6, -0x5920c0,6, -0x5920e0,6, -0x592100,6, -0x592120,6, -0x592140,6, -0x592160,6, -0x592180,6, -0x5921a0,6, -0x5921c0,6, -0x5921e0,6, -0x592200,6, -0x592220,6, -0x592240,6, -0x592260,6, -0x592280,6, -0x5922a0,6, -0x5922c0,6, -0x5922e0,6, -0x592300,6, -0x592320,6, -0x592340,6, -0x592360,6, -0x592380,6, -0x5923a0,6, -0x5923c0,6, -0x5923e0,6, -0x592400,6, -0x592420,6, -0x592440,6, -0x592460,6, -0x592480,6, -0x5924a0,6, -0x5924c0,6, -0x5924e0,6, -0x592500,6, -0x592520,6, -0x592540,6, -0x592560,6, -0x592580,6, -0x5925a0,6, -0x5925c0,6, -0x5925e0,6, -0x592600,6, -0x592620,6, -0x592640,6, -0x592660,6, -0x592680,6, -0x5926a0,6, -0x5926c0,6, -0x5926e0,6, -0x592700,6, -0x592720,6, -0x592740,6, -0x592760,6, -0x592780,6, -0x5927a0,6, -0x5927c0,6, -0x5927e0,6, -0x592800,6, -0x592820,6, -0x592840,6, -0x592860,6, -0x592880,6, -0x5928a0,6, -0x5928c0,6, -0x5928e0,6, -0x592900,6, -0x592920,6, -0x592940,6, -0x592960,6, -0x592980,6, -0x5929a0,6, -0x5929c0,6, -0x5929e0,6, -0x592a00,6, -0x592a20,6, -0x592a40,6, -0x592a60,6, -0x592a80,6, -0x592aa0,6, -0x592ac0,6, -0x592ae0,6, -0x592b00,6, -0x592b20,6, -0x592b40,6, -0x592b60,6, -0x592b80,6, -0x592ba0,6, -0x592bc0,6, -0x592be0,6, -0x592c00,6, -0x592c20,6, -0x592c40,6, -0x592c60,6, -0x592c80,6, -0x592ca0,6, -0x592cc0,6, -0x592ce0,6, -0x592d00,6, -0x592d20,6, -0x592d40,6, -0x592d60,6, -0x592d80,6, -0x592da0,6, -0x592dc0,6, -0x592de0,6, -0x592e00,6, -0x592e20,6, -0x592e40,6, -0x592e60,6, -0x592e80,7, -0x593000,8, -0x593100,128, -0x593400,116, -0x593600,20, -0x593680,39, -0x593740,4, +0x590050,5, +0x590080,24, +0x590100,20, +0x590180,20, +0x590200,20, +0x590280,20, +0x590400,16, +0x590480,20, +0x590500,20, +0x590580,20, +0x590600,20, +0x590800,5, +0x590820,1, +0x590840,7, +0x590860,32, +0x591000,276, +0x591800,1, +0x591820,7, +0x591840,10, +0x591880,10, +0x5918c0,9, +0x591900,10, +0x591a00,2, +0x591b04,1, +0x591b68,43, +0x591d00,7, +0x591d84,7, +0x591da4,10, +0x591e00,53, +0x592000,96, +0x592200,96, +0x592400,8, +0x592500,137, +0x592744,1, +0x59274c,14, +0x5927a4,1, +0x5927b4,11, +0x592800,3, +0x592810,3, +0x592820,3, +0x592830,3, +0x592840,3, +0x592850,3, +0x592860,3, +0x592870,3, +0x592880,3, +0x592890,3, +0x5928a0,3, +0x5928b0,3, +0x5928c0,3, +0x5928d0,3, +0x5928e0,3, +0x5928f0,3, +0x592900,3, +0x592910,3, +0x592920,3, +0x592930,3, +0x592940,3, +0x592950,3, +0x592960,3, +0x592970,3, +0x592980,3, +0x592990,3, +0x5929a0,3, +0x5929b0,3, +0x5929c0,3, +0x5929d0,3, +0x5929e0,3, +0x5929f0,3, +0x592a00,3, +0x592a10,3, +0x592a20,3, +0x592a30,3, +0x592a40,3, +0x592a50,3, +0x592a60,3, +0x592a70,3, +0x592a80,3, +0x592a90,3, +0x592aa0,3, +0x592ab0,3, +0x592ac0,3, +0x592ad0,3, +0x592ae0,3, +0x592af0,3, +0x592b00,3, +0x592b10,3, +0x592b20,3, +0x592b30,3, +0x592b40,3, +0x592b50,3, +0x592b60,3, +0x592b70,3, +0x592b80,3, +0x592b90,3, +0x592ba0,3, +0x592bb0,3, +0x592bc0,3, +0x592bd0,3, +0x592be0,3, +0x592bf0,3, +0x592c00,192, +0x592f04,1, +0x592f0c,8, +0x593000,5, +0x593020,5, +0x593040,5, +0x593060,5, +0x593080,5, +0x5930a0,5, +0x5930c0,5, +0x5930e0,5, +0x593100,5, +0x593120,5, +0x593140,5, +0x593160,5, +0x593180,5, +0x5931a0,5, +0x5931c0,5, +0x5931e0,5, +0x593200,5, +0x593220,5, +0x593240,5, +0x593260,5, +0x593280,5, +0x5932a0,5, +0x5932c0,5, +0x5932e0,5, +0x593300,5, +0x593320,5, +0x593340,5, +0x593360,5, +0x593380,5, +0x5933a0,5, +0x5933c0,5, +0x5933e0,5, +0x593400,5, +0x593420,5, +0x593440,5, +0x593460,5, +0x593480,5, +0x5934a0,5, +0x5934c0,5, +0x5934e0,5, +0x593500,5, +0x593520,5, +0x593540,5, +0x593560,5, +0x593580,5, +0x5935a0,5, +0x5935c0,5, +0x5935e0,5, +0x593600,5, +0x593620,5, +0x593640,5, +0x593660,5, +0x593680,5, +0x5936a0,5, +0x5936c0,5, +0x5936e0,5, +0x593700,5, +0x593720,5, +0x593740,5, 0x593760,5, -0x593780,4, +0x593780,5, 0x5937a0,5, -0x5937c0,4, +0x5937c0,5, 0x5937e0,5, -0x593800,4, -0x593820,5, -0x593840,4, -0x593860,5, -0x593880,4, -0x5938a0,5, -0x5938c0,4, -0x5938e0,5, -0x593900,4, -0x593920,7, -0x593940,4, -0x593960,7, -0x593980,15, -0x5939c0,38, -0x593a60,6, -0x593a80,14, -0x593ac0,7, -0x593b00,4, -0x593b20,7, -0x593b40,2, -0x593b4c,2, -0x593b80,4, -0x593ba0,5, -0x593bc0,7, -0x593be0,1, -0x593bf0,8, -0x593c20,1, -0x593c40,16, -0x593d00,27, -0x593d80,1, -0x593da0,6, -0x593e00,27, -0x593e80,1, -0x593ea0,6, -0x593f00,27, -0x593f80,1, -0x593fa0,6, -0x594000,27, -0x594080,1, -0x5940a0,6, -0x594100,27, -0x594180,1, -0x5941a0,6, -0x594200,27, -0x594280,1, -0x5942a0,6, -0x594300,27, -0x594380,1, -0x5943a0,6, -0x594400,27, -0x594480,1, -0x5944a0,6, -0x594500,27, -0x594580,1, -0x5945a0,6, -0x594600,27, -0x594680,1, -0x5946a0,6, -0x594700,11, -0x595000,5, -0x595020,5, -0x595040,5, -0x595060,5, -0x595080,5, -0x5950a0,5, -0x5950c0,5, -0x5950e0,5, -0x595100,5, -0x595120,5, -0x595140,5, -0x595160,5, -0x595180,5, -0x5951a0,5, -0x5951c0,5, -0x5951e0,5, -0x595200,5, -0x595220,5, -0x595240,5, -0x595260,5, -0x595280,5, -0x5952a0,5, -0x5952c0,5, -0x5952e0,5, -0x595300,5, -0x595320,5, -0x595340,5, -0x595360,5, -0x595380,5, -0x5953a0,5, -0x5953c0,5, -0x5953e0,5, -0x595400,5, -0x595420,5, -0x595440,5, -0x595460,5, -0x595480,5, -0x5954a0,5, -0x5954c0,5, -0x5954e0,5, -0x595500,5, -0x595520,5, -0x595540,5, -0x595560,5, -0x595580,5, -0x5955a0,5, -0x5955c0,5, -0x5955e0,5, -0x595600,5, -0x595620,5, -0x595640,5, -0x595660,5, -0x595680,5, -0x5956a0,5, -0x5956c0,5, -0x5956e0,5, -0x595700,5, -0x595720,5, -0x595740,5, -0x595760,5, -0x595780,5, -0x5957a0,5, -0x5957c0,5, -0x5957e0,5, -0x595800,23, -0x595864,10, -0x595890,3, -0x5958a0,2, -0x596000,5, -0x596020,5, -0x596040,5, -0x596060,5, -0x596080,5, -0x5960a0,5, -0x5960c0,5, -0x5960e0,5, -0x596100,5, -0x596120,5, -0x596140,5, -0x596160,5, -0x596180,5, -0x5961a0,5, -0x5961c0,5, -0x5961e0,5, -0x596200,5, -0x596220,5, -0x596240,5, -0x596260,5, -0x596280,5, -0x5962a0,5, -0x5962c0,5, -0x5962e0,5, -0x596300,5, -0x596320,5, -0x596340,5, -0x596360,5, -0x596380,5, -0x5963a0,5, -0x5963c0,5, -0x5963e0,5, -0x596400,5, -0x596420,5, -0x596440,5, -0x596460,5, -0x596480,5, -0x5964a0,5, -0x5964c0,5, -0x5964e0,5, -0x596500,5, -0x596520,5, -0x596540,5, -0x596560,5, -0x596580,5, -0x5965a0,5, -0x5965c0,5, -0x5965e0,5, -0x596600,5, -0x596620,5, -0x596640,5, -0x596660,5, -0x596680,5, -0x5966a0,5, -0x5966c0,5, -0x5966e0,5, -0x596700,5, -0x596720,5, -0x596740,5, -0x596760,5, -0x596780,5, -0x5967a0,5, -0x5967c0,5, -0x5967e0,5, -0x596800,23, -0x596864,10, -0x597000,1, +0x593800,131, +0x593a10,3, +0x593a20,3, +0x593a30,3, +0x593a40,3, +0x593a50,3, +0x593a60,3, +0x593a70,3, +0x593a80,3, +0x593a90,3, +0x593aa0,3, +0x593ab0,3, +0x593ac0,3, +0x593ad0,3, +0x593ae0,3, +0x593af0,3, +0x593b00,3, +0x593b10,3, +0x593b20,3, +0x593b30,3, +0x593b40,3, +0x593b50,3, +0x593b60,3, +0x593b70,3, +0x593b80,3, +0x593b90,3, +0x593ba0,3, +0x593bb0,3, +0x593bc0,3, +0x593bd0,3, +0x593be0,3, +0x593bf0,3, +0x593c00,3, +0x593c10,3, +0x593c20,3, +0x593c30,3, +0x593c40,3, +0x593c50,3, +0x593c60,3, +0x593c70,3, +0x593c80,3, +0x593c90,3, +0x593ca0,3, +0x593cb0,3, +0x593cc0,3, +0x593cd0,3, +0x593ce0,3, +0x593cf0,3, +0x593d00,3, +0x593d10,3, +0x593d20,3, +0x593d30,3, +0x593d40,3, +0x593d50,3, +0x593d60,3, +0x593d70,3, +0x593d80,3, +0x593d90,3, +0x593da0,3, +0x593db0,3, +0x593dc0,3, +0x593dd0,3, +0x593de0,3, +0x593df0,3, +0x593e04,1, +0x593e24,10, +0x594000,10, +0x598000,1, +0x598200,2, +0x598220,6, +0x598240,7, +0x598260,7, +0x598280,7, +0x5982a0,7, +0x5982c0,6, +0x5982e0,6, +0x598300,6, +0x598400,2, +0x598420,6, +0x598440,7, +0x598460,7, +0x598480,7, +0x5984a0,7, +0x5984c0,6, +0x5984e0,6, +0x598500,6, +0x598600,7, +0x598620,7, +0x598640,7, +0x598660,7, +0x598680,7, +0x5986a0,7, +0x5986c0,7, +0x5986e0,7, +0x598700,7, +0x598720,7, +0x598740,7, +0x598760,7, +0x598780,7, +0x5987a0,7, +0x5987c0,7, +0x5987e0,7, +0x598800,7, +0x598820,7, +0x598840,7, +0x598860,7, +0x598880,7, +0x5988a0,7, +0x5988c0,7, +0x5988e0,7, +0x598900,25, +0x598980,5, +0x5989a0,1, +0x5989a8,5, +0x5989c0,5, +0x5989e0,1, +0x5989e8,5, +0x598a00,5, +0x598a20,1, +0x598a28,5, +0x598a80,20, +0x598b00,20, +0x598b80,20, +0x599000,4, +0x599020,25, +0x599104,47, +0x599200,128, +0x599404,1, +0x599414,11, +0x599800,3, +0x599810,3, +0x599820,3, +0x599830,3, +0x599840,3, +0x599850,3, +0x599860,3, +0x599870,3, +0x599880,3, +0x599890,3, +0x5998a0,3, +0x5998b0,3, +0x5998c0,3, +0x5998d0,3, +0x5998e0,3, +0x5998f0,3, +0x599900,3, +0x599910,3, +0x599920,3, +0x599930,3, +0x599940,3, +0x599950,3, +0x599960,3, +0x599970,3, +0x599980,3, +0x599990,3, +0x5999a0,3, +0x5999b0,3, +0x5999c0,3, +0x5999d0,3, +0x5999e0,3, +0x5999f0,3, +0x599a00,3, +0x599a10,3, +0x599a20,3, +0x599a30,3, +0x599a40,3, +0x599a50,3, +0x599a60,3, +0x599a70,3, +0x599a80,3, +0x599a90,3, +0x599aa0,3, +0x599ab0,3, +0x599ac0,3, +0x599ad0,3, +0x599ae0,3, +0x599af0,3, +0x599b00,3, +0x599b10,3, +0x599b20,3, +0x599b30,3, +0x599b40,3, +0x599b50,3, +0x599b60,3, +0x599b70,3, +0x599b80,3, +0x599b90,3, +0x599ba0,3, +0x599bb0,3, +0x599bc0,3, +0x599bd0,3, +0x599be0,3, +0x599bf0,3, +0x599c00,192, +0x599f04,1, +0x599f0c,10, +0x59a000,1, +0x59a00c,3, +0x59c000,8, +0x59c100,292, +0x59c600,51, +0x59c6e0,2, +0x59c700,5, +0x59c720,5, +0x59c740,6, +0x59c760,1, +0x59c780,6, +0x59c7a0,1, +0x59c7c0,4, +0x59c7e0,6, +0x59c800,4, +0x59c820,6, +0x59c840,4, +0x59c860,6, +0x59c880,4, +0x59c8a0,6, +0x59c8c0,4, +0x59c8e0,6, +0x59c900,4, +0x59c920,6, +0x59c940,4, +0x59c960,7, +0x59c980,4, +0x59c9a0,7, +0x59c9c0,15, +0x59ca00,7, +0x59ca20,46, +0x59cae0,6, +0x59cb00,6, +0x59cb20,14, +0x59cb60,7, +0x59cb80,4, +0x59cba0,7, +0x59cbc0,2, +0x59cbcc,2, +0x59cc00,4, +0x59cc20,5, +0x59cc40,7, +0x59cc60,7, +0x59cc80,25, +0x59ccf0,8, +0x59cd20,31, +0x59ce00,1, +0x59ce08,2, +0x59cf00,37, +0x59d000,9, +0x59d040,1, +0x59d048,2, +0x59d200,6, +0x59d240,11, +0x59d280,11, +0x59d2c0,1, +0x59d2e0,25, +0x59d384,1, +0x59d394,6, +0x59d3c0,1, +0x59d3d0,3, +0x59d400,27, +0x59d480,4, +0x59d4c0,25, +0x59d540,6, +0x59d560,2, +0x59d56c,3, +0x59d600,8, +0x59d624,56, +0x59d800,27, +0x59d880,1, +0x59d8a0,6, +0x59d900,27, +0x59d980,1, +0x59d9a0,6, +0x59da00,27, +0x59da80,1, +0x59daa0,6, +0x59db00,27, +0x59db80,1, +0x59dba0,6, +0x59dc00,27, +0x59dc80,1, +0x59dca0,6, +0x59dd00,27, +0x59dd80,1, +0x59dda0,6, +0x59de00,27, +0x59de80,1, +0x59dea0,6, +0x59df00,27, +0x59df80,1, +0x59dfa0,6, +0x59e000,27, +0x59e080,1, +0x59e0a0,6, +0x59e100,3, +0x59e110,10, 0x600000,22, 0x600060,6, 0x600080,6, @@ -13254,25 +14458,25 @@ 0x79a900,2, 0x79a910,4, 0x79a980,1, -0x79b000,20, +0x79b000,36, 0x79b800,10, 0x79b880,3, 0x79b900,2, 0x79b910,4, 0x79b980,1, -0x79c000,20, +0x79c000,36, 0x79c800,10, 0x79c880,3, 0x79c900,2, 0x79c910,4, 0x79c980,1, -0x79d000,20, +0x79d000,36, 0x79d800,10, 0x79d880,3, 0x79d900,2, 0x79d910,4, 0x79d980,1, -0x79e000,20, +0x79e000,36, 0x79e800,10, 0x79e880,3, 0x79e900,2, @@ -13415,7 +14619,154 @@ 0x7be900,2, 0x7be910,4, 0x7be980,1, -0x7d4000,10, +0x7c0000,10, +0x7c0080,3, +0x7c0100,2, +0x7c0110,4, +0x7c0800,1, +0x7c0810,3, +0x7c0820,3, +0x7c0830,3, +0x7c0840,3, +0x7c0850,3, +0x7c0860,3, +0x7c0870,3, +0x7c0880,3, +0x7c0890,32, +0x7c0940,10, +0x7c0980,10, +0x7c09c0,10, +0x7c0a00,10, +0x7c0a40,10, +0x7c0a80,10, +0x7c0ac0,10, +0x7c0b00,10, +0x7c0b40,11, +0x7c0b70,2, +0x7c1000,1, +0x7c4000,10, +0x7c4080,3, +0x7c4100,2, +0x7c4110,4, +0x7c4200,1, +0x7c4210,3, +0x7c4220,3, +0x7c4230,8, +0x7c4280,10, +0x7c42c0,10, +0x7c4300,2, +0x7c4310,3, +0x7c4320,2, +0x7c4400,1, +0x7c8000,10, +0x7c8080,3, +0x7c8100,2, +0x7c8110,4, +0x7c9000,1, +0x7c9010,3, +0x7c9020,3, +0x7c9030,3, +0x7c9040,3, +0x7c9050,3, +0x7c9060,3, +0x7c9070,3, +0x7c9080,3, +0x7c9090,3, +0x7c90a0,3, +0x7c90b0,3, +0x7c90c0,3, +0x7c90d0,3, +0x7c90e0,3, +0x7c90f0,3, +0x7c9100,3, +0x7c9110,64, +0x7c9240,10, +0x7c9280,10, +0x7c92c0,10, +0x7c9300,10, +0x7c9340,10, +0x7c9380,10, +0x7c93c0,10, +0x7c9400,10, +0x7c9440,10, +0x7c9480,10, +0x7c94c0,10, +0x7c9500,10, +0x7c9540,10, +0x7c9580,10, +0x7c95c0,10, +0x7c9600,10, +0x7c9640,19, +0x7c9690,3, +0x7c96a0,3, +0x7c96b0,3, +0x7c96c0,8, +0x7ca000,1, +0x7cc000,10, +0x7cc080,3, +0x7cc100,2, +0x7cc110,4, +0x7cd000,1, +0x7cd010,3, +0x7cd020,3, +0x7cd030,3, +0x7cd040,3, +0x7cd050,3, +0x7cd060,3, +0x7cd070,3, +0x7cd080,3, +0x7cd090,3, +0x7cd0a0,3, +0x7cd0b0,3, +0x7cd0c0,3, +0x7cd0d0,3, +0x7cd0e0,3, +0x7cd0f0,3, +0x7cd100,3, +0x7cd110,64, +0x7cd240,10, +0x7cd280,10, +0x7cd2c0,10, +0x7cd300,10, +0x7cd340,10, +0x7cd380,10, +0x7cd3c0,10, +0x7cd400,10, +0x7cd440,10, +0x7cd480,10, +0x7cd4c0,10, +0x7cd500,10, +0x7cd540,10, +0x7cd580,10, +0x7cd5c0,10, +0x7cd600,10, +0x7cd640,19, +0x7cd690,3, +0x7cd6a0,3, +0x7cd6b0,3, +0x7cd6c0,8, +0x7ce000,1, +0x7d0000,10, +0x7d0080,3, +0x7d0100,2, +0x7d0110,4, +0x7d0200,1, +0x7d0210,3, +0x7d0220,3, +0x7d0230,8, +0x7d0280,10, +0x7d02c0,10, +0x7d0300,2, +0x7d0310,3, +0x7d0320,2, +0x7d0400,1, +0x7d4000,36, +0x7d4800,10, +0x7d4880,3, +0x7d4900,2, +0x7d4910,4, +0x7d4980,1, +0x7d5000,10, 0x800000,3, 0x800010,3, 0x800020,1, @@ -13696,6 +15047,76 @@ 0x80e3e0,2, 0x80e3ec,3, 0x80e400,9, +0x820000,1, +0x821000,977, +0x822000,161, +0x823000,977, +0x824000,977, +0x825000,977, +0x826000,977, +0x827000,977, +0x828000,977, +0x829000,977, +0x82a000,977, +0x82b000,161, +0x82c000,13, +0x82c040,14, +0x82c080,20, +0x82c104,1, +0x82c10c,3, +0x82c200,13, +0x82c240,14, +0x82c280,20, +0x82c304,1, +0x82c30c,3, +0x82c400,13, +0x82c440,14, +0x82c480,20, +0x82c504,1, +0x82c50c,3, +0x82c600,13, +0x82c640,14, +0x82c680,20, +0x82c704,1, +0x82c70c,3, +0x82c800,13, +0x82c840,14, +0x82c880,20, +0x82c904,1, +0x82c90c,3, +0x82ca00,13, +0x82ca40,14, +0x82ca80,20, +0x82cb04,1, +0x82cb0c,3, +0x82cc00,13, +0x82cc40,14, +0x82cc80,20, +0x82cd04,1, +0x82cd0c,3, +0x82ce00,13, +0x82ce40,14, +0x82ce80,20, +0x82cf04,1, +0x82cf0c,3, +0x82d000,13, +0x82d040,14, +0x82d080,20, +0x82d104,1, +0x82d10c,3, +0x82d200,17, +0x82d250,2, +0x82d260,4, +0x82e000,1, +0x82e014,1, +0x82e01c,10, +0x82e060,9, +0x82e094,1, +0x82e09c,10, +0x82e0e0,15, +0x82e200,12, +0x82e240,9, +0x82e280,6, 0x880000,582, 0x881000,2, 0x881040,9, @@ -15424,7 +16845,7 @@ 0x9604c4,17, 0x960544,28, 0x9605c0,2, -0x9605cc,2, +0x9605cc,3, 0x9605e0,1, 0x9605e8,2, 0x960600,7, @@ -15445,6 +16866,7 @@ 0x960c00,1, 0x960c20,1, 0x960c28,7, +0x960c48,2, 0x964004,1, 0x96400c,13, 0x964044,1, @@ -15452,7 +16874,7 @@ 0x964084,1, 0x9640c0,16, 0x964104,1, -0x964138,18, +0x964134,19, 0x964184,1, 0x9641c0,16, 0x964204,19, @@ -15468,7 +16890,8 @@ 0x9644c0,1, 0x9644d0,4, 0x9644e4,1, -0x9644ec,1, +0x9644ec,4, +0x964500,3, 0x964804,1, 0x96480c,13, 0x964844,1, @@ -15476,7 +16899,7 @@ 0x964884,1, 0x9648c0,16, 0x964904,1, -0x964938,18, +0x964934,19, 0x964984,1, 0x9649c0,16, 0x964a04,19, @@ -15492,7 +16915,8 @@ 0x964cc0,1, 0x964cd0,4, 0x964ce4,1, -0x964cec,1, +0x964cec,4, +0x964d00,3, 0x965004,1, 0x96500c,13, 0x965044,1, @@ -15500,7 +16924,7 @@ 0x965084,1, 0x9650c0,16, 0x965104,1, -0x965138,18, +0x965134,19, 0x965184,1, 0x9651c0,16, 0x965204,19, @@ -15516,7 +16940,8 @@ 0x9654c0,1, 0x9654d0,4, 0x9654e4,1, -0x9654ec,1, +0x9654ec,4, +0x965500,3, 0x965804,1, 0x96580c,13, 0x965844,1, @@ -15524,7 +16949,7 @@ 0x965884,1, 0x9658c0,16, 0x965904,1, -0x965938,18, +0x965934,19, 0x965984,1, 0x9659c0,16, 0x965a04,19, @@ -15540,24 +16965,25 @@ 0x965cc0,1, 0x965cd0,4, 0x965ce4,1, -0x965cec,1, -0x966000,27, -0x966080,6, -0x9660a0,6, +0x965cec,4, +0x965d00,3, +0x966000,46, 0x9660c0,6, 0x9660e0,6, 0x966100,6, 0x966120,6, 0x966140,6, 0x966160,6, -0x966180,75, -0x9662b0,2, +0x966180,6, +0x9661c0,139, +0x9663f0,2, +0x966400,7, 0x968004,1, 0x968030,20, 0x968084,1, 0x9680c0,16, 0x968104,1, -0x968138,22, +0x968134,23, 0x968200,1, 0x96820c,1, 0x968240,1, @@ -15570,7 +16996,7 @@ 0x968484,1, 0x9684c0,16, 0x968504,1, -0x968538,22, +0x968534,23, 0x968600,1, 0x96860c,1, 0x968640,1, @@ -15583,7 +17009,7 @@ 0x968884,1, 0x9688c0,16, 0x968904,1, -0x968938,22, +0x968934,23, 0x968a00,1, 0x968a0c,1, 0x968a40,1, @@ -15596,7 +17022,7 @@ 0x968c84,1, 0x968cc0,16, 0x968d04,1, -0x968d38,22, +0x968d34,23, 0x968e00,1, 0x968e0c,1, 0x968e40,1, @@ -15614,142 +17040,176 @@ 0x96a100,2, 0x96a110,3, 0x96a120,3, -0x96a140,9, -0x96a16c,4, -0x96a180,1, -0x96a1c0,1, -0x96a1e0,10, -0x96a220,7, -0x96a240,1, -0x96a260,10, -0x96a400,1, -0x96a408,65, -0x96a510,65, -0x96a618,64, -0x96a800,8, -0x96a840,11, -0x96a880,1, -0x96a8a0,7, -0x96a8c4,1, -0x96a8cc,1, -0x96a900,18, -0x96a980,4, -0x96a9c0,9, -0x96aa00,3, -0x96ac00,7, -0x96ac40,2, -0x96ac64,1, -0x96ac74,5, -0x96acc0,20, -0x96ae00,6, -0x96ae20,1, -0x96b000,1, -0x96b020,1, -0x96b028,4, -0x96b040,6, -0x96b060,6, -0x96b080,3, -0x96b090,3, -0x96b0a0,3, -0x96b0b0,3, -0x96b0c0,3, -0x96b0d0,3, -0x96b0e0,3, -0x96b0f0,3, -0x96b100,3, -0x96b110,3, -0x96b120,3, -0x96b130,3, -0x96b140,3, -0x96b150,3, -0x96b160,3, -0x96b170,3, -0x96b180,3, -0x96b190,3, -0x96b1a0,3, -0x96b1b0,3, -0x96b1c0,3, -0x96b1d0,3, -0x96b1e0,3, -0x96b1f0,3, -0x96b200,3, -0x96b210,3, -0x96b220,3, -0x96b230,3, -0x96b240,3, -0x96b250,3, -0x96b260,3, -0x96b270,3, -0x96b280,3, -0x96b290,3, -0x96b2a0,3, -0x96b2b0,3, -0x96b2c0,3, -0x96b2d0,3, -0x96b2e0,3, -0x96b2f0,3, -0x96b300,3, -0x96b310,3, -0x96b320,3, -0x96b330,3, -0x96b340,3, -0x96b350,3, -0x96b360,3, -0x96b370,3, -0x96b380,3, -0x96b390,3, -0x96b3a0,3, -0x96b3b0,3, -0x96b3c0,3, -0x96b3d0,3, -0x96b3e0,3, -0x96b3f0,3, -0x96b400,3, -0x96b410,3, -0x96b420,3, -0x96b430,3, -0x96b440,3, -0x96b450,3, -0x96b460,3, -0x96b470,3, -0x96b484,42, -0x96b53c,12, -0x96b57c,1, -0x96b800,70, -0x96b920,32, -0x96ba04,4, -0x96ba20,9, -0x96ba48,7, -0x96ba68,3, -0x96ba80,2, -0x96baa4,10, -0x96bad0,2, -0x96bae0,1, -0x96baf0,11, -0x96bb24,1, -0x96bb2c,1, -0x96bb40,1, -0x96bb60,10, -0x96bb94,1, -0x96bb9c,3, -0x96bbb0,17, -0x96bbfc,8, -0x96bc20,1, -0x96bc28,4, -0x96bc40,1, -0x96bc48,2, -0x96bc80,4, -0x96bcc0,10, -0x96bd00,5, -0x96bd20,5, -0x96bd40,5, -0x96bd60,5, -0x96bd80,5, -0x96bda0,5, -0x96bdc0,21, -0x96c000,4, -0x96c040,9, -0x96c080,5, +0x96a140,1, +0x96a14c,1, +0x96a160,1, +0x96a170,11, +0x96a1a0,1, +0x96a1b0,19, +0x96a200,7, +0x96a224,1, +0x96a22c,1, +0x96a240,20, +0x96a2c0,9, +0x96a300,3, +0x96a310,3, +0x96a320,3, +0x96a330,2, +0x96a340,14, +0x96a380,3, +0x96a390,2, +0x96a404,1, +0x96a414,11, +0x96a444,1, +0x96a458,10, +0x96a484,1, +0x96a494,7, +0x96a500,2, +0x96a510,3, +0x96a520,3, +0x96a540,1, +0x96a54c,1, +0x96a560,1, +0x96a570,11, +0x96a5a0,1, +0x96a5b0,19, +0x96a600,7, +0x96a624,1, +0x96a62c,1, +0x96a640,20, +0x96a6c0,9, +0x96a700,3, +0x96a710,3, +0x96a720,3, +0x96a730,2, +0x96a740,14, +0x96a780,3, +0x96a790,2, +0x96a800,9, +0x96a828,4, +0x96ac00,1, +0x96ac08,65, +0x96ad10,65, +0x96ae18,64, +0x96b000,3, +0x96b200,34, +0x96b2c0,2, +0x96b2e4,1, +0x96b2f4,5, +0x96b324,1, +0x96b334,5, +0x96b380,20, +0x96b400,13, +0x96c000,1, +0x96c020,1, +0x96c028,4, +0x96c040,6, +0x96c060,6, +0x96c080,3, +0x96c090,3, +0x96c0a0,3, +0x96c0b0,3, +0x96c0c0,3, +0x96c0d0,3, +0x96c0e0,3, +0x96c0f0,3, +0x96c100,3, +0x96c110,3, +0x96c120,3, +0x96c130,3, +0x96c140,3, +0x96c150,3, +0x96c160,3, +0x96c170,3, +0x96c180,3, +0x96c190,3, +0x96c1a0,3, +0x96c1b0,3, +0x96c1c0,3, +0x96c1d0,3, +0x96c1e0,3, +0x96c1f0,3, +0x96c200,3, +0x96c210,3, +0x96c220,3, +0x96c230,3, +0x96c240,3, +0x96c250,3, +0x96c260,3, +0x96c270,3, +0x96c280,3, +0x96c290,3, +0x96c2a0,3, +0x96c2b0,3, +0x96c2c0,3, +0x96c2d0,3, +0x96c2e0,3, +0x96c2f0,3, +0x96c300,3, +0x96c310,3, +0x96c320,3, +0x96c330,3, +0x96c340,3, +0x96c350,3, +0x96c360,3, +0x96c370,3, +0x96c380,3, +0x96c390,3, +0x96c3a0,3, +0x96c3b0,3, +0x96c3c0,3, +0x96c3d0,3, +0x96c3e0,3, +0x96c3f0,3, +0x96c400,3, +0x96c410,3, +0x96c420,3, +0x96c430,3, +0x96c440,3, +0x96c450,3, +0x96c460,3, +0x96c470,3, +0x96c484,42, +0x96c53c,12, +0x96c57c,1, +0x96c800,70, +0x96c920,32, +0x96ca04,4, +0x96ca20,9, +0x96ca48,7, +0x96ca68,3, +0x96ca80,2, +0x96caa4,10, +0x96cad0,2, +0x96cae0,1, +0x96caf0,11, +0x96cb24,1, +0x96cb2c,1, +0x96cb40,1, +0x96cb60,10, +0x96cb94,1, +0x96cb9c,3, +0x96cbb0,17, +0x96cbfc,8, +0x96cc20,1, +0x96cc28,4, +0x96cc40,1, +0x96cc48,2, +0x96cc80,4, +0x96ccc0,10, +0x96cd00,5, +0x96cd20,5, +0x96cd40,5, +0x96cd60,5, +0x96cd80,5, +0x96cda0,5, +0x96cdc0,21, +0x96ce18,2, +0x96d000,4, +0x96d040,9, +0x96d080,5, +0x96d0a0,3, +0x96d0b0,1, 0x970000,1, 0x970008,4, 0x970020,1, @@ -15810,267 +17270,272 @@ 0x971880,6, 0x9718a0,6, 0x9718c0,19, -0x972000,22, +0x972000,10, +0x972040,10, 0x972080,10, -0x9720c0,9, -0x972100,2, -0x97210c,2, -0x972120,1, -0x972128,4, -0x972400,27, -0x972480,4, -0x9724c0,25, -0x972540,6, -0x972560,2, -0x97256c,3, -0x972600,8, -0x972624,47, -0x972800,137, -0x972a30,4, -0x972c00,6, -0x972c20,3, -0x972c30,6, -0x972c60,8, -0x980000,1, -0x980080,17, -0x980100,37, -0x980200,1, -0x980210,11, -0x980240,1, -0x980280,1, -0x980288,4, -0x9802a0,4, -0x9802c0,1, -0x980300,2, -0x980400,15, -0x980440,4, -0x980460,17, -0x9804c0,6, -0x9804e0,2, -0x9804ec,3, -0x980500,8, -0x980524,4, -0x980600,12, -0x981000,1, -0x981080,17, -0x981100,37, -0x981200,1, -0x981210,11, -0x981240,1, -0x981280,1, -0x981288,4, -0x9812a0,4, -0x9812c0,1, -0x981300,2, -0x981400,15, -0x981440,4, -0x981460,17, -0x9814c0,6, -0x9814e0,2, -0x9814ec,3, -0x981500,8, -0x981524,4, -0x981600,12, -0x982000,1, -0x982080,17, -0x982100,37, -0x982200,1, -0x982210,11, -0x982240,1, -0x982280,1, -0x982288,4, -0x9822a0,4, -0x9822c0,1, -0x982300,2, -0x982400,15, -0x982440,4, -0x982460,17, -0x9824c0,6, -0x9824e0,2, -0x9824ec,3, -0x982500,8, -0x982524,4, -0x982600,12, -0x983000,1, -0x983080,17, -0x983100,37, -0x983200,1, -0x983210,11, -0x983240,1, -0x983280,1, -0x983288,4, -0x9832a0,4, -0x9832c0,1, -0x983300,2, -0x983400,15, -0x983440,4, -0x983460,17, -0x9834c0,6, -0x9834e0,2, -0x9834ec,3, -0x983500,8, -0x983524,4, -0x983600,12, -0x984000,1, -0x984080,17, -0x984100,37, -0x984200,1, -0x984210,11, -0x984240,1, -0x984280,1, -0x984288,4, -0x9842a0,4, -0x9842c0,1, -0x984300,2, -0x984400,15, -0x984440,4, -0x984460,17, -0x9844c0,6, -0x9844e0,2, -0x9844ec,3, -0x984500,8, -0x984524,4, -0x984600,12, -0x985000,1, -0x985080,17, -0x985100,37, -0x985200,1, -0x985210,11, -0x985240,1, -0x985280,1, -0x985288,4, -0x9852a0,4, -0x9852c0,1, -0x985300,2, -0x985400,15, -0x985440,4, -0x985460,17, -0x9854c0,6, -0x9854e0,2, -0x9854ec,3, -0x985500,8, -0x985524,4, -0x985600,12, -0x986000,1, -0x986080,17, -0x986100,37, -0x986200,1, -0x986210,11, -0x986240,1, -0x986280,1, -0x986288,4, -0x9862a0,4, -0x9862c0,1, -0x986300,2, -0x986400,15, -0x986440,4, -0x986460,17, -0x9864c0,6, -0x9864e0,2, -0x9864ec,3, -0x986500,8, -0x986524,4, -0x986600,12, -0x987000,1, -0x987080,17, -0x987100,37, -0x987200,1, -0x987210,11, -0x987240,1, -0x987280,1, -0x987288,4, -0x9872a0,4, -0x9872c0,1, -0x987300,2, -0x987400,15, -0x987440,4, -0x987460,17, -0x9874c0,6, -0x9874e0,2, -0x9874ec,3, -0x987500,8, -0x987524,4, -0x987600,12, +0x9720c0,10, +0x972100,10, +0x972140,10, +0x972180,10, +0x9721c0,10, +0x972200,10, +0x972240,10, +0x972280,10, +0x972400,10, +0x972440,10, +0x972480,10, +0x9724c0,10, +0x972500,2, +0x972600,9, +0x972640,2, +0x97264c,2, +0x972660,1, +0x972668,4, +0x972800,27, +0x972880,4, +0x9728c0,25, +0x972940,6, +0x972960,2, +0x97296c,3, +0x972a00,8, +0x972a24,57, +0x972c00,137, +0x972e30,4, +0x973000,6, +0x973020,3, +0x973030,6, +0x973060,8, +0x980004,1, +0x98001c,25, +0x980084,1, +0x9800bc,19, +0x980204,1, +0x98027c,62, +0x980380,29, +0x980400,4, +0x980480,29, +0x980504,1, +0x98053c,20, +0x980600,2, +0x980614,1, +0x98061c,3, +0x980634,1, +0x98063c,14, +0x980678,14, +0x9806c0,19, +0x980804,1, +0x98081c,25, +0x980884,1, +0x9808bc,19, +0x980a04,1, +0x980a7c,62, +0x980b80,29, +0x980c00,4, +0x980c80,29, +0x980d04,1, +0x980d3c,20, +0x980e00,2, +0x980e14,1, +0x980e1c,3, +0x980e34,1, +0x980e3c,14, +0x980e78,14, +0x980ec0,19, +0x981004,1, +0x98101c,25, +0x981084,1, +0x9810bc,19, +0x981204,1, +0x98127c,62, +0x981380,29, +0x981400,4, +0x981480,29, +0x981504,1, +0x98153c,20, +0x981600,2, +0x981614,1, +0x98161c,3, +0x981634,1, +0x98163c,14, +0x981678,14, +0x9816c0,19, +0x981804,1, +0x98181c,25, +0x981884,1, +0x9818bc,19, +0x981a04,1, +0x981a7c,62, +0x981b80,29, +0x981c00,4, +0x981c80,29, +0x981d04,1, +0x981d3c,20, +0x981e00,2, +0x981e14,1, +0x981e1c,3, +0x981e34,1, +0x981e3c,14, +0x981e78,14, +0x981ec0,19, +0x982004,1, +0x98201c,25, +0x982084,1, +0x9820bc,19, +0x982204,1, +0x98227c,62, +0x982380,29, +0x982400,4, +0x982480,29, +0x982504,1, +0x98253c,20, +0x982600,2, +0x982614,1, +0x98261c,3, +0x982634,1, +0x98263c,14, +0x982678,14, +0x9826c0,19, +0x982804,1, +0x98281c,25, +0x982884,1, +0x9828bc,19, +0x982a04,1, +0x982a7c,62, +0x982b80,29, +0x982c00,4, +0x982c80,29, +0x982d04,1, +0x982d3c,20, +0x982e00,2, +0x982e14,1, +0x982e1c,3, +0x982e34,1, +0x982e3c,14, +0x982e78,14, +0x982ec0,19, +0x983004,1, +0x98301c,25, +0x983084,1, +0x9830bc,19, +0x983204,1, +0x98327c,62, +0x983380,29, +0x983400,4, +0x983480,29, +0x983504,1, +0x98353c,20, +0x983600,2, +0x983614,1, +0x98361c,3, +0x983634,1, +0x98363c,14, +0x983678,14, +0x9836c0,19, +0x983804,1, +0x98381c,25, +0x983884,1, +0x9838bc,19, +0x983a04,1, +0x983a7c,62, +0x983b80,29, +0x983c00,4, +0x983c80,29, +0x983d04,1, +0x983d3c,20, +0x983e00,2, +0x983e14,1, +0x983e1c,3, +0x983e34,1, +0x983e3c,14, +0x983e78,14, +0x983ec0,19, +0x984000,160, +0x984284,1, +0x9842a0,8, +0x9842c4,1, +0x9842d4,3, +0x984300,21, +0x984380,21, +0x984400,21, +0x984480,21, +0x984500,4, +0x984580,21, +0x984600,4, +0x984680,21, +0x984700,19, +0x984780,19, +0x984800,19, +0x984880,19, +0x984900,19, +0x984980,19, +0x984a00,19, +0x984a80,19, +0x984b00,19, +0x984b80,19, +0x984c00,19, +0x984c80,19, +0x984d00,19, +0x984d80,19, +0x984e00,19, +0x984e80,19, +0x984f00,4, +0x984f80,19, +0x985000,4, +0x985080,19, +0x985100,4, +0x985180,19, +0x985200,4, +0x985280,19, +0x985300,4, +0x985380,19, +0x985400,4, +0x985480,19, +0x985500,4, +0x985580,19, +0x985600,4, +0x985680,19, +0x985700,12, +0x985740,1, 0x988000,1, -0x988080,17, -0x988100,37, -0x988200,1, -0x988210,11, -0x988240,1, -0x988280,1, -0x988288,4, -0x9882a0,4, -0x9882c0,1, -0x988300,2, -0x988400,15, -0x988440,4, -0x988460,17, -0x9884c0,6, -0x9884e0,2, -0x9884ec,3, -0x988500,8, -0x988524,4, -0x988600,12, -0x989000,1, -0x989080,17, -0x989100,37, -0x989200,1, -0x989210,11, -0x989240,1, -0x989280,1, -0x989288,4, -0x9892a0,4, -0x9892c0,1, -0x989300,2, -0x989400,15, -0x989440,4, -0x989460,17, -0x9894c0,6, -0x9894e0,2, -0x9894ec,3, -0x989500,8, -0x989524,4, -0x989600,12, +0x988024,6, +0x988040,1, +0x988050,8, +0x988200,2, +0x988280,10, +0x9882c0,10, +0x988300,4, +0x988340,10, +0x988400,2, +0x988800,1, +0x988824,6, +0x988840,1, +0x988850,8, +0x988a00,2, +0x988a80,10, +0x988ac0,10, +0x988b00,4, +0x988b40,10, +0x988c00,2, +0x989000,42, +0x9890c0,7, +0x9890e0,6, +0x989100,15, +0x989200,108, +0x989400,6, 0x98a000,1, -0x98a080,17, -0x98a100,37, -0x98a200,1, -0x98a210,11, -0x98a240,1, -0x98a280,1, -0x98a288,4, -0x98a2a0,4, -0x98a2c0,1, -0x98a300,2, -0x98a400,15, -0x98a440,4, -0x98a460,17, -0x98a4c0,6, -0x98a4e0,2, -0x98a4ec,3, -0x98a500,8, -0x98a524,4, -0x98a600,12, -0x98b000,1, -0x98b080,17, -0x98b100,37, -0x98b200,1, -0x98b210,11, -0x98b240,1, -0x98b280,1, -0x98b288,4, -0x98b2a0,4, -0x98b2c0,1, -0x98b300,2, -0x98b400,15, -0x98b440,4, -0x98b460,17, -0x98b4c0,6, -0x98b4e0,2, -0x98b4ec,3, -0x98b500,8, -0x98b524,4, -0x98b600,12, +0x98a800,129, +0x98ac00,16, +0x98ac44,1, +0x98ac4c,2, +0x98ac58,2, +0x98b000,23, +0x98b080,23, +0x98b100,4, +0x98b180,23, +0x98b204,11, +0x98b404,1, +0x98b410,10, +0x98b440,8, 0x98c000,1, 0x98c080,17, 0x98c100,37, @@ -16151,378 +17616,453 @@ 0x98f500,8, 0x98f524,4, 0x98f600,12, -0x990004,1, -0x99001c,25, -0x990084,1, -0x9900bc,19, -0x990204,1, -0x99027c,62, -0x990380,29, -0x990400,4, -0x990480,29, -0x990504,1, -0x99053c,20, -0x990600,2, -0x990614,1, -0x99061c,3, -0x990634,1, -0x99063c,1, -0x990644,16, -0x990688,25, -0x990804,1, -0x99081c,25, -0x990884,1, -0x9908bc,19, -0x990a04,1, -0x990a7c,62, -0x990b80,29, -0x990c00,4, -0x990c80,29, -0x990d04,1, -0x990d3c,20, -0x990e00,2, -0x990e14,1, -0x990e1c,3, -0x990e34,1, -0x990e3c,1, -0x990e44,16, -0x990e88,25, -0x991004,1, -0x99101c,25, -0x991084,1, -0x9910bc,19, -0x991204,1, -0x99127c,62, -0x991380,29, -0x991400,4, -0x991480,29, -0x991504,1, -0x99153c,20, -0x991600,2, -0x991614,1, -0x99161c,3, -0x991634,1, -0x99163c,1, -0x991644,16, -0x991688,25, -0x991804,1, -0x99181c,25, -0x991884,1, -0x9918bc,19, -0x991a04,1, -0x991a7c,62, -0x991b80,29, -0x991c00,4, -0x991c80,29, -0x991d04,1, -0x991d3c,20, -0x991e00,2, -0x991e14,1, -0x991e1c,3, -0x991e34,1, -0x991e3c,1, -0x991e44,16, -0x991e88,25, -0x992004,1, -0x99201c,25, -0x992084,1, -0x9920bc,19, -0x992204,1, -0x99227c,62, -0x992380,29, -0x992400,4, -0x992480,29, -0x992504,1, -0x99253c,20, -0x992600,2, -0x992614,1, -0x99261c,3, -0x992634,1, -0x99263c,1, -0x992644,16, -0x992688,25, -0x992804,1, -0x99281c,25, -0x992884,1, -0x9928bc,19, -0x992a04,1, -0x992a7c,62, -0x992b80,29, -0x992c00,4, -0x992c80,29, -0x992d04,1, -0x992d3c,20, -0x992e00,2, -0x992e14,1, -0x992e1c,3, -0x992e34,1, -0x992e3c,1, -0x992e44,16, -0x992e88,25, -0x993004,1, -0x99301c,25, -0x993084,1, -0x9930bc,19, -0x993204,1, -0x99327c,62, -0x993380,29, -0x993400,4, -0x993480,29, -0x993504,1, -0x99353c,20, -0x993600,2, -0x993614,1, -0x99361c,3, -0x993634,1, -0x99363c,1, -0x993644,16, -0x993688,25, -0x993804,1, -0x99381c,25, -0x993884,1, -0x9938bc,19, -0x993a04,1, -0x993a7c,62, -0x993b80,29, -0x993c00,4, -0x993c80,29, -0x993d04,1, -0x993d3c,20, -0x993e00,2, -0x993e14,1, -0x993e1c,3, -0x993e34,1, -0x993e3c,1, -0x993e44,16, -0x993e88,25, -0x994000,160, -0x994284,1, -0x9942a0,8, -0x9942c4,1, -0x9942d4,3, -0x994300,21, -0x994380,21, -0x994400,21, -0x994480,21, -0x994500,4, -0x994580,21, -0x994600,4, -0x994680,21, -0x994700,19, -0x994780,19, -0x994800,4, -0x994880,19, -0x998000,3, -0x998010,3, -0x998020,3, -0x998030,3, -0x998040,3, -0x998050,3, -0x998060,3, -0x998070,3, -0x998080,3, -0x998090,3, -0x9980a0,3, -0x9980b0,3, -0x9980c0,3, -0x9980d0,3, -0x9980e0,3, -0x9980f0,3, -0x998100,3, -0x998110,3, -0x998120,50, -0x998200,292, -0x9986a0,12, -0x9986e0,12, -0x998720,12, -0x998760,12, -0x9987a0,12, -0x9987e0,12, -0x998820,12, -0x998860,12, -0x9988a0,12, -0x9988e0,12, -0x998920,12, -0x998960,12, -0x9989a0,12, -0x9989e0,12, -0x998a20,12, -0x998a60,12, -0x998aa0,12, -0x998ae0,86, -0x998c40,6, -0x998c60,6, -0x998c80,6, -0x998ca0,6, -0x998cc0,6, -0x998ce0,6, -0x998d00,6, -0x998d20,6, -0x998d40,6, -0x998d60,6, -0x998d80,6, -0x998da0,6, -0x998dc0,6, -0x998de0,6, -0x998e00,6, -0x998e20,6, -0x998e40,6, -0x998e60,2, -0x999000,78, -0x999140,212, -0x9994a0,12, -0x9994e0,12, -0x999520,12, -0x999560,12, -0x9995a0,12, -0x9995e0,12, -0x999620,12, -0x999660,12, -0x9996a0,12, -0x9996e0,12, -0x999720,12, -0x999760,12, -0x9997a0,9, -0x999804,1, -0x999820,24, -0x999884,1, -0x999894,6, -0x9998b0,3, -0x9998c0,3, -0x9998d0,3, -0x9998e0,3, -0x9998f0,3, -0x999900,3, -0x999910,3, -0x999920,3, -0x999930,3, -0x999940,3, -0x999950,3, -0x999960,3, -0x999970,3, -0x999980,3, -0x999990,3, -0x9999a0,3, +0x990000,1, +0x990080,17, +0x990100,37, +0x990200,1, +0x990210,11, +0x990240,1, +0x990280,1, +0x990288,4, +0x9902a0,4, +0x9902c0,1, +0x990300,2, +0x990400,15, +0x990440,4, +0x990460,17, +0x9904c0,6, +0x9904e0,2, +0x9904ec,3, +0x990500,8, +0x990524,4, +0x990600,12, +0x991000,1, +0x991080,17, +0x991100,37, +0x991200,1, +0x991210,11, +0x991240,1, +0x991280,1, +0x991288,4, +0x9912a0,4, +0x9912c0,1, +0x991300,2, +0x991400,15, +0x991440,4, +0x991460,17, +0x9914c0,6, +0x9914e0,2, +0x9914ec,3, +0x991500,8, +0x991524,4, +0x991600,12, +0x992000,1, +0x992080,17, +0x992100,37, +0x992200,1, +0x992210,11, +0x992240,1, +0x992280,1, +0x992288,4, +0x9922a0,4, +0x9922c0,1, +0x992300,2, +0x992400,15, +0x992440,4, +0x992460,17, +0x9924c0,6, +0x9924e0,2, +0x9924ec,3, +0x992500,8, +0x992524,4, +0x992600,12, +0x993000,1, +0x993080,17, +0x993100,37, +0x993200,1, +0x993210,11, +0x993240,1, +0x993280,1, +0x993288,4, +0x9932a0,4, +0x9932c0,1, +0x993300,2, +0x993400,15, +0x993440,4, +0x993460,17, +0x9934c0,6, +0x9934e0,2, +0x9934ec,3, +0x993500,8, +0x993524,4, +0x993600,12, +0x994000,1, +0x994080,17, +0x994100,37, +0x994200,1, +0x994210,11, +0x994240,1, +0x994280,1, +0x994288,4, +0x9942a0,4, +0x9942c0,1, +0x994300,2, +0x994400,15, +0x994440,4, +0x994460,17, +0x9944c0,6, +0x9944e0,2, +0x9944ec,3, +0x994500,8, +0x994524,4, +0x994600,12, +0x995000,1, +0x995080,17, +0x995100,37, +0x995200,1, +0x995210,11, +0x995240,1, +0x995280,1, +0x995288,4, +0x9952a0,4, +0x9952c0,1, +0x995300,2, +0x995400,15, +0x995440,4, +0x995460,17, +0x9954c0,6, +0x9954e0,2, +0x9954ec,3, +0x995500,8, +0x995524,4, +0x995600,12, +0x996000,1, +0x996080,17, +0x996100,37, +0x996200,1, +0x996210,11, +0x996240,1, +0x996280,1, +0x996288,4, +0x9962a0,4, +0x9962c0,1, +0x996300,2, +0x996400,15, +0x996440,4, +0x996460,17, +0x9964c0,6, +0x9964e0,2, +0x9964ec,3, +0x996500,8, +0x996524,4, +0x996600,12, +0x997000,1, +0x997080,17, +0x997100,37, +0x997200,1, +0x997210,11, +0x997240,1, +0x997280,1, +0x997288,4, +0x9972a0,4, +0x9972c0,1, +0x997300,2, +0x997400,15, +0x997440,4, +0x997460,17, +0x9974c0,6, +0x9974e0,2, +0x9974ec,3, +0x997500,8, +0x997524,4, +0x997600,12, +0x998000,1, +0x998080,17, +0x998100,37, +0x998200,1, +0x998210,11, +0x998240,1, +0x998280,1, +0x998288,4, +0x9982a0,4, +0x9982c0,1, +0x998300,2, +0x998400,15, +0x998440,4, +0x998460,17, +0x9984c0,6, +0x9984e0,2, +0x9984ec,3, +0x998500,8, +0x998524,4, +0x998600,12, +0x999000,1, +0x999080,17, +0x999100,37, +0x999200,1, +0x999210,11, +0x999240,1, +0x999280,1, +0x999288,4, +0x9992a0,4, +0x9992c0,1, +0x999300,2, +0x999400,15, +0x999440,4, +0x999460,17, +0x9994c0,6, +0x9994e0,2, +0x9994ec,3, +0x999500,8, +0x999524,4, +0x999600,12, 0x99a000,1, -0x99a024,6, -0x99a040,1, -0x99a050,8, -0x99a200,2, -0x99a280,10, -0x99a2c0,10, -0x99a300,4, -0x99a340,10, -0x99a400,2, -0x99a800,1, -0x99a824,6, -0x99a840,1, -0x99a850,8, -0x99aa00,2, -0x99aa80,10, -0x99aac0,10, -0x99ab00,4, -0x99ab40,10, -0x99ac00,2, -0x99b000,42, -0x99b0c0,7, -0x99b0e0,6, -0x99b100,21, -0x99c000,1, -0x99c800,129, -0x99cc00,16, -0x99cc44,1, -0x99cc4c,2, -0x99cc58,2, -0x99d000,23, -0x99d080,23, -0x99d100,4, -0x99d180,23, -0x99d204,11, -0x99d404,1, -0x99d410,10, -0x99e000,12, -0x99e084,1, -0x99e09c,12, -0x99e100,21, -0x99e180,21, -0x99e200,4, -0x99e280,21, -0x99e400,34, -0x99e500,34, -0x99e600,4, -0x99e700,34, +0x99a080,17, +0x99a100,37, +0x99a200,1, +0x99a210,11, +0x99a240,1, +0x99a280,1, +0x99a288,4, +0x99a2a0,4, +0x99a2c0,1, +0x99a300,2, +0x99a400,15, +0x99a440,4, +0x99a460,17, +0x99a4c0,6, +0x99a4e0,2, +0x99a4ec,3, +0x99a500,8, +0x99a524,4, +0x99a600,12, +0x99b000,1, +0x99b080,17, +0x99b100,37, +0x99b200,1, +0x99b210,11, +0x99b240,1, +0x99b280,1, +0x99b288,4, +0x99b2a0,4, +0x99b2c0,1, +0x99b300,2, +0x99b400,15, +0x99b440,4, +0x99b460,17, +0x99b4c0,6, +0x99b4e0,2, +0x99b4ec,3, +0x99b500,8, +0x99b524,4, +0x99b600,12, +0x99c000,3, +0x99c010,3, +0x99c020,3, +0x99c030,3, +0x99c040,3, +0x99c050,3, +0x99c060,3, +0x99c070,3, +0x99c080,3, +0x99c090,3, +0x99c0a0,3, +0x99c0b0,3, +0x99c0c0,3, +0x99c0d0,3, +0x99c0e0,3, +0x99c0f0,3, +0x99c100,3, +0x99c110,3, +0x99c120,18, +0x99c180,289, +0x99c800,78, +0x99ca04,1, +0x99ca20,24, +0x99ca84,1, +0x99ca94,3, +0x99cb00,52, +0x99cc00,3, +0x99cc10,3, +0x99cc20,3, +0x99cc30,3, +0x99cc40,3, +0x99cc50,3, +0x99cc60,3, +0x99cc70,3, +0x99cc80,3, +0x99cc90,3, +0x99cca0,3, +0x99ccb0,3, +0x99ccc0,3, +0x99ccd0,3, +0x99cce0,3, +0x99ccf0,3, +0x99cd00,3, +0x99cd10,1, +0x99d000,12, +0x99d084,1, +0x99d09c,12, +0x99d100,21, +0x99d180,21, +0x99d200,4, +0x99d280,21, +0x99d400,34, +0x99d500,34, +0x99d600,4, +0x99d700,34, +0x99d800,1, +0x99d820,8, +0x99e000,3, +0x99e200,36, +0x99e300,36, +0x99e400,4, +0x99e500,36, +0x99e600,7, +0x99e620,1, 0x99e800,1, +0x99e810,8, +0x99e840,3, +0x99e850,2, +0x99e880,9, +0x99e8c0,2, +0x99e904,1, +0x99e914,6, +0x99e940,20, 0x99f000,3, -0x99f200,36, -0x99f300,36, -0x99f400,4, -0x99f500,36, -0x99f600,7, -0x99f620,1, -0x99f800,1, -0x99f810,8, -0x99f840,3, -0x99f850,2, -0x99f880,9, -0x99f8c0,2, -0x99f904,1, -0x99f914,6, -0x99f940,20, -0x9a0000,3, -0x9a0080,10, -0x9a00c0,10, -0x9a0100,4, -0x9a0140,10, -0x9a0180,20, -0x9a01e0,11, -0x9a0210,3, -0x9a0220,7, -0x9a0240,1, +0x99f080,10, +0x99f0c0,10, +0x99f100,4, +0x99f140,10, +0x99f180,20, +0x99f1e0,11, +0x99f210,3, +0x99f220,7, +0x99f240,1, +0x99f400,1, +0x99f408,2, +0x99f424,3, +0x99f434,4, +0x99f448,7, +0x99f468,9, +0x99f810,26, +0x99f880,17, +0x99f8d0,13, +0x99f940,80, +0x99fc00,27, +0x99fc80,4, +0x99fcc0,25, +0x99fd40,6, +0x99fd60,2, +0x99fd6c,3, +0x99fe04,88, +0x9a0000,14, +0x9a0040,7, +0x9a0060,7, +0x9a0080,4, +0x9a00a0,7, +0x9a00c0,1, +0x9a0104,3, +0x9a0114,1, +0x9a011c,4, +0x9a0130,8, +0x9a0200,5, +0x9a0220,2, +0x9a0244,1, +0x9a0254,6, +0x9a0280,8, +0x9a02c0,3, +0x9a02d0,3, +0x9a02e0,7, +0x9a0300,36, 0x9a0400,1, -0x9a0408,2, -0x9a0424,3, -0x9a0434,4, -0x9a0448,7, -0x9a0468,9, -0x9a0810,26, -0x9a0880,17, -0x9a08d0,13, -0x9a0940,80, -0x9a0c00,14, -0x9a0c40,6, -0x9a0c60,6, -0x9a0c80,4, -0x9a0ca0,6, -0x9a0cc0,17, -0x9a0e04,5, -0x9a0e24,1, -0x9a0e2c,1, -0x9a0e40,3, -0x9a0e50,8, -0x9a1000,27, -0x9a1080,4, -0x9a10c0,25, -0x9a1140,6, -0x9a1160,2, -0x9a116c,3, -0x9a1204,85, -0x9a1400,5, -0x9a1420,2, -0x9a1444,1, -0x9a1454,6, -0x9a1480,8, -0x9a14c0,3, -0x9a14d0,3, -0x9a14e0,7, -0x9a1500,1, -0x9a1508,8, -0x9a1540,2, -0x9c0000,164, -0x9c0400,132, -0x9c0800,1, -0x9c0808,18, -0x9c0880,12, -0x9c08c0,4, +0x9a0408,4, +0x9a0420,4, +0x9a0440,1, +0x9a0448,4, +0x9a0460,4, +0x9a0480,1, +0x9a0488,8, +0x9a04c0,8, +0x9a0500,2, +0x9c0000,1, +0x9c0008,4, +0x9c0020,4, +0x9c0040,1, +0x9c0048,4, +0x9c0060,4, +0x9c0080,17, +0x9c4004,1, +0x9c401c,25, +0x9c4084,1, +0x9c40bc,19, +0x9c4204,1, +0x9c427c,62, +0x9c4380,29, +0x9c4400,4, +0x9c4480,29, +0x9c4504,1, +0x9c453c,20, +0x9c4600,2, +0x9c4614,1, +0x9c461c,3, +0x9c4634,1, +0x9c463c,14, +0x9c4678,14, +0x9c46c0,19, +0x9c4804,1, +0x9c481c,25, +0x9c4884,1, +0x9c48bc,19, +0x9c4a04,1, +0x9c4a7c,62, +0x9c4b80,29, +0x9c4c00,4, +0x9c4c80,29, +0x9c4d04,1, +0x9c4d3c,20, +0x9c4e00,2, +0x9c4e14,1, +0x9c4e1c,3, +0x9c4e34,1, +0x9c4e3c,14, +0x9c4e78,14, +0x9c4ec0,19, +0x9c5000,141, +0x9c5244,1, +0x9c5260,8, +0x9c5284,1, +0x9c5294,3, +0x9c5300,21, +0x9c5380,21, +0x9c5400,21, +0x9c5480,21, +0x9c5500,4, +0x9c5580,21, +0x9c5600,4, +0x9c5680,21, +0x9c5700,19, +0x9c5780,19, +0x9c5800,19, +0x9c5880,19, +0x9c5900,4, +0x9c5980,19, +0x9c5a00,4, +0x9c5a80,19, +0x9c5b00,12, +0x9c6000,8, +0x9c8000,24, +0x9d0000,27, +0x9d0080,4, +0x9d00c0,25, +0x9d0140,6, +0x9d0160,2, +0x9d016c,3, +0x9d0184,11, +0x9d0200,4, +0x9e0000,1, +0x9e0008,18, +0x9e0080,29, 0x1000004,3, 0x1000014,3, 0x1000024,1, @@ -16582,7 +18122,8 @@ 0x1000960,2, 0x100096c,3, 0x100097c,1, -0x1000a00,6, +0x1000a00,1, +0x1000a10,6, 0x11d0000,2, 0x11d000c,1, 0x11d0014,1, @@ -16854,7 +18395,8 @@ 0x1200960,2, 0x120096c,3, 0x120097c,1, -0x1200a00,6, +0x1200a00,1, +0x1200a10,6, 0x13d0000,2, 0x13d000c,1, 0x13d0014,1, @@ -17126,7 +18668,8 @@ 0x1400960,2, 0x140096c,3, 0x140097c,1, -0x1400a00,6, +0x1400a00,1, +0x1400a10,6, 0x15d0000,2, 0x15d000c,1, 0x15d0014,1, @@ -17398,7 +18941,8 @@ 0x1600960,2, 0x160096c,3, 0x160097c,1, -0x1600a00,6, +0x1600a00,1, +0x1600a10,6, 0x17d0000,2, 0x17d000c,1, 0x17d0014,1, @@ -17670,7 +19214,8 @@ 0x1800960,2, 0x180096c,3, 0x180097c,1, -0x1800a00,6, +0x1800a00,1, +0x1800a10,6, 0x19d0000,2, 0x19d000c,1, 0x19d0014,1, @@ -17942,7 +19487,8 @@ 0x1a00960,2, 0x1a0096c,3, 0x1a0097c,1, -0x1a00a00,6, +0x1a00a00,1, +0x1a00a10,6, 0x1bd0000,2, 0x1bd000c,1, 0x1bd0014,1, @@ -18214,7 +19760,8 @@ 0x1c00960,2, 0x1c0096c,3, 0x1c0097c,1, -0x1c00a00,6, +0x1c00a00,1, +0x1c00a10,6, 0x1dd0000,2, 0x1dd000c,1, 0x1dd0014,1, @@ -18486,7 +20033,8 @@ 0x1e00960,2, 0x1e0096c,3, 0x1e0097c,1, -0x1e00a00,6, +0x1e00a00,1, +0x1e00a10,6, 0x1fd0000,2, 0x1fd000c,1, 0x1fd0014,1, @@ -19740,6 +21288,9 @@ 0x300052c,1, 0x3000534,1, 0x300053c,3, +0x300054c,1, +0x3000554,1, +0x300055c,1, 0x3000564,1, 0x3000574,1, 0x300057c,1, @@ -19774,51 +21325,60 @@ 0x3000964,1, 0x300096c,1, 0x3000974,1, +0x300097c,1, 0x3000984,1, 0x300098c,1, -0x30009a4,1, -0x30009ac,1, +0x3000994,1, +0x300099c,1, 0x30009b4,1, +0x30009bc,1, +0x30009c4,1, 0x3000c04,3, -0x3000c20,12, +0x3000c40,14, 0x3000dc4,1, 0x3000e00,2, 0x3000f04,3, 0x3000f14,33, -0x3001000,2, -0x3002004,1, +0x3001004,1, +0x3002000,2, 0x3004000,2, -0x3005004,1, -0x3005080,2, -0x3006080,2, -0x3006104,1, -0x3006180,2, -0x300618c,1, -0x3006194,1, -0x300619c,1, -0x30061a4,1, -0x30061ac,1, -0x30061b4,1, -0x30061bc,1, -0x30061c4,1, -0x30061cc,1, -0x30061d4,1, -0x30061dc,1, -0x30061e4,1, -0x30061ec,1, -0x30061f4,1, -0x30061fc,1, +0x3005000,2, +0x3006004,3, +0x3006104,3, 0x3006204,1, -0x300620c,3, +0x300620c,1, +0x3006214,1, 0x300621c,1, 0x3006224,1, 0x300622c,1, 0x3006234,1, 0x300623c,1, -0x3006244,1, -0x300624c,1, -0x3006254,1, -0x300625c,1, +0x3006284,1, +0x300628c,1, +0x3006294,1, +0x300629c,1, +0x30062a4,1, +0x30062ac,1, +0x30062b4,1, +0x30062bc,1, +0x30062c4,3, +0x3006304,1, +0x300630c,1, +0x3006314,1, +0x300631c,1, +0x3006324,1, +0x300632c,1, +0x3006334,1, +0x300633c,1, +0x3006344,1, +0x300634c,1, +0x3006354,1, +0x300635c,1, +0x3006364,1, +0x300636c,1, +0x3006374,1, +0x300637c,1, +0x3006384,1, 0x3008000,32, 0x3008280,384, 0x3008884,7, @@ -19884,7 +21444,7 @@ 0x3009434,1, 0x300943c,1, 0x3009444,1, -0x300944c,1, +0x3009484,47, 0x3010000,2, 0x3010018,1, 0x3010020,11, @@ -19904,7 +21464,6 @@ 0x301220c,1, 0x3012400,4, 0x3012414,1, -0x3012440,16, 0x3020000,1, 0x3020008,1, 0x3020010,2, @@ -20019,6 +21578,7 @@ 0x30a100c,1, 0x30a1014,1, 0x30a1020,2, +0x30a102c,1, 0x30a1034,1, 0x30a103c,1, 0x30a1044,1, @@ -20053,6 +21613,32 @@ 0x30a15bc,1, 0x30a15c4,1, 0x30a15d4,5, +0x30a15ec,1, +0x30a8000,12, +0x30a8040,3, +0x30aa000,8, +0x30aa024,6, +0x30aa040,8, +0x30aa080,7, +0x30aa0a0,7, +0x30aa0c0,7, +0x30aa0e0,7, +0x30aa800,381, +0x30aae00,10, +0x30ab000,40, +0x30ab100,1, +0x30ab110,2, +0x30ab200,8, +0x30ab240,12, +0x30ab400,27, +0x30ab480,9, +0x30ab4c0,6, +0x30ab4e0,4, +0x30ab504,4, +0x30ab800,218, +0x30ac000,1, +0x30ac040,13, +0x30ac080,5, 0x30c0000,2, 0x30c0010,3, 0x30c0020,10, @@ -20062,76 +21648,88 @@ 0x30c0204,1, 0x30c020c,1, 0x30c0240,28, -0x30c0300,13, +0x30c0300,14, 0x30c0340,2, 0x30c0400,5, 0x30c0418,2, 0x30c0440,9, 0x30c0480,3, 0x30c04a0,12, -0x3100000,12, -0x3100040,3, -0x3102000,8, -0x3102024,6, -0x3102040,8, -0x3102080,7, -0x31020a0,7, -0x31020c0,7, -0x31020e0,7, -0x3102800,381, -0x3102e00,10, -0x3103000,40, -0x3103100,1, -0x3103110,2, -0x3103200,8, -0x3103240,12, -0x3103400,27, -0x3103480,9, -0x31034c0,6, -0x31034e0,4, -0x3103504,4, -0x3103800,218, -0x3104000,1, -0x3104040,13, -0x3104080,5, -0x3108000,1, -0x3108014,3, -0x3108024,1, -0x310802c,2, -0x3109000,28, -0x3109074,3, -0x31090e4,2, -0x31090fc,1, -0x3109184,1, -0x3109500,3, -0x3109510,1, -0x310952c,3, -0x3109540,2, -0x3109f6c,1, -0x310a000,23, -0x310a080,4, -0x310a100,7, -0x310a120,7, -0x310a140,1, -0x310a180,4, -0x310a1a0,7, -0x310a1c0,9, -0x310a200,8, -0x310a280,7, -0x310a2a0,7, -0x310a2c0,1, -0x310a300,4, -0x310a320,7, -0x310a340,3, -0x310a360,7, -0x310a380,3, -0x310a3a0,2, -0x310a3ac,2, -0x310a3c0,3, -0x310c000,3, -0x3400000,3, -0x3400200,27, -0x3400280,3, +0x30e0000,1, +0x30e1000,977, +0x30e2000,161, +0x30e3000,977, +0x30e4000,977, +0x30e5000,161, +0x30e6000,13, +0x30e6040,14, +0x30e6080,20, +0x30e6104,1, +0x30e610c,3, +0x30e6200,13, +0x30e6240,14, +0x30e6280,20, +0x30e6304,1, +0x30e630c,3, +0x30e6400,13, +0x30e6440,14, +0x30e6480,20, +0x30e6504,1, +0x30e650c,3, +0x30e6600,17, +0x30e6650,2, +0x30e6660,4, +0x30e6800,1, +0x30e6814,1, +0x30e681c,10, +0x30e6860,9, +0x30e6894,1, +0x30e689c,10, +0x30e68e0,15, +0x30e6a00,6, +0x30e6a40,9, +0x30e6a80,6, +0x3100000,1, +0x3100014,3, +0x3100024,1, +0x310002c,2, +0x3101000,28, +0x3101074,3, +0x31010e4,2, +0x31010fc,1, +0x3101184,1, +0x3101500,3, +0x3101510,1, +0x310152c,3, +0x3101540,2, +0x3101f6c,1, +0x3102000,23, +0x3102080,4, +0x3102100,7, +0x3102120,7, +0x3102140,1, +0x3102180,4, +0x31021a0,7, +0x31021c0,9, +0x3102200,8, +0x3102280,7, +0x31022a0,7, +0x31022c0,1, +0x3102300,4, +0x3102320,7, +0x3102340,3, +0x3102360,7, +0x3102380,3, +0x31023a0,2, +0x31023ac,2, +0x31023c0,3, +0x3104000,10, +0x3400000,189, +0x3400400,8, +0x3400600,27, +0x3400680,3, +0x3400804,1, +0x3400944,175, 0x3401000,56, 0x3401128,8, 0x34011a8,8, @@ -20155,7 +21753,7 @@ 0x3401a10,3, 0x3401a20,13, 0x3401c00,148, -0x3402000,63, +0x3402000,56, 0x3402400,2, 0x3402410,3, 0x3402420,3, @@ -20208,7 +21806,7 @@ 0x3403834,3, 0x3403844,1, 0x340384c,1, -0x3403860,8, +0x3403880,9, 0x3403900,6, 0x3403920,7, 0x3403940,6, @@ -20321,7 +21919,7 @@ 0x34080f0,3, 0x3408100,3, 0x3408204,1, -0x3408214,53, +0x3408210,54, 0x34082f0,3, 0x3408300,3, 0x3408310,3, @@ -20345,10 +21943,948 @@ 0x3408840,131, 0x3408a80,128, 0x3409000,8, -0x3409080,19, +0x3409080,27, 0x3409100,1, 0x3409800,309, -0x340a000,158, +0x3600000,22, +0x3600060,6, +0x3600080,6, +0x36000a0,6, +0x36000c0,6, +0x3600400,6, +0x3600424,1, +0x3600434,5, +0x3600600,128, +0x3600804,1, +0x3600828,86, +0x3600984,1, +0x3600c00,1, +0x3600c80,1, +0x3600c90,2, +0x3600d00,20, +0x3600d80,1, +0x3600da0,3, +0x3600e00,2, +0x3600e10,4, +0x370a000,10, +0x370a080,3, +0x370a200,2, +0x370a240,9, +0x370a400,2, +0x370a420,8, +0x370a480,1, +0x370b000,10, +0x370b080,1, +0x370b100,2, +0x370b110,4, +0x370b180,5, +0x370b1a0,7, +0x370b1c0,1, +0x370b200,1, +0x370c000,10, +0x370c080,2, +0x370c090,4, +0x370c100,1, +0x370d000,10, +0x370d080,2, +0x370d090,4, +0x370d100,1, +0x370e000,10, +0x370e080,3, +0x370e200,2, +0x370e240,9, +0x370e400,2, +0x370e420,8, +0x370e480,1, +0x370f000,10, +0x370f080,1, +0x370f100,2, +0x370f110,4, +0x370f180,5, +0x370f1a0,7, +0x370f1c0,1, +0x370f200,1, +0x3710000,10, +0x3710080,2, +0x3710090,4, +0x3710100,1, +0x3711000,10, +0x3711080,2, +0x3711090,4, +0x3711100,1, +0x3712000,10, +0x3712080,3, +0x3712200,2, +0x3712240,9, +0x3712400,2, +0x3712420,8, +0x3712480,1, +0x3713000,10, +0x3713080,1, +0x3713100,2, +0x3713110,4, +0x3713180,5, +0x37131a0,7, +0x37131c0,1, +0x3713200,1, +0x3714000,10, +0x3714080,2, +0x3714090,4, +0x3714100,1, +0x3715000,10, +0x3715080,2, +0x3715090,4, +0x3715100,1, +0x3716000,10, +0x3716080,3, +0x3716200,2, +0x3716240,9, +0x3716400,2, +0x3716420,8, +0x3716480,1, +0x3717000,10, +0x3717080,1, +0x3717100,2, +0x3717110,4, +0x3717180,5, +0x37171a0,7, +0x37171c0,1, +0x3717200,1, +0x3718000,10, +0x3718080,2, +0x3718090,4, +0x3718100,1, +0x3719000,10, +0x3719080,2, +0x3719090,4, +0x3719100,1, +0x371a000,10, +0x371a080,3, +0x371a200,2, +0x371a240,9, +0x371a400,2, +0x371a420,8, +0x371a480,1, +0x371b000,10, +0x371b080,1, +0x371b100,2, +0x371b110,4, +0x371b180,5, +0x371b1a0,7, +0x371b1c0,1, +0x371b200,1, +0x371c000,10, +0x371c080,2, +0x371c090,4, +0x371c100,1, +0x371d000,10, +0x371d080,2, +0x371d090,4, +0x371d100,1, +0x371e000,10, +0x371e080,3, +0x371e200,2, +0x371e240,9, +0x371e400,2, +0x371e420,8, +0x371e480,1, +0x371f000,10, +0x371f080,1, +0x371f100,2, +0x371f110,4, +0x371f180,5, +0x371f1a0,7, +0x371f1c0,1, +0x371f200,1, +0x3720000,10, +0x3720080,2, +0x3720090,4, +0x3720100,1, +0x3721000,10, +0x3721080,2, +0x3721090,4, +0x3721100,1, +0x3722000,10, +0x3722080,3, +0x3722200,2, +0x3722240,9, +0x3722400,2, +0x3722420,8, +0x3722480,1, +0x3723000,10, +0x3723080,1, +0x3723100,2, +0x3723110,4, +0x3723180,5, +0x37231a0,7, +0x37231c0,1, +0x3723200,1, +0x3724000,10, +0x3724080,2, +0x3724090,4, +0x3724100,1, +0x3725000,10, +0x3725080,2, +0x3725090,4, +0x3725100,1, +0x3726000,10, +0x3726080,3, +0x3726200,2, +0x3726240,9, +0x3726400,2, +0x3726420,8, +0x3726480,1, +0x3727000,10, +0x3727080,1, +0x3727100,2, +0x3727110,4, +0x3727180,5, +0x37271a0,7, +0x37271c0,1, +0x3727200,1, +0x3728000,10, +0x3728080,2, +0x3728090,4, +0x3728100,1, +0x3729000,10, +0x3729080,2, +0x3729090,4, +0x3729100,1, +0x372a000,10, +0x372a080,2, +0x372a0a0,8, +0x372a100,1, +0x372b000,36, +0x372b800,10, +0x372b880,3, +0x372b8a0,1, +0x372b900,2, +0x372b910,4, +0x372b980,1, +0x372c000,20, +0x372c800,1, +0x372d000,20, +0x372d800,1, +0x372e000,10, +0x372e080,2, +0x372e0a0,8, +0x372e100,1, +0x372f000,36, +0x372f800,10, +0x372f880,3, +0x372f8a0,1, +0x372f900,2, +0x372f910,4, +0x372f980,1, +0x3730000,20, +0x3730800,1, +0x3731000,20, +0x3731800,1, +0x3732000,10, +0x3732080,2, +0x37320a0,8, +0x3732100,1, +0x3733000,36, +0x3733800,10, +0x3733880,3, +0x37338a0,1, +0x3733900,2, +0x3733910,4, +0x3733980,1, +0x3734000,20, +0x3734800,1, +0x3735000,20, +0x3735800,1, +0x3736000,10, +0x3736080,2, +0x37360a0,8, +0x3736100,1, +0x3737000,36, +0x3737800,10, +0x3737880,3, +0x37378a0,1, +0x3737900,2, +0x3737910,4, +0x3737980,1, +0x3738000,20, +0x3738800,1, +0x3739000,20, +0x3739800,1, +0x373a000,10, +0x373a080,2, +0x373a0a0,8, +0x373a100,1, +0x373b000,36, +0x373b800,10, +0x373b880,3, +0x373b8a0,1, +0x373b900,2, +0x373b910,4, +0x373b980,1, +0x373c000,20, +0x373c800,1, +0x373d000,20, +0x373d800,1, +0x373e000,10, +0x373e080,2, +0x373e0a0,8, +0x373e100,1, +0x373f000,36, +0x373f800,10, +0x373f880,3, +0x373f8a0,1, +0x373f900,2, +0x373f910,4, +0x373f980,1, +0x3740000,20, +0x3740800,1, +0x3741000,20, +0x3741800,1, +0x3742000,10, +0x3742080,2, +0x37420a0,8, +0x3742100,1, +0x3743000,36, +0x3743800,10, +0x3743880,3, +0x37438a0,1, +0x3743900,2, +0x3743910,4, +0x3743980,1, +0x3744000,20, +0x3744800,1, +0x3745000,20, +0x3745800,1, +0x3746000,10, +0x3746080,2, +0x37460a0,8, +0x3746100,1, +0x3747000,36, +0x3747800,10, +0x3747880,3, +0x37478a0,1, +0x3747900,2, +0x3747910,4, +0x3747980,1, +0x3748000,20, +0x3748800,1, +0x3749000,20, +0x3749800,1, +0x374a000,10, +0x374a080,3, +0x374a100,2, +0x374a110,4, +0x374a180,1, +0x374b000,10, +0x374b080,3, +0x374b100,2, +0x374b110,4, +0x374b180,1, +0x374c000,10, +0x374c080,3, +0x374c100,2, +0x374c110,4, +0x374c180,1, +0x374d000,20, +0x374d800,10, +0x374d880,1, +0x374e000,20, +0x374e800,10, +0x374e880,1, +0x374f000,20, +0x374f800,10, +0x374f880,1, +0x3750000,20, +0x3750080,20, +0x3750100,20, +0x3750180,4, +0x3750800,10, +0x3750880,3, +0x3750900,2, +0x3750910,4, +0x3750980,1, +0x3751000,10, +0x3751080,3, +0x3751100,2, +0x3751110,4, +0x3751180,9, +0x37511c0,8, +0x3751200,1, +0x3752000,20, +0x3752800,10, +0x3752880,1, +0x3753000,20, +0x3753800,10, +0x3753880,1, +0x3754000,20, +0x3754800,10, +0x3754880,1, +0x3755000,20, +0x3755800,10, +0x3755880,1, +0x3756000,20, +0x3756800,10, +0x3756880,1, +0x3757000,20, +0x3757800,10, +0x3757880,1, +0x3758000,20, +0x3758800,10, +0x3758880,1, +0x3759000,20, +0x3759800,10, +0x3759880,1, +0x375a000,10, +0x375a080,3, +0x375a100,2, +0x375a110,4, +0x375a180,9, +0x375a1c0,8, +0x375a200,1, +0x375b000,20, +0x375b800,10, +0x375b880,1, +0x375c000,20, +0x375c800,10, +0x375c880,1, +0x375d000,20, +0x375d800,10, +0x375d880,1, +0x375e000,20, +0x375e800,10, +0x375e880,1, +0x375f000,20, +0x375f800,10, +0x375f880,1, +0x3760000,20, +0x3760800,10, +0x3760880,1, +0x3761000,20, +0x3761800,10, +0x3761880,1, +0x3762000,20, +0x3762800,10, +0x3762880,1, +0x3763000,10, +0x3763080,3, +0x3763100,2, +0x3763110,4, +0x3763180,9, +0x37631c0,8, +0x3763200,1, +0x3764000,20, +0x3764800,10, +0x3764880,1, +0x3765000,20, +0x3765800,10, +0x3765880,1, +0x3766000,20, +0x3766800,10, +0x3766880,1, +0x3767000,20, +0x3767800,10, +0x3767880,1, +0x3768000,20, +0x3768800,10, +0x3768880,1, +0x3769000,20, +0x3769800,10, +0x3769880,1, +0x376a000,20, +0x376a800,10, +0x376a880,1, +0x376b000,20, +0x376b800,10, +0x376b880,1, +0x3770000,20, +0x3770800,10, +0x3770880,3, +0x3770900,2, +0x3770910,4, +0x3770980,1, +0x3771000,20, +0x3771800,1, +0x3772000,20, +0x3772800,10, +0x3772880,3, +0x37728a0,1, +0x3773000,100, +0x3773800,10, +0x3773880,1, +0x3774000,20, +0x3774800,10, +0x3774880,1, +0x3775000,20, +0x3775800,10, +0x3775880,1, +0x3776000,20, +0x3776800,10, +0x3776880,1, +0x3777000,20, +0x3777800,10, +0x3777880,1, +0x3778000,20, +0x3778800,10, +0x3778880,1, +0x3779000,20, +0x3779800,10, +0x3779880,1, +0x377a000,20, +0x377a800,10, +0x377a880,3, +0x377a900,2, +0x377a910,4, +0x377a980,1, +0x377b000,20, +0x377b800,1, +0x377c000,20, +0x377c800,10, +0x377c880,3, +0x377c8a0,1, +0x377d000,100, +0x377d800,10, +0x377d880,1, +0x377e000,20, +0x377e800,10, +0x377e880,1, +0x377f000,20, +0x377f800,10, +0x377f880,1, +0x3780000,20, +0x3780800,10, +0x3780880,1, +0x3781000,20, +0x3781800,10, +0x3781880,1, +0x3782000,20, +0x3782800,10, +0x3782880,1, +0x3783000,20, +0x3783800,10, +0x3783880,1, +0x3784000,36, +0x3784800,10, +0x3784880,3, +0x3784900,2, +0x3784910,4, +0x3784980,1, +0x3785000,20, +0x3785800,1, +0x3786000,36, +0x3786800,10, +0x3786880,3, +0x3786900,2, +0x3786910,4, +0x3786980,1, +0x3787000,20, +0x3787800,1, +0x3788000,36, +0x3788800,10, +0x3788880,3, +0x3788900,2, +0x3788910,4, +0x3788980,1, +0x3789000,20, +0x3789800,10, +0x3789880,3, +0x3789900,2, +0x3789910,4, +0x3789980,1, +0x378a000,68, +0x378a800,10, +0x378a880,3, +0x378a900,2, +0x378a910,4, +0x378a980,1, +0x378b000,20, +0x378b800,10, +0x378b880,3, +0x378b900,2, +0x378b910,4, +0x378b980,1, +0x378c000,20, +0x378c800,1, +0x378d000,20, +0x378d800,1, +0x378e000,52, +0x378e800,10, +0x378e880,3, +0x378e900,2, +0x378e910,4, +0x378e980,1, +0x378f000,20, +0x378f800,1, +0x3790000,36, +0x3790800,10, +0x3790880,3, +0x3790900,2, +0x3790910,4, +0x3790980,1, +0x3791000,36, +0x3791800,10, +0x3791880,3, +0x3791900,2, +0x3791910,4, +0x3791980,1, +0x3792000,36, +0x3792800,10, +0x3792880,3, +0x3792900,2, +0x3792910,4, +0x3792980,1, +0x3793000,36, +0x3793800,10, +0x3793880,3, +0x3793900,2, +0x3793910,4, +0x3793980,1, +0x3794000,36, +0x3794800,10, +0x3794880,3, +0x3794900,2, +0x3794910,4, +0x3794980,1, +0x3795000,20, +0x3795800,10, +0x3795880,3, +0x3795900,2, +0x3795910,4, +0x3795980,1, +0x3796000,36, +0x3796800,10, +0x3796880,3, +0x3796900,2, +0x3796910,4, +0x3796980,1, +0x3797000,20, +0x3797800,10, +0x3797880,3, +0x3797900,2, +0x3797910,4, +0x3797980,1, +0x3798000,20, +0x3798800,1, +0x3799000,20, +0x3799800,10, +0x3799880,3, +0x3799900,2, +0x3799910,4, +0x3799980,1, +0x379a000,20, +0x379a800,10, +0x379a880,3, +0x379a900,2, +0x379a910,4, +0x379a980,1, +0x379b000,36, +0x379b800,10, +0x379b880,3, +0x379b900,2, +0x379b910,4, +0x379b980,1, +0x379c000,36, +0x379c800,10, +0x379c880,3, +0x379c900,2, +0x379c910,4, +0x379c980,1, +0x379d000,36, +0x379d800,10, +0x379d880,3, +0x379d900,2, +0x379d910,4, +0x379d980,1, +0x379e000,36, +0x379e800,10, +0x379e880,3, +0x379e900,2, +0x379e910,4, +0x379e980,1, +0x379f000,20, +0x379f800,10, +0x379f880,3, +0x379f900,2, +0x379f910,4, +0x379f980,1, +0x37a0000,20, +0x37a0800,10, +0x37a0880,3, +0x37a0900,2, +0x37a0910,4, +0x37a0980,1, +0x37a1000,20, +0x37a1800,10, +0x37a1880,3, +0x37a1900,2, +0x37a1910,4, +0x37a1980,1, +0x37a2000,36, +0x37a2800,10, +0x37a2880,3, +0x37a2900,2, +0x37a2910,4, +0x37a2980,1, +0x37a3000,36, +0x37a3800,10, +0x37a3880,3, +0x37a3900,2, +0x37a3910,4, +0x37a3980,1, +0x37a4000,20, +0x37a4800,10, +0x37a4880,3, +0x37a4900,2, +0x37a4910,4, +0x37a4980,1, +0x37a5000,20, +0x37a5800,10, +0x37a5880,3, +0x37a5900,2, +0x37a5910,4, +0x37a5980,1, +0x37a6000,20, +0x37a6080,20, +0x37a6100,4, +0x37a6800,10, +0x37a6880,3, +0x37a6900,2, +0x37a6910,4, +0x37a6980,1, +0x37a7000,20, +0x37a7080,20, +0x37a7100,4, +0x37a7800,10, +0x37a7880,3, +0x37a7900,2, +0x37a7910,4, +0x37a7980,1, +0x37a8000,20, +0x37a8080,20, +0x37a8100,4, +0x37a8800,10, +0x37a8880,3, +0x37a8900,2, +0x37a8910,4, +0x37a8980,1, +0x37a9000,36, +0x37a9800,10, +0x37a9880,3, +0x37a98a0,1, +0x37a9900,2, +0x37a9910,4, +0x37a9980,1, +0x37aa000,20, +0x37aa800,10, +0x37aa880,3, +0x37aa900,2, +0x37aa910,4, +0x37aa980,1, +0x37ab000,36, +0x37ab800,10, +0x37ab880,3, +0x37ab900,2, +0x37ab910,4, +0x37ab984,5, +0x37ab9a0,3, +0x37aba00,1, +0x37ac000,36, +0x37ac800,10, +0x37ac880,3, +0x37ac900,2, +0x37ac910,4, +0x37ac980,1, +0x37ad000,52, +0x37ad800,10, +0x37ad880,3, +0x37ad900,2, +0x37ad910,4, +0x37ad980,1, +0x37ae000,36, +0x37ae800,1, +0x37af000,36, +0x37af800,1, +0x37b0000,36, +0x37b0800,1, +0x37b1000,36, +0x37b1800,1, +0x37b2000,36, +0x37b2800,1, +0x37b3000,36, +0x37b3800,1, +0x37b4000,36, +0x37b4800,1, +0x37b5000,36, +0x37b5800,1, +0x37b6000,36, +0x37b6800,1, +0x37b7000,36, +0x37b7800,1, +0x37b8000,36, +0x37b8800,1, +0x37b9000,36, +0x37b9800,1, +0x37ba000,36, +0x37ba800,1, +0x37bb000,36, +0x37bb800,1, +0x37bc000,36, +0x37bc800,1, +0x37bd000,36, +0x37bd800,1, +0x37be000,20, +0x37be800,10, +0x37be880,3, +0x37be900,2, +0x37be910,4, +0x37be980,1, +0x37c0000,10, +0x37c0080,3, +0x37c0100,2, +0x37c0110,4, +0x37c0800,1, +0x37c0810,3, +0x37c0820,3, +0x37c0830,3, +0x37c0840,3, +0x37c0850,3, +0x37c0860,3, +0x37c0870,3, +0x37c0880,3, +0x37c0890,32, +0x37c0940,10, +0x37c0980,10, +0x37c09c0,10, +0x37c0a00,10, +0x37c0a40,10, +0x37c0a80,10, +0x37c0ac0,10, +0x37c0b00,10, +0x37c0b40,11, +0x37c0b70,2, +0x37c1000,1, +0x37c4000,10, +0x37c4080,3, +0x37c4100,2, +0x37c4110,4, +0x37c4200,1, +0x37c4210,3, +0x37c4220,3, +0x37c4230,8, +0x37c4280,10, +0x37c42c0,10, +0x37c4300,2, +0x37c4310,3, +0x37c4320,2, +0x37c4400,1, +0x37c8000,10, +0x37c8080,3, +0x37c8100,2, +0x37c8110,4, +0x37c9000,1, +0x37c9010,3, +0x37c9020,3, +0x37c9030,3, +0x37c9040,3, +0x37c9050,3, +0x37c9060,3, +0x37c9070,3, +0x37c9080,3, +0x37c9090,3, +0x37c90a0,3, +0x37c90b0,3, +0x37c90c0,3, +0x37c90d0,3, +0x37c90e0,3, +0x37c90f0,3, +0x37c9100,3, +0x37c9110,64, +0x37c9240,10, +0x37c9280,10, +0x37c92c0,10, +0x37c9300,10, +0x37c9340,10, +0x37c9380,10, +0x37c93c0,10, +0x37c9400,10, +0x37c9440,10, +0x37c9480,10, +0x37c94c0,10, +0x37c9500,10, +0x37c9540,10, +0x37c9580,10, +0x37c95c0,10, +0x37c9600,10, +0x37c9640,19, +0x37c9690,3, +0x37c96a0,3, +0x37c96b0,3, +0x37c96c0,8, +0x37ca000,1, +0x37cc000,10, +0x37cc080,3, +0x37cc100,2, +0x37cc110,4, +0x37cd000,1, +0x37cd010,3, +0x37cd020,3, +0x37cd030,3, +0x37cd040,3, +0x37cd050,3, +0x37cd060,3, +0x37cd070,3, +0x37cd080,3, +0x37cd090,3, +0x37cd0a0,3, +0x37cd0b0,3, +0x37cd0c0,3, +0x37cd0d0,3, +0x37cd0e0,3, +0x37cd0f0,3, +0x37cd100,3, +0x37cd110,64, +0x37cd240,10, +0x37cd280,10, +0x37cd2c0,10, +0x37cd300,10, +0x37cd340,10, +0x37cd380,10, +0x37cd3c0,10, +0x37cd400,10, +0x37cd440,10, +0x37cd480,10, +0x37cd4c0,10, +0x37cd500,10, +0x37cd540,10, +0x37cd580,10, +0x37cd5c0,10, +0x37cd600,10, +0x37cd640,19, +0x37cd690,3, +0x37cd6a0,3, +0x37cd6b0,3, +0x37cd6c0,8, +0x37ce000,1, +0x37d0000,10, +0x37d0080,3, +0x37d0100,2, +0x37d0110,4, +0x37d0200,1, +0x37d0210,3, +0x37d0220,3, +0x37d0230,8, +0x37d0280,10, +0x37d02c0,10, +0x37d0300,2, +0x37d0310,3, +0x37d0320,2, +0x37d0400,1, +0x37d4000,36, +0x37d4800,10, +0x37d4880,3, +0x37d4900,2, +0x37d4910,4, +0x37d4980,1, +0x37d5000,10, 0x3800000,4, 0x3800014,7, 0x3800044,1, @@ -20606,6 +23142,32 @@ 0x3932600,4, 0x3932c80,1, 0x3932cc0,1, +0x3940fd0,1, +0x3940fe0,8, +0x3942400,4, +0x3942a00,1, +0x3942c00,1, +0x3942c20,1, +0x3942c40,1, +0x3942c60,1, +0x3942df8,1, +0x3942e00,2, +0x3942e20,4, +0x3942e50,2, +0x3942e70,1, +0x3942fb8,2, +0x3942fcc,2, +0x3942fe0,8, +0x3948e00,1, +0x3948e18,1, +0x3948e80,1, +0x3948e88,1, +0x3948e90,1, +0x3948ec0,1, +0x3952000,4, +0x3952600,4, +0x3952c80,1, +0x3952cc0,1, 0x3a00000,10, 0x3a80000,11, 0x3a80034,3, @@ -20640,49 +23202,46 @@ 0x3a8d020,3, 0x3a8d800,1, 0x3b00004,1, -0x3b00010,5, +0x3b0000c,2, 0x3b00140,5, -0x3b00158,9, +0x3b00158,8, 0x3b00180,3, 0x3b001a0,2, 0x3b001ac,2, 0x3b001c0,1, -0x3b00400,146, -0x3b00800,37, -0x3b00900,8, -0x3b00940,10, +0x3b00400,145, +0x3b00800,34, +0x3b00900,14, 0x3b00980,7, 0x3b009a0,7, 0x3b009c0,1, 0x3b00a00,4, 0x3b00a20,7, -0x3b00a80,6, -0x3b00aa0,6, -0x3b00ac0,1, -0x3b00b00,4, -0x3b00b20,6, -0x3b00b80,7, +0x3b00a40,3, +0x3b00a50,3, +0x3b00a60,1, +0x3b00a80,7, +0x3b00b00,7, +0x3b00b20,7, +0x3b00b40,1, +0x3b00b80,4, 0x3b00ba0,7, -0x3b00bc0,1, -0x3b00c00,4, -0x3b00c20,7, -0x3b00c40,3, -0x3b00c80,4, -0x3b00ca0,5, -0x3b00cc0,3, -0x3b00ce0,2, -0x3b00cec,2, -0x3b00d00,9, -0x3b00d40,8, -0x3b00d80,9, -0x3b00dc0,8, -0x3b00e00,3, -0x3b00e10,3, -0x3b00e20,1, -0x3b00e40,7, -0x3b00e60,5, -0x3b00e80,6, -0x3b00ea0,8, +0x3b00bc0,3, +0x3b00be0,6, +0x3b00c00,3, +0x3b00c20,2, +0x3b00c2c,2, +0x3b00c40,9, +0x3b00c80,8, +0x3b00cc0,9, +0x3b00d00,8, +0x3b00d40,3, +0x3b00d50,3, +0x3b00d60,1, +0x3b00d80,7, +0x3b00da0,5, +0x3b00dc0,6, +0x3b00de0,8, 0x3c00000,8, 0x3c00804,1, 0x3c0080c,4, @@ -20961,7 +23520,24 @@ 0x3fd5384,13, 0x3fd5400,2, 0x3fd5440,12, -0x3fd5800,4, +0x3fd5800,3, +0x3fd5810,3, +0x3fd5820,3, +0x3fd5830,3, +0x3fd5840,3, +0x3fd5850,3, +0x3fd5860,3, +0x3fd5870,3, +0x3fd5880,3, +0x3fd5890,3, +0x3fd58a0,3, +0x3fd58b0,3, +0x3fd58c0,3, +0x3fd58d0,3, +0x3fd58e0,3, +0x3fd58f0,3, +0x3fd5900,1, +0x3fd5a00,4, 0x5fd0000,2, 0x5fd000c,1, 0x5fd0014,1, @@ -21104,6 +23680,7 @@ 0xa0004c0,1, 0xa000500,4, 0xa000520,7, +0xa000540,8, 0xa000800,2, 0xa000900,4, 0xa000980,25, @@ -21198,7 +23775,7 @@ 0xa005850,3, 0xa005860,1, 0xa005880,20, -0xa006000,28, +0xa006000,36, 0xa008000,1, 0xa008400,27, 0xa008480,4, @@ -21220,13 +23797,14 @@ 0xa010600,10, 0xa010640,10, 0xa010680,1, -0xa010700,35, +0xa010700,36, 0xa010800,1, 0xa010808,82, 0xa010a00,11, 0xa010a40,11, 0xa010a80,1, -0xa010b00,32, +0xa010b00,1, +0xa010b08,32, 0xa010c00,17, 0xa010c48,35, 0xa010d00,3, @@ -21244,7 +23822,7 @@ 0xa011800,35, 0xa011890,64, 0xa011a00,4, -0xa011a80,17, +0xa011a80,18, 0xa011b00,4, 0xa011b80,19, 0xa011c00,35, @@ -21258,33 +23836,34 @@ 0xa014200,10, 0xa014240,10, 0xa014280,1, -0xa014300,61, +0xa014300,62, 0xa014800,9, 0xa014828,4, 0xa014900,11, 0xa014940,11, 0xa014980,1, -0xa014a00,17, -0xa014a48,35, -0xa014b00,2, -0xa014b10,5, -0xa014b28,16, -0xa014b70,5, -0xa014b88,7, -0xa014ba8,7, -0xa014bc8,7, -0xa014be8,7, -0xa014c08,7, -0xa014c28,7, -0xa014c48,7, -0xa014c68,7, +0xa014a00,31, +0xa014b00,17, +0xa014b48,35, +0xa014c00,2, +0xa014c10,5, +0xa014c28,16, +0xa014c70,5, 0xa014c88,7, 0xa014ca8,7, 0xa014cc8,7, 0xa014ce8,7, -0xa014d08,10, +0xa014d08,7, +0xa014d28,7, +0xa014d48,7, +0xa014d68,7, +0xa014d88,7, +0xa014da8,7, +0xa014dc8,7, +0xa014de8,7, +0xa014e08,10, 0xa015000,89, -0xa015200,3, +0xa015200,5, 0xa016000,10, 0xa016040,6, 0xa016060,1, @@ -21309,7 +23888,7 @@ 0xa018940,6, 0xa018960,2, 0xa01896c,3, -0xa018a04,42, +0xa018a04,43, 0xa018c00,84, 0xa018e00,4, 0xa018e80,25, @@ -21337,7 +23916,7 @@ 0xa01a130,3, 0xa01a140,15, 0xa01a180,2, -0xa01a200,11, +0xa01a200,12, 0xa020000,5, 0xa020018,8, 0xa020080,5, @@ -21352,7 +23931,9 @@ 0xa020480,5, 0xa0204a0,5, 0xa0204c0,1, -0xa020500,80, +0xa020500,99, +0xa020690,3, +0xa0206a0,13, 0xa020800,4, 0xa020a00,27, 0xa020a80,4, @@ -21363,7 +23944,7 @@ 0xa020b84,5, 0xa020c00,28, 0xa020c84,1, -0xa020cb0,22, +0xa020cb0,25, 0xa020d40,4, 0xa020d60,7, 0xa020d80,4, @@ -21384,16 +23965,16 @@ 0xa022384,8, 0xa022400,1, 0xa022500,4, -0xa022580,17, +0xa022580,18, 0xa022600,4, 0xa022680,18, 0xa022700,4, -0xa022780,17, +0xa022780,18, 0xa022800,4, 0xa022880,18, 0xa022900,4, 0xa022940,14, -0xa022980,3, +0xa022980,4, 0xa024000,117, 0xa0241e4,2, 0xa0241f0,3, @@ -21406,16 +23987,16 @@ 0xa024384,8, 0xa024400,1, 0xa024500,4, -0xa024580,17, +0xa024580,18, 0xa024600,4, 0xa024680,18, 0xa024700,4, -0xa024780,17, +0xa024780,18, 0xa024800,4, 0xa024880,18, 0xa024900,4, 0xa024940,14, -0xa024980,3, +0xa024980,4, 0xa026000,117, 0xa0261e4,2, 0xa0261f0,3, @@ -21428,16 +24009,16 @@ 0xa026384,8, 0xa026400,1, 0xa026500,4, -0xa026580,17, +0xa026580,18, 0xa026600,4, 0xa026680,18, 0xa026700,4, -0xa026780,17, +0xa026780,18, 0xa026800,4, 0xa026880,18, 0xa026900,4, 0xa026940,14, -0xa026980,3, +0xa026980,4, 0xa028000,117, 0xa0281e4,2, 0xa0281f0,3, @@ -21450,16 +24031,16 @@ 0xa028384,8, 0xa028400,1, 0xa028500,4, -0xa028580,17, +0xa028580,18, 0xa028600,4, 0xa028680,18, 0xa028700,4, -0xa028780,17, +0xa028780,18, 0xa028800,4, 0xa028880,18, 0xa028900,4, 0xa028940,14, -0xa028980,3, +0xa028980,4, 0xa030004,1, 0xa03007c,69, 0xa030200,2, @@ -21561,18 +24142,18 @@ 0xa039110,3, 0xa039120,1, 0xa039200,4, -0xa039280,17, +0xa039280,18, 0xa039300,4, 0xa039380,19, 0xa039400,4, 0xa039480,18, 0xa039500,4, -0xa039580,17, +0xa039580,18, 0xa039600,4, 0xa039640,15, 0xa039700,4, 0xa039780,18, -0xa039800,3, +0xa039800,4, 0xa039a00,27, 0xa039a80,4, 0xa039ac0,25, @@ -21582,8 +24163,8 @@ 0xa039b84,8, 0xa039c00,10, 0xa03a000,3, -0xa03a010,3, -0xa03a080,20, +0xa03a010,4, +0xa03a080,28, 0xa03a100,1, 0xa040000,2, 0xa04000c,1, @@ -21686,6 +24267,7 @@ 0xa2004c0,1, 0xa200500,4, 0xa200520,7, +0xa200540,8, 0xa200800,2, 0xa200900,4, 0xa200980,25, @@ -21780,7 +24362,7 @@ 0xa205850,3, 0xa205860,1, 0xa205880,20, -0xa206000,28, +0xa206000,36, 0xa208000,1, 0xa208400,27, 0xa208480,4, @@ -21802,13 +24384,14 @@ 0xa210600,10, 0xa210640,10, 0xa210680,1, -0xa210700,35, +0xa210700,36, 0xa210800,1, 0xa210808,82, 0xa210a00,11, 0xa210a40,11, 0xa210a80,1, -0xa210b00,32, +0xa210b00,1, +0xa210b08,32, 0xa210c00,17, 0xa210c48,35, 0xa210d00,3, @@ -21826,7 +24409,7 @@ 0xa211800,35, 0xa211890,64, 0xa211a00,4, -0xa211a80,17, +0xa211a80,18, 0xa211b00,4, 0xa211b80,19, 0xa211c00,35, @@ -21840,33 +24423,34 @@ 0xa214200,10, 0xa214240,10, 0xa214280,1, -0xa214300,61, +0xa214300,62, 0xa214800,9, 0xa214828,4, 0xa214900,11, 0xa214940,11, 0xa214980,1, -0xa214a00,17, -0xa214a48,35, -0xa214b00,2, -0xa214b10,5, -0xa214b28,16, -0xa214b70,5, -0xa214b88,7, -0xa214ba8,7, -0xa214bc8,7, -0xa214be8,7, -0xa214c08,7, -0xa214c28,7, -0xa214c48,7, -0xa214c68,7, +0xa214a00,31, +0xa214b00,17, +0xa214b48,35, +0xa214c00,2, +0xa214c10,5, +0xa214c28,16, +0xa214c70,5, 0xa214c88,7, 0xa214ca8,7, 0xa214cc8,7, 0xa214ce8,7, -0xa214d08,10, +0xa214d08,7, +0xa214d28,7, +0xa214d48,7, +0xa214d68,7, +0xa214d88,7, +0xa214da8,7, +0xa214dc8,7, +0xa214de8,7, +0xa214e08,10, 0xa215000,89, -0xa215200,3, +0xa215200,5, 0xa216000,10, 0xa216040,6, 0xa216060,1, @@ -21891,7 +24475,7 @@ 0xa218940,6, 0xa218960,2, 0xa21896c,3, -0xa218a04,42, +0xa218a04,43, 0xa218c00,84, 0xa218e00,4, 0xa218e80,25, @@ -21919,7 +24503,7 @@ 0xa21a130,3, 0xa21a140,15, 0xa21a180,2, -0xa21a200,11, +0xa21a200,12, 0xa220000,5, 0xa220018,8, 0xa220080,5, @@ -21934,7 +24518,9 @@ 0xa220480,5, 0xa2204a0,5, 0xa2204c0,1, -0xa220500,80, +0xa220500,99, +0xa220690,3, +0xa2206a0,13, 0xa220800,4, 0xa220a00,27, 0xa220a80,4, @@ -21945,7 +24531,7 @@ 0xa220b84,5, 0xa220c00,28, 0xa220c84,1, -0xa220cb0,22, +0xa220cb0,25, 0xa220d40,4, 0xa220d60,7, 0xa220d80,4, @@ -21966,16 +24552,16 @@ 0xa222384,8, 0xa222400,1, 0xa222500,4, -0xa222580,17, +0xa222580,18, 0xa222600,4, 0xa222680,18, 0xa222700,4, -0xa222780,17, +0xa222780,18, 0xa222800,4, 0xa222880,18, 0xa222900,4, 0xa222940,14, -0xa222980,3, +0xa222980,4, 0xa224000,117, 0xa2241e4,2, 0xa2241f0,3, @@ -21988,16 +24574,16 @@ 0xa224384,8, 0xa224400,1, 0xa224500,4, -0xa224580,17, +0xa224580,18, 0xa224600,4, 0xa224680,18, 0xa224700,4, -0xa224780,17, +0xa224780,18, 0xa224800,4, 0xa224880,18, 0xa224900,4, 0xa224940,14, -0xa224980,3, +0xa224980,4, 0xa226000,117, 0xa2261e4,2, 0xa2261f0,3, @@ -22010,16 +24596,16 @@ 0xa226384,8, 0xa226400,1, 0xa226500,4, -0xa226580,17, +0xa226580,18, 0xa226600,4, 0xa226680,18, 0xa226700,4, -0xa226780,17, +0xa226780,18, 0xa226800,4, 0xa226880,18, 0xa226900,4, 0xa226940,14, -0xa226980,3, +0xa226980,4, 0xa228000,117, 0xa2281e4,2, 0xa2281f0,3, @@ -22032,16 +24618,16 @@ 0xa228384,8, 0xa228400,1, 0xa228500,4, -0xa228580,17, +0xa228580,18, 0xa228600,4, 0xa228680,18, 0xa228700,4, -0xa228780,17, +0xa228780,18, 0xa228800,4, 0xa228880,18, 0xa228900,4, 0xa228940,14, -0xa228980,3, +0xa228980,4, 0xa230004,1, 0xa23007c,69, 0xa230200,2, @@ -22143,18 +24729,18 @@ 0xa239110,3, 0xa239120,1, 0xa239200,4, -0xa239280,17, +0xa239280,18, 0xa239300,4, 0xa239380,19, 0xa239400,4, 0xa239480,18, 0xa239500,4, -0xa239580,17, +0xa239580,18, 0xa239600,4, 0xa239640,15, 0xa239700,4, 0xa239780,18, -0xa239800,3, +0xa239800,4, 0xa239a00,27, 0xa239a80,4, 0xa239ac0,25, @@ -22164,8 +24750,8 @@ 0xa239b84,8, 0xa239c00,10, 0xa23a000,3, -0xa23a010,3, -0xa23a080,20, +0xa23a010,4, +0xa23a080,28, 0xa23a100,1, 0xa240000,2, 0xa24000c,1, @@ -22255,13 +24841,16 @@ 0xa400034,1, 0xa40003c,1, 0xa400044,1, -0xa400050,2, -0xa400064,1, +0xa400064,3, +0xa400074,1, +0xa40007c,1, +0xa400084,1, 0xa400404,1, 0xa40040c,1, 0xa400414,1, 0xa40041c,1, 0xa400424,1, +0xa400480,2, 0xa400504,1, 0xa40050c,1, 0xa400514,1, @@ -22282,12 +24871,13 @@ 0xa400704,1, 0xa40070c,1, 0xa400800,4, -0xa400814,1, 0xa400820,4, +0xa400834,1, 0xa400840,11, 0xa400880,2, -0xa400894,1, -0xa40089c,1, +0xa4008a4,1, +0xa4008ac,1, +0xa4008b4,3, 0xa401000,18, 0xa401100,18, 0xa401200,18, @@ -22298,9 +24888,26 @@ 0xa401540,6, 0xa401560,2, 0xa40156c,3, -0xa40157c,1, +0xa401584,2, 0xa401800,2, -0xa401810,5, +0xa401a00,3, +0xa401a10,3, +0xa401a20,3, +0xa401a30,3, +0xa401a40,3, +0xa401a50,3, +0xa401a60,3, +0xa401a70,3, +0xa401a80,3, +0xa401a90,3, +0xa401aa0,3, +0xa401ab0,3, +0xa401ac0,3, +0xa401ad0,3, +0xa401ae0,3, +0xa401af0,3, +0xa401b00,1, +0xa401c00,10, 0xa5d0000,2, 0xa5d000c,1, 0xa5d0014,1, @@ -22595,13 +25202,16 @@ 0xa600034,1, 0xa60003c,1, 0xa600044,1, -0xa600050,2, -0xa600064,1, +0xa600064,3, +0xa600074,1, +0xa60007c,1, +0xa600084,1, 0xa600404,1, 0xa60040c,1, 0xa600414,1, 0xa60041c,1, 0xa600424,1, +0xa600480,2, 0xa600504,1, 0xa60050c,1, 0xa600514,1, @@ -22622,12 +25232,13 @@ 0xa600704,1, 0xa60070c,1, 0xa600800,4, -0xa600814,1, 0xa600820,4, +0xa600834,1, 0xa600840,11, 0xa600880,2, -0xa600894,1, -0xa60089c,1, +0xa6008a4,1, +0xa6008ac,1, +0xa6008b4,3, 0xa601000,18, 0xa601100,18, 0xa601200,18, @@ -22638,9 +25249,26 @@ 0xa601540,6, 0xa601560,2, 0xa60156c,3, -0xa60157c,1, +0xa601584,2, 0xa601800,2, -0xa601810,5, +0xa601a00,3, +0xa601a10,3, +0xa601a20,3, +0xa601a30,3, +0xa601a40,3, +0xa601a50,3, +0xa601a60,3, +0xa601a70,3, +0xa601a80,3, +0xa601a90,3, +0xa601aa0,3, +0xa601ab0,3, +0xa601ac0,3, +0xa601ad0,3, +0xa601ae0,3, +0xa601af0,3, +0xa601b00,1, +0xa601c00,10, 0xa7d0000,2, 0xa7d000c,1, 0xa7d0014,1, @@ -22935,13 +25563,16 @@ 0xa800034,1, 0xa80003c,1, 0xa800044,1, -0xa800050,2, -0xa800064,1, +0xa800064,3, +0xa800074,1, +0xa80007c,1, +0xa800084,1, 0xa800404,1, 0xa80040c,1, 0xa800414,1, 0xa80041c,1, 0xa800424,1, +0xa800480,2, 0xa800504,1, 0xa80050c,1, 0xa800514,1, @@ -22962,12 +25593,13 @@ 0xa800704,1, 0xa80070c,1, 0xa800800,4, -0xa800814,1, 0xa800820,4, +0xa800834,1, 0xa800840,11, 0xa800880,2, -0xa800894,1, -0xa80089c,1, +0xa8008a4,1, +0xa8008ac,1, +0xa8008b4,3, 0xa801000,18, 0xa801100,18, 0xa801200,18, @@ -22978,9 +25610,26 @@ 0xa801540,6, 0xa801560,2, 0xa80156c,3, -0xa80157c,1, +0xa801584,2, 0xa801800,2, -0xa801810,5, +0xa801a00,3, +0xa801a10,3, +0xa801a20,3, +0xa801a30,3, +0xa801a40,3, +0xa801a50,3, +0xa801a60,3, +0xa801a70,3, +0xa801a80,3, +0xa801a90,3, +0xa801aa0,3, +0xa801ab0,3, +0xa801ac0,3, +0xa801ad0,3, +0xa801ae0,3, +0xa801af0,3, +0xa801b00,1, +0xa801c00,10, 0xa9d0000,2, 0xa9d000c,1, 0xa9d0014,1, @@ -23909,6 +26558,7 @@ 0xb0c04c0,1, 0xb0c0500,148, 0xb0c0780,11, +0xb0c07c0,1, 0xb0c0800,51, 0xb0c0900,4, 0xb0c0980,41, @@ -23925,8 +26575,8 @@ 0xb0c0d84,3, 0xb0c0e00,36, 0xb0c0f04,1, -0xb0c0f30,22, -0xb0c0f90,7, +0xb0c0f30,26, +0xb0c0fa0,7, 0xb100000,1, 0xb100010,4, 0xb1d0000,2, @@ -24333,6 +26983,7 @@ 0xb2c04c0,1, 0xb2c0500,148, 0xb2c0780,11, +0xb2c07c0,1, 0xb2c0800,51, 0xb2c0900,4, 0xb2c0980,41, @@ -24349,8 +27000,8 @@ 0xb2c0d84,3, 0xb2c0e00,36, 0xb2c0f04,1, -0xb2c0f30,22, -0xb2c0f90,7, +0xb2c0f30,26, +0xb2c0fa0,7, 0xb300000,1, 0xb300010,4, 0xb3d0000,2, @@ -24757,6 +27408,7 @@ 0xb4c04c0,1, 0xb4c0500,148, 0xb4c0780,11, +0xb4c07c0,1, 0xb4c0800,51, 0xb4c0900,4, 0xb4c0980,41, @@ -24773,8 +27425,8 @@ 0xb4c0d84,3, 0xb4c0e00,36, 0xb4c0f04,1, -0xb4c0f30,22, -0xb4c0f90,7, +0xb4c0f30,26, +0xb4c0fa0,7, 0xb500000,1, 0xb500010,4, 0xb5d0000,2, @@ -25181,6 +27833,7 @@ 0xb6c04c0,1, 0xb6c0500,148, 0xb6c0780,11, +0xb6c07c0,1, 0xb6c0800,51, 0xb6c0900,4, 0xb6c0980,41, @@ -25197,8 +27850,8 @@ 0xb6c0d84,3, 0xb6c0e00,36, 0xb6c0f04,1, -0xb6c0f30,22, -0xb6c0f90,7, +0xb6c0f30,26, +0xb6c0fa0,7, 0xb700000,1, 0xb700010,4, 0xb7d0000,2, @@ -25605,6 +28258,7 @@ 0xb8c04c0,1, 0xb8c0500,148, 0xb8c0780,11, +0xb8c07c0,1, 0xb8c0800,51, 0xb8c0900,4, 0xb8c0980,41, @@ -25621,8 +28275,8 @@ 0xb8c0d84,3, 0xb8c0e00,36, 0xb8c0f04,1, -0xb8c0f30,22, -0xb8c0f90,7, +0xb8c0f30,26, +0xb8c0fa0,7, 0xb900000,1, 0xb900010,4, 0xb9d0000,2, @@ -26029,6 +28683,7 @@ 0xbac04c0,1, 0xbac0500,148, 0xbac0780,11, +0xbac07c0,1, 0xbac0800,51, 0xbac0900,4, 0xbac0980,41, @@ -26045,8 +28700,8 @@ 0xbac0d84,3, 0xbac0e00,36, 0xbac0f04,1, -0xbac0f30,22, -0xbac0f90,7, +0xbac0f30,26, +0xbac0fa0,7, 0xbb00000,1, 0xbb00010,4, 0xbbd0000,2, @@ -26453,6 +29108,7 @@ 0xbcc04c0,1, 0xbcc0500,148, 0xbcc0780,11, +0xbcc07c0,1, 0xbcc0800,51, 0xbcc0900,4, 0xbcc0980,41, @@ -26469,8 +29125,8 @@ 0xbcc0d84,3, 0xbcc0e00,36, 0xbcc0f04,1, -0xbcc0f30,22, -0xbcc0f90,7, +0xbcc0f30,26, +0xbcc0fa0,7, 0xbd00000,1, 0xbd00010,4, 0xbdd0000,2, @@ -26877,6 +29533,7 @@ 0xbec04c0,1, 0xbec0500,148, 0xbec0780,11, +0xbec07c0,1, 0xbec0800,51, 0xbec0900,4, 0xbec0980,41, @@ -26893,8 +29550,8 @@ 0xbec0d84,3, 0xbec0e00,36, 0xbec0f04,1, -0xbec0f30,22, -0xbec0f90,7, +0xbec0f30,26, +0xbec0fa0,7, 0xbf00000,1, 0xbf00010,4, 0xbfd0000,2, diff --git a/mstdump/mstdump_dbs/ConnectX7.csv b/mstdump/mstdump_dbs/ConnectX7.csv index a26a9124..e7ba9c75 100644 --- a/mstdump/mstdump_dbs/ConnectX7.csv +++ b/mstdump/mstdump_dbs/ConnectX7.csv @@ -4093,87 +4093,43 @@ 0x1488e0,2, 0x148900,211, 0x148c50,6, -0x14c000,10, -0x14c040,10, -0x14c080,10, -0x14c0c0,10, -0x14c100,10, -0x14c140,10, -0x14c180,10, -0x14c1c0,10, -0x14c200,10, -0x14c400,10, -0x14c440,10, -0x14c480,10, -0x14c4c0,10, -0x14c500,10, -0x14c540,10, -0x14c580,10, -0x14c5c0,10, -0x14c600,10, -0x14c800,10, -0x14c840,10, -0x14c880,10, -0x14c8c0,10, -0x14c900,10, -0x14c940,10, -0x14c980,10, -0x14c9c0,10, -0x14ca00,10, -0x14cc00,10, -0x14cc40,10, -0x14cc80,10, -0x14ccc0,10, -0x14cd00,10, -0x14cd40,10, -0x14cd80,10, -0x14cdc0,10, -0x14ce00,10, -0x14d000,10, -0x14d040,10, -0x14d080,10, -0x14d0c0,10, -0x14d100,10, -0x14d140,10, -0x14d180,10, -0x14d1c0,10, -0x14d200,10, -0x14d400,10, -0x14d440,10, -0x14d480,10, -0x14d4c0,10, -0x14d500,10, -0x14d540,10, -0x14d580,10, -0x14d5c0,10, -0x14d600,10, -0x14d800,10, -0x14d840,10, -0x14d880,10, -0x14d8c0,10, -0x14d900,10, -0x14d940,10, -0x14d980,10, -0x14d9c0,10, -0x14da00,10, -0x14dc00,10, -0x14dc40,10, -0x14dc80,10, -0x14dcc0,10, -0x14dd00,10, -0x14dd40,10, -0x14dd80,10, -0x14ddc0,10, -0x14de00,10, -0x14e000,10, -0x14e040,10, -0x14e080,10, -0x14e0c0,10, -0x14e100,10, -0x14e140,10, -0x14e180,10, -0x14e1c0,10, -0x14e200,10, +0x14c000,1152, +0x14e000,18, +0x14e080,18, +0x14e100,18, +0x14e180,18, +0x14e200,18, +0x14e280,18, +0x14e300,18, +0x14e380,18, +0x14e400,18, +0x14e480,18, +0x14e500,18, +0x14e580,18, +0x14e600,18, +0x14e680,18, +0x14e700,18, +0x14e780,18, +0x14e800,18, +0x14e880,18, +0x14e900,18, +0x14e980,18, +0x14ea00,18, +0x14ea80,18, +0x14eb00,18, +0x14eb80,18, +0x14ec00,18, +0x14ec80,18, +0x14ed00,18, +0x14ed80,18, +0x14ee00,18, +0x14ee80,18, +0x14ef00,18, +0x14ef80,18, +0x14f000,18, +0x14f080,18, +0x14f100,18, +0x14f180,18, 0x150000,72, 0x150200,72, 0x150400,72, @@ -4790,7 +4746,8 @@ 0x1741b4,7, 0x1741e0,5, 0x174200,1, -0x174208,10, +0x174208,4, +0x174224,3, 0x174404,5, 0x174420,1, 0x174430,10, @@ -11447,7 +11404,8 @@ 0x599400,192, 0x599704,1, 0x59970c,10, -0x599800,5, +0x599800,1, +0x59980c,2, 0x59a000,8, 0x59a100,128, 0x59a400,116, diff --git a/mstdump/mstdump_dbs/Spectrum3.csv b/mstdump/mstdump_dbs/Spectrum3.csv index 949b30b5..064a2f38 100644 --- a/mstdump/mstdump_dbs/Spectrum3.csv +++ b/mstdump/mstdump_dbs/Spectrum3.csv @@ -573,10 +573,12 @@ 0x050cc0,2572, 0x053500,524, 0x053d40,524, -0x054580,268, -0x0549c0,256, -0x054e00,268, -0x055240,302, +0x054580,3084, +0x0575c0,270, +0x057a00,12, +0x057a40,3084, +0x05aa80,3340, +0x05dec0,430, 0x060000,32, 0x060200,64, 0x060400,96, @@ -25874,3 +25876,48891 @@ 0x7b3600,10, 0x7b3680,3, 0x7b36e0,1, +0x800000,1, +0x80000c,5, +0x800044,1, +0x800054,5, +0x800200,128, +0x800404,1, +0x800428,54, +0x800600,32, +0x800704,1, +0x800800,1, +0x800900,1, +0x800910,2, +0x800920,3, +0x800980,10, +0x800a00,19, +0x800b00,1, +0xc00000,11, +0xc00040,16, +0xc00084,5, +0xc00200,7, +0xc00220,6, +0xc00240,7, +0xc00260,6, +0xc00280,6, +0xc002a0,2, +0xc002ac,2, +0xc002c0,7, +0xc002e0,7, +0xc00300,2, +0xc0030c,2, +0xc00320,6, +0xc00400,2, +0xc01000,19, +0xc02104,23, +0xc02180,7, +0xc021a0,6, +0xc021c0,7, +0xc021e0,6, +0xc02200,4, +0xc02220,4, +0xc02240,11, +0xc02270,32, +0xc02300,24, +0xc02380,20, +0xc02400,61, +0xc02500,25, +0xc02568,4, +0xc02580,2, +0xc025a0,1, +0xc025c0,11, +0xc02600,9, +0xc02640,3, +0xc02650,3, +0xc02664,3, +0xc02680,22, +0xc02800,11, +0xc03000,536, +0xc04104,23, +0xc04180,7, +0xc041a0,6, +0xc041c0,7, +0xc041e0,6, +0xc04200,4, +0xc04220,4, +0xc04240,11, +0xc04270,32, +0xc04300,24, +0xc04380,20, +0xc04400,61, +0xc04500,25, +0xc04568,4, +0xc04580,2, +0xc045a0,1, +0xc045c0,11, +0xc04600,9, +0xc04640,3, +0xc04650,3, +0xc04664,3, +0xc04680,22, +0xc04800,11, +0xc05000,536, +0xc0a000,7, +0xc0a048,8, +0xc0a080,8, +0xc0a100,7, +0xc0a148,8, +0xc0a180,8, +0xc10000,11, +0xc10040,16, +0xc10084,5, +0xc10200,7, +0xc10220,6, +0xc10240,7, +0xc10260,6, +0xc10280,6, +0xc102a0,2, +0xc102ac,2, +0xc102c0,7, +0xc102e0,7, +0xc10300,2, +0xc1030c,2, +0xc10320,6, +0xc10400,2, +0xc11000,19, +0xc12104,23, +0xc12180,7, +0xc121a0,6, +0xc121c0,7, +0xc121e0,6, +0xc12200,4, +0xc12220,4, +0xc12240,11, +0xc12270,32, +0xc12300,24, +0xc12380,20, +0xc12400,61, +0xc12500,25, +0xc12568,4, +0xc12580,2, +0xc125a0,1, +0xc125c0,11, +0xc12600,9, +0xc12640,3, +0xc12650,3, +0xc12664,3, +0xc12680,22, +0xc12800,11, +0xc13000,536, +0xc14104,23, +0xc14180,7, +0xc141a0,6, +0xc141c0,7, +0xc141e0,6, +0xc14200,4, +0xc14220,4, +0xc14240,11, +0xc14270,32, +0xc14300,24, +0xc14380,20, +0xc14400,61, +0xc14500,25, +0xc14568,4, +0xc14580,2, +0xc145a0,1, +0xc145c0,11, +0xc14600,9, +0xc14640,3, +0xc14650,3, +0xc14664,3, +0xc14680,22, +0xc14800,11, +0xc15000,536, +0xc1a000,7, +0xc1a048,8, +0xc1a080,8, +0xc1a100,7, +0xc1a148,8, +0xc1a180,8, +0xc20400,4, +0xc20440,4, +0xc205c0,1, +0xc20600,8, +0xc20800,18, +0xc20880,13, +0xc208f0,3, +0xc20900,18, +0xc20980,13, +0xc209f0,3, +0xc20e00,4, +0xc20e20,4, +0xc20e80,16, +0xc20f00,1, +0xc20f20,1, +0xc21020,2, +0xc21208,6, +0xc21228,10, +0xc21288,6, +0xc212a8,10, +0xc21600,32, +0xc218c0,8, +0xc21900,24, +0xc219b0,4, +0xc21aa0,2, +0xc21ac0,4, +0xc22200,19, +0xc22280,19, +0xc22400,14, +0xc2243c,9, +0xc22464,14, +0xc224a0,2, +0xc224ac,2, +0xc22500,14, +0xc2253c,9, +0xc22564,14, +0xc225a0,2, +0xc225ac,2, +0xc22800,19, +0xc22880,19, +0xc22a10,2, +0xc22a1c,1, +0xc22a50,2, +0xc22a5c,1, +0xc22c00,7, +0xc22c20,1, +0xc22c54,18, +0xc22ca0,1, +0xc22cd4,11, +0xc22e00,1, +0xc22e08,6, +0xc23180,3, +0xc24400,4, +0xc24440,4, +0xc245c0,1, +0xc24600,8, +0xc24800,18, +0xc24880,13, +0xc248f0,3, +0xc24900,18, +0xc24980,13, +0xc249f0,3, +0xc24e00,4, +0xc24e20,4, +0xc24e80,16, +0xc24f00,1, +0xc24f20,1, +0xc25020,2, +0xc25208,6, +0xc25228,10, +0xc25288,6, +0xc252a8,10, +0xc25600,32, +0xc258c0,8, +0xc25900,24, +0xc259b0,4, +0xc25aa0,2, +0xc25ac0,4, +0xc26200,19, +0xc26280,19, +0xc26400,14, +0xc2643c,9, +0xc26464,14, +0xc264a0,2, +0xc264ac,2, +0xc26500,14, +0xc2653c,9, +0xc26564,14, +0xc265a0,2, +0xc265ac,2, +0xc26800,19, +0xc26880,19, +0xc26a10,2, +0xc26a1c,1, +0xc26a50,2, +0xc26a5c,1, +0xc26c00,7, +0xc26c20,1, +0xc26c54,18, +0xc26ca0,1, +0xc26cd4,11, +0xc26e00,1, +0xc26e08,6, +0xc27180,3, +0xc29000,13, +0xc2e000,19, +0xc2ea00,10, +0xc2ea80,3, +0xc2f000,1, +0xc2f008,5, +0xc2f038,1, +0xc2f044,1, +0xc2f050,2, +0xc2f060,8, +0xc2f140,19, +0xc2f190,4, +0xc30000,2, +0xc3000c,2, +0xc30040,7, +0xc30100,3, +0xc30110,3, +0xc30120,5, +0xc30200,6, +0xc30240,5, +0xc30400,2, +0xc3040c,2, +0xc30440,7, +0xc30500,3, +0xc30510,3, +0xc30520,5, +0xc30600,6, +0xc30640,5, +0xc30800,2, +0xc3080c,2, +0xc30840,7, +0xc30900,3, +0xc30910,3, +0xc30920,5, +0xc30a00,6, +0xc30a40,5, +0xc30c00,2, +0xc30c0c,2, +0xc30c40,7, +0xc30d00,3, +0xc30d10,3, +0xc30d20,5, +0xc30e00,6, +0xc30e40,5, +0xc31000,2, +0xc3100c,2, +0xc31040,7, +0xc31100,3, +0xc31110,3, +0xc31120,5, +0xc31200,6, +0xc31240,5, +0xc31400,2, +0xc3140c,2, +0xc31440,7, +0xc31500,3, +0xc31510,3, +0xc31520,5, +0xc31600,6, +0xc31640,5, +0xc31800,2, +0xc3180c,2, +0xc31840,7, +0xc31900,3, +0xc31910,3, +0xc31920,5, +0xc31a00,6, +0xc31a40,5, +0xc31c00,2, +0xc31c0c,2, +0xc31c40,7, +0xc31d00,3, +0xc31d10,3, +0xc31d20,5, +0xc31e00,6, +0xc31e40,5, +0xc32000,5, +0xc32040,9, +0xc32100,3, +0xc32200,1, +0xc32210,1, +0xc32220,1, +0xc32230,1, +0xc32240,1, +0xc32300,3, +0xc32314,1, +0xc32320,4, +0xc32400,5, +0xc32440,5, +0xc33000,80, +0xc33200,1, +0xc38000,7, +0xc38030,2, +0xc38040,7, +0xc38070,2, +0xc38100,2, +0xc38120,2, +0xc38140,2, +0xc38160,2, +0xc38180,9, +0xc38200,7, +0xc38230,2, +0xc38240,7, +0xc38270,2, +0xc38300,2, +0xc38320,2, +0xc38340,2, +0xc38360,2, +0xc38380,9, +0xc38400,11, +0xc38500,11, +0xc39000,3, +0xc39010,2, +0xc3901c,5, +0xc39040,8, +0xc39080,3, +0xc39090,2, +0xc3909c,5, +0xc390c0,8, +0xc39100,3, +0xc39110,2, +0xc3911c,5, +0xc39140,8, +0xc39180,3, +0xc39190,2, +0xc3919c,5, +0xc391c0,8, +0xc39200,7, +0xc39220,12, +0xc39280,7, +0xc392a0,12, +0xc39300,3, +0xc39310,1, +0xc39400,3, +0xc39410,2, +0xc3941c,5, +0xc39440,8, +0xc39480,3, +0xc39490,2, +0xc3949c,5, +0xc394c0,8, +0xc39500,3, +0xc39510,2, +0xc3951c,5, +0xc39540,8, +0xc39580,3, +0xc39590,2, +0xc3959c,5, +0xc395c0,8, +0xc39600,7, +0xc39620,12, +0xc39680,7, +0xc396a0,12, +0xc39700,3, +0xc39710,1, +0xc39804,1, +0xc39824,21, +0xc39880,16, +0xc39900,5, +0xc39920,11, +0xc39950,9, +0xc39980,22, +0xc39a00,22, +0xc39a80,22, +0xc39b00,22, +0xc39b80,22, +0xc39c00,22, +0xc39c80,22, +0xc39d00,22, +0xc39d80,3, +0xc40000,5, +0xc40018,5, +0xc40030,3, +0xc40044,3, +0xc40100,58, +0xc401f0,3, +0xc40280,3, +0xc40400,5, +0xc40418,5, +0xc40430,3, +0xc40444,3, +0xc40500,58, +0xc405f0,3, +0xc40680,3, +0xc41018,2, +0xc41100,2, +0xc41110,10, +0xc41140,2, +0xc41150,10, +0xc41208,1, +0xc41220,12, +0xc41280,1, +0xc41288,2, +0xc41400,4, +0xc42000,5, +0xc42018,5, +0xc42030,3, +0xc42044,3, +0xc42100,58, +0xc421f0,3, +0xc42280,3, +0xc42400,5, +0xc42418,5, +0xc42430,3, +0xc42444,3, +0xc42500,58, +0xc425f0,3, +0xc42680,3, +0xc43018,2, +0xc43100,2, +0xc43110,10, +0xc43140,2, +0xc43150,10, +0xc43208,1, +0xc43220,12, +0xc43280,1, +0xc43288,2, +0xc43400,4, +0xc44000,2, +0xc4400c,1, +0xc44030,3, +0xc44040,2, +0xc4404c,1, +0xc44070,3, +0xc44100,2, +0xc4410c,1, +0xc44130,3, +0xc44140,2, +0xc4414c,1, +0xc44170,3, +0xc44200,15, +0xc44280,15, +0xc44300,15, +0xc44380,15, +0xc44400,15, +0xc44480,15, +0xc44500,15, +0xc44580,15, +0xc44604,10, +0xc44700,2, +0xc4470c,7, +0xc44740,1, +0xc44770,1, +0xc447c0,2, +0xc447d0,4, +0xc45000,3, +0xc45010,1, +0xc4501c,3, +0xc45104,1, +0xc45110,4, +0xc45124,1, +0xc45130,4, +0xc45144,1, +0xc45150,4, +0xc45164,1, +0xc45170,5, +0xc45190,4, +0xc45a00,4, +0xc45c00,129, +0xc46000,37, +0xc46098,1, +0xc46100,37, +0xc46198,1, +0xc46200,37, +0xc46298,1, +0xc46300,37, +0xc46398,1, +0xc46400,37, +0xc46498,1, +0xc46500,37, +0xc46598,1, +0xc46600,37, +0xc46698,1, +0xc46700,37, +0xc46798,1, +0xc4c000,91, +0xc4c400,4, +0xc4c440,15, +0xc4c480,4, +0xc4c4c0,15, +0xc4c500,4, +0xc4c540,15, +0xc4c580,4, +0xc4c5c0,15, +0xc4c600,4, +0xc4c640,10, +0xc4c680,4, +0xc4c6c0,10, +0xc4c800,4, +0xc4c840,33, +0xc4ca00,13, +0xc4ca80,1, +0xc4ca88,8, +0xc4cac0,6, +0xc4cae0,1, +0xc4cae8,2, +0xc4cb04,14, +0xc4cc00,4, +0xc4ccc8,1, +0xc4cfcc,3, +0xc4cfe0,99, +0xc4d400,4, +0xc4d440,15, +0xc4d480,4, +0xc4d4c0,15, +0xc4d500,4, +0xc4d540,15, +0xc4d580,4, +0xc4d5c0,15, +0xc4d600,4, +0xc4d640,10, +0xc4d680,4, +0xc4d6c0,10, +0xc4d800,4, +0xc4d840,33, +0xc4da00,13, +0xc4da80,1, +0xc4da88,8, +0xc4dac0,6, +0xc4dae0,1, +0xc4dae8,2, +0xc4db04,14, +0xc4dc00,4, +0xc4dcc8,1, +0xc4dfcc,3, +0xc4dfe0,27, +0xc4f000,19, +0xc4fa00,10, +0xc4fa80,3, +0xc4fb00,6, +0xc50000,51, +0xc50a00,10, +0xc50a80,3, +0xc51000,2, +0xc5100c,4, +0xc51028,3, +0xc51038,4, +0xc51050,2, +0xc51080,4, +0xc51098,7, +0xc51120,4, +0xc51200,4, +0xc51214,7, +0xc51234,3, +0xc51280,8, +0xc512c0,5, +0xc51300,2, +0xc5130c,3, +0xc51400,24, +0xc51464,2, +0xc51470,3, +0xc51500,25, +0xc515c0,8, +0xc515e8,5, +0xc51600,5, +0xc51618,1, +0xc51620,1, +0xc51628,1, +0xc51630,2, +0xc51640,2, +0xc51650,2, +0xc51690,4, +0xc51740,2, +0xc51760,6, +0xc51780,6, +0xc517a0,6, +0xc517c0,6, +0xc517e0,1, +0xc51800,2, +0xc5180c,4, +0xc51828,3, +0xc51838,4, +0xc51850,2, +0xc51880,4, +0xc51898,7, +0xc51920,4, +0xc51a00,4, +0xc51a14,7, +0xc51a34,3, +0xc51a80,8, +0xc51ac0,5, +0xc51b00,2, +0xc51b0c,3, +0xc51c00,24, +0xc51c64,2, +0xc51c70,3, +0xc51d00,25, +0xc51dc0,8, +0xc51de8,5, +0xc51e00,5, +0xc51e18,1, +0xc51e20,1, +0xc51e28,1, +0xc51e30,2, +0xc51e40,2, +0xc51e50,2, +0xc51e90,4, +0xc51f40,2, +0xc51f60,6, +0xc51f80,6, +0xc51fa0,6, +0xc51fc0,6, +0xc51fe0,1, +0xc52000,19, +0xc52080,2, +0xc520b0,2, +0xc520c0,2, +0xc60000,11, +0xc60040,16, +0xc60084,5, +0xc60200,7, +0xc60220,6, +0xc60240,7, +0xc60260,6, +0xc60280,6, +0xc602a0,2, +0xc602ac,2, +0xc602c0,7, +0xc602e0,7, +0xc60300,2, +0xc6030c,2, +0xc60320,6, +0xc60400,2, +0xc61000,19, +0xc62104,23, +0xc62180,7, +0xc621a0,6, +0xc621c0,7, +0xc621e0,6, +0xc62200,4, +0xc62220,4, +0xc62240,11, +0xc62270,32, +0xc62300,24, +0xc62380,20, +0xc62400,61, +0xc62500,25, +0xc62568,4, +0xc62580,2, +0xc625a0,1, +0xc625c0,11, +0xc62600,9, +0xc62640,3, +0xc62650,3, +0xc62664,3, +0xc62680,22, +0xc62800,11, +0xc63000,536, +0xc64104,23, +0xc64180,7, +0xc641a0,6, +0xc641c0,7, +0xc641e0,6, +0xc64200,4, +0xc64220,4, +0xc64240,11, +0xc64270,32, +0xc64300,24, +0xc64380,20, +0xc64400,61, +0xc64500,25, +0xc64568,4, +0xc64580,2, +0xc645a0,1, +0xc645c0,11, +0xc64600,9, +0xc64640,3, +0xc64650,3, +0xc64664,3, +0xc64680,22, +0xc64800,11, +0xc65000,536, +0xc6a000,7, +0xc6a048,8, +0xc6a080,8, +0xc6a100,7, +0xc6a148,8, +0xc6a180,8, +0xc70000,11, +0xc70040,16, +0xc70084,5, +0xc70200,7, +0xc70220,6, +0xc70240,7, +0xc70260,6, +0xc70280,6, +0xc702a0,2, +0xc702ac,2, +0xc702c0,7, +0xc702e0,7, +0xc70300,2, +0xc7030c,2, +0xc70320,6, +0xc70400,2, +0xc71000,19, +0xc72104,23, +0xc72180,7, +0xc721a0,6, +0xc721c0,7, +0xc721e0,6, +0xc72200,4, +0xc72220,4, +0xc72240,11, +0xc72270,32, +0xc72300,24, +0xc72380,20, +0xc72400,61, +0xc72500,25, +0xc72568,4, +0xc72580,2, +0xc725a0,1, +0xc725c0,11, +0xc72600,9, +0xc72640,3, +0xc72650,3, +0xc72664,3, +0xc72680,22, +0xc72800,11, +0xc73000,536, +0xc74104,23, +0xc74180,7, +0xc741a0,6, +0xc741c0,7, +0xc741e0,6, +0xc74200,4, +0xc74220,4, +0xc74240,11, +0xc74270,32, +0xc74300,24, +0xc74380,20, +0xc74400,61, +0xc74500,25, +0xc74568,4, +0xc74580,2, +0xc745a0,1, +0xc745c0,11, +0xc74600,9, +0xc74640,3, +0xc74650,3, +0xc74664,3, +0xc74680,22, +0xc74800,11, +0xc75000,536, +0xc7a000,7, +0xc7a048,8, +0xc7a080,8, +0xc7a100,7, +0xc7a148,8, +0xc7a180,8, +0xc80400,4, +0xc80440,4, +0xc805c0,1, +0xc80600,8, +0xc80800,18, +0xc80880,13, +0xc808f0,3, +0xc80900,18, +0xc80980,13, +0xc809f0,3, +0xc80e00,4, +0xc80e20,4, +0xc80e80,16, +0xc80f00,1, +0xc80f20,1, +0xc81020,2, +0xc81208,6, +0xc81228,10, +0xc81288,6, +0xc812a8,10, +0xc81600,32, +0xc818c0,8, +0xc81900,24, +0xc819b0,4, +0xc81aa0,2, +0xc81ac0,4, +0xc82200,19, +0xc82280,19, +0xc82400,14, +0xc8243c,9, +0xc82464,14, +0xc824a0,2, +0xc824ac,2, +0xc82500,14, +0xc8253c,9, +0xc82564,14, +0xc825a0,2, +0xc825ac,2, +0xc82800,19, +0xc82880,19, +0xc82a10,2, +0xc82a1c,1, +0xc82a50,2, +0xc82a5c,1, +0xc82c00,7, +0xc82c20,1, +0xc82c54,18, +0xc82ca0,1, +0xc82cd4,11, +0xc82e00,1, +0xc82e08,6, +0xc83180,3, +0xc84400,4, +0xc84440,4, +0xc845c0,1, +0xc84600,8, +0xc84800,18, +0xc84880,13, +0xc848f0,3, +0xc84900,18, +0xc84980,13, +0xc849f0,3, +0xc84e00,4, +0xc84e20,4, +0xc84e80,16, +0xc84f00,1, +0xc84f20,1, +0xc85020,2, +0xc85208,6, +0xc85228,10, +0xc85288,6, +0xc852a8,10, +0xc85600,32, +0xc858c0,8, +0xc85900,24, +0xc859b0,4, +0xc85aa0,2, +0xc85ac0,4, +0xc86200,19, +0xc86280,19, +0xc86400,14, +0xc8643c,9, +0xc86464,14, +0xc864a0,2, +0xc864ac,2, +0xc86500,14, +0xc8653c,9, +0xc86564,14, +0xc865a0,2, +0xc865ac,2, +0xc86800,19, +0xc86880,19, +0xc86a10,2, +0xc86a1c,1, +0xc86a50,2, +0xc86a5c,1, +0xc86c00,7, +0xc86c20,1, +0xc86c54,18, +0xc86ca0,1, +0xc86cd4,11, +0xc86e00,1, +0xc86e08,6, +0xc87180,3, +0xc89000,13, +0xc8e000,19, +0xc8ea00,10, +0xc8ea80,3, +0xc8f000,1, +0xc8f008,5, +0xc8f038,1, +0xc8f044,1, +0xc8f050,2, +0xc8f060,8, +0xc8f140,19, +0xc8f190,4, +0xc90000,2, +0xc9000c,2, +0xc90040,7, +0xc90100,3, +0xc90110,3, +0xc90120,5, +0xc90200,6, +0xc90240,5, +0xc90400,2, +0xc9040c,2, +0xc90440,7, +0xc90500,3, +0xc90510,3, +0xc90520,5, +0xc90600,6, +0xc90640,5, +0xc90800,2, +0xc9080c,2, +0xc90840,7, +0xc90900,3, +0xc90910,3, +0xc90920,5, +0xc90a00,6, +0xc90a40,5, +0xc90c00,2, +0xc90c0c,2, +0xc90c40,7, +0xc90d00,3, +0xc90d10,3, +0xc90d20,5, +0xc90e00,6, +0xc90e40,5, +0xc91000,2, +0xc9100c,2, +0xc91040,7, +0xc91100,3, +0xc91110,3, +0xc91120,5, +0xc91200,6, +0xc91240,5, +0xc91400,2, +0xc9140c,2, +0xc91440,7, +0xc91500,3, +0xc91510,3, +0xc91520,5, +0xc91600,6, +0xc91640,5, +0xc91800,2, +0xc9180c,2, +0xc91840,7, +0xc91900,3, +0xc91910,3, +0xc91920,5, +0xc91a00,6, +0xc91a40,5, +0xc91c00,2, +0xc91c0c,2, +0xc91c40,7, +0xc91d00,3, +0xc91d10,3, +0xc91d20,5, +0xc91e00,6, +0xc91e40,5, +0xc92000,5, +0xc92040,9, +0xc92100,3, +0xc92200,1, +0xc92210,1, +0xc92220,1, +0xc92230,1, +0xc92240,1, +0xc92300,3, +0xc92314,1, +0xc92320,4, +0xc92400,5, +0xc92440,5, +0xc93000,80, +0xc93200,1, +0xc98000,7, +0xc98030,2, +0xc98040,7, +0xc98070,2, +0xc98100,2, +0xc98120,2, +0xc98140,2, +0xc98160,2, +0xc98180,9, +0xc98200,7, +0xc98230,2, +0xc98240,7, +0xc98270,2, +0xc98300,2, +0xc98320,2, +0xc98340,2, +0xc98360,2, +0xc98380,9, +0xc98400,11, +0xc98500,11, +0xc99000,3, +0xc99010,2, +0xc9901c,5, +0xc99040,8, +0xc99080,3, +0xc99090,2, +0xc9909c,5, +0xc990c0,8, +0xc99100,3, +0xc99110,2, +0xc9911c,5, +0xc99140,8, +0xc99180,3, +0xc99190,2, +0xc9919c,5, +0xc991c0,8, +0xc99200,7, +0xc99220,12, +0xc99280,7, +0xc992a0,12, +0xc99300,3, +0xc99310,1, +0xc99400,3, +0xc99410,2, +0xc9941c,5, +0xc99440,8, +0xc99480,3, +0xc99490,2, +0xc9949c,5, +0xc994c0,8, +0xc99500,3, +0xc99510,2, +0xc9951c,5, +0xc99540,8, +0xc99580,3, +0xc99590,2, +0xc9959c,5, +0xc995c0,8, +0xc99600,7, +0xc99620,12, +0xc99680,7, +0xc996a0,12, +0xc99700,3, +0xc99710,1, +0xc99804,1, +0xc99824,21, +0xc99880,16, +0xc99900,5, +0xc99920,11, +0xc99950,9, +0xc99980,22, +0xc99a00,22, +0xc99a80,22, +0xc99b00,22, +0xc99b80,22, +0xc99c00,22, +0xc99c80,22, +0xc99d00,22, +0xc99d80,3, +0xca0000,5, +0xca0018,5, +0xca0030,3, +0xca0044,3, +0xca0100,58, +0xca01f0,3, +0xca0280,3, +0xca0400,5, +0xca0418,5, +0xca0430,3, +0xca0444,3, +0xca0500,58, +0xca05f0,3, +0xca0680,3, +0xca1018,2, +0xca1100,2, +0xca1110,10, +0xca1140,2, +0xca1150,10, +0xca1208,1, +0xca1220,12, +0xca1280,1, +0xca1288,2, +0xca1400,4, +0xca2000,5, +0xca2018,5, +0xca2030,3, +0xca2044,3, +0xca2100,58, +0xca21f0,3, +0xca2280,3, +0xca2400,5, +0xca2418,5, +0xca2430,3, +0xca2444,3, +0xca2500,58, +0xca25f0,3, +0xca2680,3, +0xca3018,2, +0xca3100,2, +0xca3110,10, +0xca3140,2, +0xca3150,10, +0xca3208,1, +0xca3220,12, +0xca3280,1, +0xca3288,2, +0xca3400,4, +0xca4000,2, +0xca400c,1, +0xca4030,3, +0xca4040,2, +0xca404c,1, +0xca4070,3, +0xca4100,2, +0xca410c,1, +0xca4130,3, +0xca4140,2, +0xca414c,1, +0xca4170,3, +0xca4200,15, +0xca4280,15, +0xca4300,15, +0xca4380,15, +0xca4400,15, +0xca4480,15, +0xca4500,15, +0xca4580,15, +0xca4604,10, +0xca4700,2, +0xca470c,7, +0xca4740,1, +0xca4770,1, +0xca47c0,2, +0xca47d0,4, +0xca5000,3, +0xca5010,1, +0xca501c,3, +0xca5104,1, +0xca5110,4, +0xca5124,1, +0xca5130,4, +0xca5144,1, +0xca5150,4, +0xca5164,1, +0xca5170,5, +0xca5190,4, +0xca5a00,4, +0xca5c00,129, +0xca6000,37, +0xca6098,1, +0xca6100,37, +0xca6198,1, +0xca6200,37, +0xca6298,1, +0xca6300,37, +0xca6398,1, +0xca6400,37, +0xca6498,1, +0xca6500,37, +0xca6598,1, +0xca6600,37, +0xca6698,1, +0xca6700,37, +0xca6798,1, +0xcac000,91, +0xcac400,4, +0xcac440,15, +0xcac480,4, +0xcac4c0,15, +0xcac500,4, +0xcac540,15, +0xcac580,4, +0xcac5c0,15, +0xcac600,4, +0xcac640,10, +0xcac680,4, +0xcac6c0,10, +0xcac800,4, +0xcac840,33, +0xcaca00,13, +0xcaca80,1, +0xcaca88,8, +0xcacac0,6, +0xcacae0,1, +0xcacae8,2, +0xcacb04,14, +0xcacc00,4, +0xcaccc8,1, +0xcacfcc,3, +0xcacfe0,99, +0xcad400,4, +0xcad440,15, +0xcad480,4, +0xcad4c0,15, +0xcad500,4, +0xcad540,15, +0xcad580,4, +0xcad5c0,15, +0xcad600,4, +0xcad640,10, +0xcad680,4, +0xcad6c0,10, +0xcad800,4, +0xcad840,33, +0xcada00,13, +0xcada80,1, +0xcada88,8, +0xcadac0,6, +0xcadae0,1, +0xcadae8,2, +0xcadb04,14, +0xcadc00,4, +0xcadcc8,1, +0xcadfcc,3, +0xcadfe0,27, +0xcaf000,19, +0xcafa00,10, +0xcafa80,3, +0xcafb00,6, +0xcb0000,51, +0xcb0a00,10, +0xcb0a80,3, +0xcb1000,2, +0xcb100c,4, +0xcb1028,3, +0xcb1038,4, +0xcb1050,2, +0xcb1080,4, +0xcb1098,7, +0xcb1120,4, +0xcb1200,4, +0xcb1214,7, +0xcb1234,3, +0xcb1280,8, +0xcb12c0,5, +0xcb1300,2, +0xcb130c,3, +0xcb1400,24, +0xcb1464,2, +0xcb1470,3, +0xcb1500,25, +0xcb15c0,8, +0xcb15e8,5, +0xcb1600,5, +0xcb1618,1, +0xcb1620,1, +0xcb1628,1, +0xcb1630,2, +0xcb1640,2, +0xcb1650,2, +0xcb1690,4, +0xcb1740,2, +0xcb1760,6, +0xcb1780,6, +0xcb17a0,6, +0xcb17c0,6, +0xcb17e0,1, +0xcb1800,2, +0xcb180c,4, +0xcb1828,3, +0xcb1838,4, +0xcb1850,2, +0xcb1880,4, +0xcb1898,7, +0xcb1920,4, +0xcb1a00,4, +0xcb1a14,7, +0xcb1a34,3, +0xcb1a80,8, +0xcb1ac0,5, +0xcb1b00,2, +0xcb1b0c,3, +0xcb1c00,24, +0xcb1c64,2, +0xcb1c70,3, +0xcb1d00,25, +0xcb1dc0,8, +0xcb1de8,5, +0xcb1e00,5, +0xcb1e18,1, +0xcb1e20,1, +0xcb1e28,1, +0xcb1e30,2, +0xcb1e40,2, +0xcb1e50,2, +0xcb1e90,4, +0xcb1f40,2, +0xcb1f60,6, +0xcb1f80,6, +0xcb1fa0,6, +0xcb1fc0,6, +0xcb1fe0,1, +0xcb2000,19, +0xcb2080,2, +0xcb20b0,2, +0xcb20c0,2, +0xcc0000,11, +0xcc0040,16, +0xcc0084,5, +0xcc0200,7, +0xcc0220,6, +0xcc0240,7, +0xcc0260,6, +0xcc0280,6, +0xcc02a0,2, +0xcc02ac,2, +0xcc02c0,7, +0xcc02e0,7, +0xcc0300,2, +0xcc030c,2, +0xcc0320,6, +0xcc0400,2, +0xcc1000,19, +0xcc2104,23, +0xcc2180,7, +0xcc21a0,6, +0xcc21c0,7, +0xcc21e0,6, +0xcc2200,4, +0xcc2220,4, +0xcc2240,11, +0xcc2270,32, +0xcc2300,24, +0xcc2380,20, +0xcc2400,61, +0xcc2500,25, +0xcc2568,4, +0xcc2580,2, +0xcc25a0,1, +0xcc25c0,11, +0xcc2600,9, +0xcc2640,3, +0xcc2650,3, +0xcc2664,3, +0xcc2680,22, +0xcc2800,11, +0xcc3000,536, +0xcc4104,23, +0xcc4180,7, +0xcc41a0,6, +0xcc41c0,7, +0xcc41e0,6, +0xcc4200,4, +0xcc4220,4, +0xcc4240,11, +0xcc4270,32, +0xcc4300,24, +0xcc4380,20, +0xcc4400,61, +0xcc4500,25, +0xcc4568,4, +0xcc4580,2, +0xcc45a0,1, +0xcc45c0,11, +0xcc4600,9, +0xcc4640,3, +0xcc4650,3, +0xcc4664,3, +0xcc4680,22, +0xcc4800,11, +0xcc5000,536, +0xcca000,7, +0xcca048,8, +0xcca080,8, +0xcca100,7, +0xcca148,8, +0xcca180,8, +0xcd0000,11, +0xcd0040,16, +0xcd0084,5, +0xcd0200,7, +0xcd0220,6, +0xcd0240,7, +0xcd0260,6, +0xcd0280,6, +0xcd02a0,2, +0xcd02ac,2, +0xcd02c0,7, +0xcd02e0,7, +0xcd0300,2, +0xcd030c,2, +0xcd0320,6, +0xcd0400,2, +0xcd1000,19, +0xcd2104,23, +0xcd2180,7, +0xcd21a0,6, +0xcd21c0,7, +0xcd21e0,6, +0xcd2200,4, +0xcd2220,4, +0xcd2240,11, +0xcd2270,32, +0xcd2300,24, +0xcd2380,20, +0xcd2400,61, +0xcd2500,25, +0xcd2568,4, +0xcd2580,2, +0xcd25a0,1, +0xcd25c0,11, +0xcd2600,9, +0xcd2640,3, +0xcd2650,3, +0xcd2664,3, +0xcd2680,22, +0xcd2800,11, +0xcd3000,536, +0xcd4104,23, +0xcd4180,7, +0xcd41a0,6, +0xcd41c0,7, +0xcd41e0,6, +0xcd4200,4, +0xcd4220,4, +0xcd4240,11, +0xcd4270,32, +0xcd4300,24, +0xcd4380,20, +0xcd4400,61, +0xcd4500,25, +0xcd4568,4, +0xcd4580,2, +0xcd45a0,1, +0xcd45c0,11, +0xcd4600,9, +0xcd4640,3, +0xcd4650,3, +0xcd4664,3, +0xcd4680,22, +0xcd4800,11, +0xcd5000,536, +0xcda000,7, +0xcda048,8, +0xcda080,8, +0xcda100,7, +0xcda148,8, +0xcda180,8, +0xce0400,4, +0xce0440,4, +0xce05c0,1, +0xce0600,8, +0xce0800,18, +0xce0880,13, +0xce08f0,3, +0xce0900,18, +0xce0980,13, +0xce09f0,3, +0xce0e00,4, +0xce0e20,4, +0xce0e80,16, +0xce0f00,1, +0xce0f20,1, +0xce1020,2, +0xce1208,6, +0xce1228,10, +0xce1288,6, +0xce12a8,10, +0xce1600,32, +0xce18c0,8, +0xce1900,24, +0xce19b0,4, +0xce1aa0,2, +0xce1ac0,4, +0xce2200,19, +0xce2280,19, +0xce2400,14, +0xce243c,9, +0xce2464,14, +0xce24a0,2, +0xce24ac,2, +0xce2500,14, +0xce253c,9, +0xce2564,14, +0xce25a0,2, +0xce25ac,2, +0xce2800,19, +0xce2880,19, +0xce2a10,2, +0xce2a1c,1, +0xce2a50,2, +0xce2a5c,1, +0xce2c00,7, +0xce2c20,1, +0xce2c54,18, +0xce2ca0,1, +0xce2cd4,11, +0xce2e00,1, +0xce2e08,6, +0xce3180,3, +0xce4400,4, +0xce4440,4, +0xce45c0,1, +0xce4600,8, +0xce4800,18, +0xce4880,13, +0xce48f0,3, +0xce4900,18, +0xce4980,13, +0xce49f0,3, +0xce4e00,4, +0xce4e20,4, +0xce4e80,16, +0xce4f00,1, +0xce4f20,1, +0xce5020,2, +0xce5208,6, +0xce5228,10, +0xce5288,6, +0xce52a8,10, +0xce5600,32, +0xce58c0,8, +0xce5900,24, +0xce59b0,4, +0xce5aa0,2, +0xce5ac0,4, +0xce6200,19, +0xce6280,19, +0xce6400,14, +0xce643c,9, +0xce6464,14, +0xce64a0,2, +0xce64ac,2, +0xce6500,14, +0xce653c,9, +0xce6564,14, +0xce65a0,2, +0xce65ac,2, +0xce6800,19, +0xce6880,19, +0xce6a10,2, +0xce6a1c,1, +0xce6a50,2, +0xce6a5c,1, +0xce6c00,7, +0xce6c20,1, +0xce6c54,18, +0xce6ca0,1, +0xce6cd4,11, +0xce6e00,1, +0xce6e08,6, +0xce7180,3, +0xce9000,13, +0xcee000,19, +0xceea00,10, +0xceea80,3, +0xcef000,1, +0xcef008,5, +0xcef038,1, +0xcef044,1, +0xcef050,2, +0xcef060,8, +0xcef140,19, +0xcef190,4, +0xcf0000,2, +0xcf000c,2, +0xcf0040,7, +0xcf0100,3, +0xcf0110,3, +0xcf0120,5, +0xcf0200,6, +0xcf0240,5, +0xcf0400,2, +0xcf040c,2, +0xcf0440,7, +0xcf0500,3, +0xcf0510,3, +0xcf0520,5, +0xcf0600,6, +0xcf0640,5, +0xcf0800,2, +0xcf080c,2, +0xcf0840,7, +0xcf0900,3, +0xcf0910,3, +0xcf0920,5, +0xcf0a00,6, +0xcf0a40,5, +0xcf0c00,2, +0xcf0c0c,2, +0xcf0c40,7, +0xcf0d00,3, +0xcf0d10,3, +0xcf0d20,5, +0xcf0e00,6, +0xcf0e40,5, +0xcf1000,2, +0xcf100c,2, +0xcf1040,7, +0xcf1100,3, +0xcf1110,3, +0xcf1120,5, +0xcf1200,6, +0xcf1240,5, +0xcf1400,2, +0xcf140c,2, +0xcf1440,7, +0xcf1500,3, +0xcf1510,3, +0xcf1520,5, +0xcf1600,6, +0xcf1640,5, +0xcf1800,2, +0xcf180c,2, +0xcf1840,7, +0xcf1900,3, +0xcf1910,3, +0xcf1920,5, +0xcf1a00,6, +0xcf1a40,5, +0xcf1c00,2, +0xcf1c0c,2, +0xcf1c40,7, +0xcf1d00,3, +0xcf1d10,3, +0xcf1d20,5, +0xcf1e00,6, +0xcf1e40,5, +0xcf2000,5, +0xcf2040,9, +0xcf2100,3, +0xcf2200,1, +0xcf2210,1, +0xcf2220,1, +0xcf2230,1, +0xcf2240,1, +0xcf2300,3, +0xcf2314,1, +0xcf2320,4, +0xcf2400,5, +0xcf2440,5, +0xcf3000,80, +0xcf3200,1, +0xcf8000,7, +0xcf8030,2, +0xcf8040,7, +0xcf8070,2, +0xcf8100,2, +0xcf8120,2, +0xcf8140,2, +0xcf8160,2, +0xcf8180,9, +0xcf8200,7, +0xcf8230,2, +0xcf8240,7, +0xcf8270,2, +0xcf8300,2, +0xcf8320,2, +0xcf8340,2, +0xcf8360,2, +0xcf8380,9, +0xcf8400,11, +0xcf8500,11, +0xcf9000,3, +0xcf9010,2, +0xcf901c,5, +0xcf9040,8, +0xcf9080,3, +0xcf9090,2, +0xcf909c,5, +0xcf90c0,8, +0xcf9100,3, +0xcf9110,2, +0xcf911c,5, +0xcf9140,8, +0xcf9180,3, +0xcf9190,2, +0xcf919c,5, +0xcf91c0,8, +0xcf9200,7, +0xcf9220,12, +0xcf9280,7, +0xcf92a0,12, +0xcf9300,3, +0xcf9310,1, +0xcf9400,3, +0xcf9410,2, +0xcf941c,5, +0xcf9440,8, +0xcf9480,3, +0xcf9490,2, +0xcf949c,5, +0xcf94c0,8, +0xcf9500,3, +0xcf9510,2, +0xcf951c,5, +0xcf9540,8, +0xcf9580,3, +0xcf9590,2, +0xcf959c,5, +0xcf95c0,8, +0xcf9600,7, +0xcf9620,12, +0xcf9680,7, +0xcf96a0,12, +0xcf9700,3, +0xcf9710,1, +0xcf9804,1, +0xcf9824,21, +0xcf9880,16, +0xcf9900,5, +0xcf9920,11, +0xcf9950,9, +0xcf9980,22, +0xcf9a00,22, +0xcf9a80,22, +0xcf9b00,22, +0xcf9b80,22, +0xcf9c00,22, +0xcf9c80,22, +0xcf9d00,22, +0xcf9d80,3, +0xd00000,5, +0xd00018,5, +0xd00030,3, +0xd00044,3, +0xd00100,58, +0xd001f0,3, +0xd00280,3, +0xd00400,5, +0xd00418,5, +0xd00430,3, +0xd00444,3, +0xd00500,58, +0xd005f0,3, +0xd00680,3, +0xd01018,2, +0xd01100,2, +0xd01110,10, +0xd01140,2, +0xd01150,10, +0xd01208,1, +0xd01220,12, +0xd01280,1, +0xd01288,2, +0xd01400,4, +0xd02000,5, +0xd02018,5, +0xd02030,3, +0xd02044,3, +0xd02100,58, +0xd021f0,3, +0xd02280,3, +0xd02400,5, +0xd02418,5, +0xd02430,3, +0xd02444,3, +0xd02500,58, +0xd025f0,3, +0xd02680,3, +0xd03018,2, +0xd03100,2, +0xd03110,10, +0xd03140,2, +0xd03150,10, +0xd03208,1, +0xd03220,12, +0xd03280,1, +0xd03288,2, +0xd03400,4, +0xd04000,2, +0xd0400c,1, +0xd04030,3, +0xd04040,2, +0xd0404c,1, +0xd04070,3, +0xd04100,2, +0xd0410c,1, +0xd04130,3, +0xd04140,2, +0xd0414c,1, +0xd04170,3, +0xd04200,15, +0xd04280,15, +0xd04300,15, +0xd04380,15, +0xd04400,15, +0xd04480,15, +0xd04500,15, +0xd04580,15, +0xd04604,10, +0xd04700,2, +0xd0470c,7, +0xd04740,1, +0xd04770,1, +0xd047c0,2, +0xd047d0,4, +0xd05000,3, +0xd05010,1, +0xd0501c,3, +0xd05104,1, +0xd05110,4, +0xd05124,1, +0xd05130,4, +0xd05144,1, +0xd05150,4, +0xd05164,1, +0xd05170,5, +0xd05190,4, +0xd05a00,4, +0xd05c00,129, +0xd06000,37, +0xd06098,1, +0xd06100,37, +0xd06198,1, +0xd06200,37, +0xd06298,1, +0xd06300,37, +0xd06398,1, +0xd06400,37, +0xd06498,1, +0xd06500,37, +0xd06598,1, +0xd06600,37, +0xd06698,1, +0xd06700,37, +0xd06798,1, +0xd0c000,91, +0xd0c400,4, +0xd0c440,15, +0xd0c480,4, +0xd0c4c0,15, +0xd0c500,4, +0xd0c540,15, +0xd0c580,4, +0xd0c5c0,15, +0xd0c600,4, +0xd0c640,10, +0xd0c680,4, +0xd0c6c0,10, +0xd0c800,4, +0xd0c840,33, +0xd0ca00,13, +0xd0ca80,1, +0xd0ca88,8, +0xd0cac0,6, +0xd0cae0,1, +0xd0cae8,2, +0xd0cb04,14, +0xd0cc00,4, +0xd0ccc8,1, +0xd0cfcc,3, +0xd0cfe0,99, +0xd0d400,4, +0xd0d440,15, +0xd0d480,4, +0xd0d4c0,15, +0xd0d500,4, +0xd0d540,15, +0xd0d580,4, +0xd0d5c0,15, +0xd0d600,4, +0xd0d640,10, +0xd0d680,4, +0xd0d6c0,10, +0xd0d800,4, +0xd0d840,33, +0xd0da00,13, +0xd0da80,1, +0xd0da88,8, +0xd0dac0,6, +0xd0dae0,1, +0xd0dae8,2, +0xd0db04,14, +0xd0dc00,4, +0xd0dcc8,1, +0xd0dfcc,3, +0xd0dfe0,27, +0xd0f000,19, +0xd0fa00,10, +0xd0fa80,3, +0xd0fb00,6, +0xd10000,51, +0xd10a00,10, +0xd10a80,3, +0xd11000,2, +0xd1100c,4, +0xd11028,3, +0xd11038,4, +0xd11050,2, +0xd11080,4, +0xd11098,7, +0xd11120,4, +0xd11200,4, +0xd11214,7, +0xd11234,3, +0xd11280,8, +0xd112c0,5, +0xd11300,2, +0xd1130c,3, +0xd11400,24, +0xd11464,2, +0xd11470,3, +0xd11500,25, +0xd115c0,8, +0xd115e8,5, +0xd11600,5, +0xd11618,1, +0xd11620,1, +0xd11628,1, +0xd11630,2, +0xd11640,2, +0xd11650,2, +0xd11690,4, +0xd11740,2, +0xd11760,6, +0xd11780,6, +0xd117a0,6, +0xd117c0,6, +0xd117e0,1, +0xd11800,2, +0xd1180c,4, +0xd11828,3, +0xd11838,4, +0xd11850,2, +0xd11880,4, +0xd11898,7, +0xd11920,4, +0xd11a00,4, +0xd11a14,7, +0xd11a34,3, +0xd11a80,8, +0xd11ac0,5, +0xd11b00,2, +0xd11b0c,3, +0xd11c00,24, +0xd11c64,2, +0xd11c70,3, +0xd11d00,25, +0xd11dc0,8, +0xd11de8,5, +0xd11e00,5, +0xd11e18,1, +0xd11e20,1, +0xd11e28,1, +0xd11e30,2, +0xd11e40,2, +0xd11e50,2, +0xd11e90,4, +0xd11f40,2, +0xd11f60,6, +0xd11f80,6, +0xd11fa0,6, +0xd11fc0,6, +0xd11fe0,1, +0xd12000,19, +0xd12080,2, +0xd120b0,2, +0xd120c0,2, +0xd20000,11, +0xd20040,16, +0xd20084,5, +0xd20200,7, +0xd20220,6, +0xd20240,7, +0xd20260,6, +0xd20280,6, +0xd202a0,2, +0xd202ac,2, +0xd202c0,7, +0xd202e0,7, +0xd20300,2, +0xd2030c,2, +0xd20320,6, +0xd20400,2, +0xd21000,19, +0xd22104,23, +0xd22180,7, +0xd221a0,6, +0xd221c0,7, +0xd221e0,6, +0xd22200,4, +0xd22220,4, +0xd22240,11, +0xd22270,32, +0xd22300,24, +0xd22380,20, +0xd22400,61, +0xd22500,25, +0xd22568,4, +0xd22580,2, +0xd225a0,1, +0xd225c0,11, +0xd22600,9, +0xd22640,3, +0xd22650,3, +0xd22664,3, +0xd22680,22, +0xd22800,11, +0xd23000,536, +0xd24104,23, +0xd24180,7, +0xd241a0,6, +0xd241c0,7, +0xd241e0,6, +0xd24200,4, +0xd24220,4, +0xd24240,11, +0xd24270,32, +0xd24300,24, +0xd24380,20, +0xd24400,61, +0xd24500,25, +0xd24568,4, +0xd24580,2, +0xd245a0,1, +0xd245c0,11, +0xd24600,9, +0xd24640,3, +0xd24650,3, +0xd24664,3, +0xd24680,22, +0xd24800,11, +0xd25000,536, +0xd2a000,7, +0xd2a048,8, +0xd2a080,8, +0xd2a100,7, +0xd2a148,8, +0xd2a180,8, +0xd30000,11, +0xd30040,16, +0xd30084,5, +0xd30200,7, +0xd30220,6, +0xd30240,7, +0xd30260,6, +0xd30280,6, +0xd302a0,2, +0xd302ac,2, +0xd302c0,7, +0xd302e0,7, +0xd30300,2, +0xd3030c,2, +0xd30320,6, +0xd30400,2, +0xd31000,19, +0xd32104,23, +0xd32180,7, +0xd321a0,6, +0xd321c0,7, +0xd321e0,6, +0xd32200,4, +0xd32220,4, +0xd32240,11, +0xd32270,32, +0xd32300,24, +0xd32380,20, +0xd32400,61, +0xd32500,25, +0xd32568,4, +0xd32580,2, +0xd325a0,1, +0xd325c0,11, +0xd32600,9, +0xd32640,3, +0xd32650,3, +0xd32664,3, +0xd32680,22, +0xd32800,11, +0xd33000,536, +0xd34104,23, +0xd34180,7, +0xd341a0,6, +0xd341c0,7, +0xd341e0,6, +0xd34200,4, +0xd34220,4, +0xd34240,11, +0xd34270,32, +0xd34300,24, +0xd34380,20, +0xd34400,61, +0xd34500,25, +0xd34568,4, +0xd34580,2, +0xd345a0,1, +0xd345c0,11, +0xd34600,9, +0xd34640,3, +0xd34650,3, +0xd34664,3, +0xd34680,22, +0xd34800,11, +0xd35000,536, +0xd3a000,7, +0xd3a048,8, +0xd3a080,8, +0xd3a100,7, +0xd3a148,8, +0xd3a180,8, +0xd40400,4, +0xd40440,4, +0xd405c0,1, +0xd40600,8, +0xd40800,18, +0xd40880,13, +0xd408f0,3, +0xd40900,18, +0xd40980,13, +0xd409f0,3, +0xd40e00,4, +0xd40e20,4, +0xd40e80,16, +0xd40f00,1, +0xd40f20,1, +0xd41020,2, +0xd41208,6, +0xd41228,10, +0xd41288,6, +0xd412a8,10, +0xd41600,32, +0xd418c0,8, +0xd41900,24, +0xd419b0,4, +0xd41aa0,2, +0xd41ac0,4, +0xd42200,19, +0xd42280,19, +0xd42400,14, +0xd4243c,9, +0xd42464,14, +0xd424a0,2, +0xd424ac,2, +0xd42500,14, +0xd4253c,9, +0xd42564,14, +0xd425a0,2, +0xd425ac,2, +0xd42800,19, +0xd42880,19, +0xd42a10,2, +0xd42a1c,1, +0xd42a50,2, +0xd42a5c,1, +0xd42c00,7, +0xd42c20,1, +0xd42c54,18, +0xd42ca0,1, +0xd42cd4,11, +0xd42e00,1, +0xd42e08,6, +0xd43180,3, +0xd44400,4, +0xd44440,4, +0xd445c0,1, +0xd44600,8, +0xd44800,18, +0xd44880,13, +0xd448f0,3, +0xd44900,18, +0xd44980,13, +0xd449f0,3, +0xd44e00,4, +0xd44e20,4, +0xd44e80,16, +0xd44f00,1, +0xd44f20,1, +0xd45020,2, +0xd45208,6, +0xd45228,10, +0xd45288,6, +0xd452a8,10, +0xd45600,32, +0xd458c0,8, +0xd45900,24, +0xd459b0,4, +0xd45aa0,2, +0xd45ac0,4, +0xd46200,19, +0xd46280,19, +0xd46400,14, +0xd4643c,9, +0xd46464,14, +0xd464a0,2, +0xd464ac,2, +0xd46500,14, +0xd4653c,9, +0xd46564,14, +0xd465a0,2, +0xd465ac,2, +0xd46800,19, +0xd46880,19, +0xd46a10,2, +0xd46a1c,1, +0xd46a50,2, +0xd46a5c,1, +0xd46c00,7, +0xd46c20,1, +0xd46c54,18, +0xd46ca0,1, +0xd46cd4,11, +0xd46e00,1, +0xd46e08,6, +0xd47180,3, +0xd49000,13, +0xd4e000,19, +0xd4ea00,10, +0xd4ea80,3, +0xd4f000,1, +0xd4f008,5, +0xd4f038,1, +0xd4f044,1, +0xd4f050,2, +0xd4f060,8, +0xd4f140,19, +0xd4f190,4, +0xd50000,2, +0xd5000c,2, +0xd50040,7, +0xd50100,3, +0xd50110,3, +0xd50120,5, +0xd50200,6, +0xd50240,5, +0xd50400,2, +0xd5040c,2, +0xd50440,7, +0xd50500,3, +0xd50510,3, +0xd50520,5, +0xd50600,6, +0xd50640,5, +0xd50800,2, +0xd5080c,2, +0xd50840,7, +0xd50900,3, +0xd50910,3, +0xd50920,5, +0xd50a00,6, +0xd50a40,5, +0xd50c00,2, +0xd50c0c,2, +0xd50c40,7, +0xd50d00,3, +0xd50d10,3, +0xd50d20,5, +0xd50e00,6, +0xd50e40,5, +0xd51000,2, +0xd5100c,2, +0xd51040,7, +0xd51100,3, +0xd51110,3, +0xd51120,5, +0xd51200,6, +0xd51240,5, +0xd51400,2, +0xd5140c,2, +0xd51440,7, +0xd51500,3, +0xd51510,3, +0xd51520,5, +0xd51600,6, +0xd51640,5, +0xd51800,2, +0xd5180c,2, +0xd51840,7, +0xd51900,3, +0xd51910,3, +0xd51920,5, +0xd51a00,6, +0xd51a40,5, +0xd51c00,2, +0xd51c0c,2, +0xd51c40,7, +0xd51d00,3, +0xd51d10,3, +0xd51d20,5, +0xd51e00,6, +0xd51e40,5, +0xd52000,5, +0xd52040,9, +0xd52100,3, +0xd52200,1, +0xd52210,1, +0xd52220,1, +0xd52230,1, +0xd52240,1, +0xd52300,3, +0xd52314,1, +0xd52320,4, +0xd52400,5, +0xd52440,5, +0xd53000,80, +0xd53200,1, +0xd58000,7, +0xd58030,2, +0xd58040,7, +0xd58070,2, +0xd58100,2, +0xd58120,2, +0xd58140,2, +0xd58160,2, +0xd58180,9, +0xd58200,7, +0xd58230,2, +0xd58240,7, +0xd58270,2, +0xd58300,2, +0xd58320,2, +0xd58340,2, +0xd58360,2, +0xd58380,9, +0xd58400,11, +0xd58500,11, +0xd59000,3, +0xd59010,2, +0xd5901c,5, +0xd59040,8, +0xd59080,3, +0xd59090,2, +0xd5909c,5, +0xd590c0,8, +0xd59100,3, +0xd59110,2, +0xd5911c,5, +0xd59140,8, +0xd59180,3, +0xd59190,2, +0xd5919c,5, +0xd591c0,8, +0xd59200,7, +0xd59220,12, +0xd59280,7, +0xd592a0,12, +0xd59300,3, +0xd59310,1, +0xd59400,3, +0xd59410,2, +0xd5941c,5, +0xd59440,8, +0xd59480,3, +0xd59490,2, +0xd5949c,5, +0xd594c0,8, +0xd59500,3, +0xd59510,2, +0xd5951c,5, +0xd59540,8, +0xd59580,3, +0xd59590,2, +0xd5959c,5, +0xd595c0,8, +0xd59600,7, +0xd59620,12, +0xd59680,7, +0xd596a0,12, +0xd59700,3, +0xd59710,1, +0xd59804,1, +0xd59824,21, +0xd59880,16, +0xd59900,5, +0xd59920,11, +0xd59950,9, +0xd59980,22, +0xd59a00,22, +0xd59a80,22, +0xd59b00,22, +0xd59b80,22, +0xd59c00,22, +0xd59c80,22, +0xd59d00,22, +0xd59d80,3, +0xd60000,5, +0xd60018,5, +0xd60030,3, +0xd60044,3, +0xd60100,58, +0xd601f0,3, +0xd60280,3, +0xd60400,5, +0xd60418,5, +0xd60430,3, +0xd60444,3, +0xd60500,58, +0xd605f0,3, +0xd60680,3, +0xd61018,2, +0xd61100,2, +0xd61110,10, +0xd61140,2, +0xd61150,10, +0xd61208,1, +0xd61220,12, +0xd61280,1, +0xd61288,2, +0xd61400,4, +0xd62000,5, +0xd62018,5, +0xd62030,3, +0xd62044,3, +0xd62100,58, +0xd621f0,3, +0xd62280,3, +0xd62400,5, +0xd62418,5, +0xd62430,3, +0xd62444,3, +0xd62500,58, +0xd625f0,3, +0xd62680,3, +0xd63018,2, +0xd63100,2, +0xd63110,10, +0xd63140,2, +0xd63150,10, +0xd63208,1, +0xd63220,12, +0xd63280,1, +0xd63288,2, +0xd63400,4, +0xd64000,2, +0xd6400c,1, +0xd64030,3, +0xd64040,2, +0xd6404c,1, +0xd64070,3, +0xd64100,2, +0xd6410c,1, +0xd64130,3, +0xd64140,2, +0xd6414c,1, +0xd64170,3, +0xd64200,15, +0xd64280,15, +0xd64300,15, +0xd64380,15, +0xd64400,15, +0xd64480,15, +0xd64500,15, +0xd64580,15, +0xd64604,10, +0xd64700,2, +0xd6470c,7, +0xd64740,1, +0xd64770,1, +0xd647c0,2, +0xd647d0,4, +0xd65000,3, +0xd65010,1, +0xd6501c,3, +0xd65104,1, +0xd65110,4, +0xd65124,1, +0xd65130,4, +0xd65144,1, +0xd65150,4, +0xd65164,1, +0xd65170,5, +0xd65190,4, +0xd65a00,4, +0xd65c00,129, +0xd66000,37, +0xd66098,1, +0xd66100,37, +0xd66198,1, +0xd66200,37, +0xd66298,1, +0xd66300,37, +0xd66398,1, +0xd66400,37, +0xd66498,1, +0xd66500,37, +0xd66598,1, +0xd66600,37, +0xd66698,1, +0xd66700,37, +0xd66798,1, +0xd6c000,91, +0xd6c400,4, +0xd6c440,15, +0xd6c480,4, +0xd6c4c0,15, +0xd6c500,4, +0xd6c540,15, +0xd6c580,4, +0xd6c5c0,15, +0xd6c600,4, +0xd6c640,10, +0xd6c680,4, +0xd6c6c0,10, +0xd6c800,4, +0xd6c840,33, +0xd6ca00,13, +0xd6ca80,1, +0xd6ca88,8, +0xd6cac0,6, +0xd6cae0,1, +0xd6cae8,2, +0xd6cb04,14, +0xd6cc00,4, +0xd6ccc8,1, +0xd6cfcc,3, +0xd6cfe0,99, +0xd6d400,4, +0xd6d440,15, +0xd6d480,4, +0xd6d4c0,15, +0xd6d500,4, +0xd6d540,15, +0xd6d580,4, +0xd6d5c0,15, +0xd6d600,4, +0xd6d640,10, +0xd6d680,4, +0xd6d6c0,10, +0xd6d800,4, +0xd6d840,33, +0xd6da00,13, +0xd6da80,1, +0xd6da88,8, +0xd6dac0,6, +0xd6dae0,1, +0xd6dae8,2, +0xd6db04,14, +0xd6dc00,4, +0xd6dcc8,1, +0xd6dfcc,3, +0xd6dfe0,27, +0xd6f000,19, +0xd6fa00,10, +0xd6fa80,3, +0xd6fb00,6, +0xd70000,51, +0xd70a00,10, +0xd70a80,3, +0xd71000,2, +0xd7100c,4, +0xd71028,3, +0xd71038,4, +0xd71050,2, +0xd71080,4, +0xd71098,7, +0xd71120,4, +0xd71200,4, +0xd71214,7, +0xd71234,3, +0xd71280,8, +0xd712c0,5, +0xd71300,2, +0xd7130c,3, +0xd71400,24, +0xd71464,2, +0xd71470,3, +0xd71500,25, +0xd715c0,8, +0xd715e8,5, +0xd71600,5, +0xd71618,1, +0xd71620,1, +0xd71628,1, +0xd71630,2, +0xd71640,2, +0xd71650,2, +0xd71690,4, +0xd71740,2, +0xd71760,6, +0xd71780,6, +0xd717a0,6, +0xd717c0,6, +0xd717e0,1, +0xd71800,2, +0xd7180c,4, +0xd71828,3, +0xd71838,4, +0xd71850,2, +0xd71880,4, +0xd71898,7, +0xd71920,4, +0xd71a00,4, +0xd71a14,7, +0xd71a34,3, +0xd71a80,8, +0xd71ac0,5, +0xd71b00,2, +0xd71b0c,3, +0xd71c00,24, +0xd71c64,2, +0xd71c70,3, +0xd71d00,25, +0xd71dc0,8, +0xd71de8,5, +0xd71e00,5, +0xd71e18,1, +0xd71e20,1, +0xd71e28,1, +0xd71e30,2, +0xd71e40,2, +0xd71e50,2, +0xd71e90,4, +0xd71f40,2, +0xd71f60,6, +0xd71f80,6, +0xd71fa0,6, +0xd71fc0,6, +0xd71fe0,1, +0xd72000,19, +0xd72080,2, +0xd720b0,2, +0xd720c0,2, +0xd80000,11, +0xd80040,16, +0xd80084,5, +0xd80200,7, +0xd80220,6, +0xd80240,7, +0xd80260,6, +0xd80280,6, +0xd802a0,2, +0xd802ac,2, +0xd802c0,7, +0xd802e0,7, +0xd80300,2, +0xd8030c,2, +0xd80320,6, +0xd80400,2, +0xd81000,19, +0xd82104,23, +0xd82180,7, +0xd821a0,6, +0xd821c0,7, +0xd821e0,6, +0xd82200,4, +0xd82220,4, +0xd82240,11, +0xd82270,32, +0xd82300,24, +0xd82380,20, +0xd82400,61, +0xd82500,25, +0xd82568,4, +0xd82580,2, +0xd825a0,1, +0xd825c0,11, +0xd82600,9, +0xd82640,3, +0xd82650,3, +0xd82664,3, +0xd82680,22, +0xd82800,11, +0xd83000,536, +0xd84104,23, +0xd84180,7, +0xd841a0,6, +0xd841c0,7, +0xd841e0,6, +0xd84200,4, +0xd84220,4, +0xd84240,11, +0xd84270,32, +0xd84300,24, +0xd84380,20, +0xd84400,61, +0xd84500,25, +0xd84568,4, +0xd84580,2, +0xd845a0,1, +0xd845c0,11, +0xd84600,9, +0xd84640,3, +0xd84650,3, +0xd84664,3, +0xd84680,22, +0xd84800,11, +0xd85000,536, +0xd8a000,7, +0xd8a048,8, +0xd8a080,8, +0xd8a100,7, +0xd8a148,8, +0xd8a180,8, +0xd90000,11, +0xd90040,16, +0xd90084,5, +0xd90200,7, +0xd90220,6, +0xd90240,7, +0xd90260,6, +0xd90280,6, +0xd902a0,2, +0xd902ac,2, +0xd902c0,7, +0xd902e0,7, +0xd90300,2, +0xd9030c,2, +0xd90320,6, +0xd90400,2, +0xd91000,19, +0xd92104,23, +0xd92180,7, +0xd921a0,6, +0xd921c0,7, +0xd921e0,6, +0xd92200,4, +0xd92220,4, +0xd92240,11, +0xd92270,32, +0xd92300,24, +0xd92380,20, +0xd92400,61, +0xd92500,25, +0xd92568,4, +0xd92580,2, +0xd925a0,1, +0xd925c0,11, +0xd92600,9, +0xd92640,3, +0xd92650,3, +0xd92664,3, +0xd92680,22, +0xd92800,11, +0xd93000,536, +0xd94104,23, +0xd94180,7, +0xd941a0,6, +0xd941c0,7, +0xd941e0,6, +0xd94200,4, +0xd94220,4, +0xd94240,11, +0xd94270,32, +0xd94300,24, +0xd94380,20, +0xd94400,61, +0xd94500,25, +0xd94568,4, +0xd94580,2, +0xd945a0,1, +0xd945c0,11, +0xd94600,9, +0xd94640,3, +0xd94650,3, +0xd94664,3, +0xd94680,22, +0xd94800,11, +0xd95000,536, +0xd9a000,7, +0xd9a048,8, +0xd9a080,8, +0xd9a100,7, +0xd9a148,8, +0xd9a180,8, +0xda0400,4, +0xda0440,4, +0xda05c0,1, +0xda0600,8, +0xda0800,18, +0xda0880,13, +0xda08f0,3, +0xda0900,18, +0xda0980,13, +0xda09f0,3, +0xda0e00,4, +0xda0e20,4, +0xda0e80,16, +0xda0f00,1, +0xda0f20,1, +0xda1020,2, +0xda1208,6, +0xda1228,10, +0xda1288,6, +0xda12a8,10, +0xda1600,32, +0xda18c0,8, +0xda1900,24, +0xda19b0,4, +0xda1aa0,2, +0xda1ac0,4, +0xda2200,19, +0xda2280,19, +0xda2400,14, +0xda243c,9, +0xda2464,14, +0xda24a0,2, +0xda24ac,2, +0xda2500,14, +0xda253c,9, +0xda2564,14, +0xda25a0,2, +0xda25ac,2, +0xda2800,19, +0xda2880,19, +0xda2a10,2, +0xda2a1c,1, +0xda2a50,2, +0xda2a5c,1, +0xda2c00,7, +0xda2c20,1, +0xda2c54,18, +0xda2ca0,1, +0xda2cd4,11, +0xda2e00,1, +0xda2e08,6, +0xda3180,3, +0xda4400,4, +0xda4440,4, +0xda45c0,1, +0xda4600,8, +0xda4800,18, +0xda4880,13, +0xda48f0,3, +0xda4900,18, +0xda4980,13, +0xda49f0,3, +0xda4e00,4, +0xda4e20,4, +0xda4e80,16, +0xda4f00,1, +0xda4f20,1, +0xda5020,2, +0xda5208,6, +0xda5228,10, +0xda5288,6, +0xda52a8,10, +0xda5600,32, +0xda58c0,8, +0xda5900,24, +0xda59b0,4, +0xda5aa0,2, +0xda5ac0,4, +0xda6200,19, +0xda6280,19, +0xda6400,14, +0xda643c,9, +0xda6464,14, +0xda64a0,2, +0xda64ac,2, +0xda6500,14, +0xda653c,9, +0xda6564,14, +0xda65a0,2, +0xda65ac,2, +0xda6800,19, +0xda6880,19, +0xda6a10,2, +0xda6a1c,1, +0xda6a50,2, +0xda6a5c,1, +0xda6c00,7, +0xda6c20,1, +0xda6c54,18, +0xda6ca0,1, +0xda6cd4,11, +0xda6e00,1, +0xda6e08,6, +0xda7180,3, +0xda9000,13, +0xdae000,19, +0xdaea00,10, +0xdaea80,3, +0xdaf000,1, +0xdaf008,5, +0xdaf038,1, +0xdaf044,1, +0xdaf050,2, +0xdaf060,8, +0xdaf140,19, +0xdaf190,4, +0xdb0000,2, +0xdb000c,2, +0xdb0040,7, +0xdb0100,3, +0xdb0110,3, +0xdb0120,5, +0xdb0200,6, +0xdb0240,5, +0xdb0400,2, +0xdb040c,2, +0xdb0440,7, +0xdb0500,3, +0xdb0510,3, +0xdb0520,5, +0xdb0600,6, +0xdb0640,5, +0xdb0800,2, +0xdb080c,2, +0xdb0840,7, +0xdb0900,3, +0xdb0910,3, +0xdb0920,5, +0xdb0a00,6, +0xdb0a40,5, +0xdb0c00,2, +0xdb0c0c,2, +0xdb0c40,7, +0xdb0d00,3, +0xdb0d10,3, +0xdb0d20,5, +0xdb0e00,6, +0xdb0e40,5, +0xdb1000,2, +0xdb100c,2, +0xdb1040,7, +0xdb1100,3, +0xdb1110,3, +0xdb1120,5, +0xdb1200,6, +0xdb1240,5, +0xdb1400,2, +0xdb140c,2, +0xdb1440,7, +0xdb1500,3, +0xdb1510,3, +0xdb1520,5, +0xdb1600,6, +0xdb1640,5, +0xdb1800,2, +0xdb180c,2, +0xdb1840,7, +0xdb1900,3, +0xdb1910,3, +0xdb1920,5, +0xdb1a00,6, +0xdb1a40,5, +0xdb1c00,2, +0xdb1c0c,2, +0xdb1c40,7, +0xdb1d00,3, +0xdb1d10,3, +0xdb1d20,5, +0xdb1e00,6, +0xdb1e40,5, +0xdb2000,5, +0xdb2040,9, +0xdb2100,3, +0xdb2200,1, +0xdb2210,1, +0xdb2220,1, +0xdb2230,1, +0xdb2240,1, +0xdb2300,3, +0xdb2314,1, +0xdb2320,4, +0xdb2400,5, +0xdb2440,5, +0xdb3000,80, +0xdb3200,1, +0xdb8000,7, +0xdb8030,2, +0xdb8040,7, +0xdb8070,2, +0xdb8100,2, +0xdb8120,2, +0xdb8140,2, +0xdb8160,2, +0xdb8180,9, +0xdb8200,7, +0xdb8230,2, +0xdb8240,7, +0xdb8270,2, +0xdb8300,2, +0xdb8320,2, +0xdb8340,2, +0xdb8360,2, +0xdb8380,9, +0xdb8400,11, +0xdb8500,11, +0xdb9000,3, +0xdb9010,2, +0xdb901c,5, +0xdb9040,8, +0xdb9080,3, +0xdb9090,2, +0xdb909c,5, +0xdb90c0,8, +0xdb9100,3, +0xdb9110,2, +0xdb911c,5, +0xdb9140,8, +0xdb9180,3, +0xdb9190,2, +0xdb919c,5, +0xdb91c0,8, +0xdb9200,7, +0xdb9220,12, +0xdb9280,7, +0xdb92a0,12, +0xdb9300,3, +0xdb9310,1, +0xdb9400,3, +0xdb9410,2, +0xdb941c,5, +0xdb9440,8, +0xdb9480,3, +0xdb9490,2, +0xdb949c,5, +0xdb94c0,8, +0xdb9500,3, +0xdb9510,2, +0xdb951c,5, +0xdb9540,8, +0xdb9580,3, +0xdb9590,2, +0xdb959c,5, +0xdb95c0,8, +0xdb9600,7, +0xdb9620,12, +0xdb9680,7, +0xdb96a0,12, +0xdb9700,3, +0xdb9710,1, +0xdb9804,1, +0xdb9824,21, +0xdb9880,16, +0xdb9900,5, +0xdb9920,11, +0xdb9950,9, +0xdb9980,22, +0xdb9a00,22, +0xdb9a80,22, +0xdb9b00,22, +0xdb9b80,22, +0xdb9c00,22, +0xdb9c80,22, +0xdb9d00,22, +0xdb9d80,3, +0xdc0000,5, +0xdc0018,5, +0xdc0030,3, +0xdc0044,3, +0xdc0100,58, +0xdc01f0,3, +0xdc0280,3, +0xdc0400,5, +0xdc0418,5, +0xdc0430,3, +0xdc0444,3, +0xdc0500,58, +0xdc05f0,3, +0xdc0680,3, +0xdc1018,2, +0xdc1100,2, +0xdc1110,10, +0xdc1140,2, +0xdc1150,10, +0xdc1208,1, +0xdc1220,12, +0xdc1280,1, +0xdc1288,2, +0xdc1400,4, +0xdc2000,5, +0xdc2018,5, +0xdc2030,3, +0xdc2044,3, +0xdc2100,58, +0xdc21f0,3, +0xdc2280,3, +0xdc2400,5, +0xdc2418,5, +0xdc2430,3, +0xdc2444,3, +0xdc2500,58, +0xdc25f0,3, +0xdc2680,3, +0xdc3018,2, +0xdc3100,2, +0xdc3110,10, +0xdc3140,2, +0xdc3150,10, +0xdc3208,1, +0xdc3220,12, +0xdc3280,1, +0xdc3288,2, +0xdc3400,4, +0xdc4000,2, +0xdc400c,1, +0xdc4030,3, +0xdc4040,2, +0xdc404c,1, +0xdc4070,3, +0xdc4100,2, +0xdc410c,1, +0xdc4130,3, +0xdc4140,2, +0xdc414c,1, +0xdc4170,3, +0xdc4200,15, +0xdc4280,15, +0xdc4300,15, +0xdc4380,15, +0xdc4400,15, +0xdc4480,15, +0xdc4500,15, +0xdc4580,15, +0xdc4604,10, +0xdc4700,2, +0xdc470c,7, +0xdc4740,1, +0xdc4770,1, +0xdc47c0,2, +0xdc47d0,4, +0xdc5000,3, +0xdc5010,1, +0xdc501c,3, +0xdc5104,1, +0xdc5110,4, +0xdc5124,1, +0xdc5130,4, +0xdc5144,1, +0xdc5150,4, +0xdc5164,1, +0xdc5170,5, +0xdc5190,4, +0xdc5a00,4, +0xdc5c00,129, +0xdc6000,37, +0xdc6098,1, +0xdc6100,37, +0xdc6198,1, +0xdc6200,37, +0xdc6298,1, +0xdc6300,37, +0xdc6398,1, +0xdc6400,37, +0xdc6498,1, +0xdc6500,37, +0xdc6598,1, +0xdc6600,37, +0xdc6698,1, +0xdc6700,37, +0xdc6798,1, +0xdcc000,91, +0xdcc400,4, +0xdcc440,15, +0xdcc480,4, +0xdcc4c0,15, +0xdcc500,4, +0xdcc540,15, +0xdcc580,4, +0xdcc5c0,15, +0xdcc600,4, +0xdcc640,10, +0xdcc680,4, +0xdcc6c0,10, +0xdcc800,4, +0xdcc840,33, +0xdcca00,13, +0xdcca80,1, +0xdcca88,8, +0xdccac0,6, +0xdccae0,1, +0xdccae8,2, +0xdccb04,14, +0xdccc00,4, +0xdcccc8,1, +0xdccfcc,3, +0xdccfe0,99, +0xdcd400,4, +0xdcd440,15, +0xdcd480,4, +0xdcd4c0,15, +0xdcd500,4, +0xdcd540,15, +0xdcd580,4, +0xdcd5c0,15, +0xdcd600,4, +0xdcd640,10, +0xdcd680,4, +0xdcd6c0,10, +0xdcd800,4, +0xdcd840,33, +0xdcda00,13, +0xdcda80,1, +0xdcda88,8, +0xdcdac0,6, +0xdcdae0,1, +0xdcdae8,2, +0xdcdb04,14, +0xdcdc00,4, +0xdcdcc8,1, +0xdcdfcc,3, +0xdcdfe0,27, +0xdcf000,19, +0xdcfa00,10, +0xdcfa80,3, +0xdcfb00,6, +0xdd0000,51, +0xdd0a00,10, +0xdd0a80,3, +0xdd1000,2, +0xdd100c,4, +0xdd1028,3, +0xdd1038,4, +0xdd1050,2, +0xdd1080,4, +0xdd1098,7, +0xdd1120,4, +0xdd1200,4, +0xdd1214,7, +0xdd1234,3, +0xdd1280,8, +0xdd12c0,5, +0xdd1300,2, +0xdd130c,3, +0xdd1400,24, +0xdd1464,2, +0xdd1470,3, +0xdd1500,25, +0xdd15c0,8, +0xdd15e8,5, +0xdd1600,5, +0xdd1618,1, +0xdd1620,1, +0xdd1628,1, +0xdd1630,2, +0xdd1640,2, +0xdd1650,2, +0xdd1690,4, +0xdd1740,2, +0xdd1760,6, +0xdd1780,6, +0xdd17a0,6, +0xdd17c0,6, +0xdd17e0,1, +0xdd1800,2, +0xdd180c,4, +0xdd1828,3, +0xdd1838,4, +0xdd1850,2, +0xdd1880,4, +0xdd1898,7, +0xdd1920,4, +0xdd1a00,4, +0xdd1a14,7, +0xdd1a34,3, +0xdd1a80,8, +0xdd1ac0,5, +0xdd1b00,2, +0xdd1b0c,3, +0xdd1c00,24, +0xdd1c64,2, +0xdd1c70,3, +0xdd1d00,25, +0xdd1dc0,8, +0xdd1de8,5, +0xdd1e00,5, +0xdd1e18,1, +0xdd1e20,1, +0xdd1e28,1, +0xdd1e30,2, +0xdd1e40,2, +0xdd1e50,2, +0xdd1e90,4, +0xdd1f40,2, +0xdd1f60,6, +0xdd1f80,6, +0xdd1fa0,6, +0xdd1fc0,6, +0xdd1fe0,1, +0xdd2000,19, +0xdd2080,2, +0xdd20b0,2, +0xdd20c0,2, +0xde0000,11, +0xde0040,16, +0xde0084,5, +0xde0200,7, +0xde0220,6, +0xde0240,7, +0xde0260,6, +0xde0280,6, +0xde02a0,2, +0xde02ac,2, +0xde02c0,7, +0xde02e0,7, +0xde0300,2, +0xde030c,2, +0xde0320,6, +0xde0400,2, +0xde1000,19, +0xde2104,23, +0xde2180,7, +0xde21a0,6, +0xde21c0,7, +0xde21e0,6, +0xde2200,4, +0xde2220,4, +0xde2240,11, +0xde2270,32, +0xde2300,24, +0xde2380,20, +0xde2400,61, +0xde2500,25, +0xde2568,4, +0xde2580,2, +0xde25a0,1, +0xde25c0,11, +0xde2600,9, +0xde2640,3, +0xde2650,3, +0xde2664,3, +0xde2680,22, +0xde2800,11, +0xde3000,536, +0xde4104,23, +0xde4180,7, +0xde41a0,6, +0xde41c0,7, +0xde41e0,6, +0xde4200,4, +0xde4220,4, +0xde4240,11, +0xde4270,32, +0xde4300,24, +0xde4380,20, +0xde4400,61, +0xde4500,25, +0xde4568,4, +0xde4580,2, +0xde45a0,1, +0xde45c0,11, +0xde4600,9, +0xde4640,3, +0xde4650,3, +0xde4664,3, +0xde4680,22, +0xde4800,11, +0xde5000,536, +0xdea000,7, +0xdea048,8, +0xdea080,8, +0xdea100,7, +0xdea148,8, +0xdea180,8, +0xdf0000,11, +0xdf0040,16, +0xdf0084,5, +0xdf0200,7, +0xdf0220,6, +0xdf0240,7, +0xdf0260,6, +0xdf0280,6, +0xdf02a0,2, +0xdf02ac,2, +0xdf02c0,7, +0xdf02e0,7, +0xdf0300,2, +0xdf030c,2, +0xdf0320,6, +0xdf0400,2, +0xdf1000,19, +0xdf2104,23, +0xdf2180,7, +0xdf21a0,6, +0xdf21c0,7, +0xdf21e0,6, +0xdf2200,4, +0xdf2220,4, +0xdf2240,11, +0xdf2270,32, +0xdf2300,24, +0xdf2380,20, +0xdf2400,61, +0xdf2500,25, +0xdf2568,4, +0xdf2580,2, +0xdf25a0,1, +0xdf25c0,11, +0xdf2600,9, +0xdf2640,3, +0xdf2650,3, +0xdf2664,3, +0xdf2680,22, +0xdf2800,11, +0xdf3000,536, +0xdf4104,23, +0xdf4180,7, +0xdf41a0,6, +0xdf41c0,7, +0xdf41e0,6, +0xdf4200,4, +0xdf4220,4, +0xdf4240,11, +0xdf4270,32, +0xdf4300,24, +0xdf4380,20, +0xdf4400,61, +0xdf4500,25, +0xdf4568,4, +0xdf4580,2, +0xdf45a0,1, +0xdf45c0,11, +0xdf4600,9, +0xdf4640,3, +0xdf4650,3, +0xdf4664,3, +0xdf4680,22, +0xdf4800,11, +0xdf5000,536, +0xdfa000,7, +0xdfa048,8, +0xdfa080,8, +0xdfa100,7, +0xdfa148,8, +0xdfa180,8, +0xe00400,4, +0xe00440,4, +0xe005c0,1, +0xe00600,8, +0xe00800,18, +0xe00880,13, +0xe008f0,3, +0xe00900,18, +0xe00980,13, +0xe009f0,3, +0xe00e00,4, +0xe00e20,4, +0xe00e80,16, +0xe00f00,1, +0xe00f20,1, +0xe01020,2, +0xe01208,6, +0xe01228,10, +0xe01288,6, +0xe012a8,10, +0xe01600,32, +0xe018c0,8, +0xe01900,24, +0xe019b0,4, +0xe01aa0,2, +0xe01ac0,4, +0xe02200,19, +0xe02280,19, +0xe02400,14, +0xe0243c,9, +0xe02464,14, +0xe024a0,2, +0xe024ac,2, +0xe02500,14, +0xe0253c,9, +0xe02564,14, +0xe025a0,2, +0xe025ac,2, +0xe02800,19, +0xe02880,19, +0xe02a10,2, +0xe02a1c,1, +0xe02a50,2, +0xe02a5c,1, +0xe02c00,7, +0xe02c20,1, +0xe02c54,18, +0xe02ca0,1, +0xe02cd4,11, +0xe02e00,1, +0xe02e08,6, +0xe03180,3, +0xe04400,4, +0xe04440,4, +0xe045c0,1, +0xe04600,8, +0xe04800,18, +0xe04880,13, +0xe048f0,3, +0xe04900,18, +0xe04980,13, +0xe049f0,3, +0xe04e00,4, +0xe04e20,4, +0xe04e80,16, +0xe04f00,1, +0xe04f20,1, +0xe05020,2, +0xe05208,6, +0xe05228,10, +0xe05288,6, +0xe052a8,10, +0xe05600,32, +0xe058c0,8, +0xe05900,24, +0xe059b0,4, +0xe05aa0,2, +0xe05ac0,4, +0xe06200,19, +0xe06280,19, +0xe06400,14, +0xe0643c,9, +0xe06464,14, +0xe064a0,2, +0xe064ac,2, +0xe06500,14, +0xe0653c,9, +0xe06564,14, +0xe065a0,2, +0xe065ac,2, +0xe06800,19, +0xe06880,19, +0xe06a10,2, +0xe06a1c,1, +0xe06a50,2, +0xe06a5c,1, +0xe06c00,7, +0xe06c20,1, +0xe06c54,18, +0xe06ca0,1, +0xe06cd4,11, +0xe06e00,1, +0xe06e08,6, +0xe07180,3, +0xe09000,13, +0xe0e000,19, +0xe0ea00,10, +0xe0ea80,3, +0xe0f000,1, +0xe0f008,5, +0xe0f038,1, +0xe0f044,1, +0xe0f050,2, +0xe0f060,8, +0xe0f140,19, +0xe0f190,4, +0xe10000,2, +0xe1000c,2, +0xe10040,7, +0xe10100,3, +0xe10110,3, +0xe10120,5, +0xe10200,6, +0xe10240,5, +0xe10400,2, +0xe1040c,2, +0xe10440,7, +0xe10500,3, +0xe10510,3, +0xe10520,5, +0xe10600,6, +0xe10640,5, +0xe10800,2, +0xe1080c,2, +0xe10840,7, +0xe10900,3, +0xe10910,3, +0xe10920,5, +0xe10a00,6, +0xe10a40,5, +0xe10c00,2, +0xe10c0c,2, +0xe10c40,7, +0xe10d00,3, +0xe10d10,3, +0xe10d20,5, +0xe10e00,6, +0xe10e40,5, +0xe11000,2, +0xe1100c,2, +0xe11040,7, +0xe11100,3, +0xe11110,3, +0xe11120,5, +0xe11200,6, +0xe11240,5, +0xe11400,2, +0xe1140c,2, +0xe11440,7, +0xe11500,3, +0xe11510,3, +0xe11520,5, +0xe11600,6, +0xe11640,5, +0xe11800,2, +0xe1180c,2, +0xe11840,7, +0xe11900,3, +0xe11910,3, +0xe11920,5, +0xe11a00,6, +0xe11a40,5, +0xe11c00,2, +0xe11c0c,2, +0xe11c40,7, +0xe11d00,3, +0xe11d10,3, +0xe11d20,5, +0xe11e00,6, +0xe11e40,5, +0xe12000,5, +0xe12040,9, +0xe12100,3, +0xe12200,1, +0xe12210,1, +0xe12220,1, +0xe12230,1, +0xe12240,1, +0xe12300,3, +0xe12314,1, +0xe12320,4, +0xe12400,5, +0xe12440,5, +0xe13000,80, +0xe13200,1, +0xe18000,7, +0xe18030,2, +0xe18040,7, +0xe18070,2, +0xe18100,2, +0xe18120,2, +0xe18140,2, +0xe18160,2, +0xe18180,9, +0xe18200,7, +0xe18230,2, +0xe18240,7, +0xe18270,2, +0xe18300,2, +0xe18320,2, +0xe18340,2, +0xe18360,2, +0xe18380,9, +0xe18400,11, +0xe18500,11, +0xe19000,3, +0xe19010,2, +0xe1901c,5, +0xe19040,8, +0xe19080,3, +0xe19090,2, +0xe1909c,5, +0xe190c0,8, +0xe19100,3, +0xe19110,2, +0xe1911c,5, +0xe19140,8, +0xe19180,3, +0xe19190,2, +0xe1919c,5, +0xe191c0,8, +0xe19200,7, +0xe19220,12, +0xe19280,7, +0xe192a0,12, +0xe19300,3, +0xe19310,1, +0xe19400,3, +0xe19410,2, +0xe1941c,5, +0xe19440,8, +0xe19480,3, +0xe19490,2, +0xe1949c,5, +0xe194c0,8, +0xe19500,3, +0xe19510,2, +0xe1951c,5, +0xe19540,8, +0xe19580,3, +0xe19590,2, +0xe1959c,5, +0xe195c0,8, +0xe19600,7, +0xe19620,12, +0xe19680,7, +0xe196a0,12, +0xe19700,3, +0xe19710,1, +0xe19804,1, +0xe19824,21, +0xe19880,16, +0xe19900,5, +0xe19920,11, +0xe19950,9, +0xe19980,22, +0xe19a00,22, +0xe19a80,22, +0xe19b00,22, +0xe19b80,22, +0xe19c00,22, +0xe19c80,22, +0xe19d00,22, +0xe19d80,3, +0xe20000,5, +0xe20018,5, +0xe20030,3, +0xe20044,3, +0xe20100,58, +0xe201f0,3, +0xe20280,3, +0xe20400,5, +0xe20418,5, +0xe20430,3, +0xe20444,3, +0xe20500,58, +0xe205f0,3, +0xe20680,3, +0xe21018,2, +0xe21100,2, +0xe21110,10, +0xe21140,2, +0xe21150,10, +0xe21208,1, +0xe21220,12, +0xe21280,1, +0xe21288,2, +0xe21400,4, +0xe22000,5, +0xe22018,5, +0xe22030,3, +0xe22044,3, +0xe22100,58, +0xe221f0,3, +0xe22280,3, +0xe22400,5, +0xe22418,5, +0xe22430,3, +0xe22444,3, +0xe22500,58, +0xe225f0,3, +0xe22680,3, +0xe23018,2, +0xe23100,2, +0xe23110,10, +0xe23140,2, +0xe23150,10, +0xe23208,1, +0xe23220,12, +0xe23280,1, +0xe23288,2, +0xe23400,4, +0xe24000,2, +0xe2400c,1, +0xe24030,3, +0xe24040,2, +0xe2404c,1, +0xe24070,3, +0xe24100,2, +0xe2410c,1, +0xe24130,3, +0xe24140,2, +0xe2414c,1, +0xe24170,3, +0xe24200,15, +0xe24280,15, +0xe24300,15, +0xe24380,15, +0xe24400,15, +0xe24480,15, +0xe24500,15, +0xe24580,15, +0xe24604,10, +0xe24700,2, +0xe2470c,7, +0xe24740,1, +0xe24770,1, +0xe247c0,2, +0xe247d0,4, +0xe25000,3, +0xe25010,1, +0xe2501c,3, +0xe25104,1, +0xe25110,4, +0xe25124,1, +0xe25130,4, +0xe25144,1, +0xe25150,4, +0xe25164,1, +0xe25170,5, +0xe25190,4, +0xe25a00,4, +0xe25c00,129, +0xe26000,37, +0xe26098,1, +0xe26100,37, +0xe26198,1, +0xe26200,37, +0xe26298,1, +0xe26300,37, +0xe26398,1, +0xe26400,37, +0xe26498,1, +0xe26500,37, +0xe26598,1, +0xe26600,37, +0xe26698,1, +0xe26700,37, +0xe26798,1, +0xe2c000,91, +0xe2c400,4, +0xe2c440,15, +0xe2c480,4, +0xe2c4c0,15, +0xe2c500,4, +0xe2c540,15, +0xe2c580,4, +0xe2c5c0,15, +0xe2c600,4, +0xe2c640,10, +0xe2c680,4, +0xe2c6c0,10, +0xe2c800,4, +0xe2c840,33, +0xe2ca00,13, +0xe2ca80,1, +0xe2ca88,8, +0xe2cac0,6, +0xe2cae0,1, +0xe2cae8,2, +0xe2cb04,14, +0xe2cc00,4, +0xe2ccc8,1, +0xe2cfcc,3, +0xe2cfe0,99, +0xe2d400,4, +0xe2d440,15, +0xe2d480,4, +0xe2d4c0,15, +0xe2d500,4, +0xe2d540,15, +0xe2d580,4, +0xe2d5c0,15, +0xe2d600,4, +0xe2d640,10, +0xe2d680,4, +0xe2d6c0,10, +0xe2d800,4, +0xe2d840,33, +0xe2da00,13, +0xe2da80,1, +0xe2da88,8, +0xe2dac0,6, +0xe2dae0,1, +0xe2dae8,2, +0xe2db04,14, +0xe2dc00,4, +0xe2dcc8,1, +0xe2dfcc,3, +0xe2dfe0,27, +0xe2f000,19, +0xe2fa00,10, +0xe2fa80,3, +0xe2fb00,6, +0xe30000,51, +0xe30a00,10, +0xe30a80,3, +0xe31000,2, +0xe3100c,4, +0xe31028,3, +0xe31038,4, +0xe31050,2, +0xe31080,4, +0xe31098,7, +0xe31120,4, +0xe31200,4, +0xe31214,7, +0xe31234,3, +0xe31280,8, +0xe312c0,5, +0xe31300,2, +0xe3130c,3, +0xe31400,24, +0xe31464,2, +0xe31470,3, +0xe31500,25, +0xe315c0,8, +0xe315e8,5, +0xe31600,5, +0xe31618,1, +0xe31620,1, +0xe31628,1, +0xe31630,2, +0xe31640,2, +0xe31650,2, +0xe31690,4, +0xe31740,2, +0xe31760,6, +0xe31780,6, +0xe317a0,6, +0xe317c0,6, +0xe317e0,1, +0xe31800,2, +0xe3180c,4, +0xe31828,3, +0xe31838,4, +0xe31850,2, +0xe31880,4, +0xe31898,7, +0xe31920,4, +0xe31a00,4, +0xe31a14,7, +0xe31a34,3, +0xe31a80,8, +0xe31ac0,5, +0xe31b00,2, +0xe31b0c,3, +0xe31c00,24, +0xe31c64,2, +0xe31c70,3, +0xe31d00,25, +0xe31dc0,8, +0xe31de8,5, +0xe31e00,5, +0xe31e18,1, +0xe31e20,1, +0xe31e28,1, +0xe31e30,2, +0xe31e40,2, +0xe31e50,2, +0xe31e90,4, +0xe31f40,2, +0xe31f60,6, +0xe31f80,6, +0xe31fa0,6, +0xe31fc0,6, +0xe31fe0,1, +0xe32000,19, +0xe32080,2, +0xe320b0,2, +0xe320c0,2, +0xe40000,11, +0xe40040,16, +0xe40084,5, +0xe40200,7, +0xe40220,6, +0xe40240,7, +0xe40260,6, +0xe40280,6, +0xe402a0,2, +0xe402ac,2, +0xe402c0,7, +0xe402e0,7, +0xe40300,2, +0xe4030c,2, +0xe40320,6, +0xe40400,2, +0xe41000,19, +0xe42104,23, +0xe42180,7, +0xe421a0,6, +0xe421c0,7, +0xe421e0,6, +0xe42200,4, +0xe42220,4, +0xe42240,11, +0xe42270,32, +0xe42300,24, +0xe42380,20, +0xe42400,61, +0xe42500,25, +0xe42568,4, +0xe42580,2, +0xe425a0,1, +0xe425c0,11, +0xe42600,9, +0xe42640,3, +0xe42650,3, +0xe42664,3, +0xe42680,22, +0xe42800,11, +0xe43000,536, +0xe44104,23, +0xe44180,7, +0xe441a0,6, +0xe441c0,7, +0xe441e0,6, +0xe44200,4, +0xe44220,4, +0xe44240,11, +0xe44270,32, +0xe44300,24, +0xe44380,20, +0xe44400,61, +0xe44500,25, +0xe44568,4, +0xe44580,2, +0xe445a0,1, +0xe445c0,11, +0xe44600,9, +0xe44640,3, +0xe44650,3, +0xe44664,3, +0xe44680,22, +0xe44800,11, +0xe45000,536, +0xe4a000,7, +0xe4a048,8, +0xe4a080,8, +0xe4a100,7, +0xe4a148,8, +0xe4a180,8, +0xe50000,11, +0xe50040,16, +0xe50084,5, +0xe50200,7, +0xe50220,6, +0xe50240,7, +0xe50260,6, +0xe50280,6, +0xe502a0,2, +0xe502ac,2, +0xe502c0,7, +0xe502e0,7, +0xe50300,2, +0xe5030c,2, +0xe50320,6, +0xe50400,2, +0xe51000,19, +0xe52104,23, +0xe52180,7, +0xe521a0,6, +0xe521c0,7, +0xe521e0,6, +0xe52200,4, +0xe52220,4, +0xe52240,11, +0xe52270,32, +0xe52300,24, +0xe52380,20, +0xe52400,61, +0xe52500,25, +0xe52568,4, +0xe52580,2, +0xe525a0,1, +0xe525c0,11, +0xe52600,9, +0xe52640,3, +0xe52650,3, +0xe52664,3, +0xe52680,22, +0xe52800,11, +0xe53000,536, +0xe54104,23, +0xe54180,7, +0xe541a0,6, +0xe541c0,7, +0xe541e0,6, +0xe54200,4, +0xe54220,4, +0xe54240,11, +0xe54270,32, +0xe54300,24, +0xe54380,20, +0xe54400,61, +0xe54500,25, +0xe54568,4, +0xe54580,2, +0xe545a0,1, +0xe545c0,11, +0xe54600,9, +0xe54640,3, +0xe54650,3, +0xe54664,3, +0xe54680,22, +0xe54800,11, +0xe55000,536, +0xe5a000,7, +0xe5a048,8, +0xe5a080,8, +0xe5a100,7, +0xe5a148,8, +0xe5a180,8, +0xe60400,4, +0xe60440,4, +0xe605c0,1, +0xe60600,8, +0xe60800,18, +0xe60880,13, +0xe608f0,3, +0xe60900,18, +0xe60980,13, +0xe609f0,3, +0xe60e00,4, +0xe60e20,4, +0xe60e80,16, +0xe60f00,1, +0xe60f20,1, +0xe61020,2, +0xe61208,6, +0xe61228,10, +0xe61288,6, +0xe612a8,10, +0xe61600,32, +0xe618c0,8, +0xe61900,24, +0xe619b0,4, +0xe61aa0,2, +0xe61ac0,4, +0xe62200,19, +0xe62280,19, +0xe62400,14, +0xe6243c,9, +0xe62464,14, +0xe624a0,2, +0xe624ac,2, +0xe62500,14, +0xe6253c,9, +0xe62564,14, +0xe625a0,2, +0xe625ac,2, +0xe62800,19, +0xe62880,19, +0xe62a10,2, +0xe62a1c,1, +0xe62a50,2, +0xe62a5c,1, +0xe62c00,7, +0xe62c20,1, +0xe62c54,18, +0xe62ca0,1, +0xe62cd4,11, +0xe62e00,1, +0xe62e08,6, +0xe63180,3, +0xe64400,4, +0xe64440,4, +0xe645c0,1, +0xe64600,8, +0xe64800,18, +0xe64880,13, +0xe648f0,3, +0xe64900,18, +0xe64980,13, +0xe649f0,3, +0xe64e00,4, +0xe64e20,4, +0xe64e80,16, +0xe64f00,1, +0xe64f20,1, +0xe65020,2, +0xe65208,6, +0xe65228,10, +0xe65288,6, +0xe652a8,10, +0xe65600,32, +0xe658c0,8, +0xe65900,24, +0xe659b0,4, +0xe65aa0,2, +0xe65ac0,4, +0xe66200,19, +0xe66280,19, +0xe66400,14, +0xe6643c,9, +0xe66464,14, +0xe664a0,2, +0xe664ac,2, +0xe66500,14, +0xe6653c,9, +0xe66564,14, +0xe665a0,2, +0xe665ac,2, +0xe66800,19, +0xe66880,19, +0xe66a10,2, +0xe66a1c,1, +0xe66a50,2, +0xe66a5c,1, +0xe66c00,7, +0xe66c20,1, +0xe66c54,18, +0xe66ca0,1, +0xe66cd4,11, +0xe66e00,1, +0xe66e08,6, +0xe67180,3, +0xe69000,13, +0xe6e000,19, +0xe6ea00,10, +0xe6ea80,3, +0xe6f000,1, +0xe6f008,5, +0xe6f038,1, +0xe6f044,1, +0xe6f050,2, +0xe6f060,8, +0xe6f140,19, +0xe6f190,4, +0xe70000,2, +0xe7000c,2, +0xe70040,7, +0xe70100,3, +0xe70110,3, +0xe70120,5, +0xe70200,6, +0xe70240,5, +0xe70400,2, +0xe7040c,2, +0xe70440,7, +0xe70500,3, +0xe70510,3, +0xe70520,5, +0xe70600,6, +0xe70640,5, +0xe70800,2, +0xe7080c,2, +0xe70840,7, +0xe70900,3, +0xe70910,3, +0xe70920,5, +0xe70a00,6, +0xe70a40,5, +0xe70c00,2, +0xe70c0c,2, +0xe70c40,7, +0xe70d00,3, +0xe70d10,3, +0xe70d20,5, +0xe70e00,6, +0xe70e40,5, +0xe71000,2, +0xe7100c,2, +0xe71040,7, +0xe71100,3, +0xe71110,3, +0xe71120,5, +0xe71200,6, +0xe71240,5, +0xe71400,2, +0xe7140c,2, +0xe71440,7, +0xe71500,3, +0xe71510,3, +0xe71520,5, +0xe71600,6, +0xe71640,5, +0xe71800,2, +0xe7180c,2, +0xe71840,7, +0xe71900,3, +0xe71910,3, +0xe71920,5, +0xe71a00,6, +0xe71a40,5, +0xe71c00,2, +0xe71c0c,2, +0xe71c40,7, +0xe71d00,3, +0xe71d10,3, +0xe71d20,5, +0xe71e00,6, +0xe71e40,5, +0xe72000,5, +0xe72040,9, +0xe72100,3, +0xe72200,1, +0xe72210,1, +0xe72220,1, +0xe72230,1, +0xe72240,1, +0xe72300,3, +0xe72314,1, +0xe72320,4, +0xe72400,5, +0xe72440,5, +0xe73000,80, +0xe73200,1, +0xe78000,7, +0xe78030,2, +0xe78040,7, +0xe78070,2, +0xe78100,2, +0xe78120,2, +0xe78140,2, +0xe78160,2, +0xe78180,9, +0xe78200,7, +0xe78230,2, +0xe78240,7, +0xe78270,2, +0xe78300,2, +0xe78320,2, +0xe78340,2, +0xe78360,2, +0xe78380,9, +0xe78400,11, +0xe78500,11, +0xe79000,3, +0xe79010,2, +0xe7901c,5, +0xe79040,8, +0xe79080,3, +0xe79090,2, +0xe7909c,5, +0xe790c0,8, +0xe79100,3, +0xe79110,2, +0xe7911c,5, +0xe79140,8, +0xe79180,3, +0xe79190,2, +0xe7919c,5, +0xe791c0,8, +0xe79200,7, +0xe79220,12, +0xe79280,7, +0xe792a0,12, +0xe79300,3, +0xe79310,1, +0xe79400,3, +0xe79410,2, +0xe7941c,5, +0xe79440,8, +0xe79480,3, +0xe79490,2, +0xe7949c,5, +0xe794c0,8, +0xe79500,3, +0xe79510,2, +0xe7951c,5, +0xe79540,8, +0xe79580,3, +0xe79590,2, +0xe7959c,5, +0xe795c0,8, +0xe79600,7, +0xe79620,12, +0xe79680,7, +0xe796a0,12, +0xe79700,3, +0xe79710,1, +0xe79804,1, +0xe79824,21, +0xe79880,16, +0xe79900,5, +0xe79920,11, +0xe79950,9, +0xe79980,22, +0xe79a00,22, +0xe79a80,22, +0xe79b00,22, +0xe79b80,22, +0xe79c00,22, +0xe79c80,22, +0xe79d00,22, +0xe79d80,3, +0xe80000,5, +0xe80018,5, +0xe80030,3, +0xe80044,3, +0xe80100,58, +0xe801f0,3, +0xe80280,3, +0xe80400,5, +0xe80418,5, +0xe80430,3, +0xe80444,3, +0xe80500,58, +0xe805f0,3, +0xe80680,3, +0xe81018,2, +0xe81100,2, +0xe81110,10, +0xe81140,2, +0xe81150,10, +0xe81208,1, +0xe81220,12, +0xe81280,1, +0xe81288,2, +0xe81400,4, +0xe82000,5, +0xe82018,5, +0xe82030,3, +0xe82044,3, +0xe82100,58, +0xe821f0,3, +0xe82280,3, +0xe82400,5, +0xe82418,5, +0xe82430,3, +0xe82444,3, +0xe82500,58, +0xe825f0,3, +0xe82680,3, +0xe83018,2, +0xe83100,2, +0xe83110,10, +0xe83140,2, +0xe83150,10, +0xe83208,1, +0xe83220,12, +0xe83280,1, +0xe83288,2, +0xe83400,4, +0xe84000,2, +0xe8400c,1, +0xe84030,3, +0xe84040,2, +0xe8404c,1, +0xe84070,3, +0xe84100,2, +0xe8410c,1, +0xe84130,3, +0xe84140,2, +0xe8414c,1, +0xe84170,3, +0xe84200,15, +0xe84280,15, +0xe84300,15, +0xe84380,15, +0xe84400,15, +0xe84480,15, +0xe84500,15, +0xe84580,15, +0xe84604,10, +0xe84700,2, +0xe8470c,7, +0xe84740,1, +0xe84770,1, +0xe847c0,2, +0xe847d0,4, +0xe85000,3, +0xe85010,1, +0xe8501c,3, +0xe85104,1, +0xe85110,4, +0xe85124,1, +0xe85130,4, +0xe85144,1, +0xe85150,4, +0xe85164,1, +0xe85170,5, +0xe85190,4, +0xe85a00,4, +0xe85c00,129, +0xe86000,37, +0xe86098,1, +0xe86100,37, +0xe86198,1, +0xe86200,37, +0xe86298,1, +0xe86300,37, +0xe86398,1, +0xe86400,37, +0xe86498,1, +0xe86500,37, +0xe86598,1, +0xe86600,37, +0xe86698,1, +0xe86700,37, +0xe86798,1, +0xe8c000,91, +0xe8c400,4, +0xe8c440,15, +0xe8c480,4, +0xe8c4c0,15, +0xe8c500,4, +0xe8c540,15, +0xe8c580,4, +0xe8c5c0,15, +0xe8c600,4, +0xe8c640,10, +0xe8c680,4, +0xe8c6c0,10, +0xe8c800,4, +0xe8c840,33, +0xe8ca00,13, +0xe8ca80,1, +0xe8ca88,8, +0xe8cac0,6, +0xe8cae0,1, +0xe8cae8,2, +0xe8cb04,14, +0xe8cc00,4, +0xe8ccc8,1, +0xe8cfcc,3, +0xe8cfe0,99, +0xe8d400,4, +0xe8d440,15, +0xe8d480,4, +0xe8d4c0,15, +0xe8d500,4, +0xe8d540,15, +0xe8d580,4, +0xe8d5c0,15, +0xe8d600,4, +0xe8d640,10, +0xe8d680,4, +0xe8d6c0,10, +0xe8d800,4, +0xe8d840,33, +0xe8da00,13, +0xe8da80,1, +0xe8da88,8, +0xe8dac0,6, +0xe8dae0,1, +0xe8dae8,2, +0xe8db04,14, +0xe8dc00,4, +0xe8dcc8,1, +0xe8dfcc,3, +0xe8dfe0,27, +0xe8f000,19, +0xe8fa00,10, +0xe8fa80,3, +0xe8fb00,6, +0xe90000,51, +0xe90a00,10, +0xe90a80,3, +0xe91000,2, +0xe9100c,4, +0xe91028,3, +0xe91038,4, +0xe91050,2, +0xe91080,4, +0xe91098,7, +0xe91120,4, +0xe91200,4, +0xe91214,7, +0xe91234,3, +0xe91280,8, +0xe912c0,5, +0xe91300,2, +0xe9130c,3, +0xe91400,24, +0xe91464,2, +0xe91470,3, +0xe91500,25, +0xe915c0,8, +0xe915e8,5, +0xe91600,5, +0xe91618,1, +0xe91620,1, +0xe91628,1, +0xe91630,2, +0xe91640,2, +0xe91650,2, +0xe91690,4, +0xe91740,2, +0xe91760,6, +0xe91780,6, +0xe917a0,6, +0xe917c0,6, +0xe917e0,1, +0xe91800,2, +0xe9180c,4, +0xe91828,3, +0xe91838,4, +0xe91850,2, +0xe91880,4, +0xe91898,7, +0xe91920,4, +0xe91a00,4, +0xe91a14,7, +0xe91a34,3, +0xe91a80,8, +0xe91ac0,5, +0xe91b00,2, +0xe91b0c,3, +0xe91c00,24, +0xe91c64,2, +0xe91c70,3, +0xe91d00,25, +0xe91dc0,8, +0xe91de8,5, +0xe91e00,5, +0xe91e18,1, +0xe91e20,1, +0xe91e28,1, +0xe91e30,2, +0xe91e40,2, +0xe91e50,2, +0xe91e90,4, +0xe91f40,2, +0xe91f60,6, +0xe91f80,6, +0xe91fa0,6, +0xe91fc0,6, +0xe91fe0,1, +0xe92000,19, +0xe92080,2, +0xe920b0,2, +0xe920c0,2, +0xea0000,11, +0xea0040,16, +0xea0084,5, +0xea0200,7, +0xea0220,6, +0xea0240,7, +0xea0260,6, +0xea0280,6, +0xea02a0,2, +0xea02ac,2, +0xea02c0,7, +0xea02e0,7, +0xea0300,2, +0xea030c,2, +0xea0320,6, +0xea0400,2, +0xea1000,19, +0xea2104,23, +0xea2180,7, +0xea21a0,6, +0xea21c0,7, +0xea21e0,6, +0xea2200,4, +0xea2220,4, +0xea2240,11, +0xea2270,32, +0xea2300,24, +0xea2380,20, +0xea2400,61, +0xea2500,25, +0xea2568,4, +0xea2580,2, +0xea25a0,1, +0xea25c0,11, +0xea2600,9, +0xea2640,3, +0xea2650,3, +0xea2664,3, +0xea2680,22, +0xea2800,11, +0xea3000,536, +0xea4104,23, +0xea4180,7, +0xea41a0,6, +0xea41c0,7, +0xea41e0,6, +0xea4200,4, +0xea4220,4, +0xea4240,11, +0xea4270,32, +0xea4300,24, +0xea4380,20, +0xea4400,61, +0xea4500,25, +0xea4568,4, +0xea4580,2, +0xea45a0,1, +0xea45c0,11, +0xea4600,9, +0xea4640,3, +0xea4650,3, +0xea4664,3, +0xea4680,22, +0xea4800,11, +0xea5000,536, +0xeaa000,7, +0xeaa048,8, +0xeaa080,8, +0xeaa100,7, +0xeaa148,8, +0xeaa180,8, +0xeb0000,11, +0xeb0040,16, +0xeb0084,5, +0xeb0200,7, +0xeb0220,6, +0xeb0240,7, +0xeb0260,6, +0xeb0280,6, +0xeb02a0,2, +0xeb02ac,2, +0xeb02c0,7, +0xeb02e0,7, +0xeb0300,2, +0xeb030c,2, +0xeb0320,6, +0xeb0400,2, +0xeb1000,19, +0xeb2104,23, +0xeb2180,7, +0xeb21a0,6, +0xeb21c0,7, +0xeb21e0,6, +0xeb2200,4, +0xeb2220,4, +0xeb2240,11, +0xeb2270,32, +0xeb2300,24, +0xeb2380,20, +0xeb2400,61, +0xeb2500,25, +0xeb2568,4, +0xeb2580,2, +0xeb25a0,1, +0xeb25c0,11, +0xeb2600,9, +0xeb2640,3, +0xeb2650,3, +0xeb2664,3, +0xeb2680,22, +0xeb2800,11, +0xeb3000,536, +0xeb4104,23, +0xeb4180,7, +0xeb41a0,6, +0xeb41c0,7, +0xeb41e0,6, +0xeb4200,4, +0xeb4220,4, +0xeb4240,11, +0xeb4270,32, +0xeb4300,24, +0xeb4380,20, +0xeb4400,61, +0xeb4500,25, +0xeb4568,4, +0xeb4580,2, +0xeb45a0,1, +0xeb45c0,11, +0xeb4600,9, +0xeb4640,3, +0xeb4650,3, +0xeb4664,3, +0xeb4680,22, +0xeb4800,11, +0xeb5000,536, +0xeba000,7, +0xeba048,8, +0xeba080,8, +0xeba100,7, +0xeba148,8, +0xeba180,8, +0xec0400,4, +0xec0440,4, +0xec05c0,1, +0xec0600,8, +0xec0800,18, +0xec0880,13, +0xec08f0,3, +0xec0900,18, +0xec0980,13, +0xec09f0,3, +0xec0e00,4, +0xec0e20,4, +0xec0e80,16, +0xec0f00,1, +0xec0f20,1, +0xec1020,2, +0xec1208,6, +0xec1228,10, +0xec1288,6, +0xec12a8,10, +0xec1600,32, +0xec18c0,8, +0xec1900,24, +0xec19b0,4, +0xec1aa0,2, +0xec1ac0,4, +0xec2200,19, +0xec2280,19, +0xec2400,14, +0xec243c,9, +0xec2464,14, +0xec24a0,2, +0xec24ac,2, +0xec2500,14, +0xec253c,9, +0xec2564,14, +0xec25a0,2, +0xec25ac,2, +0xec2800,19, +0xec2880,19, +0xec2a10,2, +0xec2a1c,1, +0xec2a50,2, +0xec2a5c,1, +0xec2c00,7, +0xec2c20,1, +0xec2c54,18, +0xec2ca0,1, +0xec2cd4,11, +0xec2e00,1, +0xec2e08,6, +0xec3180,3, +0xec4400,4, +0xec4440,4, +0xec45c0,1, +0xec4600,8, +0xec4800,18, +0xec4880,13, +0xec48f0,3, +0xec4900,18, +0xec4980,13, +0xec49f0,3, +0xec4e00,4, +0xec4e20,4, +0xec4e80,16, +0xec4f00,1, +0xec4f20,1, +0xec5020,2, +0xec5208,6, +0xec5228,10, +0xec5288,6, +0xec52a8,10, +0xec5600,32, +0xec58c0,8, +0xec5900,24, +0xec59b0,4, +0xec5aa0,2, +0xec5ac0,4, +0xec6200,19, +0xec6280,19, +0xec6400,14, +0xec643c,9, +0xec6464,14, +0xec64a0,2, +0xec64ac,2, +0xec6500,14, +0xec653c,9, +0xec6564,14, +0xec65a0,2, +0xec65ac,2, +0xec6800,19, +0xec6880,19, +0xec6a10,2, +0xec6a1c,1, +0xec6a50,2, +0xec6a5c,1, +0xec6c00,7, +0xec6c20,1, +0xec6c54,18, +0xec6ca0,1, +0xec6cd4,11, +0xec6e00,1, +0xec6e08,6, +0xec7180,3, +0xec9000,13, +0xece000,19, +0xecea00,10, +0xecea80,3, +0xecf000,1, +0xecf008,5, +0xecf038,1, +0xecf044,1, +0xecf050,2, +0xecf060,8, +0xecf140,19, +0xecf190,4, +0xed0000,2, +0xed000c,2, +0xed0040,7, +0xed0100,3, +0xed0110,3, +0xed0120,5, +0xed0200,6, +0xed0240,5, +0xed0400,2, +0xed040c,2, +0xed0440,7, +0xed0500,3, +0xed0510,3, +0xed0520,5, +0xed0600,6, +0xed0640,5, +0xed0800,2, +0xed080c,2, +0xed0840,7, +0xed0900,3, +0xed0910,3, +0xed0920,5, +0xed0a00,6, +0xed0a40,5, +0xed0c00,2, +0xed0c0c,2, +0xed0c40,7, +0xed0d00,3, +0xed0d10,3, +0xed0d20,5, +0xed0e00,6, +0xed0e40,5, +0xed1000,2, +0xed100c,2, +0xed1040,7, +0xed1100,3, +0xed1110,3, +0xed1120,5, +0xed1200,6, +0xed1240,5, +0xed1400,2, +0xed140c,2, +0xed1440,7, +0xed1500,3, +0xed1510,3, +0xed1520,5, +0xed1600,6, +0xed1640,5, +0xed1800,2, +0xed180c,2, +0xed1840,7, +0xed1900,3, +0xed1910,3, +0xed1920,5, +0xed1a00,6, +0xed1a40,5, +0xed1c00,2, +0xed1c0c,2, +0xed1c40,7, +0xed1d00,3, +0xed1d10,3, +0xed1d20,5, +0xed1e00,6, +0xed1e40,5, +0xed2000,5, +0xed2040,9, +0xed2100,3, +0xed2200,1, +0xed2210,1, +0xed2220,1, +0xed2230,1, +0xed2240,1, +0xed2300,3, +0xed2314,1, +0xed2320,4, +0xed2400,5, +0xed2440,5, +0xed3000,80, +0xed3200,1, +0xed8000,7, +0xed8030,2, +0xed8040,7, +0xed8070,2, +0xed8100,2, +0xed8120,2, +0xed8140,2, +0xed8160,2, +0xed8180,9, +0xed8200,7, +0xed8230,2, +0xed8240,7, +0xed8270,2, +0xed8300,2, +0xed8320,2, +0xed8340,2, +0xed8360,2, +0xed8380,9, +0xed8400,11, +0xed8500,11, +0xed9000,3, +0xed9010,2, +0xed901c,5, +0xed9040,8, +0xed9080,3, +0xed9090,2, +0xed909c,5, +0xed90c0,8, +0xed9100,3, +0xed9110,2, +0xed911c,5, +0xed9140,8, +0xed9180,3, +0xed9190,2, +0xed919c,5, +0xed91c0,8, +0xed9200,7, +0xed9220,12, +0xed9280,7, +0xed92a0,12, +0xed9300,3, +0xed9310,1, +0xed9400,3, +0xed9410,2, +0xed941c,5, +0xed9440,8, +0xed9480,3, +0xed9490,2, +0xed949c,5, +0xed94c0,8, +0xed9500,3, +0xed9510,2, +0xed951c,5, +0xed9540,8, +0xed9580,3, +0xed9590,2, +0xed959c,5, +0xed95c0,8, +0xed9600,7, +0xed9620,12, +0xed9680,7, +0xed96a0,12, +0xed9700,3, +0xed9710,1, +0xed9804,1, +0xed9824,21, +0xed9880,16, +0xed9900,5, +0xed9920,11, +0xed9950,9, +0xed9980,22, +0xed9a00,22, +0xed9a80,22, +0xed9b00,22, +0xed9b80,22, +0xed9c00,22, +0xed9c80,22, +0xed9d00,22, +0xed9d80,3, +0xee0000,5, +0xee0018,5, +0xee0030,3, +0xee0044,3, +0xee0100,58, +0xee01f0,3, +0xee0280,3, +0xee0400,5, +0xee0418,5, +0xee0430,3, +0xee0444,3, +0xee0500,58, +0xee05f0,3, +0xee0680,3, +0xee1018,2, +0xee1100,2, +0xee1110,10, +0xee1140,2, +0xee1150,10, +0xee1208,1, +0xee1220,12, +0xee1280,1, +0xee1288,2, +0xee1400,4, +0xee2000,5, +0xee2018,5, +0xee2030,3, +0xee2044,3, +0xee2100,58, +0xee21f0,3, +0xee2280,3, +0xee2400,5, +0xee2418,5, +0xee2430,3, +0xee2444,3, +0xee2500,58, +0xee25f0,3, +0xee2680,3, +0xee3018,2, +0xee3100,2, +0xee3110,10, +0xee3140,2, +0xee3150,10, +0xee3208,1, +0xee3220,12, +0xee3280,1, +0xee3288,2, +0xee3400,4, +0xee4000,2, +0xee400c,1, +0xee4030,3, +0xee4040,2, +0xee404c,1, +0xee4070,3, +0xee4100,2, +0xee410c,1, +0xee4130,3, +0xee4140,2, +0xee414c,1, +0xee4170,3, +0xee4200,15, +0xee4280,15, +0xee4300,15, +0xee4380,15, +0xee4400,15, +0xee4480,15, +0xee4500,15, +0xee4580,15, +0xee4604,10, +0xee4700,2, +0xee470c,7, +0xee4740,1, +0xee4770,1, +0xee47c0,2, +0xee47d0,4, +0xee5000,3, +0xee5010,1, +0xee501c,3, +0xee5104,1, +0xee5110,4, +0xee5124,1, +0xee5130,4, +0xee5144,1, +0xee5150,4, +0xee5164,1, +0xee5170,5, +0xee5190,4, +0xee5a00,4, +0xee5c00,129, +0xee6000,37, +0xee6098,1, +0xee6100,37, +0xee6198,1, +0xee6200,37, +0xee6298,1, +0xee6300,37, +0xee6398,1, +0xee6400,37, +0xee6498,1, +0xee6500,37, +0xee6598,1, +0xee6600,37, +0xee6698,1, +0xee6700,37, +0xee6798,1, +0xeec000,91, +0xeec400,4, +0xeec440,15, +0xeec480,4, +0xeec4c0,15, +0xeec500,4, +0xeec540,15, +0xeec580,4, +0xeec5c0,15, +0xeec600,4, +0xeec640,10, +0xeec680,4, +0xeec6c0,10, +0xeec800,4, +0xeec840,33, +0xeeca00,13, +0xeeca80,1, +0xeeca88,8, +0xeecac0,6, +0xeecae0,1, +0xeecae8,2, +0xeecb04,14, +0xeecc00,4, +0xeeccc8,1, +0xeecfcc,3, +0xeecfe0,99, +0xeed400,4, +0xeed440,15, +0xeed480,4, +0xeed4c0,15, +0xeed500,4, +0xeed540,15, +0xeed580,4, +0xeed5c0,15, +0xeed600,4, +0xeed640,10, +0xeed680,4, +0xeed6c0,10, +0xeed800,4, +0xeed840,33, +0xeeda00,13, +0xeeda80,1, +0xeeda88,8, +0xeedac0,6, +0xeedae0,1, +0xeedae8,2, +0xeedb04,14, +0xeedc00,4, +0xeedcc8,1, +0xeedfcc,3, +0xeedfe0,27, +0xeef000,19, +0xeefa00,10, +0xeefa80,3, +0xeefb00,6, +0xef0000,51, +0xef0a00,10, +0xef0a80,3, +0xef1000,2, +0xef100c,4, +0xef1028,3, +0xef1038,4, +0xef1050,2, +0xef1080,4, +0xef1098,7, +0xef1120,4, +0xef1200,4, +0xef1214,7, +0xef1234,3, +0xef1280,8, +0xef12c0,5, +0xef1300,2, +0xef130c,3, +0xef1400,24, +0xef1464,2, +0xef1470,3, +0xef1500,25, +0xef15c0,8, +0xef15e8,5, +0xef1600,5, +0xef1618,1, +0xef1620,1, +0xef1628,1, +0xef1630,2, +0xef1640,2, +0xef1650,2, +0xef1690,4, +0xef1740,2, +0xef1760,6, +0xef1780,6, +0xef17a0,6, +0xef17c0,6, +0xef17e0,1, +0xef1800,2, +0xef180c,4, +0xef1828,3, +0xef1838,4, +0xef1850,2, +0xef1880,4, +0xef1898,7, +0xef1920,4, +0xef1a00,4, +0xef1a14,7, +0xef1a34,3, +0xef1a80,8, +0xef1ac0,5, +0xef1b00,2, +0xef1b0c,3, +0xef1c00,24, +0xef1c64,2, +0xef1c70,3, +0xef1d00,25, +0xef1dc0,8, +0xef1de8,5, +0xef1e00,5, +0xef1e18,1, +0xef1e20,1, +0xef1e28,1, +0xef1e30,2, +0xef1e40,2, +0xef1e50,2, +0xef1e90,4, +0xef1f40,2, +0xef1f60,6, +0xef1f80,6, +0xef1fa0,6, +0xef1fc0,6, +0xef1fe0,1, +0xef2000,19, +0xef2080,2, +0xef20b0,2, +0xef20c0,2, +0xf00000,11, +0xf00040,16, +0xf00084,5, +0xf00200,7, +0xf00220,6, +0xf00240,7, +0xf00260,6, +0xf00280,6, +0xf002a0,2, +0xf002ac,2, +0xf002c0,7, +0xf002e0,7, +0xf00300,2, +0xf0030c,2, +0xf00320,6, +0xf00400,2, +0xf01000,19, +0xf02104,23, +0xf02180,7, +0xf021a0,6, +0xf021c0,7, +0xf021e0,6, +0xf02200,4, +0xf02220,4, +0xf02240,11, +0xf02270,32, +0xf02300,24, +0xf02380,20, +0xf02400,61, +0xf02500,25, +0xf02568,4, +0xf02580,2, +0xf025a0,1, +0xf025c0,11, +0xf02600,9, +0xf02640,3, +0xf02650,3, +0xf02664,3, +0xf02680,22, +0xf02800,11, +0xf03000,536, +0xf04104,23, +0xf04180,7, +0xf041a0,6, +0xf041c0,7, +0xf041e0,6, +0xf04200,4, +0xf04220,4, +0xf04240,11, +0xf04270,32, +0xf04300,24, +0xf04380,20, +0xf04400,61, +0xf04500,25, +0xf04568,4, +0xf04580,2, +0xf045a0,1, +0xf045c0,11, +0xf04600,9, +0xf04640,3, +0xf04650,3, +0xf04664,3, +0xf04680,22, +0xf04800,11, +0xf05000,536, +0xf0a000,7, +0xf0a048,8, +0xf0a080,8, +0xf0a100,7, +0xf0a148,8, +0xf0a180,8, +0xf10000,11, +0xf10040,16, +0xf10084,5, +0xf10200,7, +0xf10220,6, +0xf10240,7, +0xf10260,6, +0xf10280,6, +0xf102a0,2, +0xf102ac,2, +0xf102c0,7, +0xf102e0,7, +0xf10300,2, +0xf1030c,2, +0xf10320,6, +0xf10400,2, +0xf11000,19, +0xf12104,23, +0xf12180,7, +0xf121a0,6, +0xf121c0,7, +0xf121e0,6, +0xf12200,4, +0xf12220,4, +0xf12240,11, +0xf12270,32, +0xf12300,24, +0xf12380,20, +0xf12400,61, +0xf12500,25, +0xf12568,4, +0xf12580,2, +0xf125a0,1, +0xf125c0,11, +0xf12600,9, +0xf12640,3, +0xf12650,3, +0xf12664,3, +0xf12680,22, +0xf12800,11, +0xf13000,536, +0xf14104,23, +0xf14180,7, +0xf141a0,6, +0xf141c0,7, +0xf141e0,6, +0xf14200,4, +0xf14220,4, +0xf14240,11, +0xf14270,32, +0xf14300,24, +0xf14380,20, +0xf14400,61, +0xf14500,25, +0xf14568,4, +0xf14580,2, +0xf145a0,1, +0xf145c0,11, +0xf14600,9, +0xf14640,3, +0xf14650,3, +0xf14664,3, +0xf14680,22, +0xf14800,11, +0xf15000,536, +0xf1a000,7, +0xf1a048,8, +0xf1a080,8, +0xf1a100,7, +0xf1a148,8, +0xf1a180,8, +0xf20400,4, +0xf20440,4, +0xf205c0,1, +0xf20600,8, +0xf20800,18, +0xf20880,13, +0xf208f0,3, +0xf20900,18, +0xf20980,13, +0xf209f0,3, +0xf20e00,4, +0xf20e20,4, +0xf20e80,16, +0xf20f00,1, +0xf20f20,1, +0xf21020,2, +0xf21208,6, +0xf21228,10, +0xf21288,6, +0xf212a8,10, +0xf21600,32, +0xf218c0,8, +0xf21900,24, +0xf219b0,4, +0xf21aa0,2, +0xf21ac0,4, +0xf22200,19, +0xf22280,19, +0xf22400,14, +0xf2243c,9, +0xf22464,14, +0xf224a0,2, +0xf224ac,2, +0xf22500,14, +0xf2253c,9, +0xf22564,14, +0xf225a0,2, +0xf225ac,2, +0xf22800,19, +0xf22880,19, +0xf22a10,2, +0xf22a1c,1, +0xf22a50,2, +0xf22a5c,1, +0xf22c00,7, +0xf22c20,1, +0xf22c54,18, +0xf22ca0,1, +0xf22cd4,11, +0xf22e00,1, +0xf22e08,6, +0xf23180,3, +0xf24400,4, +0xf24440,4, +0xf245c0,1, +0xf24600,8, +0xf24800,18, +0xf24880,13, +0xf248f0,3, +0xf24900,18, +0xf24980,13, +0xf249f0,3, +0xf24e00,4, +0xf24e20,4, +0xf24e80,16, +0xf24f00,1, +0xf24f20,1, +0xf25020,2, +0xf25208,6, +0xf25228,10, +0xf25288,6, +0xf252a8,10, +0xf25600,32, +0xf258c0,8, +0xf25900,24, +0xf259b0,4, +0xf25aa0,2, +0xf25ac0,4, +0xf26200,19, +0xf26280,19, +0xf26400,14, +0xf2643c,9, +0xf26464,14, +0xf264a0,2, +0xf264ac,2, +0xf26500,14, +0xf2653c,9, +0xf26564,14, +0xf265a0,2, +0xf265ac,2, +0xf26800,19, +0xf26880,19, +0xf26a10,2, +0xf26a1c,1, +0xf26a50,2, +0xf26a5c,1, +0xf26c00,7, +0xf26c20,1, +0xf26c54,18, +0xf26ca0,1, +0xf26cd4,11, +0xf26e00,1, +0xf26e08,6, +0xf27180,3, +0xf29000,13, +0xf2e000,19, +0xf2ea00,10, +0xf2ea80,3, +0xf2f000,1, +0xf2f008,5, +0xf2f038,1, +0xf2f044,1, +0xf2f050,2, +0xf2f060,8, +0xf2f140,19, +0xf2f190,4, +0xf30000,2, +0xf3000c,2, +0xf30040,7, +0xf30100,3, +0xf30110,3, +0xf30120,5, +0xf30200,6, +0xf30240,5, +0xf30400,2, +0xf3040c,2, +0xf30440,7, +0xf30500,3, +0xf30510,3, +0xf30520,5, +0xf30600,6, +0xf30640,5, +0xf30800,2, +0xf3080c,2, +0xf30840,7, +0xf30900,3, +0xf30910,3, +0xf30920,5, +0xf30a00,6, +0xf30a40,5, +0xf30c00,2, +0xf30c0c,2, +0xf30c40,7, +0xf30d00,3, +0xf30d10,3, +0xf30d20,5, +0xf30e00,6, +0xf30e40,5, +0xf31000,2, +0xf3100c,2, +0xf31040,7, +0xf31100,3, +0xf31110,3, +0xf31120,5, +0xf31200,6, +0xf31240,5, +0xf31400,2, +0xf3140c,2, +0xf31440,7, +0xf31500,3, +0xf31510,3, +0xf31520,5, +0xf31600,6, +0xf31640,5, +0xf31800,2, +0xf3180c,2, +0xf31840,7, +0xf31900,3, +0xf31910,3, +0xf31920,5, +0xf31a00,6, +0xf31a40,5, +0xf31c00,2, +0xf31c0c,2, +0xf31c40,7, +0xf31d00,3, +0xf31d10,3, +0xf31d20,5, +0xf31e00,6, +0xf31e40,5, +0xf32000,5, +0xf32040,9, +0xf32100,3, +0xf32200,1, +0xf32210,1, +0xf32220,1, +0xf32230,1, +0xf32240,1, +0xf32300,3, +0xf32314,1, +0xf32320,4, +0xf32400,5, +0xf32440,5, +0xf33000,80, +0xf33200,1, +0xf38000,7, +0xf38030,2, +0xf38040,7, +0xf38070,2, +0xf38100,2, +0xf38120,2, +0xf38140,2, +0xf38160,2, +0xf38180,9, +0xf38200,7, +0xf38230,2, +0xf38240,7, +0xf38270,2, +0xf38300,2, +0xf38320,2, +0xf38340,2, +0xf38360,2, +0xf38380,9, +0xf38400,11, +0xf38500,11, +0xf39000,3, +0xf39010,2, +0xf3901c,5, +0xf39040,8, +0xf39080,3, +0xf39090,2, +0xf3909c,5, +0xf390c0,8, +0xf39100,3, +0xf39110,2, +0xf3911c,5, +0xf39140,8, +0xf39180,3, +0xf39190,2, +0xf3919c,5, +0xf391c0,8, +0xf39200,7, +0xf39220,12, +0xf39280,7, +0xf392a0,12, +0xf39300,3, +0xf39310,1, +0xf39400,3, +0xf39410,2, +0xf3941c,5, +0xf39440,8, +0xf39480,3, +0xf39490,2, +0xf3949c,5, +0xf394c0,8, +0xf39500,3, +0xf39510,2, +0xf3951c,5, +0xf39540,8, +0xf39580,3, +0xf39590,2, +0xf3959c,5, +0xf395c0,8, +0xf39600,7, +0xf39620,12, +0xf39680,7, +0xf396a0,12, +0xf39700,3, +0xf39710,1, +0xf39804,1, +0xf39824,21, +0xf39880,16, +0xf39900,5, +0xf39920,11, +0xf39950,9, +0xf39980,22, +0xf39a00,22, +0xf39a80,22, +0xf39b00,22, +0xf39b80,22, +0xf39c00,22, +0xf39c80,22, +0xf39d00,22, +0xf39d80,3, +0xf40000,5, +0xf40018,5, +0xf40030,3, +0xf40044,3, +0xf40100,58, +0xf401f0,3, +0xf40280,3, +0xf40400,5, +0xf40418,5, +0xf40430,3, +0xf40444,3, +0xf40500,58, +0xf405f0,3, +0xf40680,3, +0xf41018,2, +0xf41100,2, +0xf41110,10, +0xf41140,2, +0xf41150,10, +0xf41208,1, +0xf41220,12, +0xf41280,1, +0xf41288,2, +0xf41400,4, +0xf42000,5, +0xf42018,5, +0xf42030,3, +0xf42044,3, +0xf42100,58, +0xf421f0,3, +0xf42280,3, +0xf42400,5, +0xf42418,5, +0xf42430,3, +0xf42444,3, +0xf42500,58, +0xf425f0,3, +0xf42680,3, +0xf43018,2, +0xf43100,2, +0xf43110,10, +0xf43140,2, +0xf43150,10, +0xf43208,1, +0xf43220,12, +0xf43280,1, +0xf43288,2, +0xf43400,4, +0xf44000,2, +0xf4400c,1, +0xf44030,3, +0xf44040,2, +0xf4404c,1, +0xf44070,3, +0xf44100,2, +0xf4410c,1, +0xf44130,3, +0xf44140,2, +0xf4414c,1, +0xf44170,3, +0xf44200,15, +0xf44280,15, +0xf44300,15, +0xf44380,15, +0xf44400,15, +0xf44480,15, +0xf44500,15, +0xf44580,15, +0xf44604,10, +0xf44700,2, +0xf4470c,7, +0xf44740,1, +0xf44770,1, +0xf447c0,2, +0xf447d0,4, +0xf45000,3, +0xf45010,1, +0xf4501c,3, +0xf45104,1, +0xf45110,4, +0xf45124,1, +0xf45130,4, +0xf45144,1, +0xf45150,4, +0xf45164,1, +0xf45170,5, +0xf45190,4, +0xf45a00,4, +0xf45c00,129, +0xf46000,37, +0xf46098,1, +0xf46100,37, +0xf46198,1, +0xf46200,37, +0xf46298,1, +0xf46300,37, +0xf46398,1, +0xf46400,37, +0xf46498,1, +0xf46500,37, +0xf46598,1, +0xf46600,37, +0xf46698,1, +0xf46700,37, +0xf46798,1, +0xf4c000,91, +0xf4c400,4, +0xf4c440,15, +0xf4c480,4, +0xf4c4c0,15, +0xf4c500,4, +0xf4c540,15, +0xf4c580,4, +0xf4c5c0,15, +0xf4c600,4, +0xf4c640,10, +0xf4c680,4, +0xf4c6c0,10, +0xf4c800,4, +0xf4c840,33, +0xf4ca00,13, +0xf4ca80,1, +0xf4ca88,8, +0xf4cac0,6, +0xf4cae0,1, +0xf4cae8,2, +0xf4cb04,14, +0xf4cc00,4, +0xf4ccc8,1, +0xf4cfcc,3, +0xf4cfe0,99, +0xf4d400,4, +0xf4d440,15, +0xf4d480,4, +0xf4d4c0,15, +0xf4d500,4, +0xf4d540,15, +0xf4d580,4, +0xf4d5c0,15, +0xf4d600,4, +0xf4d640,10, +0xf4d680,4, +0xf4d6c0,10, +0xf4d800,4, +0xf4d840,33, +0xf4da00,13, +0xf4da80,1, +0xf4da88,8, +0xf4dac0,6, +0xf4dae0,1, +0xf4dae8,2, +0xf4db04,14, +0xf4dc00,4, +0xf4dcc8,1, +0xf4dfcc,3, +0xf4dfe0,27, +0xf4f000,19, +0xf4fa00,10, +0xf4fa80,3, +0xf4fb00,6, +0xf50000,51, +0xf50a00,10, +0xf50a80,3, +0xf51000,2, +0xf5100c,4, +0xf51028,3, +0xf51038,4, +0xf51050,2, +0xf51080,4, +0xf51098,7, +0xf51120,4, +0xf51200,4, +0xf51214,7, +0xf51234,3, +0xf51280,8, +0xf512c0,5, +0xf51300,2, +0xf5130c,3, +0xf51400,24, +0xf51464,2, +0xf51470,3, +0xf51500,25, +0xf515c0,8, +0xf515e8,5, +0xf51600,5, +0xf51618,1, +0xf51620,1, +0xf51628,1, +0xf51630,2, +0xf51640,2, +0xf51650,2, +0xf51690,4, +0xf51740,2, +0xf51760,6, +0xf51780,6, +0xf517a0,6, +0xf517c0,6, +0xf517e0,1, +0xf51800,2, +0xf5180c,4, +0xf51828,3, +0xf51838,4, +0xf51850,2, +0xf51880,4, +0xf51898,7, +0xf51920,4, +0xf51a00,4, +0xf51a14,7, +0xf51a34,3, +0xf51a80,8, +0xf51ac0,5, +0xf51b00,2, +0xf51b0c,3, +0xf51c00,24, +0xf51c64,2, +0xf51c70,3, +0xf51d00,25, +0xf51dc0,8, +0xf51de8,5, +0xf51e00,5, +0xf51e18,1, +0xf51e20,1, +0xf51e28,1, +0xf51e30,2, +0xf51e40,2, +0xf51e50,2, +0xf51e90,4, +0xf51f40,2, +0xf51f60,6, +0xf51f80,6, +0xf51fa0,6, +0xf51fc0,6, +0xf51fe0,1, +0xf52000,19, +0xf52080,2, +0xf520b0,2, +0xf520c0,2, +0xf60000,11, +0xf60040,16, +0xf60084,5, +0xf60200,7, +0xf60220,6, +0xf60240,7, +0xf60260,6, +0xf60280,6, +0xf602a0,2, +0xf602ac,2, +0xf602c0,7, +0xf602e0,7, +0xf60300,2, +0xf6030c,2, +0xf60320,6, +0xf60400,2, +0xf61000,19, +0xf62104,23, +0xf62180,7, +0xf621a0,6, +0xf621c0,7, +0xf621e0,6, +0xf62200,4, +0xf62220,4, +0xf62240,11, +0xf62270,32, +0xf62300,24, +0xf62380,20, +0xf62400,61, +0xf62500,25, +0xf62568,4, +0xf62580,2, +0xf625a0,1, +0xf625c0,11, +0xf62600,9, +0xf62640,3, +0xf62650,3, +0xf62664,3, +0xf62680,22, +0xf62800,11, +0xf63000,536, +0xf64104,23, +0xf64180,7, +0xf641a0,6, +0xf641c0,7, +0xf641e0,6, +0xf64200,4, +0xf64220,4, +0xf64240,11, +0xf64270,32, +0xf64300,24, +0xf64380,20, +0xf64400,61, +0xf64500,25, +0xf64568,4, +0xf64580,2, +0xf645a0,1, +0xf645c0,11, +0xf64600,9, +0xf64640,3, +0xf64650,3, +0xf64664,3, +0xf64680,22, +0xf64800,11, +0xf65000,536, +0xf6a000,7, +0xf6a048,8, +0xf6a080,8, +0xf6a100,7, +0xf6a148,8, +0xf6a180,8, +0xf70000,11, +0xf70040,16, +0xf70084,5, +0xf70200,7, +0xf70220,6, +0xf70240,7, +0xf70260,6, +0xf70280,6, +0xf702a0,2, +0xf702ac,2, +0xf702c0,7, +0xf702e0,7, +0xf70300,2, +0xf7030c,2, +0xf70320,6, +0xf70400,2, +0xf71000,19, +0xf72104,23, +0xf72180,7, +0xf721a0,6, +0xf721c0,7, +0xf721e0,6, +0xf72200,4, +0xf72220,4, +0xf72240,11, +0xf72270,32, +0xf72300,24, +0xf72380,20, +0xf72400,61, +0xf72500,25, +0xf72568,4, +0xf72580,2, +0xf725a0,1, +0xf725c0,11, +0xf72600,9, +0xf72640,3, +0xf72650,3, +0xf72664,3, +0xf72680,22, +0xf72800,11, +0xf73000,536, +0xf74104,23, +0xf74180,7, +0xf741a0,6, +0xf741c0,7, +0xf741e0,6, +0xf74200,4, +0xf74220,4, +0xf74240,11, +0xf74270,32, +0xf74300,24, +0xf74380,20, +0xf74400,61, +0xf74500,25, +0xf74568,4, +0xf74580,2, +0xf745a0,1, +0xf745c0,11, +0xf74600,9, +0xf74640,3, +0xf74650,3, +0xf74664,3, +0xf74680,22, +0xf74800,11, +0xf75000,536, +0xf7a000,7, +0xf7a048,8, +0xf7a080,8, +0xf7a100,7, +0xf7a148,8, +0xf7a180,8, +0xf80400,4, +0xf80440,4, +0xf805c0,1, +0xf80600,8, +0xf80800,18, +0xf80880,13, +0xf808f0,3, +0xf80900,18, +0xf80980,13, +0xf809f0,3, +0xf80e00,4, +0xf80e20,4, +0xf80e80,16, +0xf80f00,1, +0xf80f20,1, +0xf81020,2, +0xf81208,6, +0xf81228,10, +0xf81288,6, +0xf812a8,10, +0xf81600,32, +0xf818c0,8, +0xf81900,24, +0xf819b0,4, +0xf81aa0,2, +0xf81ac0,4, +0xf82200,19, +0xf82280,19, +0xf82400,14, +0xf8243c,9, +0xf82464,14, +0xf824a0,2, +0xf824ac,2, +0xf82500,14, +0xf8253c,9, +0xf82564,14, +0xf825a0,2, +0xf825ac,2, +0xf82800,19, +0xf82880,19, +0xf82a10,2, +0xf82a1c,1, +0xf82a50,2, +0xf82a5c,1, +0xf82c00,7, +0xf82c20,1, +0xf82c54,18, +0xf82ca0,1, +0xf82cd4,11, +0xf82e00,1, +0xf82e08,6, +0xf83180,3, +0xf84400,4, +0xf84440,4, +0xf845c0,1, +0xf84600,8, +0xf84800,18, +0xf84880,13, +0xf848f0,3, +0xf84900,18, +0xf84980,13, +0xf849f0,3, +0xf84e00,4, +0xf84e20,4, +0xf84e80,16, +0xf84f00,1, +0xf84f20,1, +0xf85020,2, +0xf85208,6, +0xf85228,10, +0xf85288,6, +0xf852a8,10, +0xf85600,32, +0xf858c0,8, +0xf85900,24, +0xf859b0,4, +0xf85aa0,2, +0xf85ac0,4, +0xf86200,19, +0xf86280,19, +0xf86400,14, +0xf8643c,9, +0xf86464,14, +0xf864a0,2, +0xf864ac,2, +0xf86500,14, +0xf8653c,9, +0xf86564,14, +0xf865a0,2, +0xf865ac,2, +0xf86800,19, +0xf86880,19, +0xf86a10,2, +0xf86a1c,1, +0xf86a50,2, +0xf86a5c,1, +0xf86c00,7, +0xf86c20,1, +0xf86c54,18, +0xf86ca0,1, +0xf86cd4,11, +0xf86e00,1, +0xf86e08,6, +0xf87180,3, +0xf89000,13, +0xf8e000,19, +0xf8ea00,10, +0xf8ea80,3, +0xf8f000,1, +0xf8f008,5, +0xf8f038,1, +0xf8f044,1, +0xf8f050,2, +0xf8f060,8, +0xf8f140,19, +0xf8f190,4, +0xf90000,2, +0xf9000c,2, +0xf90040,7, +0xf90100,3, +0xf90110,3, +0xf90120,5, +0xf90200,6, +0xf90240,5, +0xf90400,2, +0xf9040c,2, +0xf90440,7, +0xf90500,3, +0xf90510,3, +0xf90520,5, +0xf90600,6, +0xf90640,5, +0xf90800,2, +0xf9080c,2, +0xf90840,7, +0xf90900,3, +0xf90910,3, +0xf90920,5, +0xf90a00,6, +0xf90a40,5, +0xf90c00,2, +0xf90c0c,2, +0xf90c40,7, +0xf90d00,3, +0xf90d10,3, +0xf90d20,5, +0xf90e00,6, +0xf90e40,5, +0xf91000,2, +0xf9100c,2, +0xf91040,7, +0xf91100,3, +0xf91110,3, +0xf91120,5, +0xf91200,6, +0xf91240,5, +0xf91400,2, +0xf9140c,2, +0xf91440,7, +0xf91500,3, +0xf91510,3, +0xf91520,5, +0xf91600,6, +0xf91640,5, +0xf91800,2, +0xf9180c,2, +0xf91840,7, +0xf91900,3, +0xf91910,3, +0xf91920,5, +0xf91a00,6, +0xf91a40,5, +0xf91c00,2, +0xf91c0c,2, +0xf91c40,7, +0xf91d00,3, +0xf91d10,3, +0xf91d20,5, +0xf91e00,6, +0xf91e40,5, +0xf92000,5, +0xf92040,9, +0xf92100,3, +0xf92200,1, +0xf92210,1, +0xf92220,1, +0xf92230,1, +0xf92240,1, +0xf92300,3, +0xf92314,1, +0xf92320,4, +0xf92400,5, +0xf92440,5, +0xf93000,80, +0xf93200,1, +0xf98000,7, +0xf98030,2, +0xf98040,7, +0xf98070,2, +0xf98100,2, +0xf98120,2, +0xf98140,2, +0xf98160,2, +0xf98180,9, +0xf98200,7, +0xf98230,2, +0xf98240,7, +0xf98270,2, +0xf98300,2, +0xf98320,2, +0xf98340,2, +0xf98360,2, +0xf98380,9, +0xf98400,11, +0xf98500,11, +0xf99000,3, +0xf99010,2, +0xf9901c,5, +0xf99040,8, +0xf99080,3, +0xf99090,2, +0xf9909c,5, +0xf990c0,8, +0xf99100,3, +0xf99110,2, +0xf9911c,5, +0xf99140,8, +0xf99180,3, +0xf99190,2, +0xf9919c,5, +0xf991c0,8, +0xf99200,7, +0xf99220,12, +0xf99280,7, +0xf992a0,12, +0xf99300,3, +0xf99310,1, +0xf99400,3, +0xf99410,2, +0xf9941c,5, +0xf99440,8, +0xf99480,3, +0xf99490,2, +0xf9949c,5, +0xf994c0,8, +0xf99500,3, +0xf99510,2, +0xf9951c,5, +0xf99540,8, +0xf99580,3, +0xf99590,2, +0xf9959c,5, +0xf995c0,8, +0xf99600,7, +0xf99620,12, +0xf99680,7, +0xf996a0,12, +0xf99700,3, +0xf99710,1, +0xf99804,1, +0xf99824,21, +0xf99880,16, +0xf99900,5, +0xf99920,11, +0xf99950,9, +0xf99980,22, +0xf99a00,22, +0xf99a80,22, +0xf99b00,22, +0xf99b80,22, +0xf99c00,22, +0xf99c80,22, +0xf99d00,22, +0xf99d80,3, +0xfa0000,5, +0xfa0018,5, +0xfa0030,3, +0xfa0044,3, +0xfa0100,58, +0xfa01f0,3, +0xfa0280,3, +0xfa0400,5, +0xfa0418,5, +0xfa0430,3, +0xfa0444,3, +0xfa0500,58, +0xfa05f0,3, +0xfa0680,3, +0xfa1018,2, +0xfa1100,2, +0xfa1110,10, +0xfa1140,2, +0xfa1150,10, +0xfa1208,1, +0xfa1220,12, +0xfa1280,1, +0xfa1288,2, +0xfa1400,4, +0xfa2000,5, +0xfa2018,5, +0xfa2030,3, +0xfa2044,3, +0xfa2100,58, +0xfa21f0,3, +0xfa2280,3, +0xfa2400,5, +0xfa2418,5, +0xfa2430,3, +0xfa2444,3, +0xfa2500,58, +0xfa25f0,3, +0xfa2680,3, +0xfa3018,2, +0xfa3100,2, +0xfa3110,10, +0xfa3140,2, +0xfa3150,10, +0xfa3208,1, +0xfa3220,12, +0xfa3280,1, +0xfa3288,2, +0xfa3400,4, +0xfa4000,2, +0xfa400c,1, +0xfa4030,3, +0xfa4040,2, +0xfa404c,1, +0xfa4070,3, +0xfa4100,2, +0xfa410c,1, +0xfa4130,3, +0xfa4140,2, +0xfa414c,1, +0xfa4170,3, +0xfa4200,15, +0xfa4280,15, +0xfa4300,15, +0xfa4380,15, +0xfa4400,15, +0xfa4480,15, +0xfa4500,15, +0xfa4580,15, +0xfa4604,10, +0xfa4700,2, +0xfa470c,7, +0xfa4740,1, +0xfa4770,1, +0xfa47c0,2, +0xfa47d0,4, +0xfa5000,3, +0xfa5010,1, +0xfa501c,3, +0xfa5104,1, +0xfa5110,4, +0xfa5124,1, +0xfa5130,4, +0xfa5144,1, +0xfa5150,4, +0xfa5164,1, +0xfa5170,5, +0xfa5190,4, +0xfa5a00,4, +0xfa5c00,129, +0xfa6000,37, +0xfa6098,1, +0xfa6100,37, +0xfa6198,1, +0xfa6200,37, +0xfa6298,1, +0xfa6300,37, +0xfa6398,1, +0xfa6400,37, +0xfa6498,1, +0xfa6500,37, +0xfa6598,1, +0xfa6600,37, +0xfa6698,1, +0xfa6700,37, +0xfa6798,1, +0xfac000,91, +0xfac400,4, +0xfac440,15, +0xfac480,4, +0xfac4c0,15, +0xfac500,4, +0xfac540,15, +0xfac580,4, +0xfac5c0,15, +0xfac600,4, +0xfac640,10, +0xfac680,4, +0xfac6c0,10, +0xfac800,4, +0xfac840,33, +0xfaca00,13, +0xfaca80,1, +0xfaca88,8, +0xfacac0,6, +0xfacae0,1, +0xfacae8,2, +0xfacb04,14, +0xfacc00,4, +0xfaccc8,1, +0xfacfcc,3, +0xfacfe0,99, +0xfad400,4, +0xfad440,15, +0xfad480,4, +0xfad4c0,15, +0xfad500,4, +0xfad540,15, +0xfad580,4, +0xfad5c0,15, +0xfad600,4, +0xfad640,10, +0xfad680,4, +0xfad6c0,10, +0xfad800,4, +0xfad840,33, +0xfada00,13, +0xfada80,1, +0xfada88,8, +0xfadac0,6, +0xfadae0,1, +0xfadae8,2, +0xfadb04,14, +0xfadc00,4, +0xfadcc8,1, +0xfadfcc,3, +0xfadfe0,27, +0xfaf000,19, +0xfafa00,10, +0xfafa80,3, +0xfafb00,6, +0xfb0000,51, +0xfb0a00,10, +0xfb0a80,3, +0xfb1000,2, +0xfb100c,4, +0xfb1028,3, +0xfb1038,4, +0xfb1050,2, +0xfb1080,4, +0xfb1098,7, +0xfb1120,4, +0xfb1200,4, +0xfb1214,7, +0xfb1234,3, +0xfb1280,8, +0xfb12c0,5, +0xfb1300,2, +0xfb130c,3, +0xfb1400,24, +0xfb1464,2, +0xfb1470,3, +0xfb1500,25, +0xfb15c0,8, +0xfb15e8,5, +0xfb1600,5, +0xfb1618,1, +0xfb1620,1, +0xfb1628,1, +0xfb1630,2, +0xfb1640,2, +0xfb1650,2, +0xfb1690,4, +0xfb1740,2, +0xfb1760,6, +0xfb1780,6, +0xfb17a0,6, +0xfb17c0,6, +0xfb17e0,1, +0xfb1800,2, +0xfb180c,4, +0xfb1828,3, +0xfb1838,4, +0xfb1850,2, +0xfb1880,4, +0xfb1898,7, +0xfb1920,4, +0xfb1a00,4, +0xfb1a14,7, +0xfb1a34,3, +0xfb1a80,8, +0xfb1ac0,5, +0xfb1b00,2, +0xfb1b0c,3, +0xfb1c00,24, +0xfb1c64,2, +0xfb1c70,3, +0xfb1d00,25, +0xfb1dc0,8, +0xfb1de8,5, +0xfb1e00,5, +0xfb1e18,1, +0xfb1e20,1, +0xfb1e28,1, +0xfb1e30,2, +0xfb1e40,2, +0xfb1e50,2, +0xfb1e90,4, +0xfb1f40,2, +0xfb1f60,6, +0xfb1f80,6, +0xfb1fa0,6, +0xfb1fc0,6, +0xfb1fe0,1, +0xfb2000,19, +0xfb2080,2, +0xfb20b0,2, +0xfb20c0,2, +0xfc0000,11, +0xfc0040,16, +0xfc0084,5, +0xfc0200,7, +0xfc0220,6, +0xfc0240,7, +0xfc0260,6, +0xfc0280,6, +0xfc02a0,2, +0xfc02ac,2, +0xfc02c0,7, +0xfc02e0,7, +0xfc0300,2, +0xfc030c,2, +0xfc0320,6, +0xfc0400,2, +0xfc1000,19, +0xfc2104,23, +0xfc2180,7, +0xfc21a0,6, +0xfc21c0,7, +0xfc21e0,6, +0xfc2200,4, +0xfc2220,4, +0xfc2240,11, +0xfc2270,32, +0xfc2300,24, +0xfc2380,20, +0xfc2400,61, +0xfc2500,25, +0xfc2568,4, +0xfc2580,2, +0xfc25a0,1, +0xfc25c0,11, +0xfc2600,9, +0xfc2640,3, +0xfc2650,3, +0xfc2664,3, +0xfc2680,22, +0xfc2800,11, +0xfc3000,536, +0xfc4104,23, +0xfc4180,7, +0xfc41a0,6, +0xfc41c0,7, +0xfc41e0,6, +0xfc4200,4, +0xfc4220,4, +0xfc4240,11, +0xfc4270,32, +0xfc4300,24, +0xfc4380,20, +0xfc4400,61, +0xfc4500,25, +0xfc4568,4, +0xfc4580,2, +0xfc45a0,1, +0xfc45c0,11, +0xfc4600,9, +0xfc4640,3, +0xfc4650,3, +0xfc4664,3, +0xfc4680,22, +0xfc4800,11, +0xfc5000,536, +0xfca000,7, +0xfca048,8, +0xfca080,8, +0xfca100,7, +0xfca148,8, +0xfca180,8, +0xfd0000,11, +0xfd0040,16, +0xfd0084,5, +0xfd0200,7, +0xfd0220,6, +0xfd0240,7, +0xfd0260,6, +0xfd0280,6, +0xfd02a0,2, +0xfd02ac,2, +0xfd02c0,7, +0xfd02e0,7, +0xfd0300,2, +0xfd030c,2, +0xfd0320,6, +0xfd0400,2, +0xfd1000,19, +0xfd2104,23, +0xfd2180,7, +0xfd21a0,6, +0xfd21c0,7, +0xfd21e0,6, +0xfd2200,4, +0xfd2220,4, +0xfd2240,11, +0xfd2270,32, +0xfd2300,24, +0xfd2380,20, +0xfd2400,61, +0xfd2500,25, +0xfd2568,4, +0xfd2580,2, +0xfd25a0,1, +0xfd25c0,11, +0xfd2600,9, +0xfd2640,3, +0xfd2650,3, +0xfd2664,3, +0xfd2680,22, +0xfd2800,11, +0xfd3000,536, +0xfd4104,23, +0xfd4180,7, +0xfd41a0,6, +0xfd41c0,7, +0xfd41e0,6, +0xfd4200,4, +0xfd4220,4, +0xfd4240,11, +0xfd4270,32, +0xfd4300,24, +0xfd4380,20, +0xfd4400,61, +0xfd4500,25, +0xfd4568,4, +0xfd4580,2, +0xfd45a0,1, +0xfd45c0,11, +0xfd4600,9, +0xfd4640,3, +0xfd4650,3, +0xfd4664,3, +0xfd4680,22, +0xfd4800,11, +0xfd5000,536, +0xfda000,7, +0xfda048,8, +0xfda080,8, +0xfda100,7, +0xfda148,8, +0xfda180,8, +0xfe0400,4, +0xfe0440,4, +0xfe05c0,1, +0xfe0600,8, +0xfe0800,18, +0xfe0880,13, +0xfe08f0,3, +0xfe0900,18, +0xfe0980,13, +0xfe09f0,3, +0xfe0e00,4, +0xfe0e20,4, +0xfe0e80,16, +0xfe0f00,1, +0xfe0f20,1, +0xfe1020,2, +0xfe1208,6, +0xfe1228,10, +0xfe1288,6, +0xfe12a8,10, +0xfe1600,32, +0xfe18c0,8, +0xfe1900,24, +0xfe19b0,4, +0xfe1aa0,2, +0xfe1ac0,4, +0xfe2200,19, +0xfe2280,19, +0xfe2400,14, +0xfe243c,9, +0xfe2464,14, +0xfe24a0,2, +0xfe24ac,2, +0xfe2500,14, +0xfe253c,9, +0xfe2564,14, +0xfe25a0,2, +0xfe25ac,2, +0xfe2800,19, +0xfe2880,19, +0xfe2a10,2, +0xfe2a1c,1, +0xfe2a50,2, +0xfe2a5c,1, +0xfe2c00,7, +0xfe2c20,1, +0xfe2c54,18, +0xfe2ca0,1, +0xfe2cd4,11, +0xfe2e00,1, +0xfe2e08,6, +0xfe3180,3, +0xfe4400,4, +0xfe4440,4, +0xfe45c0,1, +0xfe4600,8, +0xfe4800,18, +0xfe4880,13, +0xfe48f0,3, +0xfe4900,18, +0xfe4980,13, +0xfe49f0,3, +0xfe4e00,4, +0xfe4e20,4, +0xfe4e80,16, +0xfe4f00,1, +0xfe4f20,1, +0xfe5020,2, +0xfe5208,6, +0xfe5228,10, +0xfe5288,6, +0xfe52a8,10, +0xfe5600,32, +0xfe58c0,8, +0xfe5900,24, +0xfe59b0,4, +0xfe5aa0,2, +0xfe5ac0,4, +0xfe6200,19, +0xfe6280,19, +0xfe6400,14, +0xfe643c,9, +0xfe6464,14, +0xfe64a0,2, +0xfe64ac,2, +0xfe6500,14, +0xfe653c,9, +0xfe6564,14, +0xfe65a0,2, +0xfe65ac,2, +0xfe6800,19, +0xfe6880,19, +0xfe6a10,2, +0xfe6a1c,1, +0xfe6a50,2, +0xfe6a5c,1, +0xfe6c00,7, +0xfe6c20,1, +0xfe6c54,18, +0xfe6ca0,1, +0xfe6cd4,11, +0xfe6e00,1, +0xfe6e08,6, +0xfe7180,3, +0xfe9000,13, +0xfee000,19, +0xfeea00,10, +0xfeea80,3, +0xfef000,1, +0xfef008,5, +0xfef038,1, +0xfef044,1, +0xfef050,2, +0xfef060,8, +0xfef140,19, +0xfef190,4, +0xff0000,2, +0xff000c,2, +0xff0040,7, +0xff0100,3, +0xff0110,3, +0xff0120,5, +0xff0200,6, +0xff0240,5, +0xff0400,2, +0xff040c,2, +0xff0440,7, +0xff0500,3, +0xff0510,3, +0xff0520,5, +0xff0600,6, +0xff0640,5, +0xff0800,2, +0xff080c,2, +0xff0840,7, +0xff0900,3, +0xff0910,3, +0xff0920,5, +0xff0a00,6, +0xff0a40,5, +0xff0c00,2, +0xff0c0c,2, +0xff0c40,7, +0xff0d00,3, +0xff0d10,3, +0xff0d20,5, +0xff0e00,6, +0xff0e40,5, +0xff1000,2, +0xff100c,2, +0xff1040,7, +0xff1100,3, +0xff1110,3, +0xff1120,5, +0xff1200,6, +0xff1240,5, +0xff1400,2, +0xff140c,2, +0xff1440,7, +0xff1500,3, +0xff1510,3, +0xff1520,5, +0xff1600,6, +0xff1640,5, +0xff1800,2, +0xff180c,2, +0xff1840,7, +0xff1900,3, +0xff1910,3, +0xff1920,5, +0xff1a00,6, +0xff1a40,5, +0xff1c00,2, +0xff1c0c,2, +0xff1c40,7, +0xff1d00,3, +0xff1d10,3, +0xff1d20,5, +0xff1e00,6, +0xff1e40,5, +0xff2000,5, +0xff2040,9, +0xff2100,3, +0xff2200,1, +0xff2210,1, +0xff2220,1, +0xff2230,1, +0xff2240,1, +0xff2300,3, +0xff2314,1, +0xff2320,4, +0xff2400,5, +0xff2440,5, +0xff3000,80, +0xff3200,1, +0xff8000,7, +0xff8030,2, +0xff8040,7, +0xff8070,2, +0xff8100,2, +0xff8120,2, +0xff8140,2, +0xff8160,2, +0xff8180,9, +0xff8200,7, +0xff8230,2, +0xff8240,7, +0xff8270,2, +0xff8300,2, +0xff8320,2, +0xff8340,2, +0xff8360,2, +0xff8380,9, +0xff8400,11, +0xff8500,11, +0xff9000,3, +0xff9010,2, +0xff901c,5, +0xff9040,8, +0xff9080,3, +0xff9090,2, +0xff909c,5, +0xff90c0,8, +0xff9100,3, +0xff9110,2, +0xff911c,5, +0xff9140,8, +0xff9180,3, +0xff9190,2, +0xff919c,5, +0xff91c0,8, +0xff9200,7, +0xff9220,12, +0xff9280,7, +0xff92a0,12, +0xff9300,3, +0xff9310,1, +0xff9400,3, +0xff9410,2, +0xff941c,5, +0xff9440,8, +0xff9480,3, +0xff9490,2, +0xff949c,5, +0xff94c0,8, +0xff9500,3, +0xff9510,2, +0xff951c,5, +0xff9540,8, +0xff9580,3, +0xff9590,2, +0xff959c,5, +0xff95c0,8, +0xff9600,7, +0xff9620,12, +0xff9680,7, +0xff96a0,12, +0xff9700,3, +0xff9710,1, +0xff9804,1, +0xff9824,21, +0xff9880,16, +0xff9900,5, +0xff9920,11, +0xff9950,9, +0xff9980,22, +0xff9a00,22, +0xff9a80,22, +0xff9b00,22, +0xff9b80,22, +0xff9c00,22, +0xff9c80,22, +0xff9d00,22, +0xff9d80,3, +0x1000000,5, +0x1000018,5, +0x1000030,3, +0x1000044,3, +0x1000100,58, +0x10001f0,3, +0x1000280,3, +0x1000400,5, +0x1000418,5, +0x1000430,3, +0x1000444,3, +0x1000500,58, +0x10005f0,3, +0x1000680,3, +0x1001018,2, +0x1001100,2, +0x1001110,10, +0x1001140,2, +0x1001150,10, +0x1001208,1, +0x1001220,12, +0x1001280,1, +0x1001288,2, +0x1001400,4, +0x1002000,5, +0x1002018,5, +0x1002030,3, +0x1002044,3, +0x1002100,58, +0x10021f0,3, +0x1002280,3, +0x1002400,5, +0x1002418,5, +0x1002430,3, +0x1002444,3, +0x1002500,58, +0x10025f0,3, +0x1002680,3, +0x1003018,2, +0x1003100,2, +0x1003110,10, +0x1003140,2, +0x1003150,10, +0x1003208,1, +0x1003220,12, +0x1003280,1, +0x1003288,2, +0x1003400,4, +0x1004000,2, +0x100400c,1, +0x1004030,3, +0x1004040,2, +0x100404c,1, +0x1004070,3, +0x1004100,2, +0x100410c,1, +0x1004130,3, +0x1004140,2, +0x100414c,1, +0x1004170,3, +0x1004200,15, +0x1004280,15, +0x1004300,15, +0x1004380,15, +0x1004400,15, +0x1004480,15, +0x1004500,15, +0x1004580,15, +0x1004604,10, +0x1004700,2, +0x100470c,7, +0x1004740,1, +0x1004770,1, +0x10047c0,2, +0x10047d0,4, +0x1005000,3, +0x1005010,1, +0x100501c,3, +0x1005104,1, +0x1005110,4, +0x1005124,1, +0x1005130,4, +0x1005144,1, +0x1005150,4, +0x1005164,1, +0x1005170,5, +0x1005190,4, +0x1005a00,4, +0x1005c00,129, +0x1006000,37, +0x1006098,1, +0x1006100,37, +0x1006198,1, +0x1006200,37, +0x1006298,1, +0x1006300,37, +0x1006398,1, +0x1006400,37, +0x1006498,1, +0x1006500,37, +0x1006598,1, +0x1006600,37, +0x1006698,1, +0x1006700,37, +0x1006798,1, +0x100c000,91, +0x100c400,4, +0x100c440,15, +0x100c480,4, +0x100c4c0,15, +0x100c500,4, +0x100c540,15, +0x100c580,4, +0x100c5c0,15, +0x100c600,4, +0x100c640,10, +0x100c680,4, +0x100c6c0,10, +0x100c800,4, +0x100c840,33, +0x100ca00,13, +0x100ca80,1, +0x100ca88,8, +0x100cac0,6, +0x100cae0,1, +0x100cae8,2, +0x100cb04,14, +0x100cc00,4, +0x100ccc8,1, +0x100cfcc,3, +0x100cfe0,99, +0x100d400,4, +0x100d440,15, +0x100d480,4, +0x100d4c0,15, +0x100d500,4, +0x100d540,15, +0x100d580,4, +0x100d5c0,15, +0x100d600,4, +0x100d640,10, +0x100d680,4, +0x100d6c0,10, +0x100d800,4, +0x100d840,33, +0x100da00,13, +0x100da80,1, +0x100da88,8, +0x100dac0,6, +0x100dae0,1, +0x100dae8,2, +0x100db04,14, +0x100dc00,4, +0x100dcc8,1, +0x100dfcc,3, +0x100dfe0,27, +0x100f000,19, +0x100fa00,10, +0x100fa80,3, +0x100fb00,6, +0x1010000,51, +0x1010a00,10, +0x1010a80,3, +0x1011000,2, +0x101100c,4, +0x1011028,3, +0x1011038,4, +0x1011050,2, +0x1011080,4, +0x1011098,7, +0x1011120,4, +0x1011200,4, +0x1011214,7, +0x1011234,3, +0x1011280,8, +0x10112c0,5, +0x1011300,2, +0x101130c,3, +0x1011400,24, +0x1011464,2, +0x1011470,3, +0x1011500,25, +0x10115c0,8, +0x10115e8,5, +0x1011600,5, +0x1011618,1, +0x1011620,1, +0x1011628,1, +0x1011630,2, +0x1011640,2, +0x1011650,2, +0x1011690,4, +0x1011740,2, +0x1011760,6, +0x1011780,6, +0x10117a0,6, +0x10117c0,6, +0x10117e0,1, +0x1011800,2, +0x101180c,4, +0x1011828,3, +0x1011838,4, +0x1011850,2, +0x1011880,4, +0x1011898,7, +0x1011920,4, +0x1011a00,4, +0x1011a14,7, +0x1011a34,3, +0x1011a80,8, +0x1011ac0,5, +0x1011b00,2, +0x1011b0c,3, +0x1011c00,24, +0x1011c64,2, +0x1011c70,3, +0x1011d00,25, +0x1011dc0,8, +0x1011de8,5, +0x1011e00,5, +0x1011e18,1, +0x1011e20,1, +0x1011e28,1, +0x1011e30,2, +0x1011e40,2, +0x1011e50,2, +0x1011e90,4, +0x1011f40,2, +0x1011f60,6, +0x1011f80,6, +0x1011fa0,6, +0x1011fc0,6, +0x1011fe0,1, +0x1012000,19, +0x1012080,2, +0x10120b0,2, +0x10120c0,2, +0x1020000,11, +0x1020040,16, +0x1020084,5, +0x1020200,7, +0x1020220,6, +0x1020240,7, +0x1020260,6, +0x1020280,6, +0x10202a0,2, +0x10202ac,2, +0x10202c0,7, +0x10202e0,7, +0x1020300,2, +0x102030c,2, +0x1020320,6, +0x1020400,2, +0x1021000,19, +0x1022104,23, +0x1022180,7, +0x10221a0,6, +0x10221c0,7, +0x10221e0,6, +0x1022200,4, +0x1022220,4, +0x1022240,11, +0x1022270,32, +0x1022300,24, +0x1022380,20, +0x1022400,61, +0x1022500,25, +0x1022568,4, +0x1022580,2, +0x10225a0,1, +0x10225c0,11, +0x1022600,9, +0x1022640,3, +0x1022650,3, +0x1022664,3, +0x1022680,22, +0x1022800,11, +0x1023000,536, +0x1024104,23, +0x1024180,7, +0x10241a0,6, +0x10241c0,7, +0x10241e0,6, +0x1024200,4, +0x1024220,4, +0x1024240,11, +0x1024270,32, +0x1024300,24, +0x1024380,20, +0x1024400,61, +0x1024500,25, +0x1024568,4, +0x1024580,2, +0x10245a0,1, +0x10245c0,11, +0x1024600,9, +0x1024640,3, +0x1024650,3, +0x1024664,3, +0x1024680,22, +0x1024800,11, +0x1025000,536, +0x102a000,7, +0x102a048,8, +0x102a080,8, +0x102a100,7, +0x102a148,8, +0x102a180,8, +0x1030000,11, +0x1030040,16, +0x1030084,5, +0x1030200,7, +0x1030220,6, +0x1030240,7, +0x1030260,6, +0x1030280,6, +0x10302a0,2, +0x10302ac,2, +0x10302c0,7, +0x10302e0,7, +0x1030300,2, +0x103030c,2, +0x1030320,6, +0x1030400,2, +0x1031000,19, +0x1032104,23, +0x1032180,7, +0x10321a0,6, +0x10321c0,7, +0x10321e0,6, +0x1032200,4, +0x1032220,4, +0x1032240,11, +0x1032270,32, +0x1032300,24, +0x1032380,20, +0x1032400,61, +0x1032500,25, +0x1032568,4, +0x1032580,2, +0x10325a0,1, +0x10325c0,11, +0x1032600,9, +0x1032640,3, +0x1032650,3, +0x1032664,3, +0x1032680,22, +0x1032800,11, +0x1033000,536, +0x1034104,23, +0x1034180,7, +0x10341a0,6, +0x10341c0,7, +0x10341e0,6, +0x1034200,4, +0x1034220,4, +0x1034240,11, +0x1034270,32, +0x1034300,24, +0x1034380,20, +0x1034400,61, +0x1034500,25, +0x1034568,4, +0x1034580,2, +0x10345a0,1, +0x10345c0,11, +0x1034600,9, +0x1034640,3, +0x1034650,3, +0x1034664,3, +0x1034680,22, +0x1034800,11, +0x1035000,536, +0x103a000,7, +0x103a048,8, +0x103a080,8, +0x103a100,7, +0x103a148,8, +0x103a180,8, +0x1040400,4, +0x1040440,4, +0x10405c0,1, +0x1040600,8, +0x1040800,18, +0x1040880,13, +0x10408f0,3, +0x1040900,18, +0x1040980,13, +0x10409f0,3, +0x1040e00,4, +0x1040e20,4, +0x1040e80,16, +0x1040f00,1, +0x1040f20,1, +0x1041020,2, +0x1041208,6, +0x1041228,10, +0x1041288,6, +0x10412a8,10, +0x1041600,32, +0x10418c0,8, +0x1041900,24, +0x10419b0,4, +0x1041aa0,2, +0x1041ac0,4, +0x1042200,19, +0x1042280,19, +0x1042400,14, +0x104243c,9, +0x1042464,14, +0x10424a0,2, +0x10424ac,2, +0x1042500,14, +0x104253c,9, +0x1042564,14, +0x10425a0,2, +0x10425ac,2, +0x1042800,19, +0x1042880,19, +0x1042a10,2, +0x1042a1c,1, +0x1042a50,2, +0x1042a5c,1, +0x1042c00,7, +0x1042c20,1, +0x1042c54,18, +0x1042ca0,1, +0x1042cd4,11, +0x1042e00,1, +0x1042e08,6, +0x1043180,3, +0x1044400,4, +0x1044440,4, +0x10445c0,1, +0x1044600,8, +0x1044800,18, +0x1044880,13, +0x10448f0,3, +0x1044900,18, +0x1044980,13, +0x10449f0,3, +0x1044e00,4, +0x1044e20,4, +0x1044e80,16, +0x1044f00,1, +0x1044f20,1, +0x1045020,2, +0x1045208,6, +0x1045228,10, +0x1045288,6, +0x10452a8,10, +0x1045600,32, +0x10458c0,8, +0x1045900,24, +0x10459b0,4, +0x1045aa0,2, +0x1045ac0,4, +0x1046200,19, +0x1046280,19, +0x1046400,14, +0x104643c,9, +0x1046464,14, +0x10464a0,2, +0x10464ac,2, +0x1046500,14, +0x104653c,9, +0x1046564,14, +0x10465a0,2, +0x10465ac,2, +0x1046800,19, +0x1046880,19, +0x1046a10,2, +0x1046a1c,1, +0x1046a50,2, +0x1046a5c,1, +0x1046c00,7, +0x1046c20,1, +0x1046c54,18, +0x1046ca0,1, +0x1046cd4,11, +0x1046e00,1, +0x1046e08,6, +0x1047180,3, +0x1049000,13, +0x104e000,19, +0x104ea00,10, +0x104ea80,3, +0x104f000,1, +0x104f008,5, +0x104f038,1, +0x104f044,1, +0x104f050,2, +0x104f060,8, +0x104f140,19, +0x104f190,4, +0x1050000,2, +0x105000c,2, +0x1050040,7, +0x1050100,3, +0x1050110,3, +0x1050120,5, +0x1050200,6, +0x1050240,5, +0x1050400,2, +0x105040c,2, +0x1050440,7, +0x1050500,3, +0x1050510,3, +0x1050520,5, +0x1050600,6, +0x1050640,5, +0x1050800,2, +0x105080c,2, +0x1050840,7, +0x1050900,3, +0x1050910,3, +0x1050920,5, +0x1050a00,6, +0x1050a40,5, +0x1050c00,2, +0x1050c0c,2, +0x1050c40,7, +0x1050d00,3, +0x1050d10,3, +0x1050d20,5, +0x1050e00,6, +0x1050e40,5, +0x1051000,2, +0x105100c,2, +0x1051040,7, +0x1051100,3, +0x1051110,3, +0x1051120,5, +0x1051200,6, +0x1051240,5, +0x1051400,2, +0x105140c,2, +0x1051440,7, +0x1051500,3, +0x1051510,3, +0x1051520,5, +0x1051600,6, +0x1051640,5, +0x1051800,2, +0x105180c,2, +0x1051840,7, +0x1051900,3, +0x1051910,3, +0x1051920,5, +0x1051a00,6, +0x1051a40,5, +0x1051c00,2, +0x1051c0c,2, +0x1051c40,7, +0x1051d00,3, +0x1051d10,3, +0x1051d20,5, +0x1051e00,6, +0x1051e40,5, +0x1052000,5, +0x1052040,9, +0x1052100,3, +0x1052200,1, +0x1052210,1, +0x1052220,1, +0x1052230,1, +0x1052240,1, +0x1052300,3, +0x1052314,1, +0x1052320,4, +0x1052400,5, +0x1052440,5, +0x1053000,80, +0x1053200,1, +0x1058000,7, +0x1058030,2, +0x1058040,7, +0x1058070,2, +0x1058100,2, +0x1058120,2, +0x1058140,2, +0x1058160,2, +0x1058180,9, +0x1058200,7, +0x1058230,2, +0x1058240,7, +0x1058270,2, +0x1058300,2, +0x1058320,2, +0x1058340,2, +0x1058360,2, +0x1058380,9, +0x1058400,11, +0x1058500,11, +0x1059000,3, +0x1059010,2, +0x105901c,5, +0x1059040,8, +0x1059080,3, +0x1059090,2, +0x105909c,5, +0x10590c0,8, +0x1059100,3, +0x1059110,2, +0x105911c,5, +0x1059140,8, +0x1059180,3, +0x1059190,2, +0x105919c,5, +0x10591c0,8, +0x1059200,7, +0x1059220,12, +0x1059280,7, +0x10592a0,12, +0x1059300,3, +0x1059310,1, +0x1059400,3, +0x1059410,2, +0x105941c,5, +0x1059440,8, +0x1059480,3, +0x1059490,2, +0x105949c,5, +0x10594c0,8, +0x1059500,3, +0x1059510,2, +0x105951c,5, +0x1059540,8, +0x1059580,3, +0x1059590,2, +0x105959c,5, +0x10595c0,8, +0x1059600,7, +0x1059620,12, +0x1059680,7, +0x10596a0,12, +0x1059700,3, +0x1059710,1, +0x1059804,1, +0x1059824,21, +0x1059880,16, +0x1059900,5, +0x1059920,11, +0x1059950,9, +0x1059980,22, +0x1059a00,22, +0x1059a80,22, +0x1059b00,22, +0x1059b80,22, +0x1059c00,22, +0x1059c80,22, +0x1059d00,22, +0x1059d80,3, +0x1060000,5, +0x1060018,5, +0x1060030,3, +0x1060044,3, +0x1060100,58, +0x10601f0,3, +0x1060280,3, +0x1060400,5, +0x1060418,5, +0x1060430,3, +0x1060444,3, +0x1060500,58, +0x10605f0,3, +0x1060680,3, +0x1061018,2, +0x1061100,2, +0x1061110,10, +0x1061140,2, +0x1061150,10, +0x1061208,1, +0x1061220,12, +0x1061280,1, +0x1061288,2, +0x1061400,4, +0x1062000,5, +0x1062018,5, +0x1062030,3, +0x1062044,3, +0x1062100,58, +0x10621f0,3, +0x1062280,3, +0x1062400,5, +0x1062418,5, +0x1062430,3, +0x1062444,3, +0x1062500,58, +0x10625f0,3, +0x1062680,3, +0x1063018,2, +0x1063100,2, +0x1063110,10, +0x1063140,2, +0x1063150,10, +0x1063208,1, +0x1063220,12, +0x1063280,1, +0x1063288,2, +0x1063400,4, +0x1064000,2, +0x106400c,1, +0x1064030,3, +0x1064040,2, +0x106404c,1, +0x1064070,3, +0x1064100,2, +0x106410c,1, +0x1064130,3, +0x1064140,2, +0x106414c,1, +0x1064170,3, +0x1064200,15, +0x1064280,15, +0x1064300,15, +0x1064380,15, +0x1064400,15, +0x1064480,15, +0x1064500,15, +0x1064580,15, +0x1064604,10, +0x1064700,2, +0x106470c,7, +0x1064740,1, +0x1064770,1, +0x10647c0,2, +0x10647d0,4, +0x1065000,3, +0x1065010,1, +0x106501c,3, +0x1065104,1, +0x1065110,4, +0x1065124,1, +0x1065130,4, +0x1065144,1, +0x1065150,4, +0x1065164,1, +0x1065170,5, +0x1065190,4, +0x1065a00,4, +0x1065c00,129, +0x1066000,37, +0x1066098,1, +0x1066100,37, +0x1066198,1, +0x1066200,37, +0x1066298,1, +0x1066300,37, +0x1066398,1, +0x1066400,37, +0x1066498,1, +0x1066500,37, +0x1066598,1, +0x1066600,37, +0x1066698,1, +0x1066700,37, +0x1066798,1, +0x106c000,91, +0x106c400,4, +0x106c440,15, +0x106c480,4, +0x106c4c0,15, +0x106c500,4, +0x106c540,15, +0x106c580,4, +0x106c5c0,15, +0x106c600,4, +0x106c640,10, +0x106c680,4, +0x106c6c0,10, +0x106c800,4, +0x106c840,33, +0x106ca00,13, +0x106ca80,1, +0x106ca88,8, +0x106cac0,6, +0x106cae0,1, +0x106cae8,2, +0x106cb04,14, +0x106cc00,4, +0x106ccc8,1, +0x106cfcc,3, +0x106cfe0,99, +0x106d400,4, +0x106d440,15, +0x106d480,4, +0x106d4c0,15, +0x106d500,4, +0x106d540,15, +0x106d580,4, +0x106d5c0,15, +0x106d600,4, +0x106d640,10, +0x106d680,4, +0x106d6c0,10, +0x106d800,4, +0x106d840,33, +0x106da00,13, +0x106da80,1, +0x106da88,8, +0x106dac0,6, +0x106dae0,1, +0x106dae8,2, +0x106db04,14, +0x106dc00,4, +0x106dcc8,1, +0x106dfcc,3, +0x106dfe0,27, +0x106f000,19, +0x106fa00,10, +0x106fa80,3, +0x106fb00,6, +0x1070000,51, +0x1070a00,10, +0x1070a80,3, +0x1071000,2, +0x107100c,4, +0x1071028,3, +0x1071038,4, +0x1071050,2, +0x1071080,4, +0x1071098,7, +0x1071120,4, +0x1071200,4, +0x1071214,7, +0x1071234,3, +0x1071280,8, +0x10712c0,5, +0x1071300,2, +0x107130c,3, +0x1071400,24, +0x1071464,2, +0x1071470,3, +0x1071500,25, +0x10715c0,8, +0x10715e8,5, +0x1071600,5, +0x1071618,1, +0x1071620,1, +0x1071628,1, +0x1071630,2, +0x1071640,2, +0x1071650,2, +0x1071690,4, +0x1071740,2, +0x1071760,6, +0x1071780,6, +0x10717a0,6, +0x10717c0,6, +0x10717e0,1, +0x1071800,2, +0x107180c,4, +0x1071828,3, +0x1071838,4, +0x1071850,2, +0x1071880,4, +0x1071898,7, +0x1071920,4, +0x1071a00,4, +0x1071a14,7, +0x1071a34,3, +0x1071a80,8, +0x1071ac0,5, +0x1071b00,2, +0x1071b0c,3, +0x1071c00,24, +0x1071c64,2, +0x1071c70,3, +0x1071d00,25, +0x1071dc0,8, +0x1071de8,5, +0x1071e00,5, +0x1071e18,1, +0x1071e20,1, +0x1071e28,1, +0x1071e30,2, +0x1071e40,2, +0x1071e50,2, +0x1071e90,4, +0x1071f40,2, +0x1071f60,6, +0x1071f80,6, +0x1071fa0,6, +0x1071fc0,6, +0x1071fe0,1, +0x1072000,19, +0x1072080,2, +0x10720b0,2, +0x10720c0,2, +0x1080000,11, +0x1080040,16, +0x1080084,5, +0x1080200,7, +0x1080220,6, +0x1080240,7, +0x1080260,6, +0x1080280,6, +0x10802a0,2, +0x10802ac,2, +0x10802c0,7, +0x10802e0,7, +0x1080300,2, +0x108030c,2, +0x1080320,6, +0x1080400,2, +0x1081000,19, +0x1082104,23, +0x1082180,7, +0x10821a0,6, +0x10821c0,7, +0x10821e0,6, +0x1082200,4, +0x1082220,4, +0x1082240,11, +0x1082270,32, +0x1082300,24, +0x1082380,20, +0x1082400,61, +0x1082500,25, +0x1082568,4, +0x1082580,2, +0x10825a0,1, +0x10825c0,11, +0x1082600,9, +0x1082640,3, +0x1082650,3, +0x1082664,3, +0x1082680,22, +0x1082800,11, +0x1083000,536, +0x1084104,23, +0x1084180,7, +0x10841a0,6, +0x10841c0,7, +0x10841e0,6, +0x1084200,4, +0x1084220,4, +0x1084240,11, +0x1084270,32, +0x1084300,24, +0x1084380,20, +0x1084400,61, +0x1084500,25, +0x1084568,4, +0x1084580,2, +0x10845a0,1, +0x10845c0,11, +0x1084600,9, +0x1084640,3, +0x1084650,3, +0x1084664,3, +0x1084680,22, +0x1084800,11, +0x1085000,536, +0x108a000,7, +0x108a048,8, +0x108a080,8, +0x108a100,7, +0x108a148,8, +0x108a180,8, +0x1090000,11, +0x1090040,16, +0x1090084,5, +0x1090200,7, +0x1090220,6, +0x1090240,7, +0x1090260,6, +0x1090280,6, +0x10902a0,2, +0x10902ac,2, +0x10902c0,7, +0x10902e0,7, +0x1090300,2, +0x109030c,2, +0x1090320,6, +0x1090400,2, +0x1091000,19, +0x1092104,23, +0x1092180,7, +0x10921a0,6, +0x10921c0,7, +0x10921e0,6, +0x1092200,4, +0x1092220,4, +0x1092240,11, +0x1092270,32, +0x1092300,24, +0x1092380,20, +0x1092400,61, +0x1092500,25, +0x1092568,4, +0x1092580,2, +0x10925a0,1, +0x10925c0,11, +0x1092600,9, +0x1092640,3, +0x1092650,3, +0x1092664,3, +0x1092680,22, +0x1092800,11, +0x1093000,536, +0x1094104,23, +0x1094180,7, +0x10941a0,6, +0x10941c0,7, +0x10941e0,6, +0x1094200,4, +0x1094220,4, +0x1094240,11, +0x1094270,32, +0x1094300,24, +0x1094380,20, +0x1094400,61, +0x1094500,25, +0x1094568,4, +0x1094580,2, +0x10945a0,1, +0x10945c0,11, +0x1094600,9, +0x1094640,3, +0x1094650,3, +0x1094664,3, +0x1094680,22, +0x1094800,11, +0x1095000,536, +0x109a000,7, +0x109a048,8, +0x109a080,8, +0x109a100,7, +0x109a148,8, +0x109a180,8, +0x10a0400,4, +0x10a0440,4, +0x10a05c0,1, +0x10a0600,8, +0x10a0800,18, +0x10a0880,13, +0x10a08f0,3, +0x10a0900,18, +0x10a0980,13, +0x10a09f0,3, +0x10a0e00,4, +0x10a0e20,4, +0x10a0e80,16, +0x10a0f00,1, +0x10a0f20,1, +0x10a1020,2, +0x10a1208,6, +0x10a1228,10, +0x10a1288,6, +0x10a12a8,10, +0x10a1600,32, +0x10a18c0,8, +0x10a1900,24, +0x10a19b0,4, +0x10a1aa0,2, +0x10a1ac0,4, +0x10a2200,19, +0x10a2280,19, +0x10a2400,14, +0x10a243c,9, +0x10a2464,14, +0x10a24a0,2, +0x10a24ac,2, +0x10a2500,14, +0x10a253c,9, +0x10a2564,14, +0x10a25a0,2, +0x10a25ac,2, +0x10a2800,19, +0x10a2880,19, +0x10a2a10,2, +0x10a2a1c,1, +0x10a2a50,2, +0x10a2a5c,1, +0x10a2c00,7, +0x10a2c20,1, +0x10a2c54,18, +0x10a2ca0,1, +0x10a2cd4,11, +0x10a2e00,1, +0x10a2e08,6, +0x10a3180,3, +0x10a4400,4, +0x10a4440,4, +0x10a45c0,1, +0x10a4600,8, +0x10a4800,18, +0x10a4880,13, +0x10a48f0,3, +0x10a4900,18, +0x10a4980,13, +0x10a49f0,3, +0x10a4e00,4, +0x10a4e20,4, +0x10a4e80,16, +0x10a4f00,1, +0x10a4f20,1, +0x10a5020,2, +0x10a5208,6, +0x10a5228,10, +0x10a5288,6, +0x10a52a8,10, +0x10a5600,32, +0x10a58c0,8, +0x10a5900,24, +0x10a59b0,4, +0x10a5aa0,2, +0x10a5ac0,4, +0x10a6200,19, +0x10a6280,19, +0x10a6400,14, +0x10a643c,9, +0x10a6464,14, +0x10a64a0,2, +0x10a64ac,2, +0x10a6500,14, +0x10a653c,9, +0x10a6564,14, +0x10a65a0,2, +0x10a65ac,2, +0x10a6800,19, +0x10a6880,19, +0x10a6a10,2, +0x10a6a1c,1, +0x10a6a50,2, +0x10a6a5c,1, +0x10a6c00,7, +0x10a6c20,1, +0x10a6c54,18, +0x10a6ca0,1, +0x10a6cd4,11, +0x10a6e00,1, +0x10a6e08,6, +0x10a7180,3, +0x10a9000,13, +0x10ae000,19, +0x10aea00,10, +0x10aea80,3, +0x10af000,1, +0x10af008,5, +0x10af038,1, +0x10af044,1, +0x10af050,2, +0x10af060,8, +0x10af140,19, +0x10af190,4, +0x10b0000,2, +0x10b000c,2, +0x10b0040,7, +0x10b0100,3, +0x10b0110,3, +0x10b0120,5, +0x10b0200,6, +0x10b0240,5, +0x10b0400,2, +0x10b040c,2, +0x10b0440,7, +0x10b0500,3, +0x10b0510,3, +0x10b0520,5, +0x10b0600,6, +0x10b0640,5, +0x10b0800,2, +0x10b080c,2, +0x10b0840,7, +0x10b0900,3, +0x10b0910,3, +0x10b0920,5, +0x10b0a00,6, +0x10b0a40,5, +0x10b0c00,2, +0x10b0c0c,2, +0x10b0c40,7, +0x10b0d00,3, +0x10b0d10,3, +0x10b0d20,5, +0x10b0e00,6, +0x10b0e40,5, +0x10b1000,2, +0x10b100c,2, +0x10b1040,7, +0x10b1100,3, +0x10b1110,3, +0x10b1120,5, +0x10b1200,6, +0x10b1240,5, +0x10b1400,2, +0x10b140c,2, +0x10b1440,7, +0x10b1500,3, +0x10b1510,3, +0x10b1520,5, +0x10b1600,6, +0x10b1640,5, +0x10b1800,2, +0x10b180c,2, +0x10b1840,7, +0x10b1900,3, +0x10b1910,3, +0x10b1920,5, +0x10b1a00,6, +0x10b1a40,5, +0x10b1c00,2, +0x10b1c0c,2, +0x10b1c40,7, +0x10b1d00,3, +0x10b1d10,3, +0x10b1d20,5, +0x10b1e00,6, +0x10b1e40,5, +0x10b2000,5, +0x10b2040,9, +0x10b2100,3, +0x10b2200,1, +0x10b2210,1, +0x10b2220,1, +0x10b2230,1, +0x10b2240,1, +0x10b2300,3, +0x10b2314,1, +0x10b2320,4, +0x10b2400,5, +0x10b2440,5, +0x10b3000,80, +0x10b3200,1, +0x10b8000,7, +0x10b8030,2, +0x10b8040,7, +0x10b8070,2, +0x10b8100,2, +0x10b8120,2, +0x10b8140,2, +0x10b8160,2, +0x10b8180,9, +0x10b8200,7, +0x10b8230,2, +0x10b8240,7, +0x10b8270,2, +0x10b8300,2, +0x10b8320,2, +0x10b8340,2, +0x10b8360,2, +0x10b8380,9, +0x10b8400,11, +0x10b8500,11, +0x10b9000,3, +0x10b9010,2, +0x10b901c,5, +0x10b9040,8, +0x10b9080,3, +0x10b9090,2, +0x10b909c,5, +0x10b90c0,8, +0x10b9100,3, +0x10b9110,2, +0x10b911c,5, +0x10b9140,8, +0x10b9180,3, +0x10b9190,2, +0x10b919c,5, +0x10b91c0,8, +0x10b9200,7, +0x10b9220,12, +0x10b9280,7, +0x10b92a0,12, +0x10b9300,3, +0x10b9310,1, +0x10b9400,3, +0x10b9410,2, +0x10b941c,5, +0x10b9440,8, +0x10b9480,3, +0x10b9490,2, +0x10b949c,5, +0x10b94c0,8, +0x10b9500,3, +0x10b9510,2, +0x10b951c,5, +0x10b9540,8, +0x10b9580,3, +0x10b9590,2, +0x10b959c,5, +0x10b95c0,8, +0x10b9600,7, +0x10b9620,12, +0x10b9680,7, +0x10b96a0,12, +0x10b9700,3, +0x10b9710,1, +0x10b9804,1, +0x10b9824,21, +0x10b9880,16, +0x10b9900,5, +0x10b9920,11, +0x10b9950,9, +0x10b9980,22, +0x10b9a00,22, +0x10b9a80,22, +0x10b9b00,22, +0x10b9b80,22, +0x10b9c00,22, +0x10b9c80,22, +0x10b9d00,22, +0x10b9d80,3, +0x10c0000,5, +0x10c0018,5, +0x10c0030,3, +0x10c0044,3, +0x10c0100,58, +0x10c01f0,3, +0x10c0280,3, +0x10c0400,5, +0x10c0418,5, +0x10c0430,3, +0x10c0444,3, +0x10c0500,58, +0x10c05f0,3, +0x10c0680,3, +0x10c1018,2, +0x10c1100,2, +0x10c1110,10, +0x10c1140,2, +0x10c1150,10, +0x10c1208,1, +0x10c1220,12, +0x10c1280,1, +0x10c1288,2, +0x10c1400,4, +0x10c2000,5, +0x10c2018,5, +0x10c2030,3, +0x10c2044,3, +0x10c2100,58, +0x10c21f0,3, +0x10c2280,3, +0x10c2400,5, +0x10c2418,5, +0x10c2430,3, +0x10c2444,3, +0x10c2500,58, +0x10c25f0,3, +0x10c2680,3, +0x10c3018,2, +0x10c3100,2, +0x10c3110,10, +0x10c3140,2, +0x10c3150,10, +0x10c3208,1, +0x10c3220,12, +0x10c3280,1, +0x10c3288,2, +0x10c3400,4, +0x10c4000,2, +0x10c400c,1, +0x10c4030,3, +0x10c4040,2, +0x10c404c,1, +0x10c4070,3, +0x10c4100,2, +0x10c410c,1, +0x10c4130,3, +0x10c4140,2, +0x10c414c,1, +0x10c4170,3, +0x10c4200,15, +0x10c4280,15, +0x10c4300,15, +0x10c4380,15, +0x10c4400,15, +0x10c4480,15, +0x10c4500,15, +0x10c4580,15, +0x10c4604,10, +0x10c4700,2, +0x10c470c,7, +0x10c4740,1, +0x10c4770,1, +0x10c47c0,2, +0x10c47d0,4, +0x10c5000,3, +0x10c5010,1, +0x10c501c,3, +0x10c5104,1, +0x10c5110,4, +0x10c5124,1, +0x10c5130,4, +0x10c5144,1, +0x10c5150,4, +0x10c5164,1, +0x10c5170,5, +0x10c5190,4, +0x10c5a00,4, +0x10c5c00,129, +0x10c6000,37, +0x10c6098,1, +0x10c6100,37, +0x10c6198,1, +0x10c6200,37, +0x10c6298,1, +0x10c6300,37, +0x10c6398,1, +0x10c6400,37, +0x10c6498,1, +0x10c6500,37, +0x10c6598,1, +0x10c6600,37, +0x10c6698,1, +0x10c6700,37, +0x10c6798,1, +0x10cc000,91, +0x10cc400,4, +0x10cc440,15, +0x10cc480,4, +0x10cc4c0,15, +0x10cc500,4, +0x10cc540,15, +0x10cc580,4, +0x10cc5c0,15, +0x10cc600,4, +0x10cc640,10, +0x10cc680,4, +0x10cc6c0,10, +0x10cc800,4, +0x10cc840,33, +0x10cca00,13, +0x10cca80,1, +0x10cca88,8, +0x10ccac0,6, +0x10ccae0,1, +0x10ccae8,2, +0x10ccb04,14, +0x10ccc00,4, +0x10cccc8,1, +0x10ccfcc,3, +0x10ccfe0,99, +0x10cd400,4, +0x10cd440,15, +0x10cd480,4, +0x10cd4c0,15, +0x10cd500,4, +0x10cd540,15, +0x10cd580,4, +0x10cd5c0,15, +0x10cd600,4, +0x10cd640,10, +0x10cd680,4, +0x10cd6c0,10, +0x10cd800,4, +0x10cd840,33, +0x10cda00,13, +0x10cda80,1, +0x10cda88,8, +0x10cdac0,6, +0x10cdae0,1, +0x10cdae8,2, +0x10cdb04,14, +0x10cdc00,4, +0x10cdcc8,1, +0x10cdfcc,3, +0x10cdfe0,27, +0x10cf000,19, +0x10cfa00,10, +0x10cfa80,3, +0x10cfb00,6, +0x10d0000,51, +0x10d0a00,10, +0x10d0a80,3, +0x10d1000,2, +0x10d100c,4, +0x10d1028,3, +0x10d1038,4, +0x10d1050,2, +0x10d1080,4, +0x10d1098,7, +0x10d1120,4, +0x10d1200,4, +0x10d1214,7, +0x10d1234,3, +0x10d1280,8, +0x10d12c0,5, +0x10d1300,2, +0x10d130c,3, +0x10d1400,24, +0x10d1464,2, +0x10d1470,3, +0x10d1500,25, +0x10d15c0,8, +0x10d15e8,5, +0x10d1600,5, +0x10d1618,1, +0x10d1620,1, +0x10d1628,1, +0x10d1630,2, +0x10d1640,2, +0x10d1650,2, +0x10d1690,4, +0x10d1740,2, +0x10d1760,6, +0x10d1780,6, +0x10d17a0,6, +0x10d17c0,6, +0x10d17e0,1, +0x10d1800,2, +0x10d180c,4, +0x10d1828,3, +0x10d1838,4, +0x10d1850,2, +0x10d1880,4, +0x10d1898,7, +0x10d1920,4, +0x10d1a00,4, +0x10d1a14,7, +0x10d1a34,3, +0x10d1a80,8, +0x10d1ac0,5, +0x10d1b00,2, +0x10d1b0c,3, +0x10d1c00,24, +0x10d1c64,2, +0x10d1c70,3, +0x10d1d00,25, +0x10d1dc0,8, +0x10d1de8,5, +0x10d1e00,5, +0x10d1e18,1, +0x10d1e20,1, +0x10d1e28,1, +0x10d1e30,2, +0x10d1e40,2, +0x10d1e50,2, +0x10d1e90,4, +0x10d1f40,2, +0x10d1f60,6, +0x10d1f80,6, +0x10d1fa0,6, +0x10d1fc0,6, +0x10d1fe0,1, +0x10d2000,19, +0x10d2080,2, +0x10d20b0,2, +0x10d20c0,2, +0x10e0000,11, +0x10e0040,16, +0x10e0084,5, +0x10e0200,7, +0x10e0220,6, +0x10e0240,7, +0x10e0260,6, +0x10e0280,6, +0x10e02a0,2, +0x10e02ac,2, +0x10e02c0,7, +0x10e02e0,7, +0x10e0300,2, +0x10e030c,2, +0x10e0320,6, +0x10e0400,2, +0x10e1000,19, +0x10e2104,23, +0x10e2180,7, +0x10e21a0,6, +0x10e21c0,7, +0x10e21e0,6, +0x10e2200,4, +0x10e2220,4, +0x10e2240,11, +0x10e2270,32, +0x10e2300,24, +0x10e2380,20, +0x10e2400,61, +0x10e2500,25, +0x10e2568,4, +0x10e2580,2, +0x10e25a0,1, +0x10e25c0,11, +0x10e2600,9, +0x10e2640,3, +0x10e2650,3, +0x10e2664,3, +0x10e2680,22, +0x10e2800,11, +0x10e3000,536, +0x10e4104,23, +0x10e4180,7, +0x10e41a0,6, +0x10e41c0,7, +0x10e41e0,6, +0x10e4200,4, +0x10e4220,4, +0x10e4240,11, +0x10e4270,32, +0x10e4300,24, +0x10e4380,20, +0x10e4400,61, +0x10e4500,25, +0x10e4568,4, +0x10e4580,2, +0x10e45a0,1, +0x10e45c0,11, +0x10e4600,9, +0x10e4640,3, +0x10e4650,3, +0x10e4664,3, +0x10e4680,22, +0x10e4800,11, +0x10e5000,536, +0x10ea000,7, +0x10ea048,8, +0x10ea080,8, +0x10ea100,7, +0x10ea148,8, +0x10ea180,8, +0x10f0000,11, +0x10f0040,16, +0x10f0084,5, +0x10f0200,7, +0x10f0220,6, +0x10f0240,7, +0x10f0260,6, +0x10f0280,6, +0x10f02a0,2, +0x10f02ac,2, +0x10f02c0,7, +0x10f02e0,7, +0x10f0300,2, +0x10f030c,2, +0x10f0320,6, +0x10f0400,2, +0x10f1000,19, +0x10f2104,23, +0x10f2180,7, +0x10f21a0,6, +0x10f21c0,7, +0x10f21e0,6, +0x10f2200,4, +0x10f2220,4, +0x10f2240,11, +0x10f2270,32, +0x10f2300,24, +0x10f2380,20, +0x10f2400,61, +0x10f2500,25, +0x10f2568,4, +0x10f2580,2, +0x10f25a0,1, +0x10f25c0,11, +0x10f2600,9, +0x10f2640,3, +0x10f2650,3, +0x10f2664,3, +0x10f2680,22, +0x10f2800,11, +0x10f3000,536, +0x10f4104,23, +0x10f4180,7, +0x10f41a0,6, +0x10f41c0,7, +0x10f41e0,6, +0x10f4200,4, +0x10f4220,4, +0x10f4240,11, +0x10f4270,32, +0x10f4300,24, +0x10f4380,20, +0x10f4400,61, +0x10f4500,25, +0x10f4568,4, +0x10f4580,2, +0x10f45a0,1, +0x10f45c0,11, +0x10f4600,9, +0x10f4640,3, +0x10f4650,3, +0x10f4664,3, +0x10f4680,22, +0x10f4800,11, +0x10f5000,536, +0x10fa000,7, +0x10fa048,8, +0x10fa080,8, +0x10fa100,7, +0x10fa148,8, +0x10fa180,8, +0x1100400,4, +0x1100440,4, +0x11005c0,1, +0x1100600,8, +0x1100800,18, +0x1100880,13, +0x11008f0,3, +0x1100900,18, +0x1100980,13, +0x11009f0,3, +0x1100e00,4, +0x1100e20,4, +0x1100e80,16, +0x1100f00,1, +0x1100f20,1, +0x1101020,2, +0x1101208,6, +0x1101228,10, +0x1101288,6, +0x11012a8,10, +0x1101600,32, +0x11018c0,8, +0x1101900,24, +0x11019b0,4, +0x1101aa0,2, +0x1101ac0,4, +0x1102200,19, +0x1102280,19, +0x1102400,14, +0x110243c,9, +0x1102464,14, +0x11024a0,2, +0x11024ac,2, +0x1102500,14, +0x110253c,9, +0x1102564,14, +0x11025a0,2, +0x11025ac,2, +0x1102800,19, +0x1102880,19, +0x1102a10,2, +0x1102a1c,1, +0x1102a50,2, +0x1102a5c,1, +0x1102c00,7, +0x1102c20,1, +0x1102c54,18, +0x1102ca0,1, +0x1102cd4,11, +0x1102e00,1, +0x1102e08,6, +0x1103180,3, +0x1104400,4, +0x1104440,4, +0x11045c0,1, +0x1104600,8, +0x1104800,18, +0x1104880,13, +0x11048f0,3, +0x1104900,18, +0x1104980,13, +0x11049f0,3, +0x1104e00,4, +0x1104e20,4, +0x1104e80,16, +0x1104f00,1, +0x1104f20,1, +0x1105020,2, +0x1105208,6, +0x1105228,10, +0x1105288,6, +0x11052a8,10, +0x1105600,32, +0x11058c0,8, +0x1105900,24, +0x11059b0,4, +0x1105aa0,2, +0x1105ac0,4, +0x1106200,19, +0x1106280,19, +0x1106400,14, +0x110643c,9, +0x1106464,14, +0x11064a0,2, +0x11064ac,2, +0x1106500,14, +0x110653c,9, +0x1106564,14, +0x11065a0,2, +0x11065ac,2, +0x1106800,19, +0x1106880,19, +0x1106a10,2, +0x1106a1c,1, +0x1106a50,2, +0x1106a5c,1, +0x1106c00,7, +0x1106c20,1, +0x1106c54,18, +0x1106ca0,1, +0x1106cd4,11, +0x1106e00,1, +0x1106e08,6, +0x1107180,3, +0x1109000,13, +0x110e000,19, +0x110ea00,10, +0x110ea80,3, +0x110f000,1, +0x110f008,5, +0x110f038,1, +0x110f044,1, +0x110f050,2, +0x110f060,8, +0x110f140,19, +0x110f190,4, +0x1110000,2, +0x111000c,2, +0x1110040,7, +0x1110100,3, +0x1110110,3, +0x1110120,5, +0x1110200,6, +0x1110240,5, +0x1110400,2, +0x111040c,2, +0x1110440,7, +0x1110500,3, +0x1110510,3, +0x1110520,5, +0x1110600,6, +0x1110640,5, +0x1110800,2, +0x111080c,2, +0x1110840,7, +0x1110900,3, +0x1110910,3, +0x1110920,5, +0x1110a00,6, +0x1110a40,5, +0x1110c00,2, +0x1110c0c,2, +0x1110c40,7, +0x1110d00,3, +0x1110d10,3, +0x1110d20,5, +0x1110e00,6, +0x1110e40,5, +0x1111000,2, +0x111100c,2, +0x1111040,7, +0x1111100,3, +0x1111110,3, +0x1111120,5, +0x1111200,6, +0x1111240,5, +0x1111400,2, +0x111140c,2, +0x1111440,7, +0x1111500,3, +0x1111510,3, +0x1111520,5, +0x1111600,6, +0x1111640,5, +0x1111800,2, +0x111180c,2, +0x1111840,7, +0x1111900,3, +0x1111910,3, +0x1111920,5, +0x1111a00,6, +0x1111a40,5, +0x1111c00,2, +0x1111c0c,2, +0x1111c40,7, +0x1111d00,3, +0x1111d10,3, +0x1111d20,5, +0x1111e00,6, +0x1111e40,5, +0x1112000,5, +0x1112040,9, +0x1112100,3, +0x1112200,1, +0x1112210,1, +0x1112220,1, +0x1112230,1, +0x1112240,1, +0x1112300,3, +0x1112314,1, +0x1112320,4, +0x1112400,5, +0x1112440,5, +0x1113000,80, +0x1113200,1, +0x1118000,7, +0x1118030,2, +0x1118040,7, +0x1118070,2, +0x1118100,2, +0x1118120,2, +0x1118140,2, +0x1118160,2, +0x1118180,9, +0x1118200,7, +0x1118230,2, +0x1118240,7, +0x1118270,2, +0x1118300,2, +0x1118320,2, +0x1118340,2, +0x1118360,2, +0x1118380,9, +0x1118400,11, +0x1118500,11, +0x1119000,3, +0x1119010,2, +0x111901c,5, +0x1119040,8, +0x1119080,3, +0x1119090,2, +0x111909c,5, +0x11190c0,8, +0x1119100,3, +0x1119110,2, +0x111911c,5, +0x1119140,8, +0x1119180,3, +0x1119190,2, +0x111919c,5, +0x11191c0,8, +0x1119200,7, +0x1119220,12, +0x1119280,7, +0x11192a0,12, +0x1119300,3, +0x1119310,1, +0x1119400,3, +0x1119410,2, +0x111941c,5, +0x1119440,8, +0x1119480,3, +0x1119490,2, +0x111949c,5, +0x11194c0,8, +0x1119500,3, +0x1119510,2, +0x111951c,5, +0x1119540,8, +0x1119580,3, +0x1119590,2, +0x111959c,5, +0x11195c0,8, +0x1119600,7, +0x1119620,12, +0x1119680,7, +0x11196a0,12, +0x1119700,3, +0x1119710,1, +0x1119804,1, +0x1119824,21, +0x1119880,16, +0x1119900,5, +0x1119920,11, +0x1119950,9, +0x1119980,22, +0x1119a00,22, +0x1119a80,22, +0x1119b00,22, +0x1119b80,22, +0x1119c00,22, +0x1119c80,22, +0x1119d00,22, +0x1119d80,3, +0x1120000,5, +0x1120018,5, +0x1120030,3, +0x1120044,3, +0x1120100,58, +0x11201f0,3, +0x1120280,3, +0x1120400,5, +0x1120418,5, +0x1120430,3, +0x1120444,3, +0x1120500,58, +0x11205f0,3, +0x1120680,3, +0x1121018,2, +0x1121100,2, +0x1121110,10, +0x1121140,2, +0x1121150,10, +0x1121208,1, +0x1121220,12, +0x1121280,1, +0x1121288,2, +0x1121400,4, +0x1122000,5, +0x1122018,5, +0x1122030,3, +0x1122044,3, +0x1122100,58, +0x11221f0,3, +0x1122280,3, +0x1122400,5, +0x1122418,5, +0x1122430,3, +0x1122444,3, +0x1122500,58, +0x11225f0,3, +0x1122680,3, +0x1123018,2, +0x1123100,2, +0x1123110,10, +0x1123140,2, +0x1123150,10, +0x1123208,1, +0x1123220,12, +0x1123280,1, +0x1123288,2, +0x1123400,4, +0x1124000,2, +0x112400c,1, +0x1124030,3, +0x1124040,2, +0x112404c,1, +0x1124070,3, +0x1124100,2, +0x112410c,1, +0x1124130,3, +0x1124140,2, +0x112414c,1, +0x1124170,3, +0x1124200,15, +0x1124280,15, +0x1124300,15, +0x1124380,15, +0x1124400,15, +0x1124480,15, +0x1124500,15, +0x1124580,15, +0x1124604,10, +0x1124700,2, +0x112470c,7, +0x1124740,1, +0x1124770,1, +0x11247c0,2, +0x11247d0,4, +0x1125000,3, +0x1125010,1, +0x112501c,3, +0x1125104,1, +0x1125110,4, +0x1125124,1, +0x1125130,4, +0x1125144,1, +0x1125150,4, +0x1125164,1, +0x1125170,5, +0x1125190,4, +0x1125a00,4, +0x1125c00,129, +0x1126000,37, +0x1126098,1, +0x1126100,37, +0x1126198,1, +0x1126200,37, +0x1126298,1, +0x1126300,37, +0x1126398,1, +0x1126400,37, +0x1126498,1, +0x1126500,37, +0x1126598,1, +0x1126600,37, +0x1126698,1, +0x1126700,37, +0x1126798,1, +0x112c000,91, +0x112c400,4, +0x112c440,15, +0x112c480,4, +0x112c4c0,15, +0x112c500,4, +0x112c540,15, +0x112c580,4, +0x112c5c0,15, +0x112c600,4, +0x112c640,10, +0x112c680,4, +0x112c6c0,10, +0x112c800,4, +0x112c840,33, +0x112ca00,13, +0x112ca80,1, +0x112ca88,8, +0x112cac0,6, +0x112cae0,1, +0x112cae8,2, +0x112cb04,14, +0x112cc00,4, +0x112ccc8,1, +0x112cfcc,3, +0x112cfe0,99, +0x112d400,4, +0x112d440,15, +0x112d480,4, +0x112d4c0,15, +0x112d500,4, +0x112d540,15, +0x112d580,4, +0x112d5c0,15, +0x112d600,4, +0x112d640,10, +0x112d680,4, +0x112d6c0,10, +0x112d800,4, +0x112d840,33, +0x112da00,13, +0x112da80,1, +0x112da88,8, +0x112dac0,6, +0x112dae0,1, +0x112dae8,2, +0x112db04,14, +0x112dc00,4, +0x112dcc8,1, +0x112dfcc,3, +0x112dfe0,27, +0x112f000,19, +0x112fa00,10, +0x112fa80,3, +0x112fb00,6, +0x1130000,51, +0x1130a00,10, +0x1130a80,3, +0x1131000,2, +0x113100c,4, +0x1131028,3, +0x1131038,4, +0x1131050,2, +0x1131080,4, +0x1131098,7, +0x1131120,4, +0x1131200,4, +0x1131214,7, +0x1131234,3, +0x1131280,8, +0x11312c0,5, +0x1131300,2, +0x113130c,3, +0x1131400,24, +0x1131464,2, +0x1131470,3, +0x1131500,25, +0x11315c0,8, +0x11315e8,5, +0x1131600,5, +0x1131618,1, +0x1131620,1, +0x1131628,1, +0x1131630,2, +0x1131640,2, +0x1131650,2, +0x1131690,4, +0x1131740,2, +0x1131760,6, +0x1131780,6, +0x11317a0,6, +0x11317c0,6, +0x11317e0,1, +0x1131800,2, +0x113180c,4, +0x1131828,3, +0x1131838,4, +0x1131850,2, +0x1131880,4, +0x1131898,7, +0x1131920,4, +0x1131a00,4, +0x1131a14,7, +0x1131a34,3, +0x1131a80,8, +0x1131ac0,5, +0x1131b00,2, +0x1131b0c,3, +0x1131c00,24, +0x1131c64,2, +0x1131c70,3, +0x1131d00,25, +0x1131dc0,8, +0x1131de8,5, +0x1131e00,5, +0x1131e18,1, +0x1131e20,1, +0x1131e28,1, +0x1131e30,2, +0x1131e40,2, +0x1131e50,2, +0x1131e90,4, +0x1131f40,2, +0x1131f60,6, +0x1131f80,6, +0x1131fa0,6, +0x1131fc0,6, +0x1131fe0,1, +0x1132000,19, +0x1132080,2, +0x11320b0,2, +0x11320c0,2, +0x1140000,11, +0x1140040,16, +0x1140084,5, +0x1140200,7, +0x1140220,6, +0x1140240,7, +0x1140260,6, +0x1140280,6, +0x11402a0,2, +0x11402ac,2, +0x11402c0,7, +0x11402e0,7, +0x1140300,2, +0x114030c,2, +0x1140320,6, +0x1140400,2, +0x1141000,19, +0x1142104,23, +0x1142180,7, +0x11421a0,6, +0x11421c0,7, +0x11421e0,6, +0x1142200,4, +0x1142220,4, +0x1142240,11, +0x1142270,32, +0x1142300,24, +0x1142380,20, +0x1142400,61, +0x1142500,25, +0x1142568,4, +0x1142580,2, +0x11425a0,1, +0x11425c0,11, +0x1142600,9, +0x1142640,3, +0x1142650,3, +0x1142664,3, +0x1142680,22, +0x1142800,11, +0x1143000,536, +0x1144104,23, +0x1144180,7, +0x11441a0,6, +0x11441c0,7, +0x11441e0,6, +0x1144200,4, +0x1144220,4, +0x1144240,11, +0x1144270,32, +0x1144300,24, +0x1144380,20, +0x1144400,61, +0x1144500,25, +0x1144568,4, +0x1144580,2, +0x11445a0,1, +0x11445c0,11, +0x1144600,9, +0x1144640,3, +0x1144650,3, +0x1144664,3, +0x1144680,22, +0x1144800,11, +0x1145000,536, +0x114a000,7, +0x114a048,8, +0x114a080,8, +0x114a100,7, +0x114a148,8, +0x114a180,8, +0x1150000,11, +0x1150040,16, +0x1150084,5, +0x1150200,7, +0x1150220,6, +0x1150240,7, +0x1150260,6, +0x1150280,6, +0x11502a0,2, +0x11502ac,2, +0x11502c0,7, +0x11502e0,7, +0x1150300,2, +0x115030c,2, +0x1150320,6, +0x1150400,2, +0x1151000,19, +0x1152104,23, +0x1152180,7, +0x11521a0,6, +0x11521c0,7, +0x11521e0,6, +0x1152200,4, +0x1152220,4, +0x1152240,11, +0x1152270,32, +0x1152300,24, +0x1152380,20, +0x1152400,61, +0x1152500,25, +0x1152568,4, +0x1152580,2, +0x11525a0,1, +0x11525c0,11, +0x1152600,9, +0x1152640,3, +0x1152650,3, +0x1152664,3, +0x1152680,22, +0x1152800,11, +0x1153000,536, +0x1154104,23, +0x1154180,7, +0x11541a0,6, +0x11541c0,7, +0x11541e0,6, +0x1154200,4, +0x1154220,4, +0x1154240,11, +0x1154270,32, +0x1154300,24, +0x1154380,20, +0x1154400,61, +0x1154500,25, +0x1154568,4, +0x1154580,2, +0x11545a0,1, +0x11545c0,11, +0x1154600,9, +0x1154640,3, +0x1154650,3, +0x1154664,3, +0x1154680,22, +0x1154800,11, +0x1155000,536, +0x115a000,7, +0x115a048,8, +0x115a080,8, +0x115a100,7, +0x115a148,8, +0x115a180,8, +0x1160400,4, +0x1160440,4, +0x11605c0,1, +0x1160600,8, +0x1160800,18, +0x1160880,13, +0x11608f0,3, +0x1160900,18, +0x1160980,13, +0x11609f0,3, +0x1160e00,4, +0x1160e20,4, +0x1160e80,16, +0x1160f00,1, +0x1160f20,1, +0x1161020,2, +0x1161208,6, +0x1161228,10, +0x1161288,6, +0x11612a8,10, +0x1161600,32, +0x11618c0,8, +0x1161900,24, +0x11619b0,4, +0x1161aa0,2, +0x1161ac0,4, +0x1162200,19, +0x1162280,19, +0x1162400,14, +0x116243c,9, +0x1162464,14, +0x11624a0,2, +0x11624ac,2, +0x1162500,14, +0x116253c,9, +0x1162564,14, +0x11625a0,2, +0x11625ac,2, +0x1162800,19, +0x1162880,19, +0x1162a10,2, +0x1162a1c,1, +0x1162a50,2, +0x1162a5c,1, +0x1162c00,7, +0x1162c20,1, +0x1162c54,18, +0x1162ca0,1, +0x1162cd4,11, +0x1162e00,1, +0x1162e08,6, +0x1163180,3, +0x1164400,4, +0x1164440,4, +0x11645c0,1, +0x1164600,8, +0x1164800,18, +0x1164880,13, +0x11648f0,3, +0x1164900,18, +0x1164980,13, +0x11649f0,3, +0x1164e00,4, +0x1164e20,4, +0x1164e80,16, +0x1164f00,1, +0x1164f20,1, +0x1165020,2, +0x1165208,6, +0x1165228,10, +0x1165288,6, +0x11652a8,10, +0x1165600,32, +0x11658c0,8, +0x1165900,24, +0x11659b0,4, +0x1165aa0,2, +0x1165ac0,4, +0x1166200,19, +0x1166280,19, +0x1166400,14, +0x116643c,9, +0x1166464,14, +0x11664a0,2, +0x11664ac,2, +0x1166500,14, +0x116653c,9, +0x1166564,14, +0x11665a0,2, +0x11665ac,2, +0x1166800,19, +0x1166880,19, +0x1166a10,2, +0x1166a1c,1, +0x1166a50,2, +0x1166a5c,1, +0x1166c00,7, +0x1166c20,1, +0x1166c54,18, +0x1166ca0,1, +0x1166cd4,11, +0x1166e00,1, +0x1166e08,6, +0x1167180,3, +0x1169000,13, +0x116e000,19, +0x116ea00,10, +0x116ea80,3, +0x116f000,1, +0x116f008,5, +0x116f038,1, +0x116f044,1, +0x116f050,2, +0x116f060,8, +0x116f140,19, +0x116f190,4, +0x1170000,2, +0x117000c,2, +0x1170040,7, +0x1170100,3, +0x1170110,3, +0x1170120,5, +0x1170200,6, +0x1170240,5, +0x1170400,2, +0x117040c,2, +0x1170440,7, +0x1170500,3, +0x1170510,3, +0x1170520,5, +0x1170600,6, +0x1170640,5, +0x1170800,2, +0x117080c,2, +0x1170840,7, +0x1170900,3, +0x1170910,3, +0x1170920,5, +0x1170a00,6, +0x1170a40,5, +0x1170c00,2, +0x1170c0c,2, +0x1170c40,7, +0x1170d00,3, +0x1170d10,3, +0x1170d20,5, +0x1170e00,6, +0x1170e40,5, +0x1171000,2, +0x117100c,2, +0x1171040,7, +0x1171100,3, +0x1171110,3, +0x1171120,5, +0x1171200,6, +0x1171240,5, +0x1171400,2, +0x117140c,2, +0x1171440,7, +0x1171500,3, +0x1171510,3, +0x1171520,5, +0x1171600,6, +0x1171640,5, +0x1171800,2, +0x117180c,2, +0x1171840,7, +0x1171900,3, +0x1171910,3, +0x1171920,5, +0x1171a00,6, +0x1171a40,5, +0x1171c00,2, +0x1171c0c,2, +0x1171c40,7, +0x1171d00,3, +0x1171d10,3, +0x1171d20,5, +0x1171e00,6, +0x1171e40,5, +0x1172000,5, +0x1172040,9, +0x1172100,3, +0x1172200,1, +0x1172210,1, +0x1172220,1, +0x1172230,1, +0x1172240,1, +0x1172300,3, +0x1172314,1, +0x1172320,4, +0x1172400,5, +0x1172440,5, +0x1173000,80, +0x1173200,1, +0x1178000,7, +0x1178030,2, +0x1178040,7, +0x1178070,2, +0x1178100,2, +0x1178120,2, +0x1178140,2, +0x1178160,2, +0x1178180,9, +0x1178200,7, +0x1178230,2, +0x1178240,7, +0x1178270,2, +0x1178300,2, +0x1178320,2, +0x1178340,2, +0x1178360,2, +0x1178380,9, +0x1178400,11, +0x1178500,11, +0x1179000,3, +0x1179010,2, +0x117901c,5, +0x1179040,8, +0x1179080,3, +0x1179090,2, +0x117909c,5, +0x11790c0,8, +0x1179100,3, +0x1179110,2, +0x117911c,5, +0x1179140,8, +0x1179180,3, +0x1179190,2, +0x117919c,5, +0x11791c0,8, +0x1179200,7, +0x1179220,12, +0x1179280,7, +0x11792a0,12, +0x1179300,3, +0x1179310,1, +0x1179400,3, +0x1179410,2, +0x117941c,5, +0x1179440,8, +0x1179480,3, +0x1179490,2, +0x117949c,5, +0x11794c0,8, +0x1179500,3, +0x1179510,2, +0x117951c,5, +0x1179540,8, +0x1179580,3, +0x1179590,2, +0x117959c,5, +0x11795c0,8, +0x1179600,7, +0x1179620,12, +0x1179680,7, +0x11796a0,12, +0x1179700,3, +0x1179710,1, +0x1179804,1, +0x1179824,21, +0x1179880,16, +0x1179900,5, +0x1179920,11, +0x1179950,9, +0x1179980,22, +0x1179a00,22, +0x1179a80,22, +0x1179b00,22, +0x1179b80,22, +0x1179c00,22, +0x1179c80,22, +0x1179d00,22, +0x1179d80,3, +0x1180000,5, +0x1180018,5, +0x1180030,3, +0x1180044,3, +0x1180100,58, +0x11801f0,3, +0x1180280,3, +0x1180400,5, +0x1180418,5, +0x1180430,3, +0x1180444,3, +0x1180500,58, +0x11805f0,3, +0x1180680,3, +0x1181018,2, +0x1181100,2, +0x1181110,10, +0x1181140,2, +0x1181150,10, +0x1181208,1, +0x1181220,12, +0x1181280,1, +0x1181288,2, +0x1181400,4, +0x1182000,5, +0x1182018,5, +0x1182030,3, +0x1182044,3, +0x1182100,58, +0x11821f0,3, +0x1182280,3, +0x1182400,5, +0x1182418,5, +0x1182430,3, +0x1182444,3, +0x1182500,58, +0x11825f0,3, +0x1182680,3, +0x1183018,2, +0x1183100,2, +0x1183110,10, +0x1183140,2, +0x1183150,10, +0x1183208,1, +0x1183220,12, +0x1183280,1, +0x1183288,2, +0x1183400,4, +0x1184000,2, +0x118400c,1, +0x1184030,3, +0x1184040,2, +0x118404c,1, +0x1184070,3, +0x1184100,2, +0x118410c,1, +0x1184130,3, +0x1184140,2, +0x118414c,1, +0x1184170,3, +0x1184200,15, +0x1184280,15, +0x1184300,15, +0x1184380,15, +0x1184400,15, +0x1184480,15, +0x1184500,15, +0x1184580,15, +0x1184604,10, +0x1184700,2, +0x118470c,7, +0x1184740,1, +0x1184770,1, +0x11847c0,2, +0x11847d0,4, +0x1185000,3, +0x1185010,1, +0x118501c,3, +0x1185104,1, +0x1185110,4, +0x1185124,1, +0x1185130,4, +0x1185144,1, +0x1185150,4, +0x1185164,1, +0x1185170,5, +0x1185190,4, +0x1185a00,4, +0x1185c00,129, +0x1186000,37, +0x1186098,1, +0x1186100,37, +0x1186198,1, +0x1186200,37, +0x1186298,1, +0x1186300,37, +0x1186398,1, +0x1186400,37, +0x1186498,1, +0x1186500,37, +0x1186598,1, +0x1186600,37, +0x1186698,1, +0x1186700,37, +0x1186798,1, +0x118c000,91, +0x118c400,4, +0x118c440,15, +0x118c480,4, +0x118c4c0,15, +0x118c500,4, +0x118c540,15, +0x118c580,4, +0x118c5c0,15, +0x118c600,4, +0x118c640,10, +0x118c680,4, +0x118c6c0,10, +0x118c800,4, +0x118c840,33, +0x118ca00,13, +0x118ca80,1, +0x118ca88,8, +0x118cac0,6, +0x118cae0,1, +0x118cae8,2, +0x118cb04,14, +0x118cc00,4, +0x118ccc8,1, +0x118cfcc,3, +0x118cfe0,99, +0x118d400,4, +0x118d440,15, +0x118d480,4, +0x118d4c0,15, +0x118d500,4, +0x118d540,15, +0x118d580,4, +0x118d5c0,15, +0x118d600,4, +0x118d640,10, +0x118d680,4, +0x118d6c0,10, +0x118d800,4, +0x118d840,33, +0x118da00,13, +0x118da80,1, +0x118da88,8, +0x118dac0,6, +0x118dae0,1, +0x118dae8,2, +0x118db04,14, +0x118dc00,4, +0x118dcc8,1, +0x118dfcc,3, +0x118dfe0,27, +0x118f000,19, +0x118fa00,10, +0x118fa80,3, +0x118fb00,6, +0x1190000,51, +0x1190a00,10, +0x1190a80,3, +0x1191000,2, +0x119100c,4, +0x1191028,3, +0x1191038,4, +0x1191050,2, +0x1191080,4, +0x1191098,7, +0x1191120,4, +0x1191200,4, +0x1191214,7, +0x1191234,3, +0x1191280,8, +0x11912c0,5, +0x1191300,2, +0x119130c,3, +0x1191400,24, +0x1191464,2, +0x1191470,3, +0x1191500,25, +0x11915c0,8, +0x11915e8,5, +0x1191600,5, +0x1191618,1, +0x1191620,1, +0x1191628,1, +0x1191630,2, +0x1191640,2, +0x1191650,2, +0x1191690,4, +0x1191740,2, +0x1191760,6, +0x1191780,6, +0x11917a0,6, +0x11917c0,6, +0x11917e0,1, +0x1191800,2, +0x119180c,4, +0x1191828,3, +0x1191838,4, +0x1191850,2, +0x1191880,4, +0x1191898,7, +0x1191920,4, +0x1191a00,4, +0x1191a14,7, +0x1191a34,3, +0x1191a80,8, +0x1191ac0,5, +0x1191b00,2, +0x1191b0c,3, +0x1191c00,24, +0x1191c64,2, +0x1191c70,3, +0x1191d00,25, +0x1191dc0,8, +0x1191de8,5, +0x1191e00,5, +0x1191e18,1, +0x1191e20,1, +0x1191e28,1, +0x1191e30,2, +0x1191e40,2, +0x1191e50,2, +0x1191e90,4, +0x1191f40,2, +0x1191f60,6, +0x1191f80,6, +0x1191fa0,6, +0x1191fc0,6, +0x1191fe0,1, +0x1192000,19, +0x1192080,2, +0x11920b0,2, +0x11920c0,2, +0x11a0000,11, +0x11a0040,16, +0x11a0084,5, +0x11a0200,7, +0x11a0220,6, +0x11a0240,7, +0x11a0260,6, +0x11a0280,6, +0x11a02a0,2, +0x11a02ac,2, +0x11a02c0,7, +0x11a02e0,7, +0x11a0300,2, +0x11a030c,2, +0x11a0320,6, +0x11a0400,2, +0x11a1000,19, +0x11a2104,23, +0x11a2180,7, +0x11a21a0,6, +0x11a21c0,7, +0x11a21e0,6, +0x11a2200,4, +0x11a2220,4, +0x11a2240,11, +0x11a2270,32, +0x11a2300,24, +0x11a2380,20, +0x11a2400,61, +0x11a2500,25, +0x11a2568,4, +0x11a2580,2, +0x11a25a0,1, +0x11a25c0,11, +0x11a2600,9, +0x11a2640,3, +0x11a2650,3, +0x11a2664,3, +0x11a2680,22, +0x11a2800,11, +0x11a3000,536, +0x11a4104,23, +0x11a4180,7, +0x11a41a0,6, +0x11a41c0,7, +0x11a41e0,6, +0x11a4200,4, +0x11a4220,4, +0x11a4240,11, +0x11a4270,32, +0x11a4300,24, +0x11a4380,20, +0x11a4400,61, +0x11a4500,25, +0x11a4568,4, +0x11a4580,2, +0x11a45a0,1, +0x11a45c0,11, +0x11a4600,9, +0x11a4640,3, +0x11a4650,3, +0x11a4664,3, +0x11a4680,22, +0x11a4800,11, +0x11a5000,536, +0x11aa000,7, +0x11aa048,8, +0x11aa080,8, +0x11aa100,7, +0x11aa148,8, +0x11aa180,8, +0x11b0000,11, +0x11b0040,16, +0x11b0084,5, +0x11b0200,7, +0x11b0220,6, +0x11b0240,7, +0x11b0260,6, +0x11b0280,6, +0x11b02a0,2, +0x11b02ac,2, +0x11b02c0,7, +0x11b02e0,7, +0x11b0300,2, +0x11b030c,2, +0x11b0320,6, +0x11b0400,2, +0x11b1000,19, +0x11b2104,23, +0x11b2180,7, +0x11b21a0,6, +0x11b21c0,7, +0x11b21e0,6, +0x11b2200,4, +0x11b2220,4, +0x11b2240,11, +0x11b2270,32, +0x11b2300,24, +0x11b2380,20, +0x11b2400,61, +0x11b2500,25, +0x11b2568,4, +0x11b2580,2, +0x11b25a0,1, +0x11b25c0,11, +0x11b2600,9, +0x11b2640,3, +0x11b2650,3, +0x11b2664,3, +0x11b2680,22, +0x11b2800,11, +0x11b3000,536, +0x11b4104,23, +0x11b4180,7, +0x11b41a0,6, +0x11b41c0,7, +0x11b41e0,6, +0x11b4200,4, +0x11b4220,4, +0x11b4240,11, +0x11b4270,32, +0x11b4300,24, +0x11b4380,20, +0x11b4400,61, +0x11b4500,25, +0x11b4568,4, +0x11b4580,2, +0x11b45a0,1, +0x11b45c0,11, +0x11b4600,9, +0x11b4640,3, +0x11b4650,3, +0x11b4664,3, +0x11b4680,22, +0x11b4800,11, +0x11b5000,536, +0x11ba000,7, +0x11ba048,8, +0x11ba080,8, +0x11ba100,7, +0x11ba148,8, +0x11ba180,8, +0x11c0400,4, +0x11c0440,4, +0x11c05c0,1, +0x11c0600,8, +0x11c0800,18, +0x11c0880,13, +0x11c08f0,3, +0x11c0900,18, +0x11c0980,13, +0x11c09f0,3, +0x11c0e00,4, +0x11c0e20,4, +0x11c0e80,16, +0x11c0f00,1, +0x11c0f20,1, +0x11c1020,2, +0x11c1208,6, +0x11c1228,10, +0x11c1288,6, +0x11c12a8,10, +0x11c1600,32, +0x11c18c0,8, +0x11c1900,24, +0x11c19b0,4, +0x11c1aa0,2, +0x11c1ac0,4, +0x11c2200,19, +0x11c2280,19, +0x11c2400,14, +0x11c243c,9, +0x11c2464,14, +0x11c24a0,2, +0x11c24ac,2, +0x11c2500,14, +0x11c253c,9, +0x11c2564,14, +0x11c25a0,2, +0x11c25ac,2, +0x11c2800,19, +0x11c2880,19, +0x11c2a10,2, +0x11c2a1c,1, +0x11c2a50,2, +0x11c2a5c,1, +0x11c2c00,7, +0x11c2c20,1, +0x11c2c54,18, +0x11c2ca0,1, +0x11c2cd4,11, +0x11c2e00,1, +0x11c2e08,6, +0x11c3180,3, +0x11c4400,4, +0x11c4440,4, +0x11c45c0,1, +0x11c4600,8, +0x11c4800,18, +0x11c4880,13, +0x11c48f0,3, +0x11c4900,18, +0x11c4980,13, +0x11c49f0,3, +0x11c4e00,4, +0x11c4e20,4, +0x11c4e80,16, +0x11c4f00,1, +0x11c4f20,1, +0x11c5020,2, +0x11c5208,6, +0x11c5228,10, +0x11c5288,6, +0x11c52a8,10, +0x11c5600,32, +0x11c58c0,8, +0x11c5900,24, +0x11c59b0,4, +0x11c5aa0,2, +0x11c5ac0,4, +0x11c6200,19, +0x11c6280,19, +0x11c6400,14, +0x11c643c,9, +0x11c6464,14, +0x11c64a0,2, +0x11c64ac,2, +0x11c6500,14, +0x11c653c,9, +0x11c6564,14, +0x11c65a0,2, +0x11c65ac,2, +0x11c6800,19, +0x11c6880,19, +0x11c6a10,2, +0x11c6a1c,1, +0x11c6a50,2, +0x11c6a5c,1, +0x11c6c00,7, +0x11c6c20,1, +0x11c6c54,18, +0x11c6ca0,1, +0x11c6cd4,11, +0x11c6e00,1, +0x11c6e08,6, +0x11c7180,3, +0x11c9000,13, +0x11ce000,19, +0x11cea00,10, +0x11cea80,3, +0x11cf000,1, +0x11cf008,5, +0x11cf038,1, +0x11cf044,1, +0x11cf050,2, +0x11cf060,8, +0x11cf140,19, +0x11cf190,4, +0x11d0000,2, +0x11d000c,2, +0x11d0040,7, +0x11d0100,3, +0x11d0110,3, +0x11d0120,5, +0x11d0200,6, +0x11d0240,5, +0x11d0400,2, +0x11d040c,2, +0x11d0440,7, +0x11d0500,3, +0x11d0510,3, +0x11d0520,5, +0x11d0600,6, +0x11d0640,5, +0x11d0800,2, +0x11d080c,2, +0x11d0840,7, +0x11d0900,3, +0x11d0910,3, +0x11d0920,5, +0x11d0a00,6, +0x11d0a40,5, +0x11d0c00,2, +0x11d0c0c,2, +0x11d0c40,7, +0x11d0d00,3, +0x11d0d10,3, +0x11d0d20,5, +0x11d0e00,6, +0x11d0e40,5, +0x11d1000,2, +0x11d100c,2, +0x11d1040,7, +0x11d1100,3, +0x11d1110,3, +0x11d1120,5, +0x11d1200,6, +0x11d1240,5, +0x11d1400,2, +0x11d140c,2, +0x11d1440,7, +0x11d1500,3, +0x11d1510,3, +0x11d1520,5, +0x11d1600,6, +0x11d1640,5, +0x11d1800,2, +0x11d180c,2, +0x11d1840,7, +0x11d1900,3, +0x11d1910,3, +0x11d1920,5, +0x11d1a00,6, +0x11d1a40,5, +0x11d1c00,2, +0x11d1c0c,2, +0x11d1c40,7, +0x11d1d00,3, +0x11d1d10,3, +0x11d1d20,5, +0x11d1e00,6, +0x11d1e40,5, +0x11d2000,5, +0x11d2040,9, +0x11d2100,3, +0x11d2200,1, +0x11d2210,1, +0x11d2220,1, +0x11d2230,1, +0x11d2240,1, +0x11d2300,3, +0x11d2314,1, +0x11d2320,4, +0x11d2400,5, +0x11d2440,5, +0x11d3000,80, +0x11d3200,1, +0x11d8000,7, +0x11d8030,2, +0x11d8040,7, +0x11d8070,2, +0x11d8100,2, +0x11d8120,2, +0x11d8140,2, +0x11d8160,2, +0x11d8180,9, +0x11d8200,7, +0x11d8230,2, +0x11d8240,7, +0x11d8270,2, +0x11d8300,2, +0x11d8320,2, +0x11d8340,2, +0x11d8360,2, +0x11d8380,9, +0x11d8400,11, +0x11d8500,11, +0x11d9000,3, +0x11d9010,2, +0x11d901c,5, +0x11d9040,8, +0x11d9080,3, +0x11d9090,2, +0x11d909c,5, +0x11d90c0,8, +0x11d9100,3, +0x11d9110,2, +0x11d911c,5, +0x11d9140,8, +0x11d9180,3, +0x11d9190,2, +0x11d919c,5, +0x11d91c0,8, +0x11d9200,7, +0x11d9220,12, +0x11d9280,7, +0x11d92a0,12, +0x11d9300,3, +0x11d9310,1, +0x11d9400,3, +0x11d9410,2, +0x11d941c,5, +0x11d9440,8, +0x11d9480,3, +0x11d9490,2, +0x11d949c,5, +0x11d94c0,8, +0x11d9500,3, +0x11d9510,2, +0x11d951c,5, +0x11d9540,8, +0x11d9580,3, +0x11d9590,2, +0x11d959c,5, +0x11d95c0,8, +0x11d9600,7, +0x11d9620,12, +0x11d9680,7, +0x11d96a0,12, +0x11d9700,3, +0x11d9710,1, +0x11d9804,1, +0x11d9824,21, +0x11d9880,16, +0x11d9900,5, +0x11d9920,11, +0x11d9950,9, +0x11d9980,22, +0x11d9a00,22, +0x11d9a80,22, +0x11d9b00,22, +0x11d9b80,22, +0x11d9c00,22, +0x11d9c80,22, +0x11d9d00,22, +0x11d9d80,3, +0x11e0000,5, +0x11e0018,5, +0x11e0030,3, +0x11e0044,3, +0x11e0100,58, +0x11e01f0,3, +0x11e0280,3, +0x11e0400,5, +0x11e0418,5, +0x11e0430,3, +0x11e0444,3, +0x11e0500,58, +0x11e05f0,3, +0x11e0680,3, +0x11e1018,2, +0x11e1100,2, +0x11e1110,10, +0x11e1140,2, +0x11e1150,10, +0x11e1208,1, +0x11e1220,12, +0x11e1280,1, +0x11e1288,2, +0x11e1400,4, +0x11e2000,5, +0x11e2018,5, +0x11e2030,3, +0x11e2044,3, +0x11e2100,58, +0x11e21f0,3, +0x11e2280,3, +0x11e2400,5, +0x11e2418,5, +0x11e2430,3, +0x11e2444,3, +0x11e2500,58, +0x11e25f0,3, +0x11e2680,3, +0x11e3018,2, +0x11e3100,2, +0x11e3110,10, +0x11e3140,2, +0x11e3150,10, +0x11e3208,1, +0x11e3220,12, +0x11e3280,1, +0x11e3288,2, +0x11e3400,4, +0x11e4000,2, +0x11e400c,1, +0x11e4030,3, +0x11e4040,2, +0x11e404c,1, +0x11e4070,3, +0x11e4100,2, +0x11e410c,1, +0x11e4130,3, +0x11e4140,2, +0x11e414c,1, +0x11e4170,3, +0x11e4200,15, +0x11e4280,15, +0x11e4300,15, +0x11e4380,15, +0x11e4400,15, +0x11e4480,15, +0x11e4500,15, +0x11e4580,15, +0x11e4604,10, +0x11e4700,2, +0x11e470c,7, +0x11e4740,1, +0x11e4770,1, +0x11e47c0,2, +0x11e47d0,4, +0x11e5000,3, +0x11e5010,1, +0x11e501c,3, +0x11e5104,1, +0x11e5110,4, +0x11e5124,1, +0x11e5130,4, +0x11e5144,1, +0x11e5150,4, +0x11e5164,1, +0x11e5170,5, +0x11e5190,4, +0x11e5a00,4, +0x11e5c00,129, +0x11e6000,37, +0x11e6098,1, +0x11e6100,37, +0x11e6198,1, +0x11e6200,37, +0x11e6298,1, +0x11e6300,37, +0x11e6398,1, +0x11e6400,37, +0x11e6498,1, +0x11e6500,37, +0x11e6598,1, +0x11e6600,37, +0x11e6698,1, +0x11e6700,37, +0x11e6798,1, +0x11ec000,91, +0x11ec400,4, +0x11ec440,15, +0x11ec480,4, +0x11ec4c0,15, +0x11ec500,4, +0x11ec540,15, +0x11ec580,4, +0x11ec5c0,15, +0x11ec600,4, +0x11ec640,10, +0x11ec680,4, +0x11ec6c0,10, +0x11ec800,4, +0x11ec840,33, +0x11eca00,13, +0x11eca80,1, +0x11eca88,8, +0x11ecac0,6, +0x11ecae0,1, +0x11ecae8,2, +0x11ecb04,14, +0x11ecc00,4, +0x11eccc8,1, +0x11ecfcc,3, +0x11ecfe0,99, +0x11ed400,4, +0x11ed440,15, +0x11ed480,4, +0x11ed4c0,15, +0x11ed500,4, +0x11ed540,15, +0x11ed580,4, +0x11ed5c0,15, +0x11ed600,4, +0x11ed640,10, +0x11ed680,4, +0x11ed6c0,10, +0x11ed800,4, +0x11ed840,33, +0x11eda00,13, +0x11eda80,1, +0x11eda88,8, +0x11edac0,6, +0x11edae0,1, +0x11edae8,2, +0x11edb04,14, +0x11edc00,4, +0x11edcc8,1, +0x11edfcc,3, +0x11edfe0,27, +0x11ef000,19, +0x11efa00,10, +0x11efa80,3, +0x11efb00,6, +0x11f0000,51, +0x11f0a00,10, +0x11f0a80,3, +0x11f1000,2, +0x11f100c,4, +0x11f1028,3, +0x11f1038,4, +0x11f1050,2, +0x11f1080,4, +0x11f1098,7, +0x11f1120,4, +0x11f1200,4, +0x11f1214,7, +0x11f1234,3, +0x11f1280,8, +0x11f12c0,5, +0x11f1300,2, +0x11f130c,3, +0x11f1400,24, +0x11f1464,2, +0x11f1470,3, +0x11f1500,25, +0x11f15c0,8, +0x11f15e8,5, +0x11f1600,5, +0x11f1618,1, +0x11f1620,1, +0x11f1628,1, +0x11f1630,2, +0x11f1640,2, +0x11f1650,2, +0x11f1690,4, +0x11f1740,2, +0x11f1760,6, +0x11f1780,6, +0x11f17a0,6, +0x11f17c0,6, +0x11f17e0,1, +0x11f1800,2, +0x11f180c,4, +0x11f1828,3, +0x11f1838,4, +0x11f1850,2, +0x11f1880,4, +0x11f1898,7, +0x11f1920,4, +0x11f1a00,4, +0x11f1a14,7, +0x11f1a34,3, +0x11f1a80,8, +0x11f1ac0,5, +0x11f1b00,2, +0x11f1b0c,3, +0x11f1c00,24, +0x11f1c64,2, +0x11f1c70,3, +0x11f1d00,25, +0x11f1dc0,8, +0x11f1de8,5, +0x11f1e00,5, +0x11f1e18,1, +0x11f1e20,1, +0x11f1e28,1, +0x11f1e30,2, +0x11f1e40,2, +0x11f1e50,2, +0x11f1e90,4, +0x11f1f40,2, +0x11f1f60,6, +0x11f1f80,6, +0x11f1fa0,6, +0x11f1fc0,6, +0x11f1fe0,1, +0x11f2000,19, +0x11f2080,2, +0x11f20b0,2, +0x11f20c0,2, +0x1200000,11, +0x1200040,16, +0x1200084,5, +0x1200200,7, +0x1200220,6, +0x1200240,7, +0x1200260,6, +0x1200280,6, +0x12002a0,2, +0x12002ac,2, +0x12002c0,7, +0x12002e0,7, +0x1200300,2, +0x120030c,2, +0x1200320,6, +0x1200400,2, +0x1201000,19, +0x1202104,23, +0x1202180,7, +0x12021a0,6, +0x12021c0,7, +0x12021e0,6, +0x1202200,4, +0x1202220,4, +0x1202240,11, +0x1202270,32, +0x1202300,24, +0x1202380,20, +0x1202400,61, +0x1202500,25, +0x1202568,4, +0x1202580,2, +0x12025a0,1, +0x12025c0,11, +0x1202600,9, +0x1202640,3, +0x1202650,3, +0x1202664,3, +0x1202680,22, +0x1202800,11, +0x1203000,536, +0x1204104,23, +0x1204180,7, +0x12041a0,6, +0x12041c0,7, +0x12041e0,6, +0x1204200,4, +0x1204220,4, +0x1204240,11, +0x1204270,32, +0x1204300,24, +0x1204380,20, +0x1204400,61, +0x1204500,25, +0x1204568,4, +0x1204580,2, +0x12045a0,1, +0x12045c0,11, +0x1204600,9, +0x1204640,3, +0x1204650,3, +0x1204664,3, +0x1204680,22, +0x1204800,11, +0x1205000,536, +0x120a000,7, +0x120a048,8, +0x120a080,8, +0x120a100,7, +0x120a148,8, +0x120a180,8, +0x1210000,11, +0x1210040,16, +0x1210084,5, +0x1210200,7, +0x1210220,6, +0x1210240,7, +0x1210260,6, +0x1210280,6, +0x12102a0,2, +0x12102ac,2, +0x12102c0,7, +0x12102e0,7, +0x1210300,2, +0x121030c,2, +0x1210320,6, +0x1210400,2, +0x1211000,19, +0x1212104,23, +0x1212180,7, +0x12121a0,6, +0x12121c0,7, +0x12121e0,6, +0x1212200,4, +0x1212220,4, +0x1212240,11, +0x1212270,32, +0x1212300,24, +0x1212380,20, +0x1212400,61, +0x1212500,25, +0x1212568,4, +0x1212580,2, +0x12125a0,1, +0x12125c0,11, +0x1212600,9, +0x1212640,3, +0x1212650,3, +0x1212664,3, +0x1212680,22, +0x1212800,11, +0x1213000,536, +0x1214104,23, +0x1214180,7, +0x12141a0,6, +0x12141c0,7, +0x12141e0,6, +0x1214200,4, +0x1214220,4, +0x1214240,11, +0x1214270,32, +0x1214300,24, +0x1214380,20, +0x1214400,61, +0x1214500,25, +0x1214568,4, +0x1214580,2, +0x12145a0,1, +0x12145c0,11, +0x1214600,9, +0x1214640,3, +0x1214650,3, +0x1214664,3, +0x1214680,22, +0x1214800,11, +0x1215000,536, +0x121a000,7, +0x121a048,8, +0x121a080,8, +0x121a100,7, +0x121a148,8, +0x121a180,8, +0x1220400,4, +0x1220440,4, +0x12205c0,1, +0x1220600,8, +0x1220800,18, +0x1220880,13, +0x12208f0,3, +0x1220900,18, +0x1220980,13, +0x12209f0,3, +0x1220e00,4, +0x1220e20,4, +0x1220e80,16, +0x1220f00,1, +0x1220f20,1, +0x1221020,2, +0x1221208,6, +0x1221228,10, +0x1221288,6, +0x12212a8,10, +0x1221600,32, +0x12218c0,8, +0x1221900,24, +0x12219b0,4, +0x1221aa0,2, +0x1221ac0,4, +0x1222200,19, +0x1222280,19, +0x1222400,14, +0x122243c,9, +0x1222464,14, +0x12224a0,2, +0x12224ac,2, +0x1222500,14, +0x122253c,9, +0x1222564,14, +0x12225a0,2, +0x12225ac,2, +0x1222800,19, +0x1222880,19, +0x1222a10,2, +0x1222a1c,1, +0x1222a50,2, +0x1222a5c,1, +0x1222c00,7, +0x1222c20,1, +0x1222c54,18, +0x1222ca0,1, +0x1222cd4,11, +0x1222e00,1, +0x1222e08,6, +0x1223180,3, +0x1224400,4, +0x1224440,4, +0x12245c0,1, +0x1224600,8, +0x1224800,18, +0x1224880,13, +0x12248f0,3, +0x1224900,18, +0x1224980,13, +0x12249f0,3, +0x1224e00,4, +0x1224e20,4, +0x1224e80,16, +0x1224f00,1, +0x1224f20,1, +0x1225020,2, +0x1225208,6, +0x1225228,10, +0x1225288,6, +0x12252a8,10, +0x1225600,32, +0x12258c0,8, +0x1225900,24, +0x12259b0,4, +0x1225aa0,2, +0x1225ac0,4, +0x1226200,19, +0x1226280,19, +0x1226400,14, +0x122643c,9, +0x1226464,14, +0x12264a0,2, +0x12264ac,2, +0x1226500,14, +0x122653c,9, +0x1226564,14, +0x12265a0,2, +0x12265ac,2, +0x1226800,19, +0x1226880,19, +0x1226a10,2, +0x1226a1c,1, +0x1226a50,2, +0x1226a5c,1, +0x1226c00,7, +0x1226c20,1, +0x1226c54,18, +0x1226ca0,1, +0x1226cd4,11, +0x1226e00,1, +0x1226e08,6, +0x1227180,3, +0x1229000,13, +0x122e000,19, +0x122ea00,10, +0x122ea80,3, +0x122f000,1, +0x122f008,5, +0x122f038,1, +0x122f044,1, +0x122f050,2, +0x122f060,8, +0x122f140,19, +0x122f190,4, +0x1230000,2, +0x123000c,2, +0x1230040,7, +0x1230100,3, +0x1230110,3, +0x1230120,5, +0x1230200,6, +0x1230240,5, +0x1230400,2, +0x123040c,2, +0x1230440,7, +0x1230500,3, +0x1230510,3, +0x1230520,5, +0x1230600,6, +0x1230640,5, +0x1230800,2, +0x123080c,2, +0x1230840,7, +0x1230900,3, +0x1230910,3, +0x1230920,5, +0x1230a00,6, +0x1230a40,5, +0x1230c00,2, +0x1230c0c,2, +0x1230c40,7, +0x1230d00,3, +0x1230d10,3, +0x1230d20,5, +0x1230e00,6, +0x1230e40,5, +0x1231000,2, +0x123100c,2, +0x1231040,7, +0x1231100,3, +0x1231110,3, +0x1231120,5, +0x1231200,6, +0x1231240,5, +0x1231400,2, +0x123140c,2, +0x1231440,7, +0x1231500,3, +0x1231510,3, +0x1231520,5, +0x1231600,6, +0x1231640,5, +0x1231800,2, +0x123180c,2, +0x1231840,7, +0x1231900,3, +0x1231910,3, +0x1231920,5, +0x1231a00,6, +0x1231a40,5, +0x1231c00,2, +0x1231c0c,2, +0x1231c40,7, +0x1231d00,3, +0x1231d10,3, +0x1231d20,5, +0x1231e00,6, +0x1231e40,5, +0x1232000,5, +0x1232040,9, +0x1232100,3, +0x1232200,1, +0x1232210,1, +0x1232220,1, +0x1232230,1, +0x1232240,1, +0x1232300,3, +0x1232314,1, +0x1232320,4, +0x1232400,5, +0x1232440,5, +0x1233000,80, +0x1233200,1, +0x1238000,7, +0x1238030,2, +0x1238040,7, +0x1238070,2, +0x1238100,2, +0x1238120,2, +0x1238140,2, +0x1238160,2, +0x1238180,9, +0x1238200,7, +0x1238230,2, +0x1238240,7, +0x1238270,2, +0x1238300,2, +0x1238320,2, +0x1238340,2, +0x1238360,2, +0x1238380,9, +0x1238400,11, +0x1238500,11, +0x1239000,3, +0x1239010,2, +0x123901c,5, +0x1239040,8, +0x1239080,3, +0x1239090,2, +0x123909c,5, +0x12390c0,8, +0x1239100,3, +0x1239110,2, +0x123911c,5, +0x1239140,8, +0x1239180,3, +0x1239190,2, +0x123919c,5, +0x12391c0,8, +0x1239200,7, +0x1239220,12, +0x1239280,7, +0x12392a0,12, +0x1239300,3, +0x1239310,1, +0x1239400,3, +0x1239410,2, +0x123941c,5, +0x1239440,8, +0x1239480,3, +0x1239490,2, +0x123949c,5, +0x12394c0,8, +0x1239500,3, +0x1239510,2, +0x123951c,5, +0x1239540,8, +0x1239580,3, +0x1239590,2, +0x123959c,5, +0x12395c0,8, +0x1239600,7, +0x1239620,12, +0x1239680,7, +0x12396a0,12, +0x1239700,3, +0x1239710,1, +0x1239804,1, +0x1239824,21, +0x1239880,16, +0x1239900,5, +0x1239920,11, +0x1239950,9, +0x1239980,22, +0x1239a00,22, +0x1239a80,22, +0x1239b00,22, +0x1239b80,22, +0x1239c00,22, +0x1239c80,22, +0x1239d00,22, +0x1239d80,3, +0x1240000,5, +0x1240018,5, +0x1240030,3, +0x1240044,3, +0x1240100,58, +0x12401f0,3, +0x1240280,3, +0x1240400,5, +0x1240418,5, +0x1240430,3, +0x1240444,3, +0x1240500,58, +0x12405f0,3, +0x1240680,3, +0x1241018,2, +0x1241100,2, +0x1241110,10, +0x1241140,2, +0x1241150,10, +0x1241208,1, +0x1241220,12, +0x1241280,1, +0x1241288,2, +0x1241400,4, +0x1242000,5, +0x1242018,5, +0x1242030,3, +0x1242044,3, +0x1242100,58, +0x12421f0,3, +0x1242280,3, +0x1242400,5, +0x1242418,5, +0x1242430,3, +0x1242444,3, +0x1242500,58, +0x12425f0,3, +0x1242680,3, +0x1243018,2, +0x1243100,2, +0x1243110,10, +0x1243140,2, +0x1243150,10, +0x1243208,1, +0x1243220,12, +0x1243280,1, +0x1243288,2, +0x1243400,4, +0x1244000,2, +0x124400c,1, +0x1244030,3, +0x1244040,2, +0x124404c,1, +0x1244070,3, +0x1244100,2, +0x124410c,1, +0x1244130,3, +0x1244140,2, +0x124414c,1, +0x1244170,3, +0x1244200,15, +0x1244280,15, +0x1244300,15, +0x1244380,15, +0x1244400,15, +0x1244480,15, +0x1244500,15, +0x1244580,15, +0x1244604,10, +0x1244700,2, +0x124470c,7, +0x1244740,1, +0x1244770,1, +0x12447c0,2, +0x12447d0,4, +0x1245000,3, +0x1245010,1, +0x124501c,3, +0x1245104,1, +0x1245110,4, +0x1245124,1, +0x1245130,4, +0x1245144,1, +0x1245150,4, +0x1245164,1, +0x1245170,5, +0x1245190,4, +0x1245a00,4, +0x1245c00,129, +0x1246000,37, +0x1246098,1, +0x1246100,37, +0x1246198,1, +0x1246200,37, +0x1246298,1, +0x1246300,37, +0x1246398,1, +0x1246400,37, +0x1246498,1, +0x1246500,37, +0x1246598,1, +0x1246600,37, +0x1246698,1, +0x1246700,37, +0x1246798,1, +0x124c000,91, +0x124c400,4, +0x124c440,15, +0x124c480,4, +0x124c4c0,15, +0x124c500,4, +0x124c540,15, +0x124c580,4, +0x124c5c0,15, +0x124c600,4, +0x124c640,10, +0x124c680,4, +0x124c6c0,10, +0x124c800,4, +0x124c840,33, +0x124ca00,13, +0x124ca80,1, +0x124ca88,8, +0x124cac0,6, +0x124cae0,1, +0x124cae8,2, +0x124cb04,14, +0x124cc00,4, +0x124ccc8,1, +0x124cfcc,3, +0x124cfe0,99, +0x124d400,4, +0x124d440,15, +0x124d480,4, +0x124d4c0,15, +0x124d500,4, +0x124d540,15, +0x124d580,4, +0x124d5c0,15, +0x124d600,4, +0x124d640,10, +0x124d680,4, +0x124d6c0,10, +0x124d800,4, +0x124d840,33, +0x124da00,13, +0x124da80,1, +0x124da88,8, +0x124dac0,6, +0x124dae0,1, +0x124dae8,2, +0x124db04,14, +0x124dc00,4, +0x124dcc8,1, +0x124dfcc,3, +0x124dfe0,27, +0x124f000,19, +0x124fa00,10, +0x124fa80,3, +0x124fb00,6, +0x1250000,51, +0x1250a00,10, +0x1250a80,3, +0x1251000,2, +0x125100c,4, +0x1251028,3, +0x1251038,4, +0x1251050,2, +0x1251080,4, +0x1251098,7, +0x1251120,4, +0x1251200,4, +0x1251214,7, +0x1251234,3, +0x1251280,8, +0x12512c0,5, +0x1251300,2, +0x125130c,3, +0x1251400,24, +0x1251464,2, +0x1251470,3, +0x1251500,25, +0x12515c0,8, +0x12515e8,5, +0x1251600,5, +0x1251618,1, +0x1251620,1, +0x1251628,1, +0x1251630,2, +0x1251640,2, +0x1251650,2, +0x1251690,4, +0x1251740,2, +0x1251760,6, +0x1251780,6, +0x12517a0,6, +0x12517c0,6, +0x12517e0,1, +0x1251800,2, +0x125180c,4, +0x1251828,3, +0x1251838,4, +0x1251850,2, +0x1251880,4, +0x1251898,7, +0x1251920,4, +0x1251a00,4, +0x1251a14,7, +0x1251a34,3, +0x1251a80,8, +0x1251ac0,5, +0x1251b00,2, +0x1251b0c,3, +0x1251c00,24, +0x1251c64,2, +0x1251c70,3, +0x1251d00,25, +0x1251dc0,8, +0x1251de8,5, +0x1251e00,5, +0x1251e18,1, +0x1251e20,1, +0x1251e28,1, +0x1251e30,2, +0x1251e40,2, +0x1251e50,2, +0x1251e90,4, +0x1251f40,2, +0x1251f60,6, +0x1251f80,6, +0x1251fa0,6, +0x1251fc0,6, +0x1251fe0,1, +0x1252000,19, +0x1252080,2, +0x12520b0,2, +0x12520c0,2, +0x1260000,11, +0x1260040,16, +0x1260084,5, +0x1260200,7, +0x1260220,6, +0x1260240,7, +0x1260260,6, +0x1260280,6, +0x12602a0,2, +0x12602ac,2, +0x12602c0,7, +0x12602e0,7, +0x1260300,2, +0x126030c,2, +0x1260320,6, +0x1260400,2, +0x1261000,19, +0x1262104,23, +0x1262180,7, +0x12621a0,6, +0x12621c0,7, +0x12621e0,6, +0x1262200,4, +0x1262220,4, +0x1262240,11, +0x1262270,32, +0x1262300,24, +0x1262380,20, +0x1262400,61, +0x1262500,25, +0x1262568,4, +0x1262580,2, +0x12625a0,1, +0x12625c0,11, +0x1262600,9, +0x1262640,3, +0x1262650,3, +0x1262664,3, +0x1262680,22, +0x1262800,11, +0x1263000,536, +0x1264104,23, +0x1264180,7, +0x12641a0,6, +0x12641c0,7, +0x12641e0,6, +0x1264200,4, +0x1264220,4, +0x1264240,11, +0x1264270,32, +0x1264300,24, +0x1264380,20, +0x1264400,61, +0x1264500,25, +0x1264568,4, +0x1264580,2, +0x12645a0,1, +0x12645c0,11, +0x1264600,9, +0x1264640,3, +0x1264650,3, +0x1264664,3, +0x1264680,22, +0x1264800,11, +0x1265000,536, +0x126a000,7, +0x126a048,8, +0x126a080,8, +0x126a100,7, +0x126a148,8, +0x126a180,8, +0x1270000,11, +0x1270040,16, +0x1270084,5, +0x1270200,7, +0x1270220,6, +0x1270240,7, +0x1270260,6, +0x1270280,6, +0x12702a0,2, +0x12702ac,2, +0x12702c0,7, +0x12702e0,7, +0x1270300,2, +0x127030c,2, +0x1270320,6, +0x1270400,2, +0x1271000,19, +0x1272104,23, +0x1272180,7, +0x12721a0,6, +0x12721c0,7, +0x12721e0,6, +0x1272200,4, +0x1272220,4, +0x1272240,11, +0x1272270,32, +0x1272300,24, +0x1272380,20, +0x1272400,61, +0x1272500,25, +0x1272568,4, +0x1272580,2, +0x12725a0,1, +0x12725c0,11, +0x1272600,9, +0x1272640,3, +0x1272650,3, +0x1272664,3, +0x1272680,22, +0x1272800,11, +0x1273000,536, +0x1274104,23, +0x1274180,7, +0x12741a0,6, +0x12741c0,7, +0x12741e0,6, +0x1274200,4, +0x1274220,4, +0x1274240,11, +0x1274270,32, +0x1274300,24, +0x1274380,20, +0x1274400,61, +0x1274500,25, +0x1274568,4, +0x1274580,2, +0x12745a0,1, +0x12745c0,11, +0x1274600,9, +0x1274640,3, +0x1274650,3, +0x1274664,3, +0x1274680,22, +0x1274800,11, +0x1275000,536, +0x127a000,7, +0x127a048,8, +0x127a080,8, +0x127a100,7, +0x127a148,8, +0x127a180,8, +0x1280400,4, +0x1280440,4, +0x12805c0,1, +0x1280600,8, +0x1280800,18, +0x1280880,13, +0x12808f0,3, +0x1280900,18, +0x1280980,13, +0x12809f0,3, +0x1280e00,4, +0x1280e20,4, +0x1280e80,16, +0x1280f00,1, +0x1280f20,1, +0x1281020,2, +0x1281208,6, +0x1281228,10, +0x1281288,6, +0x12812a8,10, +0x1281600,32, +0x12818c0,8, +0x1281900,24, +0x12819b0,4, +0x1281aa0,2, +0x1281ac0,4, +0x1282200,19, +0x1282280,19, +0x1282400,14, +0x128243c,9, +0x1282464,14, +0x12824a0,2, +0x12824ac,2, +0x1282500,14, +0x128253c,9, +0x1282564,14, +0x12825a0,2, +0x12825ac,2, +0x1282800,19, +0x1282880,19, +0x1282a10,2, +0x1282a1c,1, +0x1282a50,2, +0x1282a5c,1, +0x1282c00,7, +0x1282c20,1, +0x1282c54,18, +0x1282ca0,1, +0x1282cd4,11, +0x1282e00,1, +0x1282e08,6, +0x1283180,3, +0x1284400,4, +0x1284440,4, +0x12845c0,1, +0x1284600,8, +0x1284800,18, +0x1284880,13, +0x12848f0,3, +0x1284900,18, +0x1284980,13, +0x12849f0,3, +0x1284e00,4, +0x1284e20,4, +0x1284e80,16, +0x1284f00,1, +0x1284f20,1, +0x1285020,2, +0x1285208,6, +0x1285228,10, +0x1285288,6, +0x12852a8,10, +0x1285600,32, +0x12858c0,8, +0x1285900,24, +0x12859b0,4, +0x1285aa0,2, +0x1285ac0,4, +0x1286200,19, +0x1286280,19, +0x1286400,14, +0x128643c,9, +0x1286464,14, +0x12864a0,2, +0x12864ac,2, +0x1286500,14, +0x128653c,9, +0x1286564,14, +0x12865a0,2, +0x12865ac,2, +0x1286800,19, +0x1286880,19, +0x1286a10,2, +0x1286a1c,1, +0x1286a50,2, +0x1286a5c,1, +0x1286c00,7, +0x1286c20,1, +0x1286c54,18, +0x1286ca0,1, +0x1286cd4,11, +0x1286e00,1, +0x1286e08,6, +0x1287180,3, +0x1289000,13, +0x128e000,19, +0x128ea00,10, +0x128ea80,3, +0x128f000,1, +0x128f008,5, +0x128f038,1, +0x128f044,1, +0x128f050,2, +0x128f060,8, +0x128f140,19, +0x128f190,4, +0x1290000,2, +0x129000c,2, +0x1290040,7, +0x1290100,3, +0x1290110,3, +0x1290120,5, +0x1290200,6, +0x1290240,5, +0x1290400,2, +0x129040c,2, +0x1290440,7, +0x1290500,3, +0x1290510,3, +0x1290520,5, +0x1290600,6, +0x1290640,5, +0x1290800,2, +0x129080c,2, +0x1290840,7, +0x1290900,3, +0x1290910,3, +0x1290920,5, +0x1290a00,6, +0x1290a40,5, +0x1290c00,2, +0x1290c0c,2, +0x1290c40,7, +0x1290d00,3, +0x1290d10,3, +0x1290d20,5, +0x1290e00,6, +0x1290e40,5, +0x1291000,2, +0x129100c,2, +0x1291040,7, +0x1291100,3, +0x1291110,3, +0x1291120,5, +0x1291200,6, +0x1291240,5, +0x1291400,2, +0x129140c,2, +0x1291440,7, +0x1291500,3, +0x1291510,3, +0x1291520,5, +0x1291600,6, +0x1291640,5, +0x1291800,2, +0x129180c,2, +0x1291840,7, +0x1291900,3, +0x1291910,3, +0x1291920,5, +0x1291a00,6, +0x1291a40,5, +0x1291c00,2, +0x1291c0c,2, +0x1291c40,7, +0x1291d00,3, +0x1291d10,3, +0x1291d20,5, +0x1291e00,6, +0x1291e40,5, +0x1292000,5, +0x1292040,9, +0x1292100,3, +0x1292200,1, +0x1292210,1, +0x1292220,1, +0x1292230,1, +0x1292240,1, +0x1292300,3, +0x1292314,1, +0x1292320,4, +0x1292400,5, +0x1292440,5, +0x1293000,80, +0x1293200,1, +0x1298000,7, +0x1298030,2, +0x1298040,7, +0x1298070,2, +0x1298100,2, +0x1298120,2, +0x1298140,2, +0x1298160,2, +0x1298180,9, +0x1298200,7, +0x1298230,2, +0x1298240,7, +0x1298270,2, +0x1298300,2, +0x1298320,2, +0x1298340,2, +0x1298360,2, +0x1298380,9, +0x1298400,11, +0x1298500,11, +0x1299000,3, +0x1299010,2, +0x129901c,5, +0x1299040,8, +0x1299080,3, +0x1299090,2, +0x129909c,5, +0x12990c0,8, +0x1299100,3, +0x1299110,2, +0x129911c,5, +0x1299140,8, +0x1299180,3, +0x1299190,2, +0x129919c,5, +0x12991c0,8, +0x1299200,7, +0x1299220,12, +0x1299280,7, +0x12992a0,12, +0x1299300,3, +0x1299310,1, +0x1299400,3, +0x1299410,2, +0x129941c,5, +0x1299440,8, +0x1299480,3, +0x1299490,2, +0x129949c,5, +0x12994c0,8, +0x1299500,3, +0x1299510,2, +0x129951c,5, +0x1299540,8, +0x1299580,3, +0x1299590,2, +0x129959c,5, +0x12995c0,8, +0x1299600,7, +0x1299620,12, +0x1299680,7, +0x12996a0,12, +0x1299700,3, +0x1299710,1, +0x1299804,1, +0x1299824,21, +0x1299880,16, +0x1299900,5, +0x1299920,11, +0x1299950,9, +0x1299980,22, +0x1299a00,22, +0x1299a80,22, +0x1299b00,22, +0x1299b80,22, +0x1299c00,22, +0x1299c80,22, +0x1299d00,22, +0x1299d80,3, +0x12a0000,5, +0x12a0018,5, +0x12a0030,3, +0x12a0044,3, +0x12a0100,58, +0x12a01f0,3, +0x12a0280,3, +0x12a0400,5, +0x12a0418,5, +0x12a0430,3, +0x12a0444,3, +0x12a0500,58, +0x12a05f0,3, +0x12a0680,3, +0x12a1018,2, +0x12a1100,2, +0x12a1110,10, +0x12a1140,2, +0x12a1150,10, +0x12a1208,1, +0x12a1220,12, +0x12a1280,1, +0x12a1288,2, +0x12a1400,4, +0x12a2000,5, +0x12a2018,5, +0x12a2030,3, +0x12a2044,3, +0x12a2100,58, +0x12a21f0,3, +0x12a2280,3, +0x12a2400,5, +0x12a2418,5, +0x12a2430,3, +0x12a2444,3, +0x12a2500,58, +0x12a25f0,3, +0x12a2680,3, +0x12a3018,2, +0x12a3100,2, +0x12a3110,10, +0x12a3140,2, +0x12a3150,10, +0x12a3208,1, +0x12a3220,12, +0x12a3280,1, +0x12a3288,2, +0x12a3400,4, +0x12a4000,2, +0x12a400c,1, +0x12a4030,3, +0x12a4040,2, +0x12a404c,1, +0x12a4070,3, +0x12a4100,2, +0x12a410c,1, +0x12a4130,3, +0x12a4140,2, +0x12a414c,1, +0x12a4170,3, +0x12a4200,15, +0x12a4280,15, +0x12a4300,15, +0x12a4380,15, +0x12a4400,15, +0x12a4480,15, +0x12a4500,15, +0x12a4580,15, +0x12a4604,10, +0x12a4700,2, +0x12a470c,7, +0x12a4740,1, +0x12a4770,1, +0x12a47c0,2, +0x12a47d0,4, +0x12a5000,3, +0x12a5010,1, +0x12a501c,3, +0x12a5104,1, +0x12a5110,4, +0x12a5124,1, +0x12a5130,4, +0x12a5144,1, +0x12a5150,4, +0x12a5164,1, +0x12a5170,5, +0x12a5190,4, +0x12a5a00,4, +0x12a5c00,129, +0x12a6000,37, +0x12a6098,1, +0x12a6100,37, +0x12a6198,1, +0x12a6200,37, +0x12a6298,1, +0x12a6300,37, +0x12a6398,1, +0x12a6400,37, +0x12a6498,1, +0x12a6500,37, +0x12a6598,1, +0x12a6600,37, +0x12a6698,1, +0x12a6700,37, +0x12a6798,1, +0x12ac000,91, +0x12ac400,4, +0x12ac440,15, +0x12ac480,4, +0x12ac4c0,15, +0x12ac500,4, +0x12ac540,15, +0x12ac580,4, +0x12ac5c0,15, +0x12ac600,4, +0x12ac640,10, +0x12ac680,4, +0x12ac6c0,10, +0x12ac800,4, +0x12ac840,33, +0x12aca00,13, +0x12aca80,1, +0x12aca88,8, +0x12acac0,6, +0x12acae0,1, +0x12acae8,2, +0x12acb04,14, +0x12acc00,4, +0x12accc8,1, +0x12acfcc,3, +0x12acfe0,99, +0x12ad400,4, +0x12ad440,15, +0x12ad480,4, +0x12ad4c0,15, +0x12ad500,4, +0x12ad540,15, +0x12ad580,4, +0x12ad5c0,15, +0x12ad600,4, +0x12ad640,10, +0x12ad680,4, +0x12ad6c0,10, +0x12ad800,4, +0x12ad840,33, +0x12ada00,13, +0x12ada80,1, +0x12ada88,8, +0x12adac0,6, +0x12adae0,1, +0x12adae8,2, +0x12adb04,14, +0x12adc00,4, +0x12adcc8,1, +0x12adfcc,3, +0x12adfe0,27, +0x12af000,19, +0x12afa00,10, +0x12afa80,3, +0x12afb00,6, +0x12b0000,51, +0x12b0a00,10, +0x12b0a80,3, +0x12b1000,2, +0x12b100c,4, +0x12b1028,3, +0x12b1038,4, +0x12b1050,2, +0x12b1080,4, +0x12b1098,7, +0x12b1120,4, +0x12b1200,4, +0x12b1214,7, +0x12b1234,3, +0x12b1280,8, +0x12b12c0,5, +0x12b1300,2, +0x12b130c,3, +0x12b1400,24, +0x12b1464,2, +0x12b1470,3, +0x12b1500,25, +0x12b15c0,8, +0x12b15e8,5, +0x12b1600,5, +0x12b1618,1, +0x12b1620,1, +0x12b1628,1, +0x12b1630,2, +0x12b1640,2, +0x12b1650,2, +0x12b1690,4, +0x12b1740,2, +0x12b1760,6, +0x12b1780,6, +0x12b17a0,6, +0x12b17c0,6, +0x12b17e0,1, +0x12b1800,2, +0x12b180c,4, +0x12b1828,3, +0x12b1838,4, +0x12b1850,2, +0x12b1880,4, +0x12b1898,7, +0x12b1920,4, +0x12b1a00,4, +0x12b1a14,7, +0x12b1a34,3, +0x12b1a80,8, +0x12b1ac0,5, +0x12b1b00,2, +0x12b1b0c,3, +0x12b1c00,24, +0x12b1c64,2, +0x12b1c70,3, +0x12b1d00,25, +0x12b1dc0,8, +0x12b1de8,5, +0x12b1e00,5, +0x12b1e18,1, +0x12b1e20,1, +0x12b1e28,1, +0x12b1e30,2, +0x12b1e40,2, +0x12b1e50,2, +0x12b1e90,4, +0x12b1f40,2, +0x12b1f60,6, +0x12b1f80,6, +0x12b1fa0,6, +0x12b1fc0,6, +0x12b1fe0,1, +0x12b2000,19, +0x12b2080,2, +0x12b20b0,2, +0x12b20c0,2, +0x12c0000,11, +0x12c0040,16, +0x12c0084,5, +0x12c0200,7, +0x12c0220,6, +0x12c0240,7, +0x12c0260,6, +0x12c0280,6, +0x12c02a0,2, +0x12c02ac,2, +0x12c02c0,7, +0x12c02e0,7, +0x12c0300,2, +0x12c030c,2, +0x12c0320,6, +0x12c0400,2, +0x12c1000,19, +0x12c2104,23, +0x12c2180,7, +0x12c21a0,6, +0x12c21c0,7, +0x12c21e0,6, +0x12c2200,4, +0x12c2220,4, +0x12c2240,11, +0x12c2270,32, +0x12c2300,24, +0x12c2380,20, +0x12c2400,61, +0x12c2500,25, +0x12c2568,4, +0x12c2580,2, +0x12c25a0,1, +0x12c25c0,11, +0x12c2600,9, +0x12c2640,3, +0x12c2650,3, +0x12c2664,3, +0x12c2680,22, +0x12c2800,11, +0x12c3000,536, +0x12c4104,23, +0x12c4180,7, +0x12c41a0,6, +0x12c41c0,7, +0x12c41e0,6, +0x12c4200,4, +0x12c4220,4, +0x12c4240,11, +0x12c4270,32, +0x12c4300,24, +0x12c4380,20, +0x12c4400,61, +0x12c4500,25, +0x12c4568,4, +0x12c4580,2, +0x12c45a0,1, +0x12c45c0,11, +0x12c4600,9, +0x12c4640,3, +0x12c4650,3, +0x12c4664,3, +0x12c4680,22, +0x12c4800,11, +0x12c5000,536, +0x12ca000,7, +0x12ca048,8, +0x12ca080,8, +0x12ca100,7, +0x12ca148,8, +0x12ca180,8, +0x12d0000,11, +0x12d0040,16, +0x12d0084,5, +0x12d0200,7, +0x12d0220,6, +0x12d0240,7, +0x12d0260,6, +0x12d0280,6, +0x12d02a0,2, +0x12d02ac,2, +0x12d02c0,7, +0x12d02e0,7, +0x12d0300,2, +0x12d030c,2, +0x12d0320,6, +0x12d0400,2, +0x12d1000,19, +0x12d2104,23, +0x12d2180,7, +0x12d21a0,6, +0x12d21c0,7, +0x12d21e0,6, +0x12d2200,4, +0x12d2220,4, +0x12d2240,11, +0x12d2270,32, +0x12d2300,24, +0x12d2380,20, +0x12d2400,61, +0x12d2500,25, +0x12d2568,4, +0x12d2580,2, +0x12d25a0,1, +0x12d25c0,11, +0x12d2600,9, +0x12d2640,3, +0x12d2650,3, +0x12d2664,3, +0x12d2680,22, +0x12d2800,11, +0x12d3000,536, +0x12d4104,23, +0x12d4180,7, +0x12d41a0,6, +0x12d41c0,7, +0x12d41e0,6, +0x12d4200,4, +0x12d4220,4, +0x12d4240,11, +0x12d4270,32, +0x12d4300,24, +0x12d4380,20, +0x12d4400,61, +0x12d4500,25, +0x12d4568,4, +0x12d4580,2, +0x12d45a0,1, +0x12d45c0,11, +0x12d4600,9, +0x12d4640,3, +0x12d4650,3, +0x12d4664,3, +0x12d4680,22, +0x12d4800,11, +0x12d5000,536, +0x12da000,7, +0x12da048,8, +0x12da080,8, +0x12da100,7, +0x12da148,8, +0x12da180,8, +0x12e0400,4, +0x12e0440,4, +0x12e05c0,1, +0x12e0600,8, +0x12e0800,18, +0x12e0880,13, +0x12e08f0,3, +0x12e0900,18, +0x12e0980,13, +0x12e09f0,3, +0x12e0e00,4, +0x12e0e20,4, +0x12e0e80,16, +0x12e0f00,1, +0x12e0f20,1, +0x12e1020,2, +0x12e1208,6, +0x12e1228,10, +0x12e1288,6, +0x12e12a8,10, +0x12e1600,32, +0x12e18c0,8, +0x12e1900,24, +0x12e19b0,4, +0x12e1aa0,2, +0x12e1ac0,4, +0x12e2200,19, +0x12e2280,19, +0x12e2400,14, +0x12e243c,9, +0x12e2464,14, +0x12e24a0,2, +0x12e24ac,2, +0x12e2500,14, +0x12e253c,9, +0x12e2564,14, +0x12e25a0,2, +0x12e25ac,2, +0x12e2800,19, +0x12e2880,19, +0x12e2a10,2, +0x12e2a1c,1, +0x12e2a50,2, +0x12e2a5c,1, +0x12e2c00,7, +0x12e2c20,1, +0x12e2c54,18, +0x12e2ca0,1, +0x12e2cd4,11, +0x12e2e00,1, +0x12e2e08,6, +0x12e3180,3, +0x12e4400,4, +0x12e4440,4, +0x12e45c0,1, +0x12e4600,8, +0x12e4800,18, +0x12e4880,13, +0x12e48f0,3, +0x12e4900,18, +0x12e4980,13, +0x12e49f0,3, +0x12e4e00,4, +0x12e4e20,4, +0x12e4e80,16, +0x12e4f00,1, +0x12e4f20,1, +0x12e5020,2, +0x12e5208,6, +0x12e5228,10, +0x12e5288,6, +0x12e52a8,10, +0x12e5600,32, +0x12e58c0,8, +0x12e5900,24, +0x12e59b0,4, +0x12e5aa0,2, +0x12e5ac0,4, +0x12e6200,19, +0x12e6280,19, +0x12e6400,14, +0x12e643c,9, +0x12e6464,14, +0x12e64a0,2, +0x12e64ac,2, +0x12e6500,14, +0x12e653c,9, +0x12e6564,14, +0x12e65a0,2, +0x12e65ac,2, +0x12e6800,19, +0x12e6880,19, +0x12e6a10,2, +0x12e6a1c,1, +0x12e6a50,2, +0x12e6a5c,1, +0x12e6c00,7, +0x12e6c20,1, +0x12e6c54,18, +0x12e6ca0,1, +0x12e6cd4,11, +0x12e6e00,1, +0x12e6e08,6, +0x12e7180,3, +0x12e9000,13, +0x12ee000,19, +0x12eea00,10, +0x12eea80,3, +0x12ef000,1, +0x12ef008,5, +0x12ef038,1, +0x12ef044,1, +0x12ef050,2, +0x12ef060,8, +0x12ef140,19, +0x12ef190,4, +0x12f0000,2, +0x12f000c,2, +0x12f0040,7, +0x12f0100,3, +0x12f0110,3, +0x12f0120,5, +0x12f0200,6, +0x12f0240,5, +0x12f0400,2, +0x12f040c,2, +0x12f0440,7, +0x12f0500,3, +0x12f0510,3, +0x12f0520,5, +0x12f0600,6, +0x12f0640,5, +0x12f0800,2, +0x12f080c,2, +0x12f0840,7, +0x12f0900,3, +0x12f0910,3, +0x12f0920,5, +0x12f0a00,6, +0x12f0a40,5, +0x12f0c00,2, +0x12f0c0c,2, +0x12f0c40,7, +0x12f0d00,3, +0x12f0d10,3, +0x12f0d20,5, +0x12f0e00,6, +0x12f0e40,5, +0x12f1000,2, +0x12f100c,2, +0x12f1040,7, +0x12f1100,3, +0x12f1110,3, +0x12f1120,5, +0x12f1200,6, +0x12f1240,5, +0x12f1400,2, +0x12f140c,2, +0x12f1440,7, +0x12f1500,3, +0x12f1510,3, +0x12f1520,5, +0x12f1600,6, +0x12f1640,5, +0x12f1800,2, +0x12f180c,2, +0x12f1840,7, +0x12f1900,3, +0x12f1910,3, +0x12f1920,5, +0x12f1a00,6, +0x12f1a40,5, +0x12f1c00,2, +0x12f1c0c,2, +0x12f1c40,7, +0x12f1d00,3, +0x12f1d10,3, +0x12f1d20,5, +0x12f1e00,6, +0x12f1e40,5, +0x12f2000,5, +0x12f2040,9, +0x12f2100,3, +0x12f2200,1, +0x12f2210,1, +0x12f2220,1, +0x12f2230,1, +0x12f2240,1, +0x12f2300,3, +0x12f2314,1, +0x12f2320,4, +0x12f2400,5, +0x12f2440,5, +0x12f3000,80, +0x12f3200,1, +0x12f8000,7, +0x12f8030,2, +0x12f8040,7, +0x12f8070,2, +0x12f8100,2, +0x12f8120,2, +0x12f8140,2, +0x12f8160,2, +0x12f8180,9, +0x12f8200,7, +0x12f8230,2, +0x12f8240,7, +0x12f8270,2, +0x12f8300,2, +0x12f8320,2, +0x12f8340,2, +0x12f8360,2, +0x12f8380,9, +0x12f8400,11, +0x12f8500,11, +0x12f9000,3, +0x12f9010,2, +0x12f901c,5, +0x12f9040,8, +0x12f9080,3, +0x12f9090,2, +0x12f909c,5, +0x12f90c0,8, +0x12f9100,3, +0x12f9110,2, +0x12f911c,5, +0x12f9140,8, +0x12f9180,3, +0x12f9190,2, +0x12f919c,5, +0x12f91c0,8, +0x12f9200,7, +0x12f9220,12, +0x12f9280,7, +0x12f92a0,12, +0x12f9300,3, +0x12f9310,1, +0x12f9400,3, +0x12f9410,2, +0x12f941c,5, +0x12f9440,8, +0x12f9480,3, +0x12f9490,2, +0x12f949c,5, +0x12f94c0,8, +0x12f9500,3, +0x12f9510,2, +0x12f951c,5, +0x12f9540,8, +0x12f9580,3, +0x12f9590,2, +0x12f959c,5, +0x12f95c0,8, +0x12f9600,7, +0x12f9620,12, +0x12f9680,7, +0x12f96a0,12, +0x12f9700,3, +0x12f9710,1, +0x12f9804,1, +0x12f9824,21, +0x12f9880,16, +0x12f9900,5, +0x12f9920,11, +0x12f9950,9, +0x12f9980,22, +0x12f9a00,22, +0x12f9a80,22, +0x12f9b00,22, +0x12f9b80,22, +0x12f9c00,22, +0x12f9c80,22, +0x12f9d00,22, +0x12f9d80,3, +0x1300000,5, +0x1300018,5, +0x1300030,3, +0x1300044,3, +0x1300100,58, +0x13001f0,3, +0x1300280,3, +0x1300400,5, +0x1300418,5, +0x1300430,3, +0x1300444,3, +0x1300500,58, +0x13005f0,3, +0x1300680,3, +0x1301018,2, +0x1301100,2, +0x1301110,10, +0x1301140,2, +0x1301150,10, +0x1301208,1, +0x1301220,12, +0x1301280,1, +0x1301288,2, +0x1301400,4, +0x1302000,5, +0x1302018,5, +0x1302030,3, +0x1302044,3, +0x1302100,58, +0x13021f0,3, +0x1302280,3, +0x1302400,5, +0x1302418,5, +0x1302430,3, +0x1302444,3, +0x1302500,58, +0x13025f0,3, +0x1302680,3, +0x1303018,2, +0x1303100,2, +0x1303110,10, +0x1303140,2, +0x1303150,10, +0x1303208,1, +0x1303220,12, +0x1303280,1, +0x1303288,2, +0x1303400,4, +0x1304000,2, +0x130400c,1, +0x1304030,3, +0x1304040,2, +0x130404c,1, +0x1304070,3, +0x1304100,2, +0x130410c,1, +0x1304130,3, +0x1304140,2, +0x130414c,1, +0x1304170,3, +0x1304200,15, +0x1304280,15, +0x1304300,15, +0x1304380,15, +0x1304400,15, +0x1304480,15, +0x1304500,15, +0x1304580,15, +0x1304604,10, +0x1304700,2, +0x130470c,7, +0x1304740,1, +0x1304770,1, +0x13047c0,2, +0x13047d0,4, +0x1305000,3, +0x1305010,1, +0x130501c,3, +0x1305104,1, +0x1305110,4, +0x1305124,1, +0x1305130,4, +0x1305144,1, +0x1305150,4, +0x1305164,1, +0x1305170,5, +0x1305190,4, +0x1305a00,4, +0x1305c00,129, +0x1306000,37, +0x1306098,1, +0x1306100,37, +0x1306198,1, +0x1306200,37, +0x1306298,1, +0x1306300,37, +0x1306398,1, +0x1306400,37, +0x1306498,1, +0x1306500,37, +0x1306598,1, +0x1306600,37, +0x1306698,1, +0x1306700,37, +0x1306798,1, +0x130c000,91, +0x130c400,4, +0x130c440,15, +0x130c480,4, +0x130c4c0,15, +0x130c500,4, +0x130c540,15, +0x130c580,4, +0x130c5c0,15, +0x130c600,4, +0x130c640,10, +0x130c680,4, +0x130c6c0,10, +0x130c800,4, +0x130c840,33, +0x130ca00,13, +0x130ca80,1, +0x130ca88,8, +0x130cac0,6, +0x130cae0,1, +0x130cae8,2, +0x130cb04,14, +0x130cc00,4, +0x130ccc8,1, +0x130cfcc,3, +0x130cfe0,99, +0x130d400,4, +0x130d440,15, +0x130d480,4, +0x130d4c0,15, +0x130d500,4, +0x130d540,15, +0x130d580,4, +0x130d5c0,15, +0x130d600,4, +0x130d640,10, +0x130d680,4, +0x130d6c0,10, +0x130d800,4, +0x130d840,33, +0x130da00,13, +0x130da80,1, +0x130da88,8, +0x130dac0,6, +0x130dae0,1, +0x130dae8,2, +0x130db04,14, +0x130dc00,4, +0x130dcc8,1, +0x130dfcc,3, +0x130dfe0,27, +0x130f000,19, +0x130fa00,10, +0x130fa80,3, +0x130fb00,6, +0x1310000,51, +0x1310a00,10, +0x1310a80,3, +0x1311000,2, +0x131100c,4, +0x1311028,3, +0x1311038,4, +0x1311050,2, +0x1311080,4, +0x1311098,7, +0x1311120,4, +0x1311200,4, +0x1311214,7, +0x1311234,3, +0x1311280,8, +0x13112c0,5, +0x1311300,2, +0x131130c,3, +0x1311400,24, +0x1311464,2, +0x1311470,3, +0x1311500,25, +0x13115c0,8, +0x13115e8,5, +0x1311600,5, +0x1311618,1, +0x1311620,1, +0x1311628,1, +0x1311630,2, +0x1311640,2, +0x1311650,2, +0x1311690,4, +0x1311740,2, +0x1311760,6, +0x1311780,6, +0x13117a0,6, +0x13117c0,6, +0x13117e0,1, +0x1311800,2, +0x131180c,4, +0x1311828,3, +0x1311838,4, +0x1311850,2, +0x1311880,4, +0x1311898,7, +0x1311920,4, +0x1311a00,4, +0x1311a14,7, +0x1311a34,3, +0x1311a80,8, +0x1311ac0,5, +0x1311b00,2, +0x1311b0c,3, +0x1311c00,24, +0x1311c64,2, +0x1311c70,3, +0x1311d00,25, +0x1311dc0,8, +0x1311de8,5, +0x1311e00,5, +0x1311e18,1, +0x1311e20,1, +0x1311e28,1, +0x1311e30,2, +0x1311e40,2, +0x1311e50,2, +0x1311e90,4, +0x1311f40,2, +0x1311f60,6, +0x1311f80,6, +0x1311fa0,6, +0x1311fc0,6, +0x1311fe0,1, +0x1312000,19, +0x1312080,2, +0x13120b0,2, +0x13120c0,2, +0x1320000,11, +0x1320040,16, +0x1320084,5, +0x1320200,7, +0x1320220,6, +0x1320240,7, +0x1320260,6, +0x1320280,6, +0x13202a0,2, +0x13202ac,2, +0x13202c0,7, +0x13202e0,7, +0x1320300,2, +0x132030c,2, +0x1320320,6, +0x1320400,2, +0x1321000,19, +0x1322104,23, +0x1322180,7, +0x13221a0,6, +0x13221c0,7, +0x13221e0,6, +0x1322200,4, +0x1322220,4, +0x1322240,11, +0x1322270,32, +0x1322300,24, +0x1322380,20, +0x1322400,61, +0x1322500,25, +0x1322568,4, +0x1322580,2, +0x13225a0,1, +0x13225c0,11, +0x1322600,9, +0x1322640,3, +0x1322650,3, +0x1322664,3, +0x1322680,22, +0x1322800,11, +0x1323000,536, +0x1324104,23, +0x1324180,7, +0x13241a0,6, +0x13241c0,7, +0x13241e0,6, +0x1324200,4, +0x1324220,4, +0x1324240,11, +0x1324270,32, +0x1324300,24, +0x1324380,20, +0x1324400,61, +0x1324500,25, +0x1324568,4, +0x1324580,2, +0x13245a0,1, +0x13245c0,11, +0x1324600,9, +0x1324640,3, +0x1324650,3, +0x1324664,3, +0x1324680,22, +0x1324800,11, +0x1325000,536, +0x132a000,7, +0x132a048,8, +0x132a080,8, +0x132a100,7, +0x132a148,8, +0x132a180,8, +0x1330000,11, +0x1330040,16, +0x1330084,5, +0x1330200,7, +0x1330220,6, +0x1330240,7, +0x1330260,6, +0x1330280,6, +0x13302a0,2, +0x13302ac,2, +0x13302c0,7, +0x13302e0,7, +0x1330300,2, +0x133030c,2, +0x1330320,6, +0x1330400,2, +0x1331000,19, +0x1332104,23, +0x1332180,7, +0x13321a0,6, +0x13321c0,7, +0x13321e0,6, +0x1332200,4, +0x1332220,4, +0x1332240,11, +0x1332270,32, +0x1332300,24, +0x1332380,20, +0x1332400,61, +0x1332500,25, +0x1332568,4, +0x1332580,2, +0x13325a0,1, +0x13325c0,11, +0x1332600,9, +0x1332640,3, +0x1332650,3, +0x1332664,3, +0x1332680,22, +0x1332800,11, +0x1333000,536, +0x1334104,23, +0x1334180,7, +0x13341a0,6, +0x13341c0,7, +0x13341e0,6, +0x1334200,4, +0x1334220,4, +0x1334240,11, +0x1334270,32, +0x1334300,24, +0x1334380,20, +0x1334400,61, +0x1334500,25, +0x1334568,4, +0x1334580,2, +0x13345a0,1, +0x13345c0,11, +0x1334600,9, +0x1334640,3, +0x1334650,3, +0x1334664,3, +0x1334680,22, +0x1334800,11, +0x1335000,536, +0x133a000,7, +0x133a048,8, +0x133a080,8, +0x133a100,7, +0x133a148,8, +0x133a180,8, +0x1340400,4, +0x1340440,4, +0x13405c0,1, +0x1340600,8, +0x1340800,18, +0x1340880,13, +0x13408f0,3, +0x1340900,18, +0x1340980,13, +0x13409f0,3, +0x1340e00,4, +0x1340e20,4, +0x1340e80,16, +0x1340f00,1, +0x1340f20,1, +0x1341020,2, +0x1341208,6, +0x1341228,10, +0x1341288,6, +0x13412a8,10, +0x1341600,32, +0x13418c0,8, +0x1341900,24, +0x13419b0,4, +0x1341aa0,2, +0x1341ac0,4, +0x1342200,19, +0x1342280,19, +0x1342400,14, +0x134243c,9, +0x1342464,14, +0x13424a0,2, +0x13424ac,2, +0x1342500,14, +0x134253c,9, +0x1342564,14, +0x13425a0,2, +0x13425ac,2, +0x1342800,19, +0x1342880,19, +0x1342a10,2, +0x1342a1c,1, +0x1342a50,2, +0x1342a5c,1, +0x1342c00,7, +0x1342c20,1, +0x1342c54,18, +0x1342ca0,1, +0x1342cd4,11, +0x1342e00,1, +0x1342e08,6, +0x1343180,3, +0x1344400,4, +0x1344440,4, +0x13445c0,1, +0x1344600,8, +0x1344800,18, +0x1344880,13, +0x13448f0,3, +0x1344900,18, +0x1344980,13, +0x13449f0,3, +0x1344e00,4, +0x1344e20,4, +0x1344e80,16, +0x1344f00,1, +0x1344f20,1, +0x1345020,2, +0x1345208,6, +0x1345228,10, +0x1345288,6, +0x13452a8,10, +0x1345600,32, +0x13458c0,8, +0x1345900,24, +0x13459b0,4, +0x1345aa0,2, +0x1345ac0,4, +0x1346200,19, +0x1346280,19, +0x1346400,14, +0x134643c,9, +0x1346464,14, +0x13464a0,2, +0x13464ac,2, +0x1346500,14, +0x134653c,9, +0x1346564,14, +0x13465a0,2, +0x13465ac,2, +0x1346800,19, +0x1346880,19, +0x1346a10,2, +0x1346a1c,1, +0x1346a50,2, +0x1346a5c,1, +0x1346c00,7, +0x1346c20,1, +0x1346c54,18, +0x1346ca0,1, +0x1346cd4,11, +0x1346e00,1, +0x1346e08,6, +0x1347180,3, +0x1349000,13, +0x134e000,19, +0x134ea00,10, +0x134ea80,3, +0x134f000,1, +0x134f008,5, +0x134f038,1, +0x134f044,1, +0x134f050,2, +0x134f060,8, +0x134f140,19, +0x134f190,4, +0x1350000,2, +0x135000c,2, +0x1350040,7, +0x1350100,3, +0x1350110,3, +0x1350120,5, +0x1350200,6, +0x1350240,5, +0x1350400,2, +0x135040c,2, +0x1350440,7, +0x1350500,3, +0x1350510,3, +0x1350520,5, +0x1350600,6, +0x1350640,5, +0x1350800,2, +0x135080c,2, +0x1350840,7, +0x1350900,3, +0x1350910,3, +0x1350920,5, +0x1350a00,6, +0x1350a40,5, +0x1350c00,2, +0x1350c0c,2, +0x1350c40,7, +0x1350d00,3, +0x1350d10,3, +0x1350d20,5, +0x1350e00,6, +0x1350e40,5, +0x1351000,2, +0x135100c,2, +0x1351040,7, +0x1351100,3, +0x1351110,3, +0x1351120,5, +0x1351200,6, +0x1351240,5, +0x1351400,2, +0x135140c,2, +0x1351440,7, +0x1351500,3, +0x1351510,3, +0x1351520,5, +0x1351600,6, +0x1351640,5, +0x1351800,2, +0x135180c,2, +0x1351840,7, +0x1351900,3, +0x1351910,3, +0x1351920,5, +0x1351a00,6, +0x1351a40,5, +0x1351c00,2, +0x1351c0c,2, +0x1351c40,7, +0x1351d00,3, +0x1351d10,3, +0x1351d20,5, +0x1351e00,6, +0x1351e40,5, +0x1352000,5, +0x1352040,9, +0x1352100,3, +0x1352200,1, +0x1352210,1, +0x1352220,1, +0x1352230,1, +0x1352240,1, +0x1352300,3, +0x1352314,1, +0x1352320,4, +0x1352400,5, +0x1352440,5, +0x1353000,80, +0x1353200,1, +0x1358000,7, +0x1358030,2, +0x1358040,7, +0x1358070,2, +0x1358100,2, +0x1358120,2, +0x1358140,2, +0x1358160,2, +0x1358180,9, +0x1358200,7, +0x1358230,2, +0x1358240,7, +0x1358270,2, +0x1358300,2, +0x1358320,2, +0x1358340,2, +0x1358360,2, +0x1358380,9, +0x1358400,11, +0x1358500,11, +0x1359000,3, +0x1359010,2, +0x135901c,5, +0x1359040,8, +0x1359080,3, +0x1359090,2, +0x135909c,5, +0x13590c0,8, +0x1359100,3, +0x1359110,2, +0x135911c,5, +0x1359140,8, +0x1359180,3, +0x1359190,2, +0x135919c,5, +0x13591c0,8, +0x1359200,7, +0x1359220,12, +0x1359280,7, +0x13592a0,12, +0x1359300,3, +0x1359310,1, +0x1359400,3, +0x1359410,2, +0x135941c,5, +0x1359440,8, +0x1359480,3, +0x1359490,2, +0x135949c,5, +0x13594c0,8, +0x1359500,3, +0x1359510,2, +0x135951c,5, +0x1359540,8, +0x1359580,3, +0x1359590,2, +0x135959c,5, +0x13595c0,8, +0x1359600,7, +0x1359620,12, +0x1359680,7, +0x13596a0,12, +0x1359700,3, +0x1359710,1, +0x1359804,1, +0x1359824,21, +0x1359880,16, +0x1359900,5, +0x1359920,11, +0x1359950,9, +0x1359980,22, +0x1359a00,22, +0x1359a80,22, +0x1359b00,22, +0x1359b80,22, +0x1359c00,22, +0x1359c80,22, +0x1359d00,22, +0x1359d80,3, +0x1360000,5, +0x1360018,5, +0x1360030,3, +0x1360044,3, +0x1360100,58, +0x13601f0,3, +0x1360280,3, +0x1360400,5, +0x1360418,5, +0x1360430,3, +0x1360444,3, +0x1360500,58, +0x13605f0,3, +0x1360680,3, +0x1361018,2, +0x1361100,2, +0x1361110,10, +0x1361140,2, +0x1361150,10, +0x1361208,1, +0x1361220,12, +0x1361280,1, +0x1361288,2, +0x1361400,4, +0x1362000,5, +0x1362018,5, +0x1362030,3, +0x1362044,3, +0x1362100,58, +0x13621f0,3, +0x1362280,3, +0x1362400,5, +0x1362418,5, +0x1362430,3, +0x1362444,3, +0x1362500,58, +0x13625f0,3, +0x1362680,3, +0x1363018,2, +0x1363100,2, +0x1363110,10, +0x1363140,2, +0x1363150,10, +0x1363208,1, +0x1363220,12, +0x1363280,1, +0x1363288,2, +0x1363400,4, +0x1364000,2, +0x136400c,1, +0x1364030,3, +0x1364040,2, +0x136404c,1, +0x1364070,3, +0x1364100,2, +0x136410c,1, +0x1364130,3, +0x1364140,2, +0x136414c,1, +0x1364170,3, +0x1364200,15, +0x1364280,15, +0x1364300,15, +0x1364380,15, +0x1364400,15, +0x1364480,15, +0x1364500,15, +0x1364580,15, +0x1364604,10, +0x1364700,2, +0x136470c,7, +0x1364740,1, +0x1364770,1, +0x13647c0,2, +0x13647d0,4, +0x1365000,3, +0x1365010,1, +0x136501c,3, +0x1365104,1, +0x1365110,4, +0x1365124,1, +0x1365130,4, +0x1365144,1, +0x1365150,4, +0x1365164,1, +0x1365170,5, +0x1365190,4, +0x1365a00,4, +0x1365c00,129, +0x1366000,37, +0x1366098,1, +0x1366100,37, +0x1366198,1, +0x1366200,37, +0x1366298,1, +0x1366300,37, +0x1366398,1, +0x1366400,37, +0x1366498,1, +0x1366500,37, +0x1366598,1, +0x1366600,37, +0x1366698,1, +0x1366700,37, +0x1366798,1, +0x136c000,91, +0x136c400,4, +0x136c440,15, +0x136c480,4, +0x136c4c0,15, +0x136c500,4, +0x136c540,15, +0x136c580,4, +0x136c5c0,15, +0x136c600,4, +0x136c640,10, +0x136c680,4, +0x136c6c0,10, +0x136c800,4, +0x136c840,33, +0x136ca00,13, +0x136ca80,1, +0x136ca88,8, +0x136cac0,6, +0x136cae0,1, +0x136cae8,2, +0x136cb04,14, +0x136cc00,4, +0x136ccc8,1, +0x136cfcc,3, +0x136cfe0,99, +0x136d400,4, +0x136d440,15, +0x136d480,4, +0x136d4c0,15, +0x136d500,4, +0x136d540,15, +0x136d580,4, +0x136d5c0,15, +0x136d600,4, +0x136d640,10, +0x136d680,4, +0x136d6c0,10, +0x136d800,4, +0x136d840,33, +0x136da00,13, +0x136da80,1, +0x136da88,8, +0x136dac0,6, +0x136dae0,1, +0x136dae8,2, +0x136db04,14, +0x136dc00,4, +0x136dcc8,1, +0x136dfcc,3, +0x136dfe0,27, +0x136f000,19, +0x136fa00,10, +0x136fa80,3, +0x136fb00,6, +0x1370000,51, +0x1370a00,10, +0x1370a80,3, +0x1371000,2, +0x137100c,4, +0x1371028,3, +0x1371038,4, +0x1371050,2, +0x1371080,4, +0x1371098,7, +0x1371120,4, +0x1371200,4, +0x1371214,7, +0x1371234,3, +0x1371280,8, +0x13712c0,5, +0x1371300,2, +0x137130c,3, +0x1371400,24, +0x1371464,2, +0x1371470,3, +0x1371500,25, +0x13715c0,8, +0x13715e8,5, +0x1371600,5, +0x1371618,1, +0x1371620,1, +0x1371628,1, +0x1371630,2, +0x1371640,2, +0x1371650,2, +0x1371690,4, +0x1371740,2, +0x1371760,6, +0x1371780,6, +0x13717a0,6, +0x13717c0,6, +0x13717e0,1, +0x1371800,2, +0x137180c,4, +0x1371828,3, +0x1371838,4, +0x1371850,2, +0x1371880,4, +0x1371898,7, +0x1371920,4, +0x1371a00,4, +0x1371a14,7, +0x1371a34,3, +0x1371a80,8, +0x1371ac0,5, +0x1371b00,2, +0x1371b0c,3, +0x1371c00,24, +0x1371c64,2, +0x1371c70,3, +0x1371d00,25, +0x1371dc0,8, +0x1371de8,5, +0x1371e00,5, +0x1371e18,1, +0x1371e20,1, +0x1371e28,1, +0x1371e30,2, +0x1371e40,2, +0x1371e50,2, +0x1371e90,4, +0x1371f40,2, +0x1371f60,6, +0x1371f80,6, +0x1371fa0,6, +0x1371fc0,6, +0x1371fe0,1, +0x1372000,19, +0x1372080,2, +0x13720b0,2, +0x13720c0,2, +0x1380000,11, +0x1380040,16, +0x1380084,5, +0x1380200,7, +0x1380220,6, +0x1380240,7, +0x1380260,6, +0x1380280,6, +0x13802a0,2, +0x13802ac,2, +0x13802c0,7, +0x13802e0,7, +0x1380300,2, +0x138030c,2, +0x1380320,6, +0x1380400,2, +0x1381000,19, +0x1382104,23, +0x1382180,7, +0x13821a0,6, +0x13821c0,7, +0x13821e0,6, +0x1382200,4, +0x1382220,4, +0x1382240,11, +0x1382270,32, +0x1382300,24, +0x1382380,20, +0x1382400,61, +0x1382500,25, +0x1382568,4, +0x1382580,2, +0x13825a0,1, +0x13825c0,11, +0x1382600,9, +0x1382640,3, +0x1382650,3, +0x1382664,3, +0x1382680,22, +0x1382800,11, +0x1383000,536, +0x1384104,23, +0x1384180,7, +0x13841a0,6, +0x13841c0,7, +0x13841e0,6, +0x1384200,4, +0x1384220,4, +0x1384240,11, +0x1384270,32, +0x1384300,24, +0x1384380,20, +0x1384400,61, +0x1384500,25, +0x1384568,4, +0x1384580,2, +0x13845a0,1, +0x13845c0,11, +0x1384600,9, +0x1384640,3, +0x1384650,3, +0x1384664,3, +0x1384680,22, +0x1384800,11, +0x1385000,536, +0x138a000,7, +0x138a048,8, +0x138a080,8, +0x138a100,7, +0x138a148,8, +0x138a180,8, +0x1390000,11, +0x1390040,16, +0x1390084,5, +0x1390200,7, +0x1390220,6, +0x1390240,7, +0x1390260,6, +0x1390280,6, +0x13902a0,2, +0x13902ac,2, +0x13902c0,7, +0x13902e0,7, +0x1390300,2, +0x139030c,2, +0x1390320,6, +0x1390400,2, +0x1391000,19, +0x1392104,23, +0x1392180,7, +0x13921a0,6, +0x13921c0,7, +0x13921e0,6, +0x1392200,4, +0x1392220,4, +0x1392240,11, +0x1392270,32, +0x1392300,24, +0x1392380,20, +0x1392400,61, +0x1392500,25, +0x1392568,4, +0x1392580,2, +0x13925a0,1, +0x13925c0,11, +0x1392600,9, +0x1392640,3, +0x1392650,3, +0x1392664,3, +0x1392680,22, +0x1392800,11, +0x1393000,536, +0x1394104,23, +0x1394180,7, +0x13941a0,6, +0x13941c0,7, +0x13941e0,6, +0x1394200,4, +0x1394220,4, +0x1394240,11, +0x1394270,32, +0x1394300,24, +0x1394380,20, +0x1394400,61, +0x1394500,25, +0x1394568,4, +0x1394580,2, +0x13945a0,1, +0x13945c0,11, +0x1394600,9, +0x1394640,3, +0x1394650,3, +0x1394664,3, +0x1394680,22, +0x1394800,11, +0x1395000,536, +0x139a000,7, +0x139a048,8, +0x139a080,8, +0x139a100,7, +0x139a148,8, +0x139a180,8, +0x13a0400,4, +0x13a0440,4, +0x13a05c0,1, +0x13a0600,8, +0x13a0800,18, +0x13a0880,13, +0x13a08f0,3, +0x13a0900,18, +0x13a0980,13, +0x13a09f0,3, +0x13a0e00,4, +0x13a0e20,4, +0x13a0e80,16, +0x13a0f00,1, +0x13a0f20,1, +0x13a1020,2, +0x13a1208,6, +0x13a1228,10, +0x13a1288,6, +0x13a12a8,10, +0x13a1600,32, +0x13a18c0,8, +0x13a1900,24, +0x13a19b0,4, +0x13a1aa0,2, +0x13a1ac0,4, +0x13a2200,19, +0x13a2280,19, +0x13a2400,14, +0x13a243c,9, +0x13a2464,14, +0x13a24a0,2, +0x13a24ac,2, +0x13a2500,14, +0x13a253c,9, +0x13a2564,14, +0x13a25a0,2, +0x13a25ac,2, +0x13a2800,19, +0x13a2880,19, +0x13a2a10,2, +0x13a2a1c,1, +0x13a2a50,2, +0x13a2a5c,1, +0x13a2c00,7, +0x13a2c20,1, +0x13a2c54,18, +0x13a2ca0,1, +0x13a2cd4,11, +0x13a2e00,1, +0x13a2e08,6, +0x13a3180,3, +0x13a4400,4, +0x13a4440,4, +0x13a45c0,1, +0x13a4600,8, +0x13a4800,18, +0x13a4880,13, +0x13a48f0,3, +0x13a4900,18, +0x13a4980,13, +0x13a49f0,3, +0x13a4e00,4, +0x13a4e20,4, +0x13a4e80,16, +0x13a4f00,1, +0x13a4f20,1, +0x13a5020,2, +0x13a5208,6, +0x13a5228,10, +0x13a5288,6, +0x13a52a8,10, +0x13a5600,32, +0x13a58c0,8, +0x13a5900,24, +0x13a59b0,4, +0x13a5aa0,2, +0x13a5ac0,4, +0x13a6200,19, +0x13a6280,19, +0x13a6400,14, +0x13a643c,9, +0x13a6464,14, +0x13a64a0,2, +0x13a64ac,2, +0x13a6500,14, +0x13a653c,9, +0x13a6564,14, +0x13a65a0,2, +0x13a65ac,2, +0x13a6800,19, +0x13a6880,19, +0x13a6a10,2, +0x13a6a1c,1, +0x13a6a50,2, +0x13a6a5c,1, +0x13a6c00,7, +0x13a6c20,1, +0x13a6c54,18, +0x13a6ca0,1, +0x13a6cd4,11, +0x13a6e00,1, +0x13a6e08,6, +0x13a7180,3, +0x13a9000,13, +0x13ae000,19, +0x13aea00,10, +0x13aea80,3, +0x13af000,1, +0x13af008,5, +0x13af038,1, +0x13af044,1, +0x13af050,2, +0x13af060,8, +0x13af140,19, +0x13af190,4, +0x13b0000,2, +0x13b000c,2, +0x13b0040,7, +0x13b0100,3, +0x13b0110,3, +0x13b0120,5, +0x13b0200,6, +0x13b0240,5, +0x13b0400,2, +0x13b040c,2, +0x13b0440,7, +0x13b0500,3, +0x13b0510,3, +0x13b0520,5, +0x13b0600,6, +0x13b0640,5, +0x13b0800,2, +0x13b080c,2, +0x13b0840,7, +0x13b0900,3, +0x13b0910,3, +0x13b0920,5, +0x13b0a00,6, +0x13b0a40,5, +0x13b0c00,2, +0x13b0c0c,2, +0x13b0c40,7, +0x13b0d00,3, +0x13b0d10,3, +0x13b0d20,5, +0x13b0e00,6, +0x13b0e40,5, +0x13b1000,2, +0x13b100c,2, +0x13b1040,7, +0x13b1100,3, +0x13b1110,3, +0x13b1120,5, +0x13b1200,6, +0x13b1240,5, +0x13b1400,2, +0x13b140c,2, +0x13b1440,7, +0x13b1500,3, +0x13b1510,3, +0x13b1520,5, +0x13b1600,6, +0x13b1640,5, +0x13b1800,2, +0x13b180c,2, +0x13b1840,7, +0x13b1900,3, +0x13b1910,3, +0x13b1920,5, +0x13b1a00,6, +0x13b1a40,5, +0x13b1c00,2, +0x13b1c0c,2, +0x13b1c40,7, +0x13b1d00,3, +0x13b1d10,3, +0x13b1d20,5, +0x13b1e00,6, +0x13b1e40,5, +0x13b2000,5, +0x13b2040,9, +0x13b2100,3, +0x13b2200,1, +0x13b2210,1, +0x13b2220,1, +0x13b2230,1, +0x13b2240,1, +0x13b2300,3, +0x13b2314,1, +0x13b2320,4, +0x13b2400,5, +0x13b2440,5, +0x13b3000,80, +0x13b3200,1, +0x13b8000,7, +0x13b8030,2, +0x13b8040,7, +0x13b8070,2, +0x13b8100,2, +0x13b8120,2, +0x13b8140,2, +0x13b8160,2, +0x13b8180,9, +0x13b8200,7, +0x13b8230,2, +0x13b8240,7, +0x13b8270,2, +0x13b8300,2, +0x13b8320,2, +0x13b8340,2, +0x13b8360,2, +0x13b8380,9, +0x13b8400,11, +0x13b8500,11, +0x13b9000,3, +0x13b9010,2, +0x13b901c,5, +0x13b9040,8, +0x13b9080,3, +0x13b9090,2, +0x13b909c,5, +0x13b90c0,8, +0x13b9100,3, +0x13b9110,2, +0x13b911c,5, +0x13b9140,8, +0x13b9180,3, +0x13b9190,2, +0x13b919c,5, +0x13b91c0,8, +0x13b9200,7, +0x13b9220,12, +0x13b9280,7, +0x13b92a0,12, +0x13b9300,3, +0x13b9310,1, +0x13b9400,3, +0x13b9410,2, +0x13b941c,5, +0x13b9440,8, +0x13b9480,3, +0x13b9490,2, +0x13b949c,5, +0x13b94c0,8, +0x13b9500,3, +0x13b9510,2, +0x13b951c,5, +0x13b9540,8, +0x13b9580,3, +0x13b9590,2, +0x13b959c,5, +0x13b95c0,8, +0x13b9600,7, +0x13b9620,12, +0x13b9680,7, +0x13b96a0,12, +0x13b9700,3, +0x13b9710,1, +0x13b9804,1, +0x13b9824,21, +0x13b9880,16, +0x13b9900,5, +0x13b9920,11, +0x13b9950,9, +0x13b9980,22, +0x13b9a00,22, +0x13b9a80,22, +0x13b9b00,22, +0x13b9b80,22, +0x13b9c00,22, +0x13b9c80,22, +0x13b9d00,22, +0x13b9d80,3, +0x13c0000,5, +0x13c0018,5, +0x13c0030,3, +0x13c0044,3, +0x13c0100,58, +0x13c01f0,3, +0x13c0280,3, +0x13c0400,5, +0x13c0418,5, +0x13c0430,3, +0x13c0444,3, +0x13c0500,58, +0x13c05f0,3, +0x13c0680,3, +0x13c1018,2, +0x13c1100,2, +0x13c1110,10, +0x13c1140,2, +0x13c1150,10, +0x13c1208,1, +0x13c1220,12, +0x13c1280,1, +0x13c1288,2, +0x13c1400,4, +0x13c2000,5, +0x13c2018,5, +0x13c2030,3, +0x13c2044,3, +0x13c2100,58, +0x13c21f0,3, +0x13c2280,3, +0x13c2400,5, +0x13c2418,5, +0x13c2430,3, +0x13c2444,3, +0x13c2500,58, +0x13c25f0,3, +0x13c2680,3, +0x13c3018,2, +0x13c3100,2, +0x13c3110,10, +0x13c3140,2, +0x13c3150,10, +0x13c3208,1, +0x13c3220,12, +0x13c3280,1, +0x13c3288,2, +0x13c3400,4, +0x13c4000,2, +0x13c400c,1, +0x13c4030,3, +0x13c4040,2, +0x13c404c,1, +0x13c4070,3, +0x13c4100,2, +0x13c410c,1, +0x13c4130,3, +0x13c4140,2, +0x13c414c,1, +0x13c4170,3, +0x13c4200,15, +0x13c4280,15, +0x13c4300,15, +0x13c4380,15, +0x13c4400,15, +0x13c4480,15, +0x13c4500,15, +0x13c4580,15, +0x13c4604,10, +0x13c4700,2, +0x13c470c,7, +0x13c4740,1, +0x13c4770,1, +0x13c47c0,2, +0x13c47d0,4, +0x13c5000,3, +0x13c5010,1, +0x13c501c,3, +0x13c5104,1, +0x13c5110,4, +0x13c5124,1, +0x13c5130,4, +0x13c5144,1, +0x13c5150,4, +0x13c5164,1, +0x13c5170,5, +0x13c5190,4, +0x13c5a00,4, +0x13c5c00,129, +0x13c6000,37, +0x13c6098,1, +0x13c6100,37, +0x13c6198,1, +0x13c6200,37, +0x13c6298,1, +0x13c6300,37, +0x13c6398,1, +0x13c6400,37, +0x13c6498,1, +0x13c6500,37, +0x13c6598,1, +0x13c6600,37, +0x13c6698,1, +0x13c6700,37, +0x13c6798,1, +0x13cc000,91, +0x13cc400,4, +0x13cc440,15, +0x13cc480,4, +0x13cc4c0,15, +0x13cc500,4, +0x13cc540,15, +0x13cc580,4, +0x13cc5c0,15, +0x13cc600,4, +0x13cc640,10, +0x13cc680,4, +0x13cc6c0,10, +0x13cc800,4, +0x13cc840,33, +0x13cca00,13, +0x13cca80,1, +0x13cca88,8, +0x13ccac0,6, +0x13ccae0,1, +0x13ccae8,2, +0x13ccb04,14, +0x13ccc00,4, +0x13cccc8,1, +0x13ccfcc,3, +0x13ccfe0,99, +0x13cd400,4, +0x13cd440,15, +0x13cd480,4, +0x13cd4c0,15, +0x13cd500,4, +0x13cd540,15, +0x13cd580,4, +0x13cd5c0,15, +0x13cd600,4, +0x13cd640,10, +0x13cd680,4, +0x13cd6c0,10, +0x13cd800,4, +0x13cd840,33, +0x13cda00,13, +0x13cda80,1, +0x13cda88,8, +0x13cdac0,6, +0x13cdae0,1, +0x13cdae8,2, +0x13cdb04,14, +0x13cdc00,4, +0x13cdcc8,1, +0x13cdfcc,3, +0x13cdfe0,27, +0x13cf000,19, +0x13cfa00,10, +0x13cfa80,3, +0x13cfb00,6, +0x13d0000,51, +0x13d0a00,10, +0x13d0a80,3, +0x13d1000,2, +0x13d100c,4, +0x13d1028,3, +0x13d1038,4, +0x13d1050,2, +0x13d1080,4, +0x13d1098,7, +0x13d1120,4, +0x13d1200,4, +0x13d1214,7, +0x13d1234,3, +0x13d1280,8, +0x13d12c0,5, +0x13d1300,2, +0x13d130c,3, +0x13d1400,24, +0x13d1464,2, +0x13d1470,3, +0x13d1500,25, +0x13d15c0,8, +0x13d15e8,5, +0x13d1600,5, +0x13d1618,1, +0x13d1620,1, +0x13d1628,1, +0x13d1630,2, +0x13d1640,2, +0x13d1650,2, +0x13d1690,4, +0x13d1740,2, +0x13d1760,6, +0x13d1780,6, +0x13d17a0,6, +0x13d17c0,6, +0x13d17e0,1, +0x13d1800,2, +0x13d180c,4, +0x13d1828,3, +0x13d1838,4, +0x13d1850,2, +0x13d1880,4, +0x13d1898,7, +0x13d1920,4, +0x13d1a00,4, +0x13d1a14,7, +0x13d1a34,3, +0x13d1a80,8, +0x13d1ac0,5, +0x13d1b00,2, +0x13d1b0c,3, +0x13d1c00,24, +0x13d1c64,2, +0x13d1c70,3, +0x13d1d00,25, +0x13d1dc0,8, +0x13d1de8,5, +0x13d1e00,5, +0x13d1e18,1, +0x13d1e20,1, +0x13d1e28,1, +0x13d1e30,2, +0x13d1e40,2, +0x13d1e50,2, +0x13d1e90,4, +0x13d1f40,2, +0x13d1f60,6, +0x13d1f80,6, +0x13d1fa0,6, +0x13d1fc0,6, +0x13d1fe0,1, +0x13d2000,19, +0x13d2080,2, +0x13d20b0,2, +0x13d20c0,2, +0x13e0000,11, +0x13e0040,16, +0x13e0084,5, +0x13e0200,7, +0x13e0220,6, +0x13e0240,7, +0x13e0260,6, +0x13e0280,6, +0x13e02a0,2, +0x13e02ac,2, +0x13e02c0,7, +0x13e02e0,7, +0x13e0300,2, +0x13e030c,2, +0x13e0320,6, +0x13e0400,2, +0x13e1000,19, +0x13e2104,23, +0x13e2180,7, +0x13e21a0,6, +0x13e21c0,7, +0x13e21e0,6, +0x13e2200,4, +0x13e2220,4, +0x13e2240,11, +0x13e2270,32, +0x13e2300,24, +0x13e2380,20, +0x13e2400,61, +0x13e2500,25, +0x13e2568,4, +0x13e2580,2, +0x13e25a0,1, +0x13e25c0,11, +0x13e2600,9, +0x13e2640,3, +0x13e2650,3, +0x13e2664,3, +0x13e2680,22, +0x13e2800,11, +0x13e3000,536, +0x13e4104,23, +0x13e4180,7, +0x13e41a0,6, +0x13e41c0,7, +0x13e41e0,6, +0x13e4200,4, +0x13e4220,4, +0x13e4240,11, +0x13e4270,32, +0x13e4300,24, +0x13e4380,20, +0x13e4400,61, +0x13e4500,25, +0x13e4568,4, +0x13e4580,2, +0x13e45a0,1, +0x13e45c0,11, +0x13e4600,9, +0x13e4640,3, +0x13e4650,3, +0x13e4664,3, +0x13e4680,22, +0x13e4800,11, +0x13e5000,536, +0x13ea000,7, +0x13ea048,8, +0x13ea080,8, +0x13ea100,7, +0x13ea148,8, +0x13ea180,8, +0x13f0000,11, +0x13f0040,16, +0x13f0084,5, +0x13f0200,7, +0x13f0220,6, +0x13f0240,7, +0x13f0260,6, +0x13f0280,6, +0x13f02a0,2, +0x13f02ac,2, +0x13f02c0,7, +0x13f02e0,7, +0x13f0300,2, +0x13f030c,2, +0x13f0320,6, +0x13f0400,2, +0x13f1000,19, +0x13f2104,23, +0x13f2180,7, +0x13f21a0,6, +0x13f21c0,7, +0x13f21e0,6, +0x13f2200,4, +0x13f2220,4, +0x13f2240,11, +0x13f2270,32, +0x13f2300,24, +0x13f2380,20, +0x13f2400,61, +0x13f2500,25, +0x13f2568,4, +0x13f2580,2, +0x13f25a0,1, +0x13f25c0,11, +0x13f2600,9, +0x13f2640,3, +0x13f2650,3, +0x13f2664,3, +0x13f2680,22, +0x13f2800,11, +0x13f3000,536, +0x13f4104,23, +0x13f4180,7, +0x13f41a0,6, +0x13f41c0,7, +0x13f41e0,6, +0x13f4200,4, +0x13f4220,4, +0x13f4240,11, +0x13f4270,32, +0x13f4300,24, +0x13f4380,20, +0x13f4400,61, +0x13f4500,25, +0x13f4568,4, +0x13f4580,2, +0x13f45a0,1, +0x13f45c0,11, +0x13f4600,9, +0x13f4640,3, +0x13f4650,3, +0x13f4664,3, +0x13f4680,22, +0x13f4800,11, +0x13f5000,536, +0x13fa000,7, +0x13fa048,8, +0x13fa080,8, +0x13fa100,7, +0x13fa148,8, +0x13fa180,8, +0x1400400,4, +0x1400440,4, +0x14005c0,1, +0x1400600,8, +0x1400800,18, +0x1400880,13, +0x14008f0,3, +0x1400900,18, +0x1400980,13, +0x14009f0,3, +0x1400e00,4, +0x1400e20,4, +0x1400e80,16, +0x1400f00,1, +0x1400f20,1, +0x1401020,2, +0x1401208,6, +0x1401228,10, +0x1401288,6, +0x14012a8,10, +0x1401600,32, +0x14018c0,8, +0x1401900,24, +0x14019b0,4, +0x1401aa0,2, +0x1401ac0,4, +0x1402200,19, +0x1402280,19, +0x1402400,14, +0x140243c,9, +0x1402464,14, +0x14024a0,2, +0x14024ac,2, +0x1402500,14, +0x140253c,9, +0x1402564,14, +0x14025a0,2, +0x14025ac,2, +0x1402800,19, +0x1402880,19, +0x1402a10,2, +0x1402a1c,1, +0x1402a50,2, +0x1402a5c,1, +0x1402c00,7, +0x1402c20,1, +0x1402c54,18, +0x1402ca0,1, +0x1402cd4,11, +0x1402e00,1, +0x1402e08,6, +0x1403180,3, +0x1404400,4, +0x1404440,4, +0x14045c0,1, +0x1404600,8, +0x1404800,18, +0x1404880,13, +0x14048f0,3, +0x1404900,18, +0x1404980,13, +0x14049f0,3, +0x1404e00,4, +0x1404e20,4, +0x1404e80,16, +0x1404f00,1, +0x1404f20,1, +0x1405020,2, +0x1405208,6, +0x1405228,10, +0x1405288,6, +0x14052a8,10, +0x1405600,32, +0x14058c0,8, +0x1405900,24, +0x14059b0,4, +0x1405aa0,2, +0x1405ac0,4, +0x1406200,19, +0x1406280,19, +0x1406400,14, +0x140643c,9, +0x1406464,14, +0x14064a0,2, +0x14064ac,2, +0x1406500,14, +0x140653c,9, +0x1406564,14, +0x14065a0,2, +0x14065ac,2, +0x1406800,19, +0x1406880,19, +0x1406a10,2, +0x1406a1c,1, +0x1406a50,2, +0x1406a5c,1, +0x1406c00,7, +0x1406c20,1, +0x1406c54,18, +0x1406ca0,1, +0x1406cd4,11, +0x1406e00,1, +0x1406e08,6, +0x1407180,3, +0x1409000,13, +0x140e000,19, +0x140ea00,10, +0x140ea80,3, +0x140f000,1, +0x140f008,5, +0x140f038,1, +0x140f044,1, +0x140f050,2, +0x140f060,8, +0x140f140,19, +0x140f190,4, +0x1410000,2, +0x141000c,2, +0x1410040,7, +0x1410100,3, +0x1410110,3, +0x1410120,5, +0x1410200,6, +0x1410240,5, +0x1410400,2, +0x141040c,2, +0x1410440,7, +0x1410500,3, +0x1410510,3, +0x1410520,5, +0x1410600,6, +0x1410640,5, +0x1410800,2, +0x141080c,2, +0x1410840,7, +0x1410900,3, +0x1410910,3, +0x1410920,5, +0x1410a00,6, +0x1410a40,5, +0x1410c00,2, +0x1410c0c,2, +0x1410c40,7, +0x1410d00,3, +0x1410d10,3, +0x1410d20,5, +0x1410e00,6, +0x1410e40,5, +0x1411000,2, +0x141100c,2, +0x1411040,7, +0x1411100,3, +0x1411110,3, +0x1411120,5, +0x1411200,6, +0x1411240,5, +0x1411400,2, +0x141140c,2, +0x1411440,7, +0x1411500,3, +0x1411510,3, +0x1411520,5, +0x1411600,6, +0x1411640,5, +0x1411800,2, +0x141180c,2, +0x1411840,7, +0x1411900,3, +0x1411910,3, +0x1411920,5, +0x1411a00,6, +0x1411a40,5, +0x1411c00,2, +0x1411c0c,2, +0x1411c40,7, +0x1411d00,3, +0x1411d10,3, +0x1411d20,5, +0x1411e00,6, +0x1411e40,5, +0x1412000,5, +0x1412040,9, +0x1412100,3, +0x1412200,1, +0x1412210,1, +0x1412220,1, +0x1412230,1, +0x1412240,1, +0x1412300,3, +0x1412314,1, +0x1412320,4, +0x1412400,5, +0x1412440,5, +0x1413000,80, +0x1413200,1, +0x1418000,7, +0x1418030,2, +0x1418040,7, +0x1418070,2, +0x1418100,2, +0x1418120,2, +0x1418140,2, +0x1418160,2, +0x1418180,9, +0x1418200,7, +0x1418230,2, +0x1418240,7, +0x1418270,2, +0x1418300,2, +0x1418320,2, +0x1418340,2, +0x1418360,2, +0x1418380,9, +0x1418400,11, +0x1418500,11, +0x1419000,3, +0x1419010,2, +0x141901c,5, +0x1419040,8, +0x1419080,3, +0x1419090,2, +0x141909c,5, +0x14190c0,8, +0x1419100,3, +0x1419110,2, +0x141911c,5, +0x1419140,8, +0x1419180,3, +0x1419190,2, +0x141919c,5, +0x14191c0,8, +0x1419200,7, +0x1419220,12, +0x1419280,7, +0x14192a0,12, +0x1419300,3, +0x1419310,1, +0x1419400,3, +0x1419410,2, +0x141941c,5, +0x1419440,8, +0x1419480,3, +0x1419490,2, +0x141949c,5, +0x14194c0,8, +0x1419500,3, +0x1419510,2, +0x141951c,5, +0x1419540,8, +0x1419580,3, +0x1419590,2, +0x141959c,5, +0x14195c0,8, +0x1419600,7, +0x1419620,12, +0x1419680,7, +0x14196a0,12, +0x1419700,3, +0x1419710,1, +0x1419804,1, +0x1419824,21, +0x1419880,16, +0x1419900,5, +0x1419920,11, +0x1419950,9, +0x1419980,22, +0x1419a00,22, +0x1419a80,22, +0x1419b00,22, +0x1419b80,22, +0x1419c00,22, +0x1419c80,22, +0x1419d00,22, +0x1419d80,3, +0x1420000,5, +0x1420018,5, +0x1420030,3, +0x1420044,3, +0x1420100,58, +0x14201f0,3, +0x1420280,3, +0x1420400,5, +0x1420418,5, +0x1420430,3, +0x1420444,3, +0x1420500,58, +0x14205f0,3, +0x1420680,3, +0x1421018,2, +0x1421100,2, +0x1421110,10, +0x1421140,2, +0x1421150,10, +0x1421208,1, +0x1421220,12, +0x1421280,1, +0x1421288,2, +0x1421400,4, +0x1422000,5, +0x1422018,5, +0x1422030,3, +0x1422044,3, +0x1422100,58, +0x14221f0,3, +0x1422280,3, +0x1422400,5, +0x1422418,5, +0x1422430,3, +0x1422444,3, +0x1422500,58, +0x14225f0,3, +0x1422680,3, +0x1423018,2, +0x1423100,2, +0x1423110,10, +0x1423140,2, +0x1423150,10, +0x1423208,1, +0x1423220,12, +0x1423280,1, +0x1423288,2, +0x1423400,4, +0x1424000,2, +0x142400c,1, +0x1424030,3, +0x1424040,2, +0x142404c,1, +0x1424070,3, +0x1424100,2, +0x142410c,1, +0x1424130,3, +0x1424140,2, +0x142414c,1, +0x1424170,3, +0x1424200,15, +0x1424280,15, +0x1424300,15, +0x1424380,15, +0x1424400,15, +0x1424480,15, +0x1424500,15, +0x1424580,15, +0x1424604,10, +0x1424700,2, +0x142470c,7, +0x1424740,1, +0x1424770,1, +0x14247c0,2, +0x14247d0,4, +0x1425000,3, +0x1425010,1, +0x142501c,3, +0x1425104,1, +0x1425110,4, +0x1425124,1, +0x1425130,4, +0x1425144,1, +0x1425150,4, +0x1425164,1, +0x1425170,5, +0x1425190,4, +0x1425a00,4, +0x1425c00,129, +0x1426000,37, +0x1426098,1, +0x1426100,37, +0x1426198,1, +0x1426200,37, +0x1426298,1, +0x1426300,37, +0x1426398,1, +0x1426400,37, +0x1426498,1, +0x1426500,37, +0x1426598,1, +0x1426600,37, +0x1426698,1, +0x1426700,37, +0x1426798,1, +0x142c000,91, +0x142c400,4, +0x142c440,15, +0x142c480,4, +0x142c4c0,15, +0x142c500,4, +0x142c540,15, +0x142c580,4, +0x142c5c0,15, +0x142c600,4, +0x142c640,10, +0x142c680,4, +0x142c6c0,10, +0x142c800,4, +0x142c840,33, +0x142ca00,13, +0x142ca80,1, +0x142ca88,8, +0x142cac0,6, +0x142cae0,1, +0x142cae8,2, +0x142cb04,14, +0x142cc00,4, +0x142ccc8,1, +0x142cfcc,3, +0x142cfe0,99, +0x142d400,4, +0x142d440,15, +0x142d480,4, +0x142d4c0,15, +0x142d500,4, +0x142d540,15, +0x142d580,4, +0x142d5c0,15, +0x142d600,4, +0x142d640,10, +0x142d680,4, +0x142d6c0,10, +0x142d800,4, +0x142d840,33, +0x142da00,13, +0x142da80,1, +0x142da88,8, +0x142dac0,6, +0x142dae0,1, +0x142dae8,2, +0x142db04,14, +0x142dc00,4, +0x142dcc8,1, +0x142dfcc,3, +0x142dfe0,27, +0x142f000,19, +0x142fa00,10, +0x142fa80,3, +0x142fb00,6, +0x1430000,51, +0x1430a00,10, +0x1430a80,3, +0x1431000,2, +0x143100c,4, +0x1431028,3, +0x1431038,4, +0x1431050,2, +0x1431080,4, +0x1431098,7, +0x1431120,4, +0x1431200,4, +0x1431214,7, +0x1431234,3, +0x1431280,8, +0x14312c0,5, +0x1431300,2, +0x143130c,3, +0x1431400,24, +0x1431464,2, +0x1431470,3, +0x1431500,25, +0x14315c0,8, +0x14315e8,5, +0x1431600,5, +0x1431618,1, +0x1431620,1, +0x1431628,1, +0x1431630,2, +0x1431640,2, +0x1431650,2, +0x1431690,4, +0x1431740,2, +0x1431760,6, +0x1431780,6, +0x14317a0,6, +0x14317c0,6, +0x14317e0,1, +0x1431800,2, +0x143180c,4, +0x1431828,3, +0x1431838,4, +0x1431850,2, +0x1431880,4, +0x1431898,7, +0x1431920,4, +0x1431a00,4, +0x1431a14,7, +0x1431a34,3, +0x1431a80,8, +0x1431ac0,5, +0x1431b00,2, +0x1431b0c,3, +0x1431c00,24, +0x1431c64,2, +0x1431c70,3, +0x1431d00,25, +0x1431dc0,8, +0x1431de8,5, +0x1431e00,5, +0x1431e18,1, +0x1431e20,1, +0x1431e28,1, +0x1431e30,2, +0x1431e40,2, +0x1431e50,2, +0x1431e90,4, +0x1431f40,2, +0x1431f60,6, +0x1431f80,6, +0x1431fa0,6, +0x1431fc0,6, +0x1431fe0,1, +0x1432000,19, +0x1432080,2, +0x14320b0,2, +0x14320c0,2, +0x1440000,11, +0x1440040,16, +0x1440084,5, +0x1440200,7, +0x1440220,6, +0x1440240,7, +0x1440260,6, +0x1440280,6, +0x14402a0,2, +0x14402ac,2, +0x14402c0,7, +0x14402e0,7, +0x1440300,2, +0x144030c,2, +0x1440320,6, +0x1440400,2, +0x1441000,19, +0x1442104,23, +0x1442180,7, +0x14421a0,6, +0x14421c0,7, +0x14421e0,6, +0x1442200,4, +0x1442220,4, +0x1442240,11, +0x1442270,32, +0x1442300,24, +0x1442380,20, +0x1442400,61, +0x1442500,25, +0x1442568,4, +0x1442580,2, +0x14425a0,1, +0x14425c0,11, +0x1442600,9, +0x1442640,3, +0x1442650,3, +0x1442664,3, +0x1442680,22, +0x1442800,11, +0x1443000,536, +0x1444104,23, +0x1444180,7, +0x14441a0,6, +0x14441c0,7, +0x14441e0,6, +0x1444200,4, +0x1444220,4, +0x1444240,11, +0x1444270,32, +0x1444300,24, +0x1444380,20, +0x1444400,61, +0x1444500,25, +0x1444568,4, +0x1444580,2, +0x14445a0,1, +0x14445c0,11, +0x1444600,9, +0x1444640,3, +0x1444650,3, +0x1444664,3, +0x1444680,22, +0x1444800,11, +0x1445000,536, +0x144a000,7, +0x144a048,8, +0x144a080,8, +0x144a100,7, +0x144a148,8, +0x144a180,8, +0x1450000,11, +0x1450040,16, +0x1450084,5, +0x1450200,7, +0x1450220,6, +0x1450240,7, +0x1450260,6, +0x1450280,6, +0x14502a0,2, +0x14502ac,2, +0x14502c0,7, +0x14502e0,7, +0x1450300,2, +0x145030c,2, +0x1450320,6, +0x1450400,2, +0x1451000,19, +0x1452104,23, +0x1452180,7, +0x14521a0,6, +0x14521c0,7, +0x14521e0,6, +0x1452200,4, +0x1452220,4, +0x1452240,11, +0x1452270,32, +0x1452300,24, +0x1452380,20, +0x1452400,61, +0x1452500,25, +0x1452568,4, +0x1452580,2, +0x14525a0,1, +0x14525c0,11, +0x1452600,9, +0x1452640,3, +0x1452650,3, +0x1452664,3, +0x1452680,22, +0x1452800,11, +0x1453000,536, +0x1454104,23, +0x1454180,7, +0x14541a0,6, +0x14541c0,7, +0x14541e0,6, +0x1454200,4, +0x1454220,4, +0x1454240,11, +0x1454270,32, +0x1454300,24, +0x1454380,20, +0x1454400,61, +0x1454500,25, +0x1454568,4, +0x1454580,2, +0x14545a0,1, +0x14545c0,11, +0x1454600,9, +0x1454640,3, +0x1454650,3, +0x1454664,3, +0x1454680,22, +0x1454800,11, +0x1455000,536, +0x145a000,7, +0x145a048,8, +0x145a080,8, +0x145a100,7, +0x145a148,8, +0x145a180,8, +0x1460400,4, +0x1460440,4, +0x14605c0,1, +0x1460600,8, +0x1460800,18, +0x1460880,13, +0x14608f0,3, +0x1460900,18, +0x1460980,13, +0x14609f0,3, +0x1460e00,4, +0x1460e20,4, +0x1460e80,16, +0x1460f00,1, +0x1460f20,1, +0x1461020,2, +0x1461208,6, +0x1461228,10, +0x1461288,6, +0x14612a8,10, +0x1461600,32, +0x14618c0,8, +0x1461900,24, +0x14619b0,4, +0x1461aa0,2, +0x1461ac0,4, +0x1462200,19, +0x1462280,19, +0x1462400,14, +0x146243c,9, +0x1462464,14, +0x14624a0,2, +0x14624ac,2, +0x1462500,14, +0x146253c,9, +0x1462564,14, +0x14625a0,2, +0x14625ac,2, +0x1462800,19, +0x1462880,19, +0x1462a10,2, +0x1462a1c,1, +0x1462a50,2, +0x1462a5c,1, +0x1462c00,7, +0x1462c20,1, +0x1462c54,18, +0x1462ca0,1, +0x1462cd4,11, +0x1462e00,1, +0x1462e08,6, +0x1463180,3, +0x1464400,4, +0x1464440,4, +0x14645c0,1, +0x1464600,8, +0x1464800,18, +0x1464880,13, +0x14648f0,3, +0x1464900,18, +0x1464980,13, +0x14649f0,3, +0x1464e00,4, +0x1464e20,4, +0x1464e80,16, +0x1464f00,1, +0x1464f20,1, +0x1465020,2, +0x1465208,6, +0x1465228,10, +0x1465288,6, +0x14652a8,10, +0x1465600,32, +0x14658c0,8, +0x1465900,24, +0x14659b0,4, +0x1465aa0,2, +0x1465ac0,4, +0x1466200,19, +0x1466280,19, +0x1466400,14, +0x146643c,9, +0x1466464,14, +0x14664a0,2, +0x14664ac,2, +0x1466500,14, +0x146653c,9, +0x1466564,14, +0x14665a0,2, +0x14665ac,2, +0x1466800,19, +0x1466880,19, +0x1466a10,2, +0x1466a1c,1, +0x1466a50,2, +0x1466a5c,1, +0x1466c00,7, +0x1466c20,1, +0x1466c54,18, +0x1466ca0,1, +0x1466cd4,11, +0x1466e00,1, +0x1466e08,6, +0x1467180,3, +0x1469000,13, +0x146e000,19, +0x146ea00,10, +0x146ea80,3, +0x146f000,1, +0x146f008,5, +0x146f038,1, +0x146f044,1, +0x146f050,2, +0x146f060,8, +0x146f140,19, +0x146f190,4, +0x1470000,2, +0x147000c,2, +0x1470040,7, +0x1470100,3, +0x1470110,3, +0x1470120,5, +0x1470200,6, +0x1470240,5, +0x1470400,2, +0x147040c,2, +0x1470440,7, +0x1470500,3, +0x1470510,3, +0x1470520,5, +0x1470600,6, +0x1470640,5, +0x1470800,2, +0x147080c,2, +0x1470840,7, +0x1470900,3, +0x1470910,3, +0x1470920,5, +0x1470a00,6, +0x1470a40,5, +0x1470c00,2, +0x1470c0c,2, +0x1470c40,7, +0x1470d00,3, +0x1470d10,3, +0x1470d20,5, +0x1470e00,6, +0x1470e40,5, +0x1471000,2, +0x147100c,2, +0x1471040,7, +0x1471100,3, +0x1471110,3, +0x1471120,5, +0x1471200,6, +0x1471240,5, +0x1471400,2, +0x147140c,2, +0x1471440,7, +0x1471500,3, +0x1471510,3, +0x1471520,5, +0x1471600,6, +0x1471640,5, +0x1471800,2, +0x147180c,2, +0x1471840,7, +0x1471900,3, +0x1471910,3, +0x1471920,5, +0x1471a00,6, +0x1471a40,5, +0x1471c00,2, +0x1471c0c,2, +0x1471c40,7, +0x1471d00,3, +0x1471d10,3, +0x1471d20,5, +0x1471e00,6, +0x1471e40,5, +0x1472000,5, +0x1472040,9, +0x1472100,3, +0x1472200,1, +0x1472210,1, +0x1472220,1, +0x1472230,1, +0x1472240,1, +0x1472300,3, +0x1472314,1, +0x1472320,4, +0x1472400,5, +0x1472440,5, +0x1473000,80, +0x1473200,1, +0x1478000,7, +0x1478030,2, +0x1478040,7, +0x1478070,2, +0x1478100,2, +0x1478120,2, +0x1478140,2, +0x1478160,2, +0x1478180,9, +0x1478200,7, +0x1478230,2, +0x1478240,7, +0x1478270,2, +0x1478300,2, +0x1478320,2, +0x1478340,2, +0x1478360,2, +0x1478380,9, +0x1478400,11, +0x1478500,11, +0x1479000,3, +0x1479010,2, +0x147901c,5, +0x1479040,8, +0x1479080,3, +0x1479090,2, +0x147909c,5, +0x14790c0,8, +0x1479100,3, +0x1479110,2, +0x147911c,5, +0x1479140,8, +0x1479180,3, +0x1479190,2, +0x147919c,5, +0x14791c0,8, +0x1479200,7, +0x1479220,12, +0x1479280,7, +0x14792a0,12, +0x1479300,3, +0x1479310,1, +0x1479400,3, +0x1479410,2, +0x147941c,5, +0x1479440,8, +0x1479480,3, +0x1479490,2, +0x147949c,5, +0x14794c0,8, +0x1479500,3, +0x1479510,2, +0x147951c,5, +0x1479540,8, +0x1479580,3, +0x1479590,2, +0x147959c,5, +0x14795c0,8, +0x1479600,7, +0x1479620,12, +0x1479680,7, +0x14796a0,12, +0x1479700,3, +0x1479710,1, +0x1479804,1, +0x1479824,21, +0x1479880,16, +0x1479900,5, +0x1479920,11, +0x1479950,9, +0x1479980,22, +0x1479a00,22, +0x1479a80,22, +0x1479b00,22, +0x1479b80,22, +0x1479c00,22, +0x1479c80,22, +0x1479d00,22, +0x1479d80,3, +0x1480000,5, +0x1480018,5, +0x1480030,3, +0x1480044,3, +0x1480100,58, +0x14801f0,3, +0x1480280,3, +0x1480400,5, +0x1480418,5, +0x1480430,3, +0x1480444,3, +0x1480500,58, +0x14805f0,3, +0x1480680,3, +0x1481018,2, +0x1481100,2, +0x1481110,10, +0x1481140,2, +0x1481150,10, +0x1481208,1, +0x1481220,12, +0x1481280,1, +0x1481288,2, +0x1481400,4, +0x1482000,5, +0x1482018,5, +0x1482030,3, +0x1482044,3, +0x1482100,58, +0x14821f0,3, +0x1482280,3, +0x1482400,5, +0x1482418,5, +0x1482430,3, +0x1482444,3, +0x1482500,58, +0x14825f0,3, +0x1482680,3, +0x1483018,2, +0x1483100,2, +0x1483110,10, +0x1483140,2, +0x1483150,10, +0x1483208,1, +0x1483220,12, +0x1483280,1, +0x1483288,2, +0x1483400,4, +0x1484000,2, +0x148400c,1, +0x1484030,3, +0x1484040,2, +0x148404c,1, +0x1484070,3, +0x1484100,2, +0x148410c,1, +0x1484130,3, +0x1484140,2, +0x148414c,1, +0x1484170,3, +0x1484200,15, +0x1484280,15, +0x1484300,15, +0x1484380,15, +0x1484400,15, +0x1484480,15, +0x1484500,15, +0x1484580,15, +0x1484604,10, +0x1484700,2, +0x148470c,7, +0x1484740,1, +0x1484770,1, +0x14847c0,2, +0x14847d0,4, +0x1485000,3, +0x1485010,1, +0x148501c,3, +0x1485104,1, +0x1485110,4, +0x1485124,1, +0x1485130,4, +0x1485144,1, +0x1485150,4, +0x1485164,1, +0x1485170,5, +0x1485190,4, +0x1485a00,4, +0x1485c00,129, +0x1486000,37, +0x1486098,1, +0x1486100,37, +0x1486198,1, +0x1486200,37, +0x1486298,1, +0x1486300,37, +0x1486398,1, +0x1486400,37, +0x1486498,1, +0x1486500,37, +0x1486598,1, +0x1486600,37, +0x1486698,1, +0x1486700,37, +0x1486798,1, +0x148c000,91, +0x148c400,4, +0x148c440,15, +0x148c480,4, +0x148c4c0,15, +0x148c500,4, +0x148c540,15, +0x148c580,4, +0x148c5c0,15, +0x148c600,4, +0x148c640,10, +0x148c680,4, +0x148c6c0,10, +0x148c800,4, +0x148c840,33, +0x148ca00,13, +0x148ca80,1, +0x148ca88,8, +0x148cac0,6, +0x148cae0,1, +0x148cae8,2, +0x148cb04,14, +0x148cc00,4, +0x148ccc8,1, +0x148cfcc,3, +0x148cfe0,99, +0x148d400,4, +0x148d440,15, +0x148d480,4, +0x148d4c0,15, +0x148d500,4, +0x148d540,15, +0x148d580,4, +0x148d5c0,15, +0x148d600,4, +0x148d640,10, +0x148d680,4, +0x148d6c0,10, +0x148d800,4, +0x148d840,33, +0x148da00,13, +0x148da80,1, +0x148da88,8, +0x148dac0,6, +0x148dae0,1, +0x148dae8,2, +0x148db04,14, +0x148dc00,4, +0x148dcc8,1, +0x148dfcc,3, +0x148dfe0,27, +0x148f000,19, +0x148fa00,10, +0x148fa80,3, +0x148fb00,6, +0x1490000,51, +0x1490a00,10, +0x1490a80,3, +0x1491000,2, +0x149100c,4, +0x1491028,3, +0x1491038,4, +0x1491050,2, +0x1491080,4, +0x1491098,7, +0x1491120,4, +0x1491200,4, +0x1491214,7, +0x1491234,3, +0x1491280,8, +0x14912c0,5, +0x1491300,2, +0x149130c,3, +0x1491400,24, +0x1491464,2, +0x1491470,3, +0x1491500,25, +0x14915c0,8, +0x14915e8,5, +0x1491600,5, +0x1491618,1, +0x1491620,1, +0x1491628,1, +0x1491630,2, +0x1491640,2, +0x1491650,2, +0x1491690,4, +0x1491740,2, +0x1491760,6, +0x1491780,6, +0x14917a0,6, +0x14917c0,6, +0x14917e0,1, +0x1491800,2, +0x149180c,4, +0x1491828,3, +0x1491838,4, +0x1491850,2, +0x1491880,4, +0x1491898,7, +0x1491920,4, +0x1491a00,4, +0x1491a14,7, +0x1491a34,3, +0x1491a80,8, +0x1491ac0,5, +0x1491b00,2, +0x1491b0c,3, +0x1491c00,24, +0x1491c64,2, +0x1491c70,3, +0x1491d00,25, +0x1491dc0,8, +0x1491de8,5, +0x1491e00,5, +0x1491e18,1, +0x1491e20,1, +0x1491e28,1, +0x1491e30,2, +0x1491e40,2, +0x1491e50,2, +0x1491e90,4, +0x1491f40,2, +0x1491f60,6, +0x1491f80,6, +0x1491fa0,6, +0x1491fc0,6, +0x1491fe0,1, +0x1492000,19, +0x1492080,2, +0x14920b0,2, +0x14920c0,2, +0x14a0000,11, +0x14a0040,16, +0x14a0084,5, +0x14a0200,7, +0x14a0220,6, +0x14a0240,7, +0x14a0260,6, +0x14a0280,6, +0x14a02a0,2, +0x14a02ac,2, +0x14a02c0,7, +0x14a02e0,7, +0x14a0300,2, +0x14a030c,2, +0x14a0320,6, +0x14a0400,2, +0x14a1000,19, +0x14a2104,23, +0x14a2180,7, +0x14a21a0,6, +0x14a21c0,7, +0x14a21e0,6, +0x14a2200,4, +0x14a2220,4, +0x14a2240,11, +0x14a2270,32, +0x14a2300,24, +0x14a2380,20, +0x14a2400,61, +0x14a2500,25, +0x14a2568,4, +0x14a2580,2, +0x14a25a0,1, +0x14a25c0,11, +0x14a2600,9, +0x14a2640,3, +0x14a2650,3, +0x14a2664,3, +0x14a2680,22, +0x14a2800,11, +0x14a3000,536, +0x14a4104,23, +0x14a4180,7, +0x14a41a0,6, +0x14a41c0,7, +0x14a41e0,6, +0x14a4200,4, +0x14a4220,4, +0x14a4240,11, +0x14a4270,32, +0x14a4300,24, +0x14a4380,20, +0x14a4400,61, +0x14a4500,25, +0x14a4568,4, +0x14a4580,2, +0x14a45a0,1, +0x14a45c0,11, +0x14a4600,9, +0x14a4640,3, +0x14a4650,3, +0x14a4664,3, +0x14a4680,22, +0x14a4800,11, +0x14a5000,536, +0x14aa000,7, +0x14aa048,8, +0x14aa080,8, +0x14aa100,7, +0x14aa148,8, +0x14aa180,8, +0x14b0000,11, +0x14b0040,16, +0x14b0084,5, +0x14b0200,7, +0x14b0220,6, +0x14b0240,7, +0x14b0260,6, +0x14b0280,6, +0x14b02a0,2, +0x14b02ac,2, +0x14b02c0,7, +0x14b02e0,7, +0x14b0300,2, +0x14b030c,2, +0x14b0320,6, +0x14b0400,2, +0x14b1000,19, +0x14b2104,23, +0x14b2180,7, +0x14b21a0,6, +0x14b21c0,7, +0x14b21e0,6, +0x14b2200,4, +0x14b2220,4, +0x14b2240,11, +0x14b2270,32, +0x14b2300,24, +0x14b2380,20, +0x14b2400,61, +0x14b2500,25, +0x14b2568,4, +0x14b2580,2, +0x14b25a0,1, +0x14b25c0,11, +0x14b2600,9, +0x14b2640,3, +0x14b2650,3, +0x14b2664,3, +0x14b2680,22, +0x14b2800,11, +0x14b3000,536, +0x14b4104,23, +0x14b4180,7, +0x14b41a0,6, +0x14b41c0,7, +0x14b41e0,6, +0x14b4200,4, +0x14b4220,4, +0x14b4240,11, +0x14b4270,32, +0x14b4300,24, +0x14b4380,20, +0x14b4400,61, +0x14b4500,25, +0x14b4568,4, +0x14b4580,2, +0x14b45a0,1, +0x14b45c0,11, +0x14b4600,9, +0x14b4640,3, +0x14b4650,3, +0x14b4664,3, +0x14b4680,22, +0x14b4800,11, +0x14b5000,536, +0x14ba000,7, +0x14ba048,8, +0x14ba080,8, +0x14ba100,7, +0x14ba148,8, +0x14ba180,8, +0x14c0400,4, +0x14c0440,4, +0x14c05c0,1, +0x14c0600,8, +0x14c0800,18, +0x14c0880,13, +0x14c08f0,3, +0x14c0900,18, +0x14c0980,13, +0x14c09f0,3, +0x14c0e00,4, +0x14c0e20,4, +0x14c0e80,16, +0x14c0f00,1, +0x14c0f20,1, +0x14c1020,2, +0x14c1208,6, +0x14c1228,10, +0x14c1288,6, +0x14c12a8,10, +0x14c1600,32, +0x14c18c0,8, +0x14c1900,24, +0x14c19b0,4, +0x14c1aa0,2, +0x14c1ac0,4, +0x14c2200,19, +0x14c2280,19, +0x14c2400,14, +0x14c243c,9, +0x14c2464,14, +0x14c24a0,2, +0x14c24ac,2, +0x14c2500,14, +0x14c253c,9, +0x14c2564,14, +0x14c25a0,2, +0x14c25ac,2, +0x14c2800,19, +0x14c2880,19, +0x14c2a10,2, +0x14c2a1c,1, +0x14c2a50,2, +0x14c2a5c,1, +0x14c2c00,7, +0x14c2c20,1, +0x14c2c54,18, +0x14c2ca0,1, +0x14c2cd4,11, +0x14c2e00,1, +0x14c2e08,6, +0x14c3180,3, +0x14c4400,4, +0x14c4440,4, +0x14c45c0,1, +0x14c4600,8, +0x14c4800,18, +0x14c4880,13, +0x14c48f0,3, +0x14c4900,18, +0x14c4980,13, +0x14c49f0,3, +0x14c4e00,4, +0x14c4e20,4, +0x14c4e80,16, +0x14c4f00,1, +0x14c4f20,1, +0x14c5020,2, +0x14c5208,6, +0x14c5228,10, +0x14c5288,6, +0x14c52a8,10, +0x14c5600,32, +0x14c58c0,8, +0x14c5900,24, +0x14c59b0,4, +0x14c5aa0,2, +0x14c5ac0,4, +0x14c6200,19, +0x14c6280,19, +0x14c6400,14, +0x14c643c,9, +0x14c6464,14, +0x14c64a0,2, +0x14c64ac,2, +0x14c6500,14, +0x14c653c,9, +0x14c6564,14, +0x14c65a0,2, +0x14c65ac,2, +0x14c6800,19, +0x14c6880,19, +0x14c6a10,2, +0x14c6a1c,1, +0x14c6a50,2, +0x14c6a5c,1, +0x14c6c00,7, +0x14c6c20,1, +0x14c6c54,18, +0x14c6ca0,1, +0x14c6cd4,11, +0x14c6e00,1, +0x14c6e08,6, +0x14c7180,3, +0x14c9000,13, +0x14ce000,19, +0x14cea00,10, +0x14cea80,3, +0x14cf000,1, +0x14cf008,5, +0x14cf038,1, +0x14cf044,1, +0x14cf050,2, +0x14cf060,8, +0x14cf140,19, +0x14cf190,4, +0x14d0000,2, +0x14d000c,2, +0x14d0040,7, +0x14d0100,3, +0x14d0110,3, +0x14d0120,5, +0x14d0200,6, +0x14d0240,5, +0x14d0400,2, +0x14d040c,2, +0x14d0440,7, +0x14d0500,3, +0x14d0510,3, +0x14d0520,5, +0x14d0600,6, +0x14d0640,5, +0x14d0800,2, +0x14d080c,2, +0x14d0840,7, +0x14d0900,3, +0x14d0910,3, +0x14d0920,5, +0x14d0a00,6, +0x14d0a40,5, +0x14d0c00,2, +0x14d0c0c,2, +0x14d0c40,7, +0x14d0d00,3, +0x14d0d10,3, +0x14d0d20,5, +0x14d0e00,6, +0x14d0e40,5, +0x14d1000,2, +0x14d100c,2, +0x14d1040,7, +0x14d1100,3, +0x14d1110,3, +0x14d1120,5, +0x14d1200,6, +0x14d1240,5, +0x14d1400,2, +0x14d140c,2, +0x14d1440,7, +0x14d1500,3, +0x14d1510,3, +0x14d1520,5, +0x14d1600,6, +0x14d1640,5, +0x14d1800,2, +0x14d180c,2, +0x14d1840,7, +0x14d1900,3, +0x14d1910,3, +0x14d1920,5, +0x14d1a00,6, +0x14d1a40,5, +0x14d1c00,2, +0x14d1c0c,2, +0x14d1c40,7, +0x14d1d00,3, +0x14d1d10,3, +0x14d1d20,5, +0x14d1e00,6, +0x14d1e40,5, +0x14d2000,5, +0x14d2040,9, +0x14d2100,3, +0x14d2200,1, +0x14d2210,1, +0x14d2220,1, +0x14d2230,1, +0x14d2240,1, +0x14d2300,3, +0x14d2314,1, +0x14d2320,4, +0x14d2400,5, +0x14d2440,5, +0x14d3000,80, +0x14d3200,1, +0x14d8000,7, +0x14d8030,2, +0x14d8040,7, +0x14d8070,2, +0x14d8100,2, +0x14d8120,2, +0x14d8140,2, +0x14d8160,2, +0x14d8180,9, +0x14d8200,7, +0x14d8230,2, +0x14d8240,7, +0x14d8270,2, +0x14d8300,2, +0x14d8320,2, +0x14d8340,2, +0x14d8360,2, +0x14d8380,9, +0x14d8400,11, +0x14d8500,11, +0x14d9000,3, +0x14d9010,2, +0x14d901c,5, +0x14d9040,8, +0x14d9080,3, +0x14d9090,2, +0x14d909c,5, +0x14d90c0,8, +0x14d9100,3, +0x14d9110,2, +0x14d911c,5, +0x14d9140,8, +0x14d9180,3, +0x14d9190,2, +0x14d919c,5, +0x14d91c0,8, +0x14d9200,7, +0x14d9220,12, +0x14d9280,7, +0x14d92a0,12, +0x14d9300,3, +0x14d9310,1, +0x14d9400,3, +0x14d9410,2, +0x14d941c,5, +0x14d9440,8, +0x14d9480,3, +0x14d9490,2, +0x14d949c,5, +0x14d94c0,8, +0x14d9500,3, +0x14d9510,2, +0x14d951c,5, +0x14d9540,8, +0x14d9580,3, +0x14d9590,2, +0x14d959c,5, +0x14d95c0,8, +0x14d9600,7, +0x14d9620,12, +0x14d9680,7, +0x14d96a0,12, +0x14d9700,3, +0x14d9710,1, +0x14d9804,1, +0x14d9824,21, +0x14d9880,16, +0x14d9900,5, +0x14d9920,11, +0x14d9950,9, +0x14d9980,22, +0x14d9a00,22, +0x14d9a80,22, +0x14d9b00,22, +0x14d9b80,22, +0x14d9c00,22, +0x14d9c80,22, +0x14d9d00,22, +0x14d9d80,3, +0x14e0000,5, +0x14e0018,5, +0x14e0030,3, +0x14e0044,3, +0x14e0100,58, +0x14e01f0,3, +0x14e0280,3, +0x14e0400,5, +0x14e0418,5, +0x14e0430,3, +0x14e0444,3, +0x14e0500,58, +0x14e05f0,3, +0x14e0680,3, +0x14e1018,2, +0x14e1100,2, +0x14e1110,10, +0x14e1140,2, +0x14e1150,10, +0x14e1208,1, +0x14e1220,12, +0x14e1280,1, +0x14e1288,2, +0x14e1400,4, +0x14e2000,5, +0x14e2018,5, +0x14e2030,3, +0x14e2044,3, +0x14e2100,58, +0x14e21f0,3, +0x14e2280,3, +0x14e2400,5, +0x14e2418,5, +0x14e2430,3, +0x14e2444,3, +0x14e2500,58, +0x14e25f0,3, +0x14e2680,3, +0x14e3018,2, +0x14e3100,2, +0x14e3110,10, +0x14e3140,2, +0x14e3150,10, +0x14e3208,1, +0x14e3220,12, +0x14e3280,1, +0x14e3288,2, +0x14e3400,4, +0x14e4000,2, +0x14e400c,1, +0x14e4030,3, +0x14e4040,2, +0x14e404c,1, +0x14e4070,3, +0x14e4100,2, +0x14e410c,1, +0x14e4130,3, +0x14e4140,2, +0x14e414c,1, +0x14e4170,3, +0x14e4200,15, +0x14e4280,15, +0x14e4300,15, +0x14e4380,15, +0x14e4400,15, +0x14e4480,15, +0x14e4500,15, +0x14e4580,15, +0x14e4604,10, +0x14e4700,2, +0x14e470c,7, +0x14e4740,1, +0x14e4770,1, +0x14e47c0,2, +0x14e47d0,4, +0x14e5000,3, +0x14e5010,1, +0x14e501c,3, +0x14e5104,1, +0x14e5110,4, +0x14e5124,1, +0x14e5130,4, +0x14e5144,1, +0x14e5150,4, +0x14e5164,1, +0x14e5170,5, +0x14e5190,4, +0x14e5a00,4, +0x14e5c00,129, +0x14e6000,37, +0x14e6098,1, +0x14e6100,37, +0x14e6198,1, +0x14e6200,37, +0x14e6298,1, +0x14e6300,37, +0x14e6398,1, +0x14e6400,37, +0x14e6498,1, +0x14e6500,37, +0x14e6598,1, +0x14e6600,37, +0x14e6698,1, +0x14e6700,37, +0x14e6798,1, +0x14ec000,91, +0x14ec400,4, +0x14ec440,15, +0x14ec480,4, +0x14ec4c0,15, +0x14ec500,4, +0x14ec540,15, +0x14ec580,4, +0x14ec5c0,15, +0x14ec600,4, +0x14ec640,10, +0x14ec680,4, +0x14ec6c0,10, +0x14ec800,4, +0x14ec840,33, +0x14eca00,13, +0x14eca80,1, +0x14eca88,8, +0x14ecac0,6, +0x14ecae0,1, +0x14ecae8,2, +0x14ecb04,14, +0x14ecc00,4, +0x14eccc8,1, +0x14ecfcc,3, +0x14ecfe0,99, +0x14ed400,4, +0x14ed440,15, +0x14ed480,4, +0x14ed4c0,15, +0x14ed500,4, +0x14ed540,15, +0x14ed580,4, +0x14ed5c0,15, +0x14ed600,4, +0x14ed640,10, +0x14ed680,4, +0x14ed6c0,10, +0x14ed800,4, +0x14ed840,33, +0x14eda00,13, +0x14eda80,1, +0x14eda88,8, +0x14edac0,6, +0x14edae0,1, +0x14edae8,2, +0x14edb04,14, +0x14edc00,4, +0x14edcc8,1, +0x14edfcc,3, +0x14edfe0,27, +0x14ef000,19, +0x14efa00,10, +0x14efa80,3, +0x14efb00,6, +0x14f0000,51, +0x14f0a00,10, +0x14f0a80,3, +0x14f1000,2, +0x14f100c,4, +0x14f1028,3, +0x14f1038,4, +0x14f1050,2, +0x14f1080,4, +0x14f1098,7, +0x14f1120,4, +0x14f1200,4, +0x14f1214,7, +0x14f1234,3, +0x14f1280,8, +0x14f12c0,5, +0x14f1300,2, +0x14f130c,3, +0x14f1400,24, +0x14f1464,2, +0x14f1470,3, +0x14f1500,25, +0x14f15c0,8, +0x14f15e8,5, +0x14f1600,5, +0x14f1618,1, +0x14f1620,1, +0x14f1628,1, +0x14f1630,2, +0x14f1640,2, +0x14f1650,2, +0x14f1690,4, +0x14f1740,2, +0x14f1760,6, +0x14f1780,6, +0x14f17a0,6, +0x14f17c0,6, +0x14f17e0,1, +0x14f1800,2, +0x14f180c,4, +0x14f1828,3, +0x14f1838,4, +0x14f1850,2, +0x14f1880,4, +0x14f1898,7, +0x14f1920,4, +0x14f1a00,4, +0x14f1a14,7, +0x14f1a34,3, +0x14f1a80,8, +0x14f1ac0,5, +0x14f1b00,2, +0x14f1b0c,3, +0x14f1c00,24, +0x14f1c64,2, +0x14f1c70,3, +0x14f1d00,25, +0x14f1dc0,8, +0x14f1de8,5, +0x14f1e00,5, +0x14f1e18,1, +0x14f1e20,1, +0x14f1e28,1, +0x14f1e30,2, +0x14f1e40,2, +0x14f1e50,2, +0x14f1e90,4, +0x14f1f40,2, +0x14f1f60,6, +0x14f1f80,6, +0x14f1fa0,6, +0x14f1fc0,6, +0x14f1fe0,1, +0x14f2000,19, +0x14f2080,2, +0x14f20b0,2, +0x14f20c0,2, +0x1500000,11, +0x1500040,16, +0x1500084,5, +0x1500200,7, +0x1500220,6, +0x1500240,7, +0x1500260,6, +0x1500280,6, +0x15002a0,2, +0x15002ac,2, +0x15002c0,7, +0x15002e0,7, +0x1500300,2, +0x150030c,2, +0x1500320,6, +0x1500400,2, +0x1501000,19, +0x1502104,23, +0x1502180,7, +0x15021a0,6, +0x15021c0,7, +0x15021e0,6, +0x1502200,4, +0x1502220,4, +0x1502240,11, +0x1502270,32, +0x1502300,24, +0x1502380,20, +0x1502400,61, +0x1502500,25, +0x1502568,4, +0x1502580,2, +0x15025a0,1, +0x15025c0,11, +0x1502600,9, +0x1502640,3, +0x1502650,3, +0x1502664,3, +0x1502680,22, +0x1502800,11, +0x1503000,536, +0x1504104,23, +0x1504180,7, +0x15041a0,6, +0x15041c0,7, +0x15041e0,6, +0x1504200,4, +0x1504220,4, +0x1504240,11, +0x1504270,32, +0x1504300,24, +0x1504380,20, +0x1504400,61, +0x1504500,25, +0x1504568,4, +0x1504580,2, +0x15045a0,1, +0x15045c0,11, +0x1504600,9, +0x1504640,3, +0x1504650,3, +0x1504664,3, +0x1504680,22, +0x1504800,11, +0x1505000,536, +0x150a000,7, +0x150a048,8, +0x150a080,8, +0x150a100,7, +0x150a148,8, +0x150a180,8, +0x1510000,11, +0x1510040,16, +0x1510084,5, +0x1510200,7, +0x1510220,6, +0x1510240,7, +0x1510260,6, +0x1510280,6, +0x15102a0,2, +0x15102ac,2, +0x15102c0,7, +0x15102e0,7, +0x1510300,2, +0x151030c,2, +0x1510320,6, +0x1510400,2, +0x1511000,19, +0x1512104,23, +0x1512180,7, +0x15121a0,6, +0x15121c0,7, +0x15121e0,6, +0x1512200,4, +0x1512220,4, +0x1512240,11, +0x1512270,32, +0x1512300,24, +0x1512380,20, +0x1512400,61, +0x1512500,25, +0x1512568,4, +0x1512580,2, +0x15125a0,1, +0x15125c0,11, +0x1512600,9, +0x1512640,3, +0x1512650,3, +0x1512664,3, +0x1512680,22, +0x1512800,11, +0x1513000,536, +0x1514104,23, +0x1514180,7, +0x15141a0,6, +0x15141c0,7, +0x15141e0,6, +0x1514200,4, +0x1514220,4, +0x1514240,11, +0x1514270,32, +0x1514300,24, +0x1514380,20, +0x1514400,61, +0x1514500,25, +0x1514568,4, +0x1514580,2, +0x15145a0,1, +0x15145c0,11, +0x1514600,9, +0x1514640,3, +0x1514650,3, +0x1514664,3, +0x1514680,22, +0x1514800,11, +0x1515000,536, +0x151a000,7, +0x151a048,8, +0x151a080,8, +0x151a100,7, +0x151a148,8, +0x151a180,8, +0x1520400,4, +0x1520440,4, +0x15205c0,1, +0x1520600,8, +0x1520800,18, +0x1520880,13, +0x15208f0,3, +0x1520900,18, +0x1520980,13, +0x15209f0,3, +0x1520e00,4, +0x1520e20,4, +0x1520e80,16, +0x1520f00,1, +0x1520f20,1, +0x1521020,2, +0x1521208,6, +0x1521228,10, +0x1521288,6, +0x15212a8,10, +0x1521600,32, +0x15218c0,8, +0x1521900,24, +0x15219b0,4, +0x1521aa0,2, +0x1521ac0,4, +0x1522200,19, +0x1522280,19, +0x1522400,14, +0x152243c,9, +0x1522464,14, +0x15224a0,2, +0x15224ac,2, +0x1522500,14, +0x152253c,9, +0x1522564,14, +0x15225a0,2, +0x15225ac,2, +0x1522800,19, +0x1522880,19, +0x1522a10,2, +0x1522a1c,1, +0x1522a50,2, +0x1522a5c,1, +0x1522c00,7, +0x1522c20,1, +0x1522c54,18, +0x1522ca0,1, +0x1522cd4,11, +0x1522e00,1, +0x1522e08,6, +0x1523180,3, +0x1524400,4, +0x1524440,4, +0x15245c0,1, +0x1524600,8, +0x1524800,18, +0x1524880,13, +0x15248f0,3, +0x1524900,18, +0x1524980,13, +0x15249f0,3, +0x1524e00,4, +0x1524e20,4, +0x1524e80,16, +0x1524f00,1, +0x1524f20,1, +0x1525020,2, +0x1525208,6, +0x1525228,10, +0x1525288,6, +0x15252a8,10, +0x1525600,32, +0x15258c0,8, +0x1525900,24, +0x15259b0,4, +0x1525aa0,2, +0x1525ac0,4, +0x1526200,19, +0x1526280,19, +0x1526400,14, +0x152643c,9, +0x1526464,14, +0x15264a0,2, +0x15264ac,2, +0x1526500,14, +0x152653c,9, +0x1526564,14, +0x15265a0,2, +0x15265ac,2, +0x1526800,19, +0x1526880,19, +0x1526a10,2, +0x1526a1c,1, +0x1526a50,2, +0x1526a5c,1, +0x1526c00,7, +0x1526c20,1, +0x1526c54,18, +0x1526ca0,1, +0x1526cd4,11, +0x1526e00,1, +0x1526e08,6, +0x1527180,3, +0x1529000,13, +0x152e000,19, +0x152ea00,10, +0x152ea80,3, +0x152f000,1, +0x152f008,5, +0x152f038,1, +0x152f044,1, +0x152f050,2, +0x152f060,8, +0x152f140,19, +0x152f190,4, +0x1530000,2, +0x153000c,2, +0x1530040,7, +0x1530100,3, +0x1530110,3, +0x1530120,5, +0x1530200,6, +0x1530240,5, +0x1530400,2, +0x153040c,2, +0x1530440,7, +0x1530500,3, +0x1530510,3, +0x1530520,5, +0x1530600,6, +0x1530640,5, +0x1530800,2, +0x153080c,2, +0x1530840,7, +0x1530900,3, +0x1530910,3, +0x1530920,5, +0x1530a00,6, +0x1530a40,5, +0x1530c00,2, +0x1530c0c,2, +0x1530c40,7, +0x1530d00,3, +0x1530d10,3, +0x1530d20,5, +0x1530e00,6, +0x1530e40,5, +0x1531000,2, +0x153100c,2, +0x1531040,7, +0x1531100,3, +0x1531110,3, +0x1531120,5, +0x1531200,6, +0x1531240,5, +0x1531400,2, +0x153140c,2, +0x1531440,7, +0x1531500,3, +0x1531510,3, +0x1531520,5, +0x1531600,6, +0x1531640,5, +0x1531800,2, +0x153180c,2, +0x1531840,7, +0x1531900,3, +0x1531910,3, +0x1531920,5, +0x1531a00,6, +0x1531a40,5, +0x1531c00,2, +0x1531c0c,2, +0x1531c40,7, +0x1531d00,3, +0x1531d10,3, +0x1531d20,5, +0x1531e00,6, +0x1531e40,5, +0x1532000,5, +0x1532040,9, +0x1532100,3, +0x1532200,1, +0x1532210,1, +0x1532220,1, +0x1532230,1, +0x1532240,1, +0x1532300,3, +0x1532314,1, +0x1532320,4, +0x1532400,5, +0x1532440,5, +0x1533000,80, +0x1533200,1, +0x1538000,7, +0x1538030,2, +0x1538040,7, +0x1538070,2, +0x1538100,2, +0x1538120,2, +0x1538140,2, +0x1538160,2, +0x1538180,9, +0x1538200,7, +0x1538230,2, +0x1538240,7, +0x1538270,2, +0x1538300,2, +0x1538320,2, +0x1538340,2, +0x1538360,2, +0x1538380,9, +0x1538400,11, +0x1538500,11, +0x1539000,3, +0x1539010,2, +0x153901c,5, +0x1539040,8, +0x1539080,3, +0x1539090,2, +0x153909c,5, +0x15390c0,8, +0x1539100,3, +0x1539110,2, +0x153911c,5, +0x1539140,8, +0x1539180,3, +0x1539190,2, +0x153919c,5, +0x15391c0,8, +0x1539200,7, +0x1539220,12, +0x1539280,7, +0x15392a0,12, +0x1539300,3, +0x1539310,1, +0x1539400,3, +0x1539410,2, +0x153941c,5, +0x1539440,8, +0x1539480,3, +0x1539490,2, +0x153949c,5, +0x15394c0,8, +0x1539500,3, +0x1539510,2, +0x153951c,5, +0x1539540,8, +0x1539580,3, +0x1539590,2, +0x153959c,5, +0x15395c0,8, +0x1539600,7, +0x1539620,12, +0x1539680,7, +0x15396a0,12, +0x1539700,3, +0x1539710,1, +0x1539804,1, +0x1539824,21, +0x1539880,16, +0x1539900,5, +0x1539920,11, +0x1539950,9, +0x1539980,22, +0x1539a00,22, +0x1539a80,22, +0x1539b00,22, +0x1539b80,22, +0x1539c00,22, +0x1539c80,22, +0x1539d00,22, +0x1539d80,3, +0x1540000,5, +0x1540018,5, +0x1540030,3, +0x1540044,3, +0x1540100,58, +0x15401f0,3, +0x1540280,3, +0x1540400,5, +0x1540418,5, +0x1540430,3, +0x1540444,3, +0x1540500,58, +0x15405f0,3, +0x1540680,3, +0x1541018,2, +0x1541100,2, +0x1541110,10, +0x1541140,2, +0x1541150,10, +0x1541208,1, +0x1541220,12, +0x1541280,1, +0x1541288,2, +0x1541400,4, +0x1542000,5, +0x1542018,5, +0x1542030,3, +0x1542044,3, +0x1542100,58, +0x15421f0,3, +0x1542280,3, +0x1542400,5, +0x1542418,5, +0x1542430,3, +0x1542444,3, +0x1542500,58, +0x15425f0,3, +0x1542680,3, +0x1543018,2, +0x1543100,2, +0x1543110,10, +0x1543140,2, +0x1543150,10, +0x1543208,1, +0x1543220,12, +0x1543280,1, +0x1543288,2, +0x1543400,4, +0x1544000,2, +0x154400c,1, +0x1544030,3, +0x1544040,2, +0x154404c,1, +0x1544070,3, +0x1544100,2, +0x154410c,1, +0x1544130,3, +0x1544140,2, +0x154414c,1, +0x1544170,3, +0x1544200,15, +0x1544280,15, +0x1544300,15, +0x1544380,15, +0x1544400,15, +0x1544480,15, +0x1544500,15, +0x1544580,15, +0x1544604,10, +0x1544700,2, +0x154470c,7, +0x1544740,1, +0x1544770,1, +0x15447c0,2, +0x15447d0,4, +0x1545000,3, +0x1545010,1, +0x154501c,3, +0x1545104,1, +0x1545110,4, +0x1545124,1, +0x1545130,4, +0x1545144,1, +0x1545150,4, +0x1545164,1, +0x1545170,5, +0x1545190,4, +0x1545a00,4, +0x1545c00,129, +0x1546000,37, +0x1546098,1, +0x1546100,37, +0x1546198,1, +0x1546200,37, +0x1546298,1, +0x1546300,37, +0x1546398,1, +0x1546400,37, +0x1546498,1, +0x1546500,37, +0x1546598,1, +0x1546600,37, +0x1546698,1, +0x1546700,37, +0x1546798,1, +0x154c000,91, +0x154c400,4, +0x154c440,15, +0x154c480,4, +0x154c4c0,15, +0x154c500,4, +0x154c540,15, +0x154c580,4, +0x154c5c0,15, +0x154c600,4, +0x154c640,10, +0x154c680,4, +0x154c6c0,10, +0x154c800,4, +0x154c840,33, +0x154ca00,13, +0x154ca80,1, +0x154ca88,8, +0x154cac0,6, +0x154cae0,1, +0x154cae8,2, +0x154cb04,14, +0x154cc00,4, +0x154ccc8,1, +0x154cfcc,3, +0x154cfe0,99, +0x154d400,4, +0x154d440,15, +0x154d480,4, +0x154d4c0,15, +0x154d500,4, +0x154d540,15, +0x154d580,4, +0x154d5c0,15, +0x154d600,4, +0x154d640,10, +0x154d680,4, +0x154d6c0,10, +0x154d800,4, +0x154d840,33, +0x154da00,13, +0x154da80,1, +0x154da88,8, +0x154dac0,6, +0x154dae0,1, +0x154dae8,2, +0x154db04,14, +0x154dc00,4, +0x154dcc8,1, +0x154dfcc,3, +0x154dfe0,27, +0x154f000,19, +0x154fa00,10, +0x154fa80,3, +0x154fb00,6, +0x1550000,51, +0x1550a00,10, +0x1550a80,3, +0x1551000,2, +0x155100c,4, +0x1551028,3, +0x1551038,4, +0x1551050,2, +0x1551080,4, +0x1551098,7, +0x1551120,4, +0x1551200,4, +0x1551214,7, +0x1551234,3, +0x1551280,8, +0x15512c0,5, +0x1551300,2, +0x155130c,3, +0x1551400,24, +0x1551464,2, +0x1551470,3, +0x1551500,25, +0x15515c0,8, +0x15515e8,5, +0x1551600,5, +0x1551618,1, +0x1551620,1, +0x1551628,1, +0x1551630,2, +0x1551640,2, +0x1551650,2, +0x1551690,4, +0x1551740,2, +0x1551760,6, +0x1551780,6, +0x15517a0,6, +0x15517c0,6, +0x15517e0,1, +0x1551800,2, +0x155180c,4, +0x1551828,3, +0x1551838,4, +0x1551850,2, +0x1551880,4, +0x1551898,7, +0x1551920,4, +0x1551a00,4, +0x1551a14,7, +0x1551a34,3, +0x1551a80,8, +0x1551ac0,5, +0x1551b00,2, +0x1551b0c,3, +0x1551c00,24, +0x1551c64,2, +0x1551c70,3, +0x1551d00,25, +0x1551dc0,8, +0x1551de8,5, +0x1551e00,5, +0x1551e18,1, +0x1551e20,1, +0x1551e28,1, +0x1551e30,2, +0x1551e40,2, +0x1551e50,2, +0x1551e90,4, +0x1551f40,2, +0x1551f60,6, +0x1551f80,6, +0x1551fa0,6, +0x1551fc0,6, +0x1551fe0,1, +0x1552000,19, +0x1552080,2, +0x15520b0,2, +0x15520c0,2, +0x1560000,11, +0x1560040,16, +0x1560084,5, +0x1560200,7, +0x1560220,6, +0x1560240,7, +0x1560260,6, +0x1560280,6, +0x15602a0,2, +0x15602ac,2, +0x15602c0,7, +0x15602e0,7, +0x1560300,2, +0x156030c,2, +0x1560320,6, +0x1560400,2, +0x1561000,19, +0x1562104,23, +0x1562180,7, +0x15621a0,6, +0x15621c0,7, +0x15621e0,6, +0x1562200,4, +0x1562220,4, +0x1562240,11, +0x1562270,32, +0x1562300,24, +0x1562380,20, +0x1562400,61, +0x1562500,25, +0x1562568,4, +0x1562580,2, +0x15625a0,1, +0x15625c0,11, +0x1562600,9, +0x1562640,3, +0x1562650,3, +0x1562664,3, +0x1562680,22, +0x1562800,11, +0x1563000,536, +0x1564104,23, +0x1564180,7, +0x15641a0,6, +0x15641c0,7, +0x15641e0,6, +0x1564200,4, +0x1564220,4, +0x1564240,11, +0x1564270,32, +0x1564300,24, +0x1564380,20, +0x1564400,61, +0x1564500,25, +0x1564568,4, +0x1564580,2, +0x15645a0,1, +0x15645c0,11, +0x1564600,9, +0x1564640,3, +0x1564650,3, +0x1564664,3, +0x1564680,22, +0x1564800,11, +0x1565000,536, +0x156a000,7, +0x156a048,8, +0x156a080,8, +0x156a100,7, +0x156a148,8, +0x156a180,8, +0x1570000,11, +0x1570040,16, +0x1570084,5, +0x1570200,7, +0x1570220,6, +0x1570240,7, +0x1570260,6, +0x1570280,6, +0x15702a0,2, +0x15702ac,2, +0x15702c0,7, +0x15702e0,7, +0x1570300,2, +0x157030c,2, +0x1570320,6, +0x1570400,2, +0x1571000,19, +0x1572104,23, +0x1572180,7, +0x15721a0,6, +0x15721c0,7, +0x15721e0,6, +0x1572200,4, +0x1572220,4, +0x1572240,11, +0x1572270,32, +0x1572300,24, +0x1572380,20, +0x1572400,61, +0x1572500,25, +0x1572568,4, +0x1572580,2, +0x15725a0,1, +0x15725c0,11, +0x1572600,9, +0x1572640,3, +0x1572650,3, +0x1572664,3, +0x1572680,22, +0x1572800,11, +0x1573000,536, +0x1574104,23, +0x1574180,7, +0x15741a0,6, +0x15741c0,7, +0x15741e0,6, +0x1574200,4, +0x1574220,4, +0x1574240,11, +0x1574270,32, +0x1574300,24, +0x1574380,20, +0x1574400,61, +0x1574500,25, +0x1574568,4, +0x1574580,2, +0x15745a0,1, +0x15745c0,11, +0x1574600,9, +0x1574640,3, +0x1574650,3, +0x1574664,3, +0x1574680,22, +0x1574800,11, +0x1575000,536, +0x157a000,7, +0x157a048,8, +0x157a080,8, +0x157a100,7, +0x157a148,8, +0x157a180,8, +0x1580400,4, +0x1580440,4, +0x15805c0,1, +0x1580600,8, +0x1580800,18, +0x1580880,13, +0x15808f0,3, +0x1580900,18, +0x1580980,13, +0x15809f0,3, +0x1580e00,4, +0x1580e20,4, +0x1580e80,16, +0x1580f00,1, +0x1580f20,1, +0x1581020,2, +0x1581208,6, +0x1581228,10, +0x1581288,6, +0x15812a8,10, +0x1581600,32, +0x15818c0,8, +0x1581900,24, +0x15819b0,4, +0x1581aa0,2, +0x1581ac0,4, +0x1582200,19, +0x1582280,19, +0x1582400,14, +0x158243c,9, +0x1582464,14, +0x15824a0,2, +0x15824ac,2, +0x1582500,14, +0x158253c,9, +0x1582564,14, +0x15825a0,2, +0x15825ac,2, +0x1582800,19, +0x1582880,19, +0x1582a10,2, +0x1582a1c,1, +0x1582a50,2, +0x1582a5c,1, +0x1582c00,7, +0x1582c20,1, +0x1582c54,18, +0x1582ca0,1, +0x1582cd4,11, +0x1582e00,1, +0x1582e08,6, +0x1583180,3, +0x1584400,4, +0x1584440,4, +0x15845c0,1, +0x1584600,8, +0x1584800,18, +0x1584880,13, +0x15848f0,3, +0x1584900,18, +0x1584980,13, +0x15849f0,3, +0x1584e00,4, +0x1584e20,4, +0x1584e80,16, +0x1584f00,1, +0x1584f20,1, +0x1585020,2, +0x1585208,6, +0x1585228,10, +0x1585288,6, +0x15852a8,10, +0x1585600,32, +0x15858c0,8, +0x1585900,24, +0x15859b0,4, +0x1585aa0,2, +0x1585ac0,4, +0x1586200,19, +0x1586280,19, +0x1586400,14, +0x158643c,9, +0x1586464,14, +0x15864a0,2, +0x15864ac,2, +0x1586500,14, +0x158653c,9, +0x1586564,14, +0x15865a0,2, +0x15865ac,2, +0x1586800,19, +0x1586880,19, +0x1586a10,2, +0x1586a1c,1, +0x1586a50,2, +0x1586a5c,1, +0x1586c00,7, +0x1586c20,1, +0x1586c54,18, +0x1586ca0,1, +0x1586cd4,11, +0x1586e00,1, +0x1586e08,6, +0x1587180,3, +0x1589000,13, +0x158e000,19, +0x158ea00,10, +0x158ea80,3, +0x158f000,1, +0x158f008,5, +0x158f038,1, +0x158f044,1, +0x158f050,2, +0x158f060,8, +0x158f140,19, +0x158f190,4, +0x1590000,2, +0x159000c,2, +0x1590040,7, +0x1590100,3, +0x1590110,3, +0x1590120,5, +0x1590200,6, +0x1590240,5, +0x1590400,2, +0x159040c,2, +0x1590440,7, +0x1590500,3, +0x1590510,3, +0x1590520,5, +0x1590600,6, +0x1590640,5, +0x1590800,2, +0x159080c,2, +0x1590840,7, +0x1590900,3, +0x1590910,3, +0x1590920,5, +0x1590a00,6, +0x1590a40,5, +0x1590c00,2, +0x1590c0c,2, +0x1590c40,7, +0x1590d00,3, +0x1590d10,3, +0x1590d20,5, +0x1590e00,6, +0x1590e40,5, +0x1591000,2, +0x159100c,2, +0x1591040,7, +0x1591100,3, +0x1591110,3, +0x1591120,5, +0x1591200,6, +0x1591240,5, +0x1591400,2, +0x159140c,2, +0x1591440,7, +0x1591500,3, +0x1591510,3, +0x1591520,5, +0x1591600,6, +0x1591640,5, +0x1591800,2, +0x159180c,2, +0x1591840,7, +0x1591900,3, +0x1591910,3, +0x1591920,5, +0x1591a00,6, +0x1591a40,5, +0x1591c00,2, +0x1591c0c,2, +0x1591c40,7, +0x1591d00,3, +0x1591d10,3, +0x1591d20,5, +0x1591e00,6, +0x1591e40,5, +0x1592000,5, +0x1592040,9, +0x1592100,3, +0x1592200,1, +0x1592210,1, +0x1592220,1, +0x1592230,1, +0x1592240,1, +0x1592300,3, +0x1592314,1, +0x1592320,4, +0x1592400,5, +0x1592440,5, +0x1593000,80, +0x1593200,1, +0x1598000,7, +0x1598030,2, +0x1598040,7, +0x1598070,2, +0x1598100,2, +0x1598120,2, +0x1598140,2, +0x1598160,2, +0x1598180,9, +0x1598200,7, +0x1598230,2, +0x1598240,7, +0x1598270,2, +0x1598300,2, +0x1598320,2, +0x1598340,2, +0x1598360,2, +0x1598380,9, +0x1598400,11, +0x1598500,11, +0x1599000,3, +0x1599010,2, +0x159901c,5, +0x1599040,8, +0x1599080,3, +0x1599090,2, +0x159909c,5, +0x15990c0,8, +0x1599100,3, +0x1599110,2, +0x159911c,5, +0x1599140,8, +0x1599180,3, +0x1599190,2, +0x159919c,5, +0x15991c0,8, +0x1599200,7, +0x1599220,12, +0x1599280,7, +0x15992a0,12, +0x1599300,3, +0x1599310,1, +0x1599400,3, +0x1599410,2, +0x159941c,5, +0x1599440,8, +0x1599480,3, +0x1599490,2, +0x159949c,5, +0x15994c0,8, +0x1599500,3, +0x1599510,2, +0x159951c,5, +0x1599540,8, +0x1599580,3, +0x1599590,2, +0x159959c,5, +0x15995c0,8, +0x1599600,7, +0x1599620,12, +0x1599680,7, +0x15996a0,12, +0x1599700,3, +0x1599710,1, +0x1599804,1, +0x1599824,21, +0x1599880,16, +0x1599900,5, +0x1599920,11, +0x1599950,9, +0x1599980,22, +0x1599a00,22, +0x1599a80,22, +0x1599b00,22, +0x1599b80,22, +0x1599c00,22, +0x1599c80,22, +0x1599d00,22, +0x1599d80,3, +0x15a0000,5, +0x15a0018,5, +0x15a0030,3, +0x15a0044,3, +0x15a0100,58, +0x15a01f0,3, +0x15a0280,3, +0x15a0400,5, +0x15a0418,5, +0x15a0430,3, +0x15a0444,3, +0x15a0500,58, +0x15a05f0,3, +0x15a0680,3, +0x15a1018,2, +0x15a1100,2, +0x15a1110,10, +0x15a1140,2, +0x15a1150,10, +0x15a1208,1, +0x15a1220,12, +0x15a1280,1, +0x15a1288,2, +0x15a1400,4, +0x15a2000,5, +0x15a2018,5, +0x15a2030,3, +0x15a2044,3, +0x15a2100,58, +0x15a21f0,3, +0x15a2280,3, +0x15a2400,5, +0x15a2418,5, +0x15a2430,3, +0x15a2444,3, +0x15a2500,58, +0x15a25f0,3, +0x15a2680,3, +0x15a3018,2, +0x15a3100,2, +0x15a3110,10, +0x15a3140,2, +0x15a3150,10, +0x15a3208,1, +0x15a3220,12, +0x15a3280,1, +0x15a3288,2, +0x15a3400,4, +0x15a4000,2, +0x15a400c,1, +0x15a4030,3, +0x15a4040,2, +0x15a404c,1, +0x15a4070,3, +0x15a4100,2, +0x15a410c,1, +0x15a4130,3, +0x15a4140,2, +0x15a414c,1, +0x15a4170,3, +0x15a4200,15, +0x15a4280,15, +0x15a4300,15, +0x15a4380,15, +0x15a4400,15, +0x15a4480,15, +0x15a4500,15, +0x15a4580,15, +0x15a4604,10, +0x15a4700,2, +0x15a470c,7, +0x15a4740,1, +0x15a4770,1, +0x15a47c0,2, +0x15a47d0,4, +0x15a5000,3, +0x15a5010,1, +0x15a501c,3, +0x15a5104,1, +0x15a5110,4, +0x15a5124,1, +0x15a5130,4, +0x15a5144,1, +0x15a5150,4, +0x15a5164,1, +0x15a5170,5, +0x15a5190,4, +0x15a5a00,4, +0x15a5c00,129, +0x15a6000,37, +0x15a6098,1, +0x15a6100,37, +0x15a6198,1, +0x15a6200,37, +0x15a6298,1, +0x15a6300,37, +0x15a6398,1, +0x15a6400,37, +0x15a6498,1, +0x15a6500,37, +0x15a6598,1, +0x15a6600,37, +0x15a6698,1, +0x15a6700,37, +0x15a6798,1, +0x15ac000,91, +0x15ac400,4, +0x15ac440,15, +0x15ac480,4, +0x15ac4c0,15, +0x15ac500,4, +0x15ac540,15, +0x15ac580,4, +0x15ac5c0,15, +0x15ac600,4, +0x15ac640,10, +0x15ac680,4, +0x15ac6c0,10, +0x15ac800,4, +0x15ac840,33, +0x15aca00,13, +0x15aca80,1, +0x15aca88,8, +0x15acac0,6, +0x15acae0,1, +0x15acae8,2, +0x15acb04,14, +0x15acc00,4, +0x15accc8,1, +0x15acfcc,3, +0x15acfe0,99, +0x15ad400,4, +0x15ad440,15, +0x15ad480,4, +0x15ad4c0,15, +0x15ad500,4, +0x15ad540,15, +0x15ad580,4, +0x15ad5c0,15, +0x15ad600,4, +0x15ad640,10, +0x15ad680,4, +0x15ad6c0,10, +0x15ad800,4, +0x15ad840,33, +0x15ada00,13, +0x15ada80,1, +0x15ada88,8, +0x15adac0,6, +0x15adae0,1, +0x15adae8,2, +0x15adb04,14, +0x15adc00,4, +0x15adcc8,1, +0x15adfcc,3, +0x15adfe0,27, +0x15af000,19, +0x15afa00,10, +0x15afa80,3, +0x15afb00,6, +0x15b0000,51, +0x15b0a00,10, +0x15b0a80,3, +0x15b1000,2, +0x15b100c,4, +0x15b1028,3, +0x15b1038,4, +0x15b1050,2, +0x15b1080,4, +0x15b1098,7, +0x15b1120,4, +0x15b1200,4, +0x15b1214,7, +0x15b1234,3, +0x15b1280,8, +0x15b12c0,5, +0x15b1300,2, +0x15b130c,3, +0x15b1400,24, +0x15b1464,2, +0x15b1470,3, +0x15b1500,25, +0x15b15c0,8, +0x15b15e8,5, +0x15b1600,5, +0x15b1618,1, +0x15b1620,1, +0x15b1628,1, +0x15b1630,2, +0x15b1640,2, +0x15b1650,2, +0x15b1690,4, +0x15b1740,2, +0x15b1760,6, +0x15b1780,6, +0x15b17a0,6, +0x15b17c0,6, +0x15b17e0,1, +0x15b1800,2, +0x15b180c,4, +0x15b1828,3, +0x15b1838,4, +0x15b1850,2, +0x15b1880,4, +0x15b1898,7, +0x15b1920,4, +0x15b1a00,4, +0x15b1a14,7, +0x15b1a34,3, +0x15b1a80,8, +0x15b1ac0,5, +0x15b1b00,2, +0x15b1b0c,3, +0x15b1c00,24, +0x15b1c64,2, +0x15b1c70,3, +0x15b1d00,25, +0x15b1dc0,8, +0x15b1de8,5, +0x15b1e00,5, +0x15b1e18,1, +0x15b1e20,1, +0x15b1e28,1, +0x15b1e30,2, +0x15b1e40,2, +0x15b1e50,2, +0x15b1e90,4, +0x15b1f40,2, +0x15b1f60,6, +0x15b1f80,6, +0x15b1fa0,6, +0x15b1fc0,6, +0x15b1fe0,1, +0x15b2000,19, +0x15b2080,2, +0x15b20b0,2, +0x15b20c0,2, +0x15c0000,11, +0x15c0040,16, +0x15c0084,5, +0x15c0200,7, +0x15c0220,6, +0x15c0240,7, +0x15c0260,6, +0x15c0280,6, +0x15c02a0,2, +0x15c02ac,2, +0x15c02c0,7, +0x15c02e0,7, +0x15c0300,2, +0x15c030c,2, +0x15c0320,6, +0x15c0400,2, +0x15c1000,19, +0x15c2104,23, +0x15c2180,7, +0x15c21a0,6, +0x15c21c0,7, +0x15c21e0,6, +0x15c2200,4, +0x15c2220,4, +0x15c2240,11, +0x15c2270,32, +0x15c2300,24, +0x15c2380,20, +0x15c2400,61, +0x15c2500,25, +0x15c2568,4, +0x15c2580,2, +0x15c25a0,1, +0x15c25c0,11, +0x15c2600,9, +0x15c2640,3, +0x15c2650,3, +0x15c2664,3, +0x15c2680,22, +0x15c2800,11, +0x15c3000,536, +0x15c4104,23, +0x15c4180,7, +0x15c41a0,6, +0x15c41c0,7, +0x15c41e0,6, +0x15c4200,4, +0x15c4220,4, +0x15c4240,11, +0x15c4270,32, +0x15c4300,24, +0x15c4380,20, +0x15c4400,61, +0x15c4500,25, +0x15c4568,4, +0x15c4580,2, +0x15c45a0,1, +0x15c45c0,11, +0x15c4600,9, +0x15c4640,3, +0x15c4650,3, +0x15c4664,3, +0x15c4680,22, +0x15c4800,11, +0x15c5000,536, +0x15ca000,7, +0x15ca048,8, +0x15ca080,8, +0x15ca100,7, +0x15ca148,8, +0x15ca180,8, +0x15d0000,11, +0x15d0040,16, +0x15d0084,5, +0x15d0200,7, +0x15d0220,6, +0x15d0240,7, +0x15d0260,6, +0x15d0280,6, +0x15d02a0,2, +0x15d02ac,2, +0x15d02c0,7, +0x15d02e0,7, +0x15d0300,2, +0x15d030c,2, +0x15d0320,6, +0x15d0400,2, +0x15d1000,19, +0x15d2104,23, +0x15d2180,7, +0x15d21a0,6, +0x15d21c0,7, +0x15d21e0,6, +0x15d2200,4, +0x15d2220,4, +0x15d2240,11, +0x15d2270,32, +0x15d2300,24, +0x15d2380,20, +0x15d2400,61, +0x15d2500,25, +0x15d2568,4, +0x15d2580,2, +0x15d25a0,1, +0x15d25c0,11, +0x15d2600,9, +0x15d2640,3, +0x15d2650,3, +0x15d2664,3, +0x15d2680,22, +0x15d2800,11, +0x15d3000,536, +0x15d4104,23, +0x15d4180,7, +0x15d41a0,6, +0x15d41c0,7, +0x15d41e0,6, +0x15d4200,4, +0x15d4220,4, +0x15d4240,11, +0x15d4270,32, +0x15d4300,24, +0x15d4380,20, +0x15d4400,61, +0x15d4500,25, +0x15d4568,4, +0x15d4580,2, +0x15d45a0,1, +0x15d45c0,11, +0x15d4600,9, +0x15d4640,3, +0x15d4650,3, +0x15d4664,3, +0x15d4680,22, +0x15d4800,11, +0x15d5000,536, +0x15da000,7, +0x15da048,8, +0x15da080,8, +0x15da100,7, +0x15da148,8, +0x15da180,8, +0x15e0400,4, +0x15e0440,4, +0x15e05c0,1, +0x15e0600,8, +0x15e0800,18, +0x15e0880,13, +0x15e08f0,3, +0x15e0900,18, +0x15e0980,13, +0x15e09f0,3, +0x15e0e00,4, +0x15e0e20,4, +0x15e0e80,16, +0x15e0f00,1, +0x15e0f20,1, +0x15e1020,2, +0x15e1208,6, +0x15e1228,10, +0x15e1288,6, +0x15e12a8,10, +0x15e1600,32, +0x15e18c0,8, +0x15e1900,24, +0x15e19b0,4, +0x15e1aa0,2, +0x15e1ac0,4, +0x15e2200,19, +0x15e2280,19, +0x15e2400,14, +0x15e243c,9, +0x15e2464,14, +0x15e24a0,2, +0x15e24ac,2, +0x15e2500,14, +0x15e253c,9, +0x15e2564,14, +0x15e25a0,2, +0x15e25ac,2, +0x15e2800,19, +0x15e2880,19, +0x15e2a10,2, +0x15e2a1c,1, +0x15e2a50,2, +0x15e2a5c,1, +0x15e2c00,7, +0x15e2c20,1, +0x15e2c54,18, +0x15e2ca0,1, +0x15e2cd4,11, +0x15e2e00,1, +0x15e2e08,6, +0x15e3180,3, +0x15e4400,4, +0x15e4440,4, +0x15e45c0,1, +0x15e4600,8, +0x15e4800,18, +0x15e4880,13, +0x15e48f0,3, +0x15e4900,18, +0x15e4980,13, +0x15e49f0,3, +0x15e4e00,4, +0x15e4e20,4, +0x15e4e80,16, +0x15e4f00,1, +0x15e4f20,1, +0x15e5020,2, +0x15e5208,6, +0x15e5228,10, +0x15e5288,6, +0x15e52a8,10, +0x15e5600,32, +0x15e58c0,8, +0x15e5900,24, +0x15e59b0,4, +0x15e5aa0,2, +0x15e5ac0,4, +0x15e6200,19, +0x15e6280,19, +0x15e6400,14, +0x15e643c,9, +0x15e6464,14, +0x15e64a0,2, +0x15e64ac,2, +0x15e6500,14, +0x15e653c,9, +0x15e6564,14, +0x15e65a0,2, +0x15e65ac,2, +0x15e6800,19, +0x15e6880,19, +0x15e6a10,2, +0x15e6a1c,1, +0x15e6a50,2, +0x15e6a5c,1, +0x15e6c00,7, +0x15e6c20,1, +0x15e6c54,18, +0x15e6ca0,1, +0x15e6cd4,11, +0x15e6e00,1, +0x15e6e08,6, +0x15e7180,3, +0x15e9000,13, +0x15ee000,19, +0x15eea00,10, +0x15eea80,3, +0x15ef000,1, +0x15ef008,5, +0x15ef038,1, +0x15ef044,1, +0x15ef050,2, +0x15ef060,8, +0x15ef140,19, +0x15ef190,4, +0x15f0000,2, +0x15f000c,2, +0x15f0040,7, +0x15f0100,3, +0x15f0110,3, +0x15f0120,5, +0x15f0200,6, +0x15f0240,5, +0x15f0400,2, +0x15f040c,2, +0x15f0440,7, +0x15f0500,3, +0x15f0510,3, +0x15f0520,5, +0x15f0600,6, +0x15f0640,5, +0x15f0800,2, +0x15f080c,2, +0x15f0840,7, +0x15f0900,3, +0x15f0910,3, +0x15f0920,5, +0x15f0a00,6, +0x15f0a40,5, +0x15f0c00,2, +0x15f0c0c,2, +0x15f0c40,7, +0x15f0d00,3, +0x15f0d10,3, +0x15f0d20,5, +0x15f0e00,6, +0x15f0e40,5, +0x15f1000,2, +0x15f100c,2, +0x15f1040,7, +0x15f1100,3, +0x15f1110,3, +0x15f1120,5, +0x15f1200,6, +0x15f1240,5, +0x15f1400,2, +0x15f140c,2, +0x15f1440,7, +0x15f1500,3, +0x15f1510,3, +0x15f1520,5, +0x15f1600,6, +0x15f1640,5, +0x15f1800,2, +0x15f180c,2, +0x15f1840,7, +0x15f1900,3, +0x15f1910,3, +0x15f1920,5, +0x15f1a00,6, +0x15f1a40,5, +0x15f1c00,2, +0x15f1c0c,2, +0x15f1c40,7, +0x15f1d00,3, +0x15f1d10,3, +0x15f1d20,5, +0x15f1e00,6, +0x15f1e40,5, +0x15f2000,5, +0x15f2040,9, +0x15f2100,3, +0x15f2200,1, +0x15f2210,1, +0x15f2220,1, +0x15f2230,1, +0x15f2240,1, +0x15f2300,3, +0x15f2314,1, +0x15f2320,4, +0x15f2400,5, +0x15f2440,5, +0x15f3000,80, +0x15f3200,1, +0x15f8000,7, +0x15f8030,2, +0x15f8040,7, +0x15f8070,2, +0x15f8100,2, +0x15f8120,2, +0x15f8140,2, +0x15f8160,2, +0x15f8180,9, +0x15f8200,7, +0x15f8230,2, +0x15f8240,7, +0x15f8270,2, +0x15f8300,2, +0x15f8320,2, +0x15f8340,2, +0x15f8360,2, +0x15f8380,9, +0x15f8400,11, +0x15f8500,11, +0x15f9000,3, +0x15f9010,2, +0x15f901c,5, +0x15f9040,8, +0x15f9080,3, +0x15f9090,2, +0x15f909c,5, +0x15f90c0,8, +0x15f9100,3, +0x15f9110,2, +0x15f911c,5, +0x15f9140,8, +0x15f9180,3, +0x15f9190,2, +0x15f919c,5, +0x15f91c0,8, +0x15f9200,7, +0x15f9220,12, +0x15f9280,7, +0x15f92a0,12, +0x15f9300,3, +0x15f9310,1, +0x15f9400,3, +0x15f9410,2, +0x15f941c,5, +0x15f9440,8, +0x15f9480,3, +0x15f9490,2, +0x15f949c,5, +0x15f94c0,8, +0x15f9500,3, +0x15f9510,2, +0x15f951c,5, +0x15f9540,8, +0x15f9580,3, +0x15f9590,2, +0x15f959c,5, +0x15f95c0,8, +0x15f9600,7, +0x15f9620,12, +0x15f9680,7, +0x15f96a0,12, +0x15f9700,3, +0x15f9710,1, +0x15f9804,1, +0x15f9824,21, +0x15f9880,16, +0x15f9900,5, +0x15f9920,11, +0x15f9950,9, +0x15f9980,22, +0x15f9a00,22, +0x15f9a80,22, +0x15f9b00,22, +0x15f9b80,22, +0x15f9c00,22, +0x15f9c80,22, +0x15f9d00,22, +0x15f9d80,3, +0x1600000,5, +0x1600018,5, +0x1600030,3, +0x1600044,3, +0x1600100,58, +0x16001f0,3, +0x1600280,3, +0x1600400,5, +0x1600418,5, +0x1600430,3, +0x1600444,3, +0x1600500,58, +0x16005f0,3, +0x1600680,3, +0x1601018,2, +0x1601100,2, +0x1601110,10, +0x1601140,2, +0x1601150,10, +0x1601208,1, +0x1601220,12, +0x1601280,1, +0x1601288,2, +0x1601400,4, +0x1602000,5, +0x1602018,5, +0x1602030,3, +0x1602044,3, +0x1602100,58, +0x16021f0,3, +0x1602280,3, +0x1602400,5, +0x1602418,5, +0x1602430,3, +0x1602444,3, +0x1602500,58, +0x16025f0,3, +0x1602680,3, +0x1603018,2, +0x1603100,2, +0x1603110,10, +0x1603140,2, +0x1603150,10, +0x1603208,1, +0x1603220,12, +0x1603280,1, +0x1603288,2, +0x1603400,4, +0x1604000,2, +0x160400c,1, +0x1604030,3, +0x1604040,2, +0x160404c,1, +0x1604070,3, +0x1604100,2, +0x160410c,1, +0x1604130,3, +0x1604140,2, +0x160414c,1, +0x1604170,3, +0x1604200,15, +0x1604280,15, +0x1604300,15, +0x1604380,15, +0x1604400,15, +0x1604480,15, +0x1604500,15, +0x1604580,15, +0x1604604,10, +0x1604700,2, +0x160470c,7, +0x1604740,1, +0x1604770,1, +0x16047c0,2, +0x16047d0,4, +0x1605000,3, +0x1605010,1, +0x160501c,3, +0x1605104,1, +0x1605110,4, +0x1605124,1, +0x1605130,4, +0x1605144,1, +0x1605150,4, +0x1605164,1, +0x1605170,5, +0x1605190,4, +0x1605a00,4, +0x1605c00,129, +0x1606000,37, +0x1606098,1, +0x1606100,37, +0x1606198,1, +0x1606200,37, +0x1606298,1, +0x1606300,37, +0x1606398,1, +0x1606400,37, +0x1606498,1, +0x1606500,37, +0x1606598,1, +0x1606600,37, +0x1606698,1, +0x1606700,37, +0x1606798,1, +0x160c000,91, +0x160c400,4, +0x160c440,15, +0x160c480,4, +0x160c4c0,15, +0x160c500,4, +0x160c540,15, +0x160c580,4, +0x160c5c0,15, +0x160c600,4, +0x160c640,10, +0x160c680,4, +0x160c6c0,10, +0x160c800,4, +0x160c840,33, +0x160ca00,13, +0x160ca80,1, +0x160ca88,8, +0x160cac0,6, +0x160cae0,1, +0x160cae8,2, +0x160cb04,14, +0x160cc00,4, +0x160ccc8,1, +0x160cfcc,3, +0x160cfe0,99, +0x160d400,4, +0x160d440,15, +0x160d480,4, +0x160d4c0,15, +0x160d500,4, +0x160d540,15, +0x160d580,4, +0x160d5c0,15, +0x160d600,4, +0x160d640,10, +0x160d680,4, +0x160d6c0,10, +0x160d800,4, +0x160d840,33, +0x160da00,13, +0x160da80,1, +0x160da88,8, +0x160dac0,6, +0x160dae0,1, +0x160dae8,2, +0x160db04,14, +0x160dc00,4, +0x160dcc8,1, +0x160dfcc,3, +0x160dfe0,27, +0x160f000,19, +0x160fa00,10, +0x160fa80,3, +0x160fb00,6, +0x1610000,51, +0x1610a00,10, +0x1610a80,3, +0x1611000,2, +0x161100c,4, +0x1611028,3, +0x1611038,4, +0x1611050,2, +0x1611080,4, +0x1611098,7, +0x1611120,4, +0x1611200,4, +0x1611214,7, +0x1611234,3, +0x1611280,8, +0x16112c0,5, +0x1611300,2, +0x161130c,3, +0x1611400,24, +0x1611464,2, +0x1611470,3, +0x1611500,25, +0x16115c0,8, +0x16115e8,5, +0x1611600,5, +0x1611618,1, +0x1611620,1, +0x1611628,1, +0x1611630,2, +0x1611640,2, +0x1611650,2, +0x1611690,4, +0x1611740,2, +0x1611760,6, +0x1611780,6, +0x16117a0,6, +0x16117c0,6, +0x16117e0,1, +0x1611800,2, +0x161180c,4, +0x1611828,3, +0x1611838,4, +0x1611850,2, +0x1611880,4, +0x1611898,7, +0x1611920,4, +0x1611a00,4, +0x1611a14,7, +0x1611a34,3, +0x1611a80,8, +0x1611ac0,5, +0x1611b00,2, +0x1611b0c,3, +0x1611c00,24, +0x1611c64,2, +0x1611c70,3, +0x1611d00,25, +0x1611dc0,8, +0x1611de8,5, +0x1611e00,5, +0x1611e18,1, +0x1611e20,1, +0x1611e28,1, +0x1611e30,2, +0x1611e40,2, +0x1611e50,2, +0x1611e90,4, +0x1611f40,2, +0x1611f60,6, +0x1611f80,6, +0x1611fa0,6, +0x1611fc0,6, +0x1611fe0,1, +0x1612000,19, +0x1612080,2, +0x16120b0,2, +0x16120c0,2, +0x1620000,11, +0x1620040,16, +0x1620084,5, +0x1620200,7, +0x1620220,6, +0x1620240,7, +0x1620260,6, +0x1620280,6, +0x16202a0,2, +0x16202ac,2, +0x16202c0,7, +0x16202e0,7, +0x1620300,2, +0x162030c,2, +0x1620320,6, +0x1620400,2, +0x1621000,19, +0x1622104,23, +0x1622180,7, +0x16221a0,6, +0x16221c0,7, +0x16221e0,6, +0x1622200,4, +0x1622220,4, +0x1622240,11, +0x1622270,32, +0x1622300,24, +0x1622380,20, +0x1622400,61, +0x1622500,25, +0x1622568,4, +0x1622580,2, +0x16225a0,1, +0x16225c0,11, +0x1622600,9, +0x1622640,3, +0x1622650,3, +0x1622664,3, +0x1622680,22, +0x1622800,11, +0x1623000,536, +0x1624104,23, +0x1624180,7, +0x16241a0,6, +0x16241c0,7, +0x16241e0,6, +0x1624200,4, +0x1624220,4, +0x1624240,11, +0x1624270,32, +0x1624300,24, +0x1624380,20, +0x1624400,61, +0x1624500,25, +0x1624568,4, +0x1624580,2, +0x16245a0,1, +0x16245c0,11, +0x1624600,9, +0x1624640,3, +0x1624650,3, +0x1624664,3, +0x1624680,22, +0x1624800,11, +0x1625000,536, +0x162a000,7, +0x162a048,8, +0x162a080,8, +0x162a100,7, +0x162a148,8, +0x162a180,8, +0x1630000,11, +0x1630040,16, +0x1630084,5, +0x1630200,7, +0x1630220,6, +0x1630240,7, +0x1630260,6, +0x1630280,6, +0x16302a0,2, +0x16302ac,2, +0x16302c0,7, +0x16302e0,7, +0x1630300,2, +0x163030c,2, +0x1630320,6, +0x1630400,2, +0x1631000,19, +0x1632104,23, +0x1632180,7, +0x16321a0,6, +0x16321c0,7, +0x16321e0,6, +0x1632200,4, +0x1632220,4, +0x1632240,11, +0x1632270,32, +0x1632300,24, +0x1632380,20, +0x1632400,61, +0x1632500,25, +0x1632568,4, +0x1632580,2, +0x16325a0,1, +0x16325c0,11, +0x1632600,9, +0x1632640,3, +0x1632650,3, +0x1632664,3, +0x1632680,22, +0x1632800,11, +0x1633000,536, +0x1634104,23, +0x1634180,7, +0x16341a0,6, +0x16341c0,7, +0x16341e0,6, +0x1634200,4, +0x1634220,4, +0x1634240,11, +0x1634270,32, +0x1634300,24, +0x1634380,20, +0x1634400,61, +0x1634500,25, +0x1634568,4, +0x1634580,2, +0x16345a0,1, +0x16345c0,11, +0x1634600,9, +0x1634640,3, +0x1634650,3, +0x1634664,3, +0x1634680,22, +0x1634800,11, +0x1635000,536, +0x163a000,7, +0x163a048,8, +0x163a080,8, +0x163a100,7, +0x163a148,8, +0x163a180,8, +0x1640400,4, +0x1640440,4, +0x16405c0,1, +0x1640600,8, +0x1640800,18, +0x1640880,13, +0x16408f0,3, +0x1640900,18, +0x1640980,13, +0x16409f0,3, +0x1640e00,4, +0x1640e20,4, +0x1640e80,16, +0x1640f00,1, +0x1640f20,1, +0x1641020,2, +0x1641208,6, +0x1641228,10, +0x1641288,6, +0x16412a8,10, +0x1641600,32, +0x16418c0,8, +0x1641900,24, +0x16419b0,4, +0x1641aa0,2, +0x1641ac0,4, +0x1642200,19, +0x1642280,19, +0x1642400,14, +0x164243c,9, +0x1642464,14, +0x16424a0,2, +0x16424ac,2, +0x1642500,14, +0x164253c,9, +0x1642564,14, +0x16425a0,2, +0x16425ac,2, +0x1642800,19, +0x1642880,19, +0x1642a10,2, +0x1642a1c,1, +0x1642a50,2, +0x1642a5c,1, +0x1642c00,7, +0x1642c20,1, +0x1642c54,18, +0x1642ca0,1, +0x1642cd4,11, +0x1642e00,1, +0x1642e08,6, +0x1643180,3, +0x1644400,4, +0x1644440,4, +0x16445c0,1, +0x1644600,8, +0x1644800,18, +0x1644880,13, +0x16448f0,3, +0x1644900,18, +0x1644980,13, +0x16449f0,3, +0x1644e00,4, +0x1644e20,4, +0x1644e80,16, +0x1644f00,1, +0x1644f20,1, +0x1645020,2, +0x1645208,6, +0x1645228,10, +0x1645288,6, +0x16452a8,10, +0x1645600,32, +0x16458c0,8, +0x1645900,24, +0x16459b0,4, +0x1645aa0,2, +0x1645ac0,4, +0x1646200,19, +0x1646280,19, +0x1646400,14, +0x164643c,9, +0x1646464,14, +0x16464a0,2, +0x16464ac,2, +0x1646500,14, +0x164653c,9, +0x1646564,14, +0x16465a0,2, +0x16465ac,2, +0x1646800,19, +0x1646880,19, +0x1646a10,2, +0x1646a1c,1, +0x1646a50,2, +0x1646a5c,1, +0x1646c00,7, +0x1646c20,1, +0x1646c54,18, +0x1646ca0,1, +0x1646cd4,11, +0x1646e00,1, +0x1646e08,6, +0x1647180,3, +0x1649000,13, +0x164e000,19, +0x164ea00,10, +0x164ea80,3, +0x164f000,1, +0x164f008,5, +0x164f038,1, +0x164f044,1, +0x164f050,2, +0x164f060,8, +0x164f140,19, +0x164f190,4, +0x1650000,2, +0x165000c,2, +0x1650040,7, +0x1650100,3, +0x1650110,3, +0x1650120,5, +0x1650200,6, +0x1650240,5, +0x1650400,2, +0x165040c,2, +0x1650440,7, +0x1650500,3, +0x1650510,3, +0x1650520,5, +0x1650600,6, +0x1650640,5, +0x1650800,2, +0x165080c,2, +0x1650840,7, +0x1650900,3, +0x1650910,3, +0x1650920,5, +0x1650a00,6, +0x1650a40,5, +0x1650c00,2, +0x1650c0c,2, +0x1650c40,7, +0x1650d00,3, +0x1650d10,3, +0x1650d20,5, +0x1650e00,6, +0x1650e40,5, +0x1651000,2, +0x165100c,2, +0x1651040,7, +0x1651100,3, +0x1651110,3, +0x1651120,5, +0x1651200,6, +0x1651240,5, +0x1651400,2, +0x165140c,2, +0x1651440,7, +0x1651500,3, +0x1651510,3, +0x1651520,5, +0x1651600,6, +0x1651640,5, +0x1651800,2, +0x165180c,2, +0x1651840,7, +0x1651900,3, +0x1651910,3, +0x1651920,5, +0x1651a00,6, +0x1651a40,5, +0x1651c00,2, +0x1651c0c,2, +0x1651c40,7, +0x1651d00,3, +0x1651d10,3, +0x1651d20,5, +0x1651e00,6, +0x1651e40,5, +0x1652000,5, +0x1652040,9, +0x1652100,3, +0x1652200,1, +0x1652210,1, +0x1652220,1, +0x1652230,1, +0x1652240,1, +0x1652300,3, +0x1652314,1, +0x1652320,4, +0x1652400,5, +0x1652440,5, +0x1653000,80, +0x1653200,1, +0x1658000,7, +0x1658030,2, +0x1658040,7, +0x1658070,2, +0x1658100,2, +0x1658120,2, +0x1658140,2, +0x1658160,2, +0x1658180,9, +0x1658200,7, +0x1658230,2, +0x1658240,7, +0x1658270,2, +0x1658300,2, +0x1658320,2, +0x1658340,2, +0x1658360,2, +0x1658380,9, +0x1658400,11, +0x1658500,11, +0x1659000,3, +0x1659010,2, +0x165901c,5, +0x1659040,8, +0x1659080,3, +0x1659090,2, +0x165909c,5, +0x16590c0,8, +0x1659100,3, +0x1659110,2, +0x165911c,5, +0x1659140,8, +0x1659180,3, +0x1659190,2, +0x165919c,5, +0x16591c0,8, +0x1659200,7, +0x1659220,12, +0x1659280,7, +0x16592a0,12, +0x1659300,3, +0x1659310,1, +0x1659400,3, +0x1659410,2, +0x165941c,5, +0x1659440,8, +0x1659480,3, +0x1659490,2, +0x165949c,5, +0x16594c0,8, +0x1659500,3, +0x1659510,2, +0x165951c,5, +0x1659540,8, +0x1659580,3, +0x1659590,2, +0x165959c,5, +0x16595c0,8, +0x1659600,7, +0x1659620,12, +0x1659680,7, +0x16596a0,12, +0x1659700,3, +0x1659710,1, +0x1659804,1, +0x1659824,21, +0x1659880,16, +0x1659900,5, +0x1659920,11, +0x1659950,9, +0x1659980,22, +0x1659a00,22, +0x1659a80,22, +0x1659b00,22, +0x1659b80,22, +0x1659c00,22, +0x1659c80,22, +0x1659d00,22, +0x1659d80,3, +0x1660000,5, +0x1660018,5, +0x1660030,3, +0x1660044,3, +0x1660100,58, +0x16601f0,3, +0x1660280,3, +0x1660400,5, +0x1660418,5, +0x1660430,3, +0x1660444,3, +0x1660500,58, +0x16605f0,3, +0x1660680,3, +0x1661018,2, +0x1661100,2, +0x1661110,10, +0x1661140,2, +0x1661150,10, +0x1661208,1, +0x1661220,12, +0x1661280,1, +0x1661288,2, +0x1661400,4, +0x1662000,5, +0x1662018,5, +0x1662030,3, +0x1662044,3, +0x1662100,58, +0x16621f0,3, +0x1662280,3, +0x1662400,5, +0x1662418,5, +0x1662430,3, +0x1662444,3, +0x1662500,58, +0x16625f0,3, +0x1662680,3, +0x1663018,2, +0x1663100,2, +0x1663110,10, +0x1663140,2, +0x1663150,10, +0x1663208,1, +0x1663220,12, +0x1663280,1, +0x1663288,2, +0x1663400,4, +0x1664000,2, +0x166400c,1, +0x1664030,3, +0x1664040,2, +0x166404c,1, +0x1664070,3, +0x1664100,2, +0x166410c,1, +0x1664130,3, +0x1664140,2, +0x166414c,1, +0x1664170,3, +0x1664200,15, +0x1664280,15, +0x1664300,15, +0x1664380,15, +0x1664400,15, +0x1664480,15, +0x1664500,15, +0x1664580,15, +0x1664604,10, +0x1664700,2, +0x166470c,7, +0x1664740,1, +0x1664770,1, +0x16647c0,2, +0x16647d0,4, +0x1665000,3, +0x1665010,1, +0x166501c,3, +0x1665104,1, +0x1665110,4, +0x1665124,1, +0x1665130,4, +0x1665144,1, +0x1665150,4, +0x1665164,1, +0x1665170,5, +0x1665190,4, +0x1665a00,4, +0x1665c00,129, +0x1666000,37, +0x1666098,1, +0x1666100,37, +0x1666198,1, +0x1666200,37, +0x1666298,1, +0x1666300,37, +0x1666398,1, +0x1666400,37, +0x1666498,1, +0x1666500,37, +0x1666598,1, +0x1666600,37, +0x1666698,1, +0x1666700,37, +0x1666798,1, +0x166c000,91, +0x166c400,4, +0x166c440,15, +0x166c480,4, +0x166c4c0,15, +0x166c500,4, +0x166c540,15, +0x166c580,4, +0x166c5c0,15, +0x166c600,4, +0x166c640,10, +0x166c680,4, +0x166c6c0,10, +0x166c800,4, +0x166c840,33, +0x166ca00,13, +0x166ca80,1, +0x166ca88,8, +0x166cac0,6, +0x166cae0,1, +0x166cae8,2, +0x166cb04,14, +0x166cc00,4, +0x166ccc8,1, +0x166cfcc,3, +0x166cfe0,99, +0x166d400,4, +0x166d440,15, +0x166d480,4, +0x166d4c0,15, +0x166d500,4, +0x166d540,15, +0x166d580,4, +0x166d5c0,15, +0x166d600,4, +0x166d640,10, +0x166d680,4, +0x166d6c0,10, +0x166d800,4, +0x166d840,33, +0x166da00,13, +0x166da80,1, +0x166da88,8, +0x166dac0,6, +0x166dae0,1, +0x166dae8,2, +0x166db04,14, +0x166dc00,4, +0x166dcc8,1, +0x166dfcc,3, +0x166dfe0,27, +0x166f000,19, +0x166fa00,10, +0x166fa80,3, +0x166fb00,6, +0x1670000,51, +0x1670a00,10, +0x1670a80,3, +0x1671000,2, +0x167100c,4, +0x1671028,3, +0x1671038,4, +0x1671050,2, +0x1671080,4, +0x1671098,7, +0x1671120,4, +0x1671200,4, +0x1671214,7, +0x1671234,3, +0x1671280,8, +0x16712c0,5, +0x1671300,2, +0x167130c,3, +0x1671400,24, +0x1671464,2, +0x1671470,3, +0x1671500,25, +0x16715c0,8, +0x16715e8,5, +0x1671600,5, +0x1671618,1, +0x1671620,1, +0x1671628,1, +0x1671630,2, +0x1671640,2, +0x1671650,2, +0x1671690,4, +0x1671740,2, +0x1671760,6, +0x1671780,6, +0x16717a0,6, +0x16717c0,6, +0x16717e0,1, +0x1671800,2, +0x167180c,4, +0x1671828,3, +0x1671838,4, +0x1671850,2, +0x1671880,4, +0x1671898,7, +0x1671920,4, +0x1671a00,4, +0x1671a14,7, +0x1671a34,3, +0x1671a80,8, +0x1671ac0,5, +0x1671b00,2, +0x1671b0c,3, +0x1671c00,24, +0x1671c64,2, +0x1671c70,3, +0x1671d00,25, +0x1671dc0,8, +0x1671de8,5, +0x1671e00,5, +0x1671e18,1, +0x1671e20,1, +0x1671e28,1, +0x1671e30,2, +0x1671e40,2, +0x1671e50,2, +0x1671e90,4, +0x1671f40,2, +0x1671f60,6, +0x1671f80,6, +0x1671fa0,6, +0x1671fc0,6, +0x1671fe0,1, +0x1672000,19, +0x1672080,2, +0x16720b0,2, +0x16720c0,2, +0x1680000,11, +0x1680040,16, +0x1680084,5, +0x1680200,7, +0x1680220,6, +0x1680240,7, +0x1680260,6, +0x1680280,6, +0x16802a0,2, +0x16802ac,2, +0x16802c0,7, +0x16802e0,7, +0x1680300,2, +0x168030c,2, +0x1680320,6, +0x1680400,2, +0x1681000,19, +0x1682104,23, +0x1682180,7, +0x16821a0,6, +0x16821c0,7, +0x16821e0,6, +0x1682200,4, +0x1682220,4, +0x1682240,11, +0x1682270,32, +0x1682300,24, +0x1682380,20, +0x1682400,61, +0x1682500,25, +0x1682568,4, +0x1682580,2, +0x16825a0,1, +0x16825c0,11, +0x1682600,9, +0x1682640,3, +0x1682650,3, +0x1682664,3, +0x1682680,22, +0x1682800,11, +0x1683000,536, +0x1684104,23, +0x1684180,7, +0x16841a0,6, +0x16841c0,7, +0x16841e0,6, +0x1684200,4, +0x1684220,4, +0x1684240,11, +0x1684270,32, +0x1684300,24, +0x1684380,20, +0x1684400,61, +0x1684500,25, +0x1684568,4, +0x1684580,2, +0x16845a0,1, +0x16845c0,11, +0x1684600,9, +0x1684640,3, +0x1684650,3, +0x1684664,3, +0x1684680,22, +0x1684800,11, +0x1685000,536, +0x168a000,7, +0x168a048,8, +0x168a080,8, +0x168a100,7, +0x168a148,8, +0x168a180,8, +0x1690000,11, +0x1690040,16, +0x1690084,5, +0x1690200,7, +0x1690220,6, +0x1690240,7, +0x1690260,6, +0x1690280,6, +0x16902a0,2, +0x16902ac,2, +0x16902c0,7, +0x16902e0,7, +0x1690300,2, +0x169030c,2, +0x1690320,6, +0x1690400,2, +0x1691000,19, +0x1692104,23, +0x1692180,7, +0x16921a0,6, +0x16921c0,7, +0x16921e0,6, +0x1692200,4, +0x1692220,4, +0x1692240,11, +0x1692270,32, +0x1692300,24, +0x1692380,20, +0x1692400,61, +0x1692500,25, +0x1692568,4, +0x1692580,2, +0x16925a0,1, +0x16925c0,11, +0x1692600,9, +0x1692640,3, +0x1692650,3, +0x1692664,3, +0x1692680,22, +0x1692800,11, +0x1693000,536, +0x1694104,23, +0x1694180,7, +0x16941a0,6, +0x16941c0,7, +0x16941e0,6, +0x1694200,4, +0x1694220,4, +0x1694240,11, +0x1694270,32, +0x1694300,24, +0x1694380,20, +0x1694400,61, +0x1694500,25, +0x1694568,4, +0x1694580,2, +0x16945a0,1, +0x16945c0,11, +0x1694600,9, +0x1694640,3, +0x1694650,3, +0x1694664,3, +0x1694680,22, +0x1694800,11, +0x1695000,536, +0x169a000,7, +0x169a048,8, +0x169a080,8, +0x169a100,7, +0x169a148,8, +0x169a180,8, +0x16a0400,4, +0x16a0440,4, +0x16a05c0,1, +0x16a0600,8, +0x16a0800,18, +0x16a0880,13, +0x16a08f0,3, +0x16a0900,18, +0x16a0980,13, +0x16a09f0,3, +0x16a0e00,4, +0x16a0e20,4, +0x16a0e80,16, +0x16a0f00,1, +0x16a0f20,1, +0x16a1020,2, +0x16a1208,6, +0x16a1228,10, +0x16a1288,6, +0x16a12a8,10, +0x16a1600,32, +0x16a18c0,8, +0x16a1900,24, +0x16a19b0,4, +0x16a1aa0,2, +0x16a1ac0,4, +0x16a2200,19, +0x16a2280,19, +0x16a2400,14, +0x16a243c,9, +0x16a2464,14, +0x16a24a0,2, +0x16a24ac,2, +0x16a2500,14, +0x16a253c,9, +0x16a2564,14, +0x16a25a0,2, +0x16a25ac,2, +0x16a2800,19, +0x16a2880,19, +0x16a2a10,2, +0x16a2a1c,1, +0x16a2a50,2, +0x16a2a5c,1, +0x16a2c00,7, +0x16a2c20,1, +0x16a2c54,18, +0x16a2ca0,1, +0x16a2cd4,11, +0x16a2e00,1, +0x16a2e08,6, +0x16a3180,3, +0x16a4400,4, +0x16a4440,4, +0x16a45c0,1, +0x16a4600,8, +0x16a4800,18, +0x16a4880,13, +0x16a48f0,3, +0x16a4900,18, +0x16a4980,13, +0x16a49f0,3, +0x16a4e00,4, +0x16a4e20,4, +0x16a4e80,16, +0x16a4f00,1, +0x16a4f20,1, +0x16a5020,2, +0x16a5208,6, +0x16a5228,10, +0x16a5288,6, +0x16a52a8,10, +0x16a5600,32, +0x16a58c0,8, +0x16a5900,24, +0x16a59b0,4, +0x16a5aa0,2, +0x16a5ac0,4, +0x16a6200,19, +0x16a6280,19, +0x16a6400,14, +0x16a643c,9, +0x16a6464,14, +0x16a64a0,2, +0x16a64ac,2, +0x16a6500,14, +0x16a653c,9, +0x16a6564,14, +0x16a65a0,2, +0x16a65ac,2, +0x16a6800,19, +0x16a6880,19, +0x16a6a10,2, +0x16a6a1c,1, +0x16a6a50,2, +0x16a6a5c,1, +0x16a6c00,7, +0x16a6c20,1, +0x16a6c54,18, +0x16a6ca0,1, +0x16a6cd4,11, +0x16a6e00,1, +0x16a6e08,6, +0x16a7180,3, +0x16a9000,13, +0x16ae000,19, +0x16aea00,10, +0x16aea80,3, +0x16af000,1, +0x16af008,5, +0x16af038,1, +0x16af044,1, +0x16af050,2, +0x16af060,8, +0x16af140,19, +0x16af190,4, +0x16b0000,2, +0x16b000c,2, +0x16b0040,7, +0x16b0100,3, +0x16b0110,3, +0x16b0120,5, +0x16b0200,6, +0x16b0240,5, +0x16b0400,2, +0x16b040c,2, +0x16b0440,7, +0x16b0500,3, +0x16b0510,3, +0x16b0520,5, +0x16b0600,6, +0x16b0640,5, +0x16b0800,2, +0x16b080c,2, +0x16b0840,7, +0x16b0900,3, +0x16b0910,3, +0x16b0920,5, +0x16b0a00,6, +0x16b0a40,5, +0x16b0c00,2, +0x16b0c0c,2, +0x16b0c40,7, +0x16b0d00,3, +0x16b0d10,3, +0x16b0d20,5, +0x16b0e00,6, +0x16b0e40,5, +0x16b1000,2, +0x16b100c,2, +0x16b1040,7, +0x16b1100,3, +0x16b1110,3, +0x16b1120,5, +0x16b1200,6, +0x16b1240,5, +0x16b1400,2, +0x16b140c,2, +0x16b1440,7, +0x16b1500,3, +0x16b1510,3, +0x16b1520,5, +0x16b1600,6, +0x16b1640,5, +0x16b1800,2, +0x16b180c,2, +0x16b1840,7, +0x16b1900,3, +0x16b1910,3, +0x16b1920,5, +0x16b1a00,6, +0x16b1a40,5, +0x16b1c00,2, +0x16b1c0c,2, +0x16b1c40,7, +0x16b1d00,3, +0x16b1d10,3, +0x16b1d20,5, +0x16b1e00,6, +0x16b1e40,5, +0x16b2000,5, +0x16b2040,9, +0x16b2100,3, +0x16b2200,1, +0x16b2210,1, +0x16b2220,1, +0x16b2230,1, +0x16b2240,1, +0x16b2300,3, +0x16b2314,1, +0x16b2320,4, +0x16b2400,5, +0x16b2440,5, +0x16b3000,80, +0x16b3200,1, +0x16b8000,7, +0x16b8030,2, +0x16b8040,7, +0x16b8070,2, +0x16b8100,2, +0x16b8120,2, +0x16b8140,2, +0x16b8160,2, +0x16b8180,9, +0x16b8200,7, +0x16b8230,2, +0x16b8240,7, +0x16b8270,2, +0x16b8300,2, +0x16b8320,2, +0x16b8340,2, +0x16b8360,2, +0x16b8380,9, +0x16b8400,11, +0x16b8500,11, +0x16b9000,3, +0x16b9010,2, +0x16b901c,5, +0x16b9040,8, +0x16b9080,3, +0x16b9090,2, +0x16b909c,5, +0x16b90c0,8, +0x16b9100,3, +0x16b9110,2, +0x16b911c,5, +0x16b9140,8, +0x16b9180,3, +0x16b9190,2, +0x16b919c,5, +0x16b91c0,8, +0x16b9200,7, +0x16b9220,12, +0x16b9280,7, +0x16b92a0,12, +0x16b9300,3, +0x16b9310,1, +0x16b9400,3, +0x16b9410,2, +0x16b941c,5, +0x16b9440,8, +0x16b9480,3, +0x16b9490,2, +0x16b949c,5, +0x16b94c0,8, +0x16b9500,3, +0x16b9510,2, +0x16b951c,5, +0x16b9540,8, +0x16b9580,3, +0x16b9590,2, +0x16b959c,5, +0x16b95c0,8, +0x16b9600,7, +0x16b9620,12, +0x16b9680,7, +0x16b96a0,12, +0x16b9700,3, +0x16b9710,1, +0x16b9804,1, +0x16b9824,21, +0x16b9880,16, +0x16b9900,5, +0x16b9920,11, +0x16b9950,9, +0x16b9980,22, +0x16b9a00,22, +0x16b9a80,22, +0x16b9b00,22, +0x16b9b80,22, +0x16b9c00,22, +0x16b9c80,22, +0x16b9d00,22, +0x16b9d80,3, +0x16c0000,5, +0x16c0018,5, +0x16c0030,3, +0x16c0044,3, +0x16c0100,58, +0x16c01f0,3, +0x16c0280,3, +0x16c0400,5, +0x16c0418,5, +0x16c0430,3, +0x16c0444,3, +0x16c0500,58, +0x16c05f0,3, +0x16c0680,3, +0x16c1018,2, +0x16c1100,2, +0x16c1110,10, +0x16c1140,2, +0x16c1150,10, +0x16c1208,1, +0x16c1220,12, +0x16c1280,1, +0x16c1288,2, +0x16c1400,4, +0x16c2000,5, +0x16c2018,5, +0x16c2030,3, +0x16c2044,3, +0x16c2100,58, +0x16c21f0,3, +0x16c2280,3, +0x16c2400,5, +0x16c2418,5, +0x16c2430,3, +0x16c2444,3, +0x16c2500,58, +0x16c25f0,3, +0x16c2680,3, +0x16c3018,2, +0x16c3100,2, +0x16c3110,10, +0x16c3140,2, +0x16c3150,10, +0x16c3208,1, +0x16c3220,12, +0x16c3280,1, +0x16c3288,2, +0x16c3400,4, +0x16c4000,2, +0x16c400c,1, +0x16c4030,3, +0x16c4040,2, +0x16c404c,1, +0x16c4070,3, +0x16c4100,2, +0x16c410c,1, +0x16c4130,3, +0x16c4140,2, +0x16c414c,1, +0x16c4170,3, +0x16c4200,15, +0x16c4280,15, +0x16c4300,15, +0x16c4380,15, +0x16c4400,15, +0x16c4480,15, +0x16c4500,15, +0x16c4580,15, +0x16c4604,10, +0x16c4700,2, +0x16c470c,7, +0x16c4740,1, +0x16c4770,1, +0x16c47c0,2, +0x16c47d0,4, +0x16c5000,3, +0x16c5010,1, +0x16c501c,3, +0x16c5104,1, +0x16c5110,4, +0x16c5124,1, +0x16c5130,4, +0x16c5144,1, +0x16c5150,4, +0x16c5164,1, +0x16c5170,5, +0x16c5190,4, +0x16c5a00,4, +0x16c5c00,129, +0x16c6000,37, +0x16c6098,1, +0x16c6100,37, +0x16c6198,1, +0x16c6200,37, +0x16c6298,1, +0x16c6300,37, +0x16c6398,1, +0x16c6400,37, +0x16c6498,1, +0x16c6500,37, +0x16c6598,1, +0x16c6600,37, +0x16c6698,1, +0x16c6700,37, +0x16c6798,1, +0x16cc000,91, +0x16cc400,4, +0x16cc440,15, +0x16cc480,4, +0x16cc4c0,15, +0x16cc500,4, +0x16cc540,15, +0x16cc580,4, +0x16cc5c0,15, +0x16cc600,4, +0x16cc640,10, +0x16cc680,4, +0x16cc6c0,10, +0x16cc800,4, +0x16cc840,33, +0x16cca00,13, +0x16cca80,1, +0x16cca88,8, +0x16ccac0,6, +0x16ccae0,1, +0x16ccae8,2, +0x16ccb04,14, +0x16ccc00,4, +0x16cccc8,1, +0x16ccfcc,3, +0x16ccfe0,99, +0x16cd400,4, +0x16cd440,15, +0x16cd480,4, +0x16cd4c0,15, +0x16cd500,4, +0x16cd540,15, +0x16cd580,4, +0x16cd5c0,15, +0x16cd600,4, +0x16cd640,10, +0x16cd680,4, +0x16cd6c0,10, +0x16cd800,4, +0x16cd840,33, +0x16cda00,13, +0x16cda80,1, +0x16cda88,8, +0x16cdac0,6, +0x16cdae0,1, +0x16cdae8,2, +0x16cdb04,14, +0x16cdc00,4, +0x16cdcc8,1, +0x16cdfcc,3, +0x16cdfe0,27, +0x16cf000,19, +0x16cfa00,10, +0x16cfa80,3, +0x16cfb00,6, +0x16d0000,51, +0x16d0a00,10, +0x16d0a80,3, +0x16d1000,2, +0x16d100c,4, +0x16d1028,3, +0x16d1038,4, +0x16d1050,2, +0x16d1080,4, +0x16d1098,7, +0x16d1120,4, +0x16d1200,4, +0x16d1214,7, +0x16d1234,3, +0x16d1280,8, +0x16d12c0,5, +0x16d1300,2, +0x16d130c,3, +0x16d1400,24, +0x16d1464,2, +0x16d1470,3, +0x16d1500,25, +0x16d15c0,8, +0x16d15e8,5, +0x16d1600,5, +0x16d1618,1, +0x16d1620,1, +0x16d1628,1, +0x16d1630,2, +0x16d1640,2, +0x16d1650,2, +0x16d1690,4, +0x16d1740,2, +0x16d1760,6, +0x16d1780,6, +0x16d17a0,6, +0x16d17c0,6, +0x16d17e0,1, +0x16d1800,2, +0x16d180c,4, +0x16d1828,3, +0x16d1838,4, +0x16d1850,2, +0x16d1880,4, +0x16d1898,7, +0x16d1920,4, +0x16d1a00,4, +0x16d1a14,7, +0x16d1a34,3, +0x16d1a80,8, +0x16d1ac0,5, +0x16d1b00,2, +0x16d1b0c,3, +0x16d1c00,24, +0x16d1c64,2, +0x16d1c70,3, +0x16d1d00,25, +0x16d1dc0,8, +0x16d1de8,5, +0x16d1e00,5, +0x16d1e18,1, +0x16d1e20,1, +0x16d1e28,1, +0x16d1e30,2, +0x16d1e40,2, +0x16d1e50,2, +0x16d1e90,4, +0x16d1f40,2, +0x16d1f60,6, +0x16d1f80,6, +0x16d1fa0,6, +0x16d1fc0,6, +0x16d1fe0,1, +0x16d2000,19, +0x16d2080,2, +0x16d20b0,2, +0x16d20c0,2, +0x16e0000,11, +0x16e0040,16, +0x16e0084,5, +0x16e0200,7, +0x16e0220,6, +0x16e0240,7, +0x16e0260,6, +0x16e0280,6, +0x16e02a0,2, +0x16e02ac,2, +0x16e02c0,7, +0x16e02e0,7, +0x16e0300,2, +0x16e030c,2, +0x16e0320,6, +0x16e0400,2, +0x16e1000,19, +0x16e2104,23, +0x16e2180,7, +0x16e21a0,6, +0x16e21c0,7, +0x16e21e0,6, +0x16e2200,4, +0x16e2220,4, +0x16e2240,11, +0x16e2270,32, +0x16e2300,24, +0x16e2380,20, +0x16e2400,61, +0x16e2500,25, +0x16e2568,4, +0x16e2580,2, +0x16e25a0,1, +0x16e25c0,11, +0x16e2600,9, +0x16e2640,3, +0x16e2650,3, +0x16e2664,3, +0x16e2680,22, +0x16e2800,11, +0x16e3000,536, +0x16e4104,23, +0x16e4180,7, +0x16e41a0,6, +0x16e41c0,7, +0x16e41e0,6, +0x16e4200,4, +0x16e4220,4, +0x16e4240,11, +0x16e4270,32, +0x16e4300,24, +0x16e4380,20, +0x16e4400,61, +0x16e4500,25, +0x16e4568,4, +0x16e4580,2, +0x16e45a0,1, +0x16e45c0,11, +0x16e4600,9, +0x16e4640,3, +0x16e4650,3, +0x16e4664,3, +0x16e4680,22, +0x16e4800,11, +0x16e5000,536, +0x16ea000,7, +0x16ea048,8, +0x16ea080,8, +0x16ea100,7, +0x16ea148,8, +0x16ea180,8, +0x16f0000,11, +0x16f0040,16, +0x16f0084,5, +0x16f0200,7, +0x16f0220,6, +0x16f0240,7, +0x16f0260,6, +0x16f0280,6, +0x16f02a0,2, +0x16f02ac,2, +0x16f02c0,7, +0x16f02e0,7, +0x16f0300,2, +0x16f030c,2, +0x16f0320,6, +0x16f0400,2, +0x16f1000,19, +0x16f2104,23, +0x16f2180,7, +0x16f21a0,6, +0x16f21c0,7, +0x16f21e0,6, +0x16f2200,4, +0x16f2220,4, +0x16f2240,11, +0x16f2270,32, +0x16f2300,24, +0x16f2380,20, +0x16f2400,61, +0x16f2500,25, +0x16f2568,4, +0x16f2580,2, +0x16f25a0,1, +0x16f25c0,11, +0x16f2600,9, +0x16f2640,3, +0x16f2650,3, +0x16f2664,3, +0x16f2680,22, +0x16f2800,11, +0x16f3000,536, +0x16f4104,23, +0x16f4180,7, +0x16f41a0,6, +0x16f41c0,7, +0x16f41e0,6, +0x16f4200,4, +0x16f4220,4, +0x16f4240,11, +0x16f4270,32, +0x16f4300,24, +0x16f4380,20, +0x16f4400,61, +0x16f4500,25, +0x16f4568,4, +0x16f4580,2, +0x16f45a0,1, +0x16f45c0,11, +0x16f4600,9, +0x16f4640,3, +0x16f4650,3, +0x16f4664,3, +0x16f4680,22, +0x16f4800,11, +0x16f5000,536, +0x16fa000,7, +0x16fa048,8, +0x16fa080,8, +0x16fa100,7, +0x16fa148,8, +0x16fa180,8, +0x1700400,4, +0x1700440,4, +0x17005c0,1, +0x1700600,8, +0x1700800,18, +0x1700880,13, +0x17008f0,3, +0x1700900,18, +0x1700980,13, +0x17009f0,3, +0x1700e00,4, +0x1700e20,4, +0x1700e80,16, +0x1700f00,1, +0x1700f20,1, +0x1701020,2, +0x1701208,6, +0x1701228,10, +0x1701288,6, +0x17012a8,10, +0x1701600,32, +0x17018c0,8, +0x1701900,24, +0x17019b0,4, +0x1701aa0,2, +0x1701ac0,4, +0x1702200,19, +0x1702280,19, +0x1702400,14, +0x170243c,9, +0x1702464,14, +0x17024a0,2, +0x17024ac,2, +0x1702500,14, +0x170253c,9, +0x1702564,14, +0x17025a0,2, +0x17025ac,2, +0x1702800,19, +0x1702880,19, +0x1702a10,2, +0x1702a1c,1, +0x1702a50,2, +0x1702a5c,1, +0x1702c00,7, +0x1702c20,1, +0x1702c54,18, +0x1702ca0,1, +0x1702cd4,11, +0x1702e00,1, +0x1702e08,6, +0x1703180,3, +0x1704400,4, +0x1704440,4, +0x17045c0,1, +0x1704600,8, +0x1704800,18, +0x1704880,13, +0x17048f0,3, +0x1704900,18, +0x1704980,13, +0x17049f0,3, +0x1704e00,4, +0x1704e20,4, +0x1704e80,16, +0x1704f00,1, +0x1704f20,1, +0x1705020,2, +0x1705208,6, +0x1705228,10, +0x1705288,6, +0x17052a8,10, +0x1705600,32, +0x17058c0,8, +0x1705900,24, +0x17059b0,4, +0x1705aa0,2, +0x1705ac0,4, +0x1706200,19, +0x1706280,19, +0x1706400,14, +0x170643c,9, +0x1706464,14, +0x17064a0,2, +0x17064ac,2, +0x1706500,14, +0x170653c,9, +0x1706564,14, +0x17065a0,2, +0x17065ac,2, +0x1706800,19, +0x1706880,19, +0x1706a10,2, +0x1706a1c,1, +0x1706a50,2, +0x1706a5c,1, +0x1706c00,7, +0x1706c20,1, +0x1706c54,18, +0x1706ca0,1, +0x1706cd4,11, +0x1706e00,1, +0x1706e08,6, +0x1707180,3, +0x1709000,13, +0x170e000,19, +0x170ea00,10, +0x170ea80,3, +0x170f000,1, +0x170f008,5, +0x170f038,1, +0x170f044,1, +0x170f050,2, +0x170f060,8, +0x170f140,19, +0x170f190,4, +0x1710000,2, +0x171000c,2, +0x1710040,7, +0x1710100,3, +0x1710110,3, +0x1710120,5, +0x1710200,6, +0x1710240,5, +0x1710400,2, +0x171040c,2, +0x1710440,7, +0x1710500,3, +0x1710510,3, +0x1710520,5, +0x1710600,6, +0x1710640,5, +0x1710800,2, +0x171080c,2, +0x1710840,7, +0x1710900,3, +0x1710910,3, +0x1710920,5, +0x1710a00,6, +0x1710a40,5, +0x1710c00,2, +0x1710c0c,2, +0x1710c40,7, +0x1710d00,3, +0x1710d10,3, +0x1710d20,5, +0x1710e00,6, +0x1710e40,5, +0x1711000,2, +0x171100c,2, +0x1711040,7, +0x1711100,3, +0x1711110,3, +0x1711120,5, +0x1711200,6, +0x1711240,5, +0x1711400,2, +0x171140c,2, +0x1711440,7, +0x1711500,3, +0x1711510,3, +0x1711520,5, +0x1711600,6, +0x1711640,5, +0x1711800,2, +0x171180c,2, +0x1711840,7, +0x1711900,3, +0x1711910,3, +0x1711920,5, +0x1711a00,6, +0x1711a40,5, +0x1711c00,2, +0x1711c0c,2, +0x1711c40,7, +0x1711d00,3, +0x1711d10,3, +0x1711d20,5, +0x1711e00,6, +0x1711e40,5, +0x1712000,5, +0x1712040,9, +0x1712100,3, +0x1712200,1, +0x1712210,1, +0x1712220,1, +0x1712230,1, +0x1712240,1, +0x1712300,3, +0x1712314,1, +0x1712320,4, +0x1712400,5, +0x1712440,5, +0x1713000,80, +0x1713200,1, +0x1718000,7, +0x1718030,2, +0x1718040,7, +0x1718070,2, +0x1718100,2, +0x1718120,2, +0x1718140,2, +0x1718160,2, +0x1718180,9, +0x1718200,7, +0x1718230,2, +0x1718240,7, +0x1718270,2, +0x1718300,2, +0x1718320,2, +0x1718340,2, +0x1718360,2, +0x1718380,9, +0x1718400,11, +0x1718500,11, +0x1719000,3, +0x1719010,2, +0x171901c,5, +0x1719040,8, +0x1719080,3, +0x1719090,2, +0x171909c,5, +0x17190c0,8, +0x1719100,3, +0x1719110,2, +0x171911c,5, +0x1719140,8, +0x1719180,3, +0x1719190,2, +0x171919c,5, +0x17191c0,8, +0x1719200,7, +0x1719220,12, +0x1719280,7, +0x17192a0,12, +0x1719300,3, +0x1719310,1, +0x1719400,3, +0x1719410,2, +0x171941c,5, +0x1719440,8, +0x1719480,3, +0x1719490,2, +0x171949c,5, +0x17194c0,8, +0x1719500,3, +0x1719510,2, +0x171951c,5, +0x1719540,8, +0x1719580,3, +0x1719590,2, +0x171959c,5, +0x17195c0,8, +0x1719600,7, +0x1719620,12, +0x1719680,7, +0x17196a0,12, +0x1719700,3, +0x1719710,1, +0x1719804,1, +0x1719824,21, +0x1719880,16, +0x1719900,5, +0x1719920,11, +0x1719950,9, +0x1719980,22, +0x1719a00,22, +0x1719a80,22, +0x1719b00,22, +0x1719b80,22, +0x1719c00,22, +0x1719c80,22, +0x1719d00,22, +0x1719d80,3, +0x1720000,5, +0x1720018,5, +0x1720030,3, +0x1720044,3, +0x1720100,58, +0x17201f0,3, +0x1720280,3, +0x1720400,5, +0x1720418,5, +0x1720430,3, +0x1720444,3, +0x1720500,58, +0x17205f0,3, +0x1720680,3, +0x1721018,2, +0x1721100,2, +0x1721110,10, +0x1721140,2, +0x1721150,10, +0x1721208,1, +0x1721220,12, +0x1721280,1, +0x1721288,2, +0x1721400,4, +0x1722000,5, +0x1722018,5, +0x1722030,3, +0x1722044,3, +0x1722100,58, +0x17221f0,3, +0x1722280,3, +0x1722400,5, +0x1722418,5, +0x1722430,3, +0x1722444,3, +0x1722500,58, +0x17225f0,3, +0x1722680,3, +0x1723018,2, +0x1723100,2, +0x1723110,10, +0x1723140,2, +0x1723150,10, +0x1723208,1, +0x1723220,12, +0x1723280,1, +0x1723288,2, +0x1723400,4, +0x1724000,2, +0x172400c,1, +0x1724030,3, +0x1724040,2, +0x172404c,1, +0x1724070,3, +0x1724100,2, +0x172410c,1, +0x1724130,3, +0x1724140,2, +0x172414c,1, +0x1724170,3, +0x1724200,15, +0x1724280,15, +0x1724300,15, +0x1724380,15, +0x1724400,15, +0x1724480,15, +0x1724500,15, +0x1724580,15, +0x1724604,10, +0x1724700,2, +0x172470c,7, +0x1724740,1, +0x1724770,1, +0x17247c0,2, +0x17247d0,4, +0x1725000,3, +0x1725010,1, +0x172501c,3, +0x1725104,1, +0x1725110,4, +0x1725124,1, +0x1725130,4, +0x1725144,1, +0x1725150,4, +0x1725164,1, +0x1725170,5, +0x1725190,4, +0x1725a00,4, +0x1725c00,129, +0x1726000,37, +0x1726098,1, +0x1726100,37, +0x1726198,1, +0x1726200,37, +0x1726298,1, +0x1726300,37, +0x1726398,1, +0x1726400,37, +0x1726498,1, +0x1726500,37, +0x1726598,1, +0x1726600,37, +0x1726698,1, +0x1726700,37, +0x1726798,1, +0x172c000,91, +0x172c400,4, +0x172c440,15, +0x172c480,4, +0x172c4c0,15, +0x172c500,4, +0x172c540,15, +0x172c580,4, +0x172c5c0,15, +0x172c600,4, +0x172c640,10, +0x172c680,4, +0x172c6c0,10, +0x172c800,4, +0x172c840,33, +0x172ca00,13, +0x172ca80,1, +0x172ca88,8, +0x172cac0,6, +0x172cae0,1, +0x172cae8,2, +0x172cb04,14, +0x172cc00,4, +0x172ccc8,1, +0x172cfcc,3, +0x172cfe0,99, +0x172d400,4, +0x172d440,15, +0x172d480,4, +0x172d4c0,15, +0x172d500,4, +0x172d540,15, +0x172d580,4, +0x172d5c0,15, +0x172d600,4, +0x172d640,10, +0x172d680,4, +0x172d6c0,10, +0x172d800,4, +0x172d840,33, +0x172da00,13, +0x172da80,1, +0x172da88,8, +0x172dac0,6, +0x172dae0,1, +0x172dae8,2, +0x172db04,14, +0x172dc00,4, +0x172dcc8,1, +0x172dfcc,3, +0x172dfe0,27, +0x172f000,19, +0x172fa00,10, +0x172fa80,3, +0x172fb00,6, +0x1730000,51, +0x1730a00,10, +0x1730a80,3, +0x1731000,2, +0x173100c,4, +0x1731028,3, +0x1731038,4, +0x1731050,2, +0x1731080,4, +0x1731098,7, +0x1731120,4, +0x1731200,4, +0x1731214,7, +0x1731234,3, +0x1731280,8, +0x17312c0,5, +0x1731300,2, +0x173130c,3, +0x1731400,24, +0x1731464,2, +0x1731470,3, +0x1731500,25, +0x17315c0,8, +0x17315e8,5, +0x1731600,5, +0x1731618,1, +0x1731620,1, +0x1731628,1, +0x1731630,2, +0x1731640,2, +0x1731650,2, +0x1731690,4, +0x1731740,2, +0x1731760,6, +0x1731780,6, +0x17317a0,6, +0x17317c0,6, +0x17317e0,1, +0x1731800,2, +0x173180c,4, +0x1731828,3, +0x1731838,4, +0x1731850,2, +0x1731880,4, +0x1731898,7, +0x1731920,4, +0x1731a00,4, +0x1731a14,7, +0x1731a34,3, +0x1731a80,8, +0x1731ac0,5, +0x1731b00,2, +0x1731b0c,3, +0x1731c00,24, +0x1731c64,2, +0x1731c70,3, +0x1731d00,25, +0x1731dc0,8, +0x1731de8,5, +0x1731e00,5, +0x1731e18,1, +0x1731e20,1, +0x1731e28,1, +0x1731e30,2, +0x1731e40,2, +0x1731e50,2, +0x1731e90,4, +0x1731f40,2, +0x1731f60,6, +0x1731f80,6, +0x1731fa0,6, +0x1731fc0,6, +0x1731fe0,1, +0x1732000,19, +0x1732080,2, +0x17320b0,2, +0x17320c0,2, +0x1740000,11, +0x1740040,16, +0x1740084,5, +0x1740200,7, +0x1740220,6, +0x1740240,7, +0x1740260,6, +0x1740280,6, +0x17402a0,2, +0x17402ac,2, +0x17402c0,7, +0x17402e0,7, +0x1740300,2, +0x174030c,2, +0x1740320,6, +0x1740400,2, +0x1741000,19, +0x1742104,23, +0x1742180,7, +0x17421a0,6, +0x17421c0,7, +0x17421e0,6, +0x1742200,4, +0x1742220,4, +0x1742240,11, +0x1742270,32, +0x1742300,24, +0x1742380,20, +0x1742400,61, +0x1742500,25, +0x1742568,4, +0x1742580,2, +0x17425a0,1, +0x17425c0,11, +0x1742600,9, +0x1742640,3, +0x1742650,3, +0x1742664,3, +0x1742680,22, +0x1742800,11, +0x1743000,536, +0x1744104,23, +0x1744180,7, +0x17441a0,6, +0x17441c0,7, +0x17441e0,6, +0x1744200,4, +0x1744220,4, +0x1744240,11, +0x1744270,32, +0x1744300,24, +0x1744380,20, +0x1744400,61, +0x1744500,25, +0x1744568,4, +0x1744580,2, +0x17445a0,1, +0x17445c0,11, +0x1744600,9, +0x1744640,3, +0x1744650,3, +0x1744664,3, +0x1744680,22, +0x1744800,11, +0x1745000,536, +0x174a000,7, +0x174a048,8, +0x174a080,8, +0x174a100,7, +0x174a148,8, +0x174a180,8, +0x1750000,11, +0x1750040,16, +0x1750084,5, +0x1750200,7, +0x1750220,6, +0x1750240,7, +0x1750260,6, +0x1750280,6, +0x17502a0,2, +0x17502ac,2, +0x17502c0,7, +0x17502e0,7, +0x1750300,2, +0x175030c,2, +0x1750320,6, +0x1750400,2, +0x1751000,19, +0x1752104,23, +0x1752180,7, +0x17521a0,6, +0x17521c0,7, +0x17521e0,6, +0x1752200,4, +0x1752220,4, +0x1752240,11, +0x1752270,32, +0x1752300,24, +0x1752380,20, +0x1752400,61, +0x1752500,25, +0x1752568,4, +0x1752580,2, +0x17525a0,1, +0x17525c0,11, +0x1752600,9, +0x1752640,3, +0x1752650,3, +0x1752664,3, +0x1752680,22, +0x1752800,11, +0x1753000,536, +0x1754104,23, +0x1754180,7, +0x17541a0,6, +0x17541c0,7, +0x17541e0,6, +0x1754200,4, +0x1754220,4, +0x1754240,11, +0x1754270,32, +0x1754300,24, +0x1754380,20, +0x1754400,61, +0x1754500,25, +0x1754568,4, +0x1754580,2, +0x17545a0,1, +0x17545c0,11, +0x1754600,9, +0x1754640,3, +0x1754650,3, +0x1754664,3, +0x1754680,22, +0x1754800,11, +0x1755000,536, +0x175a000,7, +0x175a048,8, +0x175a080,8, +0x175a100,7, +0x175a148,8, +0x175a180,8, +0x1760400,4, +0x1760440,4, +0x17605c0,1, +0x1760600,8, +0x1760800,18, +0x1760880,13, +0x17608f0,3, +0x1760900,18, +0x1760980,13, +0x17609f0,3, +0x1760e00,4, +0x1760e20,4, +0x1760e80,16, +0x1760f00,1, +0x1760f20,1, +0x1761020,2, +0x1761208,6, +0x1761228,10, +0x1761288,6, +0x17612a8,10, +0x1761600,32, +0x17618c0,8, +0x1761900,24, +0x17619b0,4, +0x1761aa0,2, +0x1761ac0,4, +0x1762200,19, +0x1762280,19, +0x1762400,14, +0x176243c,9, +0x1762464,14, +0x17624a0,2, +0x17624ac,2, +0x1762500,14, +0x176253c,9, +0x1762564,14, +0x17625a0,2, +0x17625ac,2, +0x1762800,19, +0x1762880,19, +0x1762a10,2, +0x1762a1c,1, +0x1762a50,2, +0x1762a5c,1, +0x1762c00,7, +0x1762c20,1, +0x1762c54,18, +0x1762ca0,1, +0x1762cd4,11, +0x1762e00,1, +0x1762e08,6, +0x1763180,3, +0x1764400,4, +0x1764440,4, +0x17645c0,1, +0x1764600,8, +0x1764800,18, +0x1764880,13, +0x17648f0,3, +0x1764900,18, +0x1764980,13, +0x17649f0,3, +0x1764e00,4, +0x1764e20,4, +0x1764e80,16, +0x1764f00,1, +0x1764f20,1, +0x1765020,2, +0x1765208,6, +0x1765228,10, +0x1765288,6, +0x17652a8,10, +0x1765600,32, +0x17658c0,8, +0x1765900,24, +0x17659b0,4, +0x1765aa0,2, +0x1765ac0,4, +0x1766200,19, +0x1766280,19, +0x1766400,14, +0x176643c,9, +0x1766464,14, +0x17664a0,2, +0x17664ac,2, +0x1766500,14, +0x176653c,9, +0x1766564,14, +0x17665a0,2, +0x17665ac,2, +0x1766800,19, +0x1766880,19, +0x1766a10,2, +0x1766a1c,1, +0x1766a50,2, +0x1766a5c,1, +0x1766c00,7, +0x1766c20,1, +0x1766c54,18, +0x1766ca0,1, +0x1766cd4,11, +0x1766e00,1, +0x1766e08,6, +0x1767180,3, +0x1769000,13, +0x176e000,19, +0x176ea00,10, +0x176ea80,3, +0x176f000,1, +0x176f008,5, +0x176f038,1, +0x176f044,1, +0x176f050,2, +0x176f060,8, +0x176f140,19, +0x176f190,4, +0x1770000,2, +0x177000c,2, +0x1770040,7, +0x1770100,3, +0x1770110,3, +0x1770120,5, +0x1770200,6, +0x1770240,5, +0x1770400,2, +0x177040c,2, +0x1770440,7, +0x1770500,3, +0x1770510,3, +0x1770520,5, +0x1770600,6, +0x1770640,5, +0x1770800,2, +0x177080c,2, +0x1770840,7, +0x1770900,3, +0x1770910,3, +0x1770920,5, +0x1770a00,6, +0x1770a40,5, +0x1770c00,2, +0x1770c0c,2, +0x1770c40,7, +0x1770d00,3, +0x1770d10,3, +0x1770d20,5, +0x1770e00,6, +0x1770e40,5, +0x1771000,2, +0x177100c,2, +0x1771040,7, +0x1771100,3, +0x1771110,3, +0x1771120,5, +0x1771200,6, +0x1771240,5, +0x1771400,2, +0x177140c,2, +0x1771440,7, +0x1771500,3, +0x1771510,3, +0x1771520,5, +0x1771600,6, +0x1771640,5, +0x1771800,2, +0x177180c,2, +0x1771840,7, +0x1771900,3, +0x1771910,3, +0x1771920,5, +0x1771a00,6, +0x1771a40,5, +0x1771c00,2, +0x1771c0c,2, +0x1771c40,7, +0x1771d00,3, +0x1771d10,3, +0x1771d20,5, +0x1771e00,6, +0x1771e40,5, +0x1772000,5, +0x1772040,9, +0x1772100,3, +0x1772200,1, +0x1772210,1, +0x1772220,1, +0x1772230,1, +0x1772240,1, +0x1772300,3, +0x1772314,1, +0x1772320,4, +0x1772400,5, +0x1772440,5, +0x1773000,80, +0x1773200,1, +0x1778000,7, +0x1778030,2, +0x1778040,7, +0x1778070,2, +0x1778100,2, +0x1778120,2, +0x1778140,2, +0x1778160,2, +0x1778180,9, +0x1778200,7, +0x1778230,2, +0x1778240,7, +0x1778270,2, +0x1778300,2, +0x1778320,2, +0x1778340,2, +0x1778360,2, +0x1778380,9, +0x1778400,11, +0x1778500,11, +0x1779000,3, +0x1779010,2, +0x177901c,5, +0x1779040,8, +0x1779080,3, +0x1779090,2, +0x177909c,5, +0x17790c0,8, +0x1779100,3, +0x1779110,2, +0x177911c,5, +0x1779140,8, +0x1779180,3, +0x1779190,2, +0x177919c,5, +0x17791c0,8, +0x1779200,7, +0x1779220,12, +0x1779280,7, +0x17792a0,12, +0x1779300,3, +0x1779310,1, +0x1779400,3, +0x1779410,2, +0x177941c,5, +0x1779440,8, +0x1779480,3, +0x1779490,2, +0x177949c,5, +0x17794c0,8, +0x1779500,3, +0x1779510,2, +0x177951c,5, +0x1779540,8, +0x1779580,3, +0x1779590,2, +0x177959c,5, +0x17795c0,8, +0x1779600,7, +0x1779620,12, +0x1779680,7, +0x17796a0,12, +0x1779700,3, +0x1779710,1, +0x1779804,1, +0x1779824,21, +0x1779880,16, +0x1779900,5, +0x1779920,11, +0x1779950,9, +0x1779980,22, +0x1779a00,22, +0x1779a80,22, +0x1779b00,22, +0x1779b80,22, +0x1779c00,22, +0x1779c80,22, +0x1779d00,22, +0x1779d80,3, +0x1780000,5, +0x1780018,5, +0x1780030,3, +0x1780044,3, +0x1780100,58, +0x17801f0,3, +0x1780280,3, +0x1780400,5, +0x1780418,5, +0x1780430,3, +0x1780444,3, +0x1780500,58, +0x17805f0,3, +0x1780680,3, +0x1781018,2, +0x1781100,2, +0x1781110,10, +0x1781140,2, +0x1781150,10, +0x1781208,1, +0x1781220,12, +0x1781280,1, +0x1781288,2, +0x1781400,4, +0x1782000,5, +0x1782018,5, +0x1782030,3, +0x1782044,3, +0x1782100,58, +0x17821f0,3, +0x1782280,3, +0x1782400,5, +0x1782418,5, +0x1782430,3, +0x1782444,3, +0x1782500,58, +0x17825f0,3, +0x1782680,3, +0x1783018,2, +0x1783100,2, +0x1783110,10, +0x1783140,2, +0x1783150,10, +0x1783208,1, +0x1783220,12, +0x1783280,1, +0x1783288,2, +0x1783400,4, +0x1784000,2, +0x178400c,1, +0x1784030,3, +0x1784040,2, +0x178404c,1, +0x1784070,3, +0x1784100,2, +0x178410c,1, +0x1784130,3, +0x1784140,2, +0x178414c,1, +0x1784170,3, +0x1784200,15, +0x1784280,15, +0x1784300,15, +0x1784380,15, +0x1784400,15, +0x1784480,15, +0x1784500,15, +0x1784580,15, +0x1784604,10, +0x1784700,2, +0x178470c,7, +0x1784740,1, +0x1784770,1, +0x17847c0,2, +0x17847d0,4, +0x1785000,3, +0x1785010,1, +0x178501c,3, +0x1785104,1, +0x1785110,4, +0x1785124,1, +0x1785130,4, +0x1785144,1, +0x1785150,4, +0x1785164,1, +0x1785170,5, +0x1785190,4, +0x1785a00,4, +0x1785c00,129, +0x1786000,37, +0x1786098,1, +0x1786100,37, +0x1786198,1, +0x1786200,37, +0x1786298,1, +0x1786300,37, +0x1786398,1, +0x1786400,37, +0x1786498,1, +0x1786500,37, +0x1786598,1, +0x1786600,37, +0x1786698,1, +0x1786700,37, +0x1786798,1, +0x178c000,91, +0x178c400,4, +0x178c440,15, +0x178c480,4, +0x178c4c0,15, +0x178c500,4, +0x178c540,15, +0x178c580,4, +0x178c5c0,15, +0x178c600,4, +0x178c640,10, +0x178c680,4, +0x178c6c0,10, +0x178c800,4, +0x178c840,33, +0x178ca00,13, +0x178ca80,1, +0x178ca88,8, +0x178cac0,6, +0x178cae0,1, +0x178cae8,2, +0x178cb04,14, +0x178cc00,4, +0x178ccc8,1, +0x178cfcc,3, +0x178cfe0,99, +0x178d400,4, +0x178d440,15, +0x178d480,4, +0x178d4c0,15, +0x178d500,4, +0x178d540,15, +0x178d580,4, +0x178d5c0,15, +0x178d600,4, +0x178d640,10, +0x178d680,4, +0x178d6c0,10, +0x178d800,4, +0x178d840,33, +0x178da00,13, +0x178da80,1, +0x178da88,8, +0x178dac0,6, +0x178dae0,1, +0x178dae8,2, +0x178db04,14, +0x178dc00,4, +0x178dcc8,1, +0x178dfcc,3, +0x178dfe0,27, +0x178f000,19, +0x178fa00,10, +0x178fa80,3, +0x178fb00,6, +0x1790000,51, +0x1790a00,10, +0x1790a80,3, +0x1791000,2, +0x179100c,4, +0x1791028,3, +0x1791038,4, +0x1791050,2, +0x1791080,4, +0x1791098,7, +0x1791120,4, +0x1791200,4, +0x1791214,7, +0x1791234,3, +0x1791280,8, +0x17912c0,5, +0x1791300,2, +0x179130c,3, +0x1791400,24, +0x1791464,2, +0x1791470,3, +0x1791500,25, +0x17915c0,8, +0x17915e8,5, +0x1791600,5, +0x1791618,1, +0x1791620,1, +0x1791628,1, +0x1791630,2, +0x1791640,2, +0x1791650,2, +0x1791690,4, +0x1791740,2, +0x1791760,6, +0x1791780,6, +0x17917a0,6, +0x17917c0,6, +0x17917e0,1, +0x1791800,2, +0x179180c,4, +0x1791828,3, +0x1791838,4, +0x1791850,2, +0x1791880,4, +0x1791898,7, +0x1791920,4, +0x1791a00,4, +0x1791a14,7, +0x1791a34,3, +0x1791a80,8, +0x1791ac0,5, +0x1791b00,2, +0x1791b0c,3, +0x1791c00,24, +0x1791c64,2, +0x1791c70,3, +0x1791d00,25, +0x1791dc0,8, +0x1791de8,5, +0x1791e00,5, +0x1791e18,1, +0x1791e20,1, +0x1791e28,1, +0x1791e30,2, +0x1791e40,2, +0x1791e50,2, +0x1791e90,4, +0x1791f40,2, +0x1791f60,6, +0x1791f80,6, +0x1791fa0,6, +0x1791fc0,6, +0x1791fe0,1, +0x1792000,19, +0x1792080,2, +0x17920b0,2, +0x17920c0,2, +0x17a0000,11, +0x17a0040,16, +0x17a0084,5, +0x17a0200,7, +0x17a0220,6, +0x17a0240,7, +0x17a0260,6, +0x17a0280,6, +0x17a02a0,2, +0x17a02ac,2, +0x17a02c0,7, +0x17a02e0,7, +0x17a0300,2, +0x17a030c,2, +0x17a0320,6, +0x17a0400,2, +0x17a1000,19, +0x17a2104,23, +0x17a2180,7, +0x17a21a0,6, +0x17a21c0,7, +0x17a21e0,6, +0x17a2200,4, +0x17a2220,4, +0x17a2240,11, +0x17a2270,32, +0x17a2300,24, +0x17a2380,20, +0x17a2400,61, +0x17a2500,25, +0x17a2568,4, +0x17a2580,2, +0x17a25a0,1, +0x17a25c0,11, +0x17a2600,9, +0x17a2640,3, +0x17a2650,3, +0x17a2664,3, +0x17a2680,22, +0x17a2800,11, +0x17a3000,536, +0x17a4104,23, +0x17a4180,7, +0x17a41a0,6, +0x17a41c0,7, +0x17a41e0,6, +0x17a4200,4, +0x17a4220,4, +0x17a4240,11, +0x17a4270,32, +0x17a4300,24, +0x17a4380,20, +0x17a4400,61, +0x17a4500,25, +0x17a4568,4, +0x17a4580,2, +0x17a45a0,1, +0x17a45c0,11, +0x17a4600,9, +0x17a4640,3, +0x17a4650,3, +0x17a4664,3, +0x17a4680,22, +0x17a4800,11, +0x17a5000,536, +0x17aa000,7, +0x17aa048,8, +0x17aa080,8, +0x17aa100,7, +0x17aa148,8, +0x17aa180,8, +0x17b0000,11, +0x17b0040,16, +0x17b0084,5, +0x17b0200,7, +0x17b0220,6, +0x17b0240,7, +0x17b0260,6, +0x17b0280,6, +0x17b02a0,2, +0x17b02ac,2, +0x17b02c0,7, +0x17b02e0,7, +0x17b0300,2, +0x17b030c,2, +0x17b0320,6, +0x17b0400,2, +0x17b1000,19, +0x17b2104,23, +0x17b2180,7, +0x17b21a0,6, +0x17b21c0,7, +0x17b21e0,6, +0x17b2200,4, +0x17b2220,4, +0x17b2240,11, +0x17b2270,32, +0x17b2300,24, +0x17b2380,20, +0x17b2400,61, +0x17b2500,25, +0x17b2568,4, +0x17b2580,2, +0x17b25a0,1, +0x17b25c0,11, +0x17b2600,9, +0x17b2640,3, +0x17b2650,3, +0x17b2664,3, +0x17b2680,22, +0x17b2800,11, +0x17b3000,536, +0x17b4104,23, +0x17b4180,7, +0x17b41a0,6, +0x17b41c0,7, +0x17b41e0,6, +0x17b4200,4, +0x17b4220,4, +0x17b4240,11, +0x17b4270,32, +0x17b4300,24, +0x17b4380,20, +0x17b4400,61, +0x17b4500,25, +0x17b4568,4, +0x17b4580,2, +0x17b45a0,1, +0x17b45c0,11, +0x17b4600,9, +0x17b4640,3, +0x17b4650,3, +0x17b4664,3, +0x17b4680,22, +0x17b4800,11, +0x17b5000,536, +0x17ba000,7, +0x17ba048,8, +0x17ba080,8, +0x17ba100,7, +0x17ba148,8, +0x17ba180,8, +0x17c0400,4, +0x17c0440,4, +0x17c05c0,1, +0x17c0600,8, +0x17c0800,18, +0x17c0880,13, +0x17c08f0,3, +0x17c0900,18, +0x17c0980,13, +0x17c09f0,3, +0x17c0e00,4, +0x17c0e20,4, +0x17c0e80,16, +0x17c0f00,1, +0x17c0f20,1, +0x17c1020,2, +0x17c1208,6, +0x17c1228,10, +0x17c1288,6, +0x17c12a8,10, +0x17c1600,32, +0x17c18c0,8, +0x17c1900,24, +0x17c19b0,4, +0x17c1aa0,2, +0x17c1ac0,4, +0x17c2200,19, +0x17c2280,19, +0x17c2400,14, +0x17c243c,9, +0x17c2464,14, +0x17c24a0,2, +0x17c24ac,2, +0x17c2500,14, +0x17c253c,9, +0x17c2564,14, +0x17c25a0,2, +0x17c25ac,2, +0x17c2800,19, +0x17c2880,19, +0x17c2a10,2, +0x17c2a1c,1, +0x17c2a50,2, +0x17c2a5c,1, +0x17c2c00,7, +0x17c2c20,1, +0x17c2c54,18, +0x17c2ca0,1, +0x17c2cd4,11, +0x17c2e00,1, +0x17c2e08,6, +0x17c3180,3, +0x17c4400,4, +0x17c4440,4, +0x17c45c0,1, +0x17c4600,8, +0x17c4800,18, +0x17c4880,13, +0x17c48f0,3, +0x17c4900,18, +0x17c4980,13, +0x17c49f0,3, +0x17c4e00,4, +0x17c4e20,4, +0x17c4e80,16, +0x17c4f00,1, +0x17c4f20,1, +0x17c5020,2, +0x17c5208,6, +0x17c5228,10, +0x17c5288,6, +0x17c52a8,10, +0x17c5600,32, +0x17c58c0,8, +0x17c5900,24, +0x17c59b0,4, +0x17c5aa0,2, +0x17c5ac0,4, +0x17c6200,19, +0x17c6280,19, +0x17c6400,14, +0x17c643c,9, +0x17c6464,14, +0x17c64a0,2, +0x17c64ac,2, +0x17c6500,14, +0x17c653c,9, +0x17c6564,14, +0x17c65a0,2, +0x17c65ac,2, +0x17c6800,19, +0x17c6880,19, +0x17c6a10,2, +0x17c6a1c,1, +0x17c6a50,2, +0x17c6a5c,1, +0x17c6c00,7, +0x17c6c20,1, +0x17c6c54,18, +0x17c6ca0,1, +0x17c6cd4,11, +0x17c6e00,1, +0x17c6e08,6, +0x17c7180,3, +0x17c9000,13, +0x17ce000,19, +0x17cea00,10, +0x17cea80,3, +0x17cf000,1, +0x17cf008,5, +0x17cf038,1, +0x17cf044,1, +0x17cf050,2, +0x17cf060,8, +0x17cf140,19, +0x17cf190,4, +0x17d0000,2, +0x17d000c,2, +0x17d0040,7, +0x17d0100,3, +0x17d0110,3, +0x17d0120,5, +0x17d0200,6, +0x17d0240,5, +0x17d0400,2, +0x17d040c,2, +0x17d0440,7, +0x17d0500,3, +0x17d0510,3, +0x17d0520,5, +0x17d0600,6, +0x17d0640,5, +0x17d0800,2, +0x17d080c,2, +0x17d0840,7, +0x17d0900,3, +0x17d0910,3, +0x17d0920,5, +0x17d0a00,6, +0x17d0a40,5, +0x17d0c00,2, +0x17d0c0c,2, +0x17d0c40,7, +0x17d0d00,3, +0x17d0d10,3, +0x17d0d20,5, +0x17d0e00,6, +0x17d0e40,5, +0x17d1000,2, +0x17d100c,2, +0x17d1040,7, +0x17d1100,3, +0x17d1110,3, +0x17d1120,5, +0x17d1200,6, +0x17d1240,5, +0x17d1400,2, +0x17d140c,2, +0x17d1440,7, +0x17d1500,3, +0x17d1510,3, +0x17d1520,5, +0x17d1600,6, +0x17d1640,5, +0x17d1800,2, +0x17d180c,2, +0x17d1840,7, +0x17d1900,3, +0x17d1910,3, +0x17d1920,5, +0x17d1a00,6, +0x17d1a40,5, +0x17d1c00,2, +0x17d1c0c,2, +0x17d1c40,7, +0x17d1d00,3, +0x17d1d10,3, +0x17d1d20,5, +0x17d1e00,6, +0x17d1e40,5, +0x17d2000,5, +0x17d2040,9, +0x17d2100,3, +0x17d2200,1, +0x17d2210,1, +0x17d2220,1, +0x17d2230,1, +0x17d2240,1, +0x17d2300,3, +0x17d2314,1, +0x17d2320,4, +0x17d2400,5, +0x17d2440,5, +0x17d3000,80, +0x17d3200,1, +0x17d8000,7, +0x17d8030,2, +0x17d8040,7, +0x17d8070,2, +0x17d8100,2, +0x17d8120,2, +0x17d8140,2, +0x17d8160,2, +0x17d8180,9, +0x17d8200,7, +0x17d8230,2, +0x17d8240,7, +0x17d8270,2, +0x17d8300,2, +0x17d8320,2, +0x17d8340,2, +0x17d8360,2, +0x17d8380,9, +0x17d8400,11, +0x17d8500,11, +0x17d9000,3, +0x17d9010,2, +0x17d901c,5, +0x17d9040,8, +0x17d9080,3, +0x17d9090,2, +0x17d909c,5, +0x17d90c0,8, +0x17d9100,3, +0x17d9110,2, +0x17d911c,5, +0x17d9140,8, +0x17d9180,3, +0x17d9190,2, +0x17d919c,5, +0x17d91c0,8, +0x17d9200,7, +0x17d9220,12, +0x17d9280,7, +0x17d92a0,12, +0x17d9300,3, +0x17d9310,1, +0x17d9400,3, +0x17d9410,2, +0x17d941c,5, +0x17d9440,8, +0x17d9480,3, +0x17d9490,2, +0x17d949c,5, +0x17d94c0,8, +0x17d9500,3, +0x17d9510,2, +0x17d951c,5, +0x17d9540,8, +0x17d9580,3, +0x17d9590,2, +0x17d959c,5, +0x17d95c0,8, +0x17d9600,7, +0x17d9620,12, +0x17d9680,7, +0x17d96a0,12, +0x17d9700,3, +0x17d9710,1, +0x17d9804,1, +0x17d9824,21, +0x17d9880,16, +0x17d9900,5, +0x17d9920,11, +0x17d9950,9, +0x17d9980,22, +0x17d9a00,22, +0x17d9a80,22, +0x17d9b00,22, +0x17d9b80,22, +0x17d9c00,22, +0x17d9c80,22, +0x17d9d00,22, +0x17d9d80,3, +0x17e0000,5, +0x17e0018,5, +0x17e0030,3, +0x17e0044,3, +0x17e0100,58, +0x17e01f0,3, +0x17e0280,3, +0x17e0400,5, +0x17e0418,5, +0x17e0430,3, +0x17e0444,3, +0x17e0500,58, +0x17e05f0,3, +0x17e0680,3, +0x17e1018,2, +0x17e1100,2, +0x17e1110,10, +0x17e1140,2, +0x17e1150,10, +0x17e1208,1, +0x17e1220,12, +0x17e1280,1, +0x17e1288,2, +0x17e1400,4, +0x17e2000,5, +0x17e2018,5, +0x17e2030,3, +0x17e2044,3, +0x17e2100,58, +0x17e21f0,3, +0x17e2280,3, +0x17e2400,5, +0x17e2418,5, +0x17e2430,3, +0x17e2444,3, +0x17e2500,58, +0x17e25f0,3, +0x17e2680,3, +0x17e3018,2, +0x17e3100,2, +0x17e3110,10, +0x17e3140,2, +0x17e3150,10, +0x17e3208,1, +0x17e3220,12, +0x17e3280,1, +0x17e3288,2, +0x17e3400,4, +0x17e4000,2, +0x17e400c,1, +0x17e4030,3, +0x17e4040,2, +0x17e404c,1, +0x17e4070,3, +0x17e4100,2, +0x17e410c,1, +0x17e4130,3, +0x17e4140,2, +0x17e414c,1, +0x17e4170,3, +0x17e4200,15, +0x17e4280,15, +0x17e4300,15, +0x17e4380,15, +0x17e4400,15, +0x17e4480,15, +0x17e4500,15, +0x17e4580,15, +0x17e4604,10, +0x17e4700,2, +0x17e470c,7, +0x17e4740,1, +0x17e4770,1, +0x17e47c0,2, +0x17e47d0,4, +0x17e5000,3, +0x17e5010,1, +0x17e501c,3, +0x17e5104,1, +0x17e5110,4, +0x17e5124,1, +0x17e5130,4, +0x17e5144,1, +0x17e5150,4, +0x17e5164,1, +0x17e5170,5, +0x17e5190,4, +0x17e5a00,4, +0x17e5c00,129, +0x17e6000,37, +0x17e6098,1, +0x17e6100,37, +0x17e6198,1, +0x17e6200,37, +0x17e6298,1, +0x17e6300,37, +0x17e6398,1, +0x17e6400,37, +0x17e6498,1, +0x17e6500,37, +0x17e6598,1, +0x17e6600,37, +0x17e6698,1, +0x17e6700,37, +0x17e6798,1, +0x17ec000,91, +0x17ec400,4, +0x17ec440,15, +0x17ec480,4, +0x17ec4c0,15, +0x17ec500,4, +0x17ec540,15, +0x17ec580,4, +0x17ec5c0,15, +0x17ec600,4, +0x17ec640,10, +0x17ec680,4, +0x17ec6c0,10, +0x17ec800,4, +0x17ec840,33, +0x17eca00,13, +0x17eca80,1, +0x17eca88,8, +0x17ecac0,6, +0x17ecae0,1, +0x17ecae8,2, +0x17ecb04,14, +0x17ecc00,4, +0x17eccc8,1, +0x17ecfcc,3, +0x17ecfe0,99, +0x17ed400,4, +0x17ed440,15, +0x17ed480,4, +0x17ed4c0,15, +0x17ed500,4, +0x17ed540,15, +0x17ed580,4, +0x17ed5c0,15, +0x17ed600,4, +0x17ed640,10, +0x17ed680,4, +0x17ed6c0,10, +0x17ed800,4, +0x17ed840,33, +0x17eda00,13, +0x17eda80,1, +0x17eda88,8, +0x17edac0,6, +0x17edae0,1, +0x17edae8,2, +0x17edb04,14, +0x17edc00,4, +0x17edcc8,1, +0x17edfcc,3, +0x17edfe0,27, +0x17ef000,19, +0x17efa00,10, +0x17efa80,3, +0x17efb00,6, +0x17f0000,51, +0x17f0a00,10, +0x17f0a80,3, +0x17f1000,2, +0x17f100c,4, +0x17f1028,3, +0x17f1038,4, +0x17f1050,2, +0x17f1080,4, +0x17f1098,7, +0x17f1120,4, +0x17f1200,4, +0x17f1214,7, +0x17f1234,3, +0x17f1280,8, +0x17f12c0,5, +0x17f1300,2, +0x17f130c,3, +0x17f1400,24, +0x17f1464,2, +0x17f1470,3, +0x17f1500,25, +0x17f15c0,8, +0x17f15e8,5, +0x17f1600,5, +0x17f1618,1, +0x17f1620,1, +0x17f1628,1, +0x17f1630,2, +0x17f1640,2, +0x17f1650,2, +0x17f1690,4, +0x17f1740,2, +0x17f1760,6, +0x17f1780,6, +0x17f17a0,6, +0x17f17c0,6, +0x17f17e0,1, +0x17f1800,2, +0x17f180c,4, +0x17f1828,3, +0x17f1838,4, +0x17f1850,2, +0x17f1880,4, +0x17f1898,7, +0x17f1920,4, +0x17f1a00,4, +0x17f1a14,7, +0x17f1a34,3, +0x17f1a80,8, +0x17f1ac0,5, +0x17f1b00,2, +0x17f1b0c,3, +0x17f1c00,24, +0x17f1c64,2, +0x17f1c70,3, +0x17f1d00,25, +0x17f1dc0,8, +0x17f1de8,5, +0x17f1e00,5, +0x17f1e18,1, +0x17f1e20,1, +0x17f1e28,1, +0x17f1e30,2, +0x17f1e40,2, +0x17f1e50,2, +0x17f1e90,4, +0x17f1f40,2, +0x17f1f60,6, +0x17f1f80,6, +0x17f1fa0,6, +0x17f1fc0,6, +0x17f1fe0,1, +0x17f2000,19, +0x17f2080,2, +0x17f20b0,2, +0x17f20c0,2, +0x2000004,5, +0x2000020,3, +0x2000030,3, +0x2000040,13, +0x2000078,4, +0x200009c,25, +0x2000104,5, +0x2000120,3, +0x2000130,3, +0x2000140,13, +0x2000178,4, +0x200019c,25, +0x2000204,5, +0x2000220,3, +0x2000230,3, +0x2000240,13, +0x2000278,4, +0x200029c,25, +0x2000304,5, +0x2000320,3, +0x2000330,3, +0x2000340,13, +0x2000378,4, +0x200039c,25, +0x2000600,4, +0x2000c00,24, +0x2000c80,24, +0x2000d00,24, +0x2000d80,24, +0x2000e00,4, +0x2000e20,4, +0x2000e40,4, +0x2000e60,4, +0x2000e80,39, +0x2000f20,7, +0x2000f40,7, +0x2000f60,7, +0x2001000,12, +0x2001200,1, +0x2001218,2, +0x200122c,1, +0x2001280,1, +0x2001298,2, +0x20012ac,1, +0x2001300,1, +0x2001318,2, +0x200132c,1, +0x2001380,1, +0x2001398,2, +0x20013ac,1, +0x2001400,4, +0x2001420,2, +0x200142c,1, +0x2001480,4, +0x20014a0,2, +0x20014ac,1, +0x2001500,4, +0x2001520,2, +0x200152c,1, +0x2001580,4, +0x20015a0,2, +0x20015ac,1, +0x2001600,4, +0x2001640,4, +0x2001680,4, +0x20016c0,4, +0x2001700,7, +0x2001720,7, +0x2001740,7, +0x2001760,7, +0x2001780,4, +0x200179c,11, +0x20017d0,2, +0x20017e0,2, +0x20017f0,2, +0x2001900,44, +0x2002000,7, +0x2002020,4, +0x2002040,4, +0x2002060,7, +0x2002080,7, +0x20020a0,4, +0x20020c0,4, +0x20020e0,7, +0x2002100,7, +0x2002120,4, +0x2002140,4, +0x2002160,7, +0x2002180,7, +0x20021a0,4, +0x20021c0,4, +0x20021e0,7, +0x2002200,32, +0x2002b00,1, +0x2002b20,1, +0x2002b28,4, +0x2002b40,1, +0x2002b60,1, +0x2002b68,4, +0x2002b80,1, +0x2002ba0,1, +0x2002ba8,4, +0x2002bc0,1, +0x2002be0,1, +0x2002be8,4, +0x2002c00,7, +0x2002c20,1, +0x2002c54,18, +0x2002ca0,1, +0x2002cd4,18, +0x2002d20,1, +0x2002d54,18, +0x2002da0,1, +0x2002dd4,12, +0x2002e08,6, +0x2003100,7, +0x2003120,7, +0x2003140,7, +0x2003160,7, +0x2003180,3, +0x2004004,5, +0x2004020,3, +0x2004030,3, +0x2004040,13, +0x2004078,4, +0x200409c,25, +0x2004104,5, +0x2004120,3, +0x2004130,3, +0x2004140,13, +0x2004178,4, +0x200419c,25, +0x2004204,5, +0x2004220,3, +0x2004230,3, +0x2004240,13, +0x2004278,4, +0x200429c,25, +0x2004304,5, +0x2004320,3, +0x2004330,3, +0x2004340,13, +0x2004378,4, +0x200439c,25, +0x2004600,4, +0x2004c00,24, +0x2004c80,24, +0x2004d00,24, +0x2004d80,24, +0x2004e00,4, +0x2004e20,4, +0x2004e40,4, +0x2004e60,4, +0x2004e80,39, +0x2004f20,7, +0x2004f40,7, +0x2004f60,7, +0x2005000,12, +0x2005200,1, +0x2005218,2, +0x200522c,1, +0x2005280,1, +0x2005298,2, +0x20052ac,1, +0x2005300,1, +0x2005318,2, +0x200532c,1, +0x2005380,1, +0x2005398,2, +0x20053ac,1, +0x2005400,4, +0x2005420,2, +0x200542c,1, +0x2005480,4, +0x20054a0,2, +0x20054ac,1, +0x2005500,4, +0x2005520,2, +0x200552c,1, +0x2005580,4, +0x20055a0,2, +0x20055ac,1, +0x2005600,4, +0x2005640,4, +0x2005680,4, +0x20056c0,4, +0x2005700,7, +0x2005720,7, +0x2005740,7, +0x2005760,7, +0x2005780,4, +0x200579c,11, +0x20057d0,2, +0x20057e0,2, +0x20057f0,2, +0x2005900,44, +0x2006000,7, +0x2006020,4, +0x2006040,4, +0x2006060,7, +0x2006080,7, +0x20060a0,4, +0x20060c0,4, +0x20060e0,7, +0x2006100,7, +0x2006120,4, +0x2006140,4, +0x2006160,7, +0x2006180,7, +0x20061a0,4, +0x20061c0,4, +0x20061e0,7, +0x2006200,32, +0x2006b00,1, +0x2006b20,1, +0x2006b28,4, +0x2006b40,1, +0x2006b60,1, +0x2006b68,4, +0x2006b80,1, +0x2006ba0,1, +0x2006ba8,4, +0x2006bc0,1, +0x2006be0,1, +0x2006be8,4, +0x2006c00,7, +0x2006c20,1, +0x2006c54,18, +0x2006ca0,1, +0x2006cd4,18, +0x2006d20,1, +0x2006d54,18, +0x2006da0,1, +0x2006dd4,12, +0x2006e08,6, +0x2007100,7, +0x2007120,7, +0x2007140,7, +0x2007160,7, +0x2007180,3, +0x2008000,10, +0x2008080,3, +0x20080c0,1, +0x2008100,21, +0x2008180,13, +0x20081c4,7, +0x20081e4,7, +0x2008204,7, +0x2008224,8, +0x2009000,7, +0x2009030,2, +0x2009040,7, +0x2009070,2, +0x2009100,2, +0x2009120,2, +0x2009140,2, +0x2009160,2, +0x2009180,9, +0x2009200,7, +0x2009230,2, +0x2009240,7, +0x2009270,2, +0x2009300,2, +0x2009320,2, +0x2009340,2, +0x2009360,2, +0x2009380,9, +0x2009400,11, +0x2009500,11, +0x200a000,3, +0x200a010,2, +0x200a01c,5, +0x200a040,8, +0x200a080,3, +0x200a090,2, +0x200a09c,5, +0x200a0c0,8, +0x200a100,3, +0x200a110,2, +0x200a11c,5, +0x200a140,8, +0x200a180,3, +0x200a190,2, +0x200a19c,5, +0x200a1c0,8, +0x200a200,7, +0x200a220,12, +0x200a280,7, +0x200a2a0,12, +0x200a300,3, +0x200a310,1, +0x200a400,3, +0x200a410,2, +0x200a41c,5, +0x200a440,8, +0x200a480,3, +0x200a490,2, +0x200a49c,5, +0x200a4c0,8, +0x200a500,3, +0x200a510,2, +0x200a51c,5, +0x200a540,8, +0x200a580,3, +0x200a590,2, +0x200a59c,5, +0x200a5c0,8, +0x200a600,7, +0x200a620,12, +0x200a680,7, +0x200a6a0,12, +0x200a700,3, +0x200a710,1, +0x200a804,1, +0x200a824,21, +0x200a880,16, +0x200a900,5, +0x200a920,11, +0x200a950,9, +0x200a980,22, +0x200aa00,22, +0x200aa80,22, +0x200ab00,22, +0x200ab80,22, +0x200ac00,22, +0x200ac80,22, +0x200ad00,22, +0x200ad80,3, +0x200c000,16, +0x200c080,11, +0x200c100,11, +0x200c204,1, +0x200c224,21, +0x200c280,16, +0x200c300,11, +0x200c340,11, +0x200c800,21, +0x200c860,5, +0x200c880,6, +0x200c8a0,5, +0x200c8c0,6, +0x200c900,21, +0x200c960,5, +0x200c980,6, +0x200c9a0,5, +0x200c9c0,6, +0x200ca00,21, +0x200ca60,5, +0x200ca80,6, +0x200caa0,5, +0x200cac0,6, +0x200cb00,21, +0x200cb60,5, +0x200cb80,6, +0x200cba0,5, +0x200cbc0,6, +0x200cc00,9, +0x200cc48,7, +0x200cc68,2, +0x200cc74,9, +0x200cc9c,2, +0x200cd00,14, +0x200cd40,14, +0x200cd80,28, +0x200ce00,19, +0x200ce50,3, +0x200ce60,25, +0x200cec8,1, +0x200ced0,2, +0x200cee0,7, +0x200cf00,1, +0x200cf08,2, +0x200cffc,20, +0x200d050,25, +0x200d100,19, +0x200d150,25, +0x200d200,19, +0x200d250,25, +0x200d300,19, +0x200d350,25, +0x200d400,19, +0x200d450,25, +0x200d500,19, +0x200d550,25, +0x200d600,19, +0x200d650,25, +0x200d700,19, +0x200d750,25, +0x200d800,19, +0x200d850,25, +0x200d904,1, +0x200d914,10, +0x200d948,11, +0x200d980,2, +0x200d9a0,6, +0x200d9c0,2, +0x200d9cc,2, +0x200e000,35, +0x200ea00,10, +0x200ea80,3, +0x200eb00,6, +0x200f000,1, +0x200f008,5, +0x200f038,1, +0x200f044,1, +0x200f050,2, +0x200f100,13, +0x200f140,11, +0x200f170,12, +0x200f1a4,1, +0x200f200,104, +0x200f400,104, +0x200f600,104, +0x200f800,104, +0x2010000,13, +0x2010040,2, +0x2010054,4, +0x2010080,27, +0x2010100,12, +0x2010140,14, +0x2010180,28, +0x2010200,6, +0x2010240,6, +0x201025c,3, +0x2010280,5, +0x20102a0,8, +0x2010400,14, +0x2010440,14, +0x2010480,14, +0x20104c0,14, +0x2010540,3, +0x2010600,7, +0x2010620,14, +0x2010680,5, +0x20106a0,7, +0x2010800,13, +0x2010840,2, +0x2010854,4, +0x2010880,27, +0x2010900,12, +0x2010940,14, +0x2010980,28, +0x2010a00,6, +0x2010a40,6, +0x2010a5c,3, +0x2010a80,5, +0x2010aa0,8, +0x2010c00,14, +0x2010c40,14, +0x2010c80,14, +0x2010cc0,14, +0x2010d40,3, +0x2010e00,7, +0x2010e20,14, +0x2010e80,5, +0x2010ea0,7, +0x2011000,13, +0x2011040,2, +0x2011054,4, +0x2011080,27, +0x2011100,12, +0x2011140,14, +0x2011180,28, +0x2011200,6, +0x2011240,6, +0x201125c,3, +0x2011280,5, +0x20112a0,8, +0x2011400,14, +0x2011440,14, +0x2011480,14, +0x20114c0,14, +0x2011540,3, +0x2011600,7, +0x2011620,14, +0x2011680,5, +0x20116a0,7, +0x2011800,13, +0x2011840,2, +0x2011854,4, +0x2011880,27, +0x2011900,12, +0x2011940,14, +0x2011980,28, +0x2011a00,6, +0x2011a40,6, +0x2011a5c,3, +0x2011a80,5, +0x2011aa0,8, +0x2011c00,14, +0x2011c40,14, +0x2011c80,14, +0x2011cc0,14, +0x2011d40,3, +0x2011e00,7, +0x2011e20,14, +0x2011e80,5, +0x2011ea0,7, +0x2012000,8, +0x2012040,8, +0x2012080,1, +0x2012098,6, +0x2012100,10, +0x2012140,3, +0x2012150,2, +0x2012180,2, +0x2012200,6, +0x2012220,18, +0x2012280,4, +0x2012300,8, +0x2012400,2, +0x2012480,2, +0x2012800,28, +0x20129f0,4, +0x2013000,40, +0x2013100,64, +0x2013800,56, +0x2013be0,8, +0x2014000,13, +0x2014040,2, +0x2014054,4, +0x2014080,27, +0x2014100,12, +0x2014140,14, +0x2014180,28, +0x2014200,6, +0x2014240,6, +0x201425c,3, +0x2014280,5, +0x20142a0,8, +0x2014400,14, +0x2014440,14, +0x2014480,14, +0x20144c0,14, +0x2014540,3, +0x2014600,7, +0x2014620,14, +0x2014680,5, +0x20146a0,7, +0x2014800,13, +0x2014840,2, +0x2014854,4, +0x2014880,27, +0x2014900,12, +0x2014940,14, +0x2014980,28, +0x2014a00,6, +0x2014a40,6, +0x2014a5c,3, +0x2014a80,5, +0x2014aa0,8, +0x2014c00,14, +0x2014c40,14, +0x2014c80,14, +0x2014cc0,14, +0x2014d40,3, +0x2014e00,7, +0x2014e20,14, +0x2014e80,5, +0x2014ea0,7, +0x2015000,13, +0x2015040,2, +0x2015054,4, +0x2015080,27, +0x2015100,12, +0x2015140,14, +0x2015180,28, +0x2015200,6, +0x2015240,6, +0x201525c,3, +0x2015280,5, +0x20152a0,8, +0x2015400,14, +0x2015440,14, +0x2015480,14, +0x20154c0,14, +0x2015540,3, +0x2015600,7, +0x2015620,14, +0x2015680,5, +0x20156a0,7, +0x2015800,13, +0x2015840,2, +0x2015854,4, +0x2015880,27, +0x2015900,12, +0x2015940,14, +0x2015980,28, +0x2015a00,6, +0x2015a40,6, +0x2015a5c,3, +0x2015a80,5, +0x2015aa0,8, +0x2015c00,14, +0x2015c40,14, +0x2015c80,14, +0x2015cc0,14, +0x2015d40,3, +0x2015e00,7, +0x2015e20,14, +0x2015e80,5, +0x2015ea0,7, +0x2016000,8, +0x2016040,8, +0x2016080,1, +0x2016098,6, +0x2016100,10, +0x2016140,3, +0x2016150,2, +0x2016180,2, +0x2016200,6, +0x2016220,18, +0x2016280,4, +0x2016300,8, +0x2016400,2, +0x2016480,2, +0x2016800,28, +0x20169f0,4, +0x2017000,40, +0x2017100,64, +0x2017800,56, +0x2017be0,8, +0x2018000,2, +0x201800c,2, +0x2018040,7, +0x2018100,3, +0x2018110,3, +0x2018120,5, +0x2018200,6, +0x2018240,5, +0x2018400,2, +0x201840c,2, +0x2018440,7, +0x2018500,3, +0x2018510,3, +0x2018520,5, +0x2018600,6, +0x2018640,5, +0x2018800,2, +0x201880c,2, +0x2018840,7, +0x2018900,3, +0x2018910,3, +0x2018920,5, +0x2018a00,6, +0x2018a40,5, +0x2018c00,2, +0x2018c0c,2, +0x2018c40,7, +0x2018d00,3, +0x2018d10,3, +0x2018d20,5, +0x2018e00,6, +0x2018e40,5, +0x2019000,2, +0x201900c,2, +0x2019040,7, +0x2019100,3, +0x2019110,3, +0x2019120,5, +0x2019200,6, +0x2019240,5, +0x2019400,2, +0x201940c,2, +0x2019440,7, +0x2019500,3, +0x2019510,3, +0x2019520,5, +0x2019600,6, +0x2019640,5, +0x2019800,2, +0x201980c,2, +0x2019840,7, +0x2019900,3, +0x2019910,3, +0x2019920,5, +0x2019a00,6, +0x2019a40,5, +0x2019c00,2, +0x2019c0c,2, +0x2019c40,7, +0x2019d00,3, +0x2019d10,3, +0x2019d20,5, +0x2019e00,6, +0x2019e40,5, +0x201a000,5, +0x201a040,9, +0x201a100,3, +0x201a200,1, +0x201a210,1, +0x201a220,1, +0x201a230,1, +0x201a240,1, +0x201a300,3, +0x201a314,1, +0x201a320,4, +0x201a400,5, +0x201a440,5, +0x201b000,80, +0x201b200,1, +0x2020004,5, +0x2020020,3, +0x2020030,3, +0x2020040,13, +0x2020078,4, +0x202009c,25, +0x2020104,5, +0x2020120,3, +0x2020130,3, +0x2020140,13, +0x2020178,4, +0x202019c,25, +0x2020204,5, +0x2020220,3, +0x2020230,3, +0x2020240,13, +0x2020278,4, +0x202029c,25, +0x2020304,5, +0x2020320,3, +0x2020330,3, +0x2020340,13, +0x2020378,4, +0x202039c,25, +0x2020600,4, +0x2020c00,24, +0x2020c80,24, +0x2020d00,24, +0x2020d80,24, +0x2020e00,4, +0x2020e20,4, +0x2020e40,4, +0x2020e60,4, +0x2020e80,39, +0x2020f20,7, +0x2020f40,7, +0x2020f60,7, +0x2021000,12, +0x2021200,1, +0x2021218,2, +0x202122c,1, +0x2021280,1, +0x2021298,2, +0x20212ac,1, +0x2021300,1, +0x2021318,2, +0x202132c,1, +0x2021380,1, +0x2021398,2, +0x20213ac,1, +0x2021400,4, +0x2021420,2, +0x202142c,1, +0x2021480,4, +0x20214a0,2, +0x20214ac,1, +0x2021500,4, +0x2021520,2, +0x202152c,1, +0x2021580,4, +0x20215a0,2, +0x20215ac,1, +0x2021600,4, +0x2021640,4, +0x2021680,4, +0x20216c0,4, +0x2021700,7, +0x2021720,7, +0x2021740,7, +0x2021760,7, +0x2021780,4, +0x202179c,11, +0x20217d0,2, +0x20217e0,2, +0x20217f0,2, +0x2021900,44, +0x2022000,7, +0x2022020,4, +0x2022040,4, +0x2022060,7, +0x2022080,7, +0x20220a0,4, +0x20220c0,4, +0x20220e0,7, +0x2022100,7, +0x2022120,4, +0x2022140,4, +0x2022160,7, +0x2022180,7, +0x20221a0,4, +0x20221c0,4, +0x20221e0,7, +0x2022200,32, +0x2022b00,1, +0x2022b20,1, +0x2022b28,4, +0x2022b40,1, +0x2022b60,1, +0x2022b68,4, +0x2022b80,1, +0x2022ba0,1, +0x2022ba8,4, +0x2022bc0,1, +0x2022be0,1, +0x2022be8,4, +0x2022c00,7, +0x2022c20,1, +0x2022c54,18, +0x2022ca0,1, +0x2022cd4,18, +0x2022d20,1, +0x2022d54,18, +0x2022da0,1, +0x2022dd4,12, +0x2022e08,6, +0x2023100,7, +0x2023120,7, +0x2023140,7, +0x2023160,7, +0x2023180,3, +0x2024004,5, +0x2024020,3, +0x2024030,3, +0x2024040,13, +0x2024078,4, +0x202409c,25, +0x2024104,5, +0x2024120,3, +0x2024130,3, +0x2024140,13, +0x2024178,4, +0x202419c,25, +0x2024204,5, +0x2024220,3, +0x2024230,3, +0x2024240,13, +0x2024278,4, +0x202429c,25, +0x2024304,5, +0x2024320,3, +0x2024330,3, +0x2024340,13, +0x2024378,4, +0x202439c,25, +0x2024600,4, +0x2024c00,24, +0x2024c80,24, +0x2024d00,24, +0x2024d80,24, +0x2024e00,4, +0x2024e20,4, +0x2024e40,4, +0x2024e60,4, +0x2024e80,39, +0x2024f20,7, +0x2024f40,7, +0x2024f60,7, +0x2025000,12, +0x2025200,1, +0x2025218,2, +0x202522c,1, +0x2025280,1, +0x2025298,2, +0x20252ac,1, +0x2025300,1, +0x2025318,2, +0x202532c,1, +0x2025380,1, +0x2025398,2, +0x20253ac,1, +0x2025400,4, +0x2025420,2, +0x202542c,1, +0x2025480,4, +0x20254a0,2, +0x20254ac,1, +0x2025500,4, +0x2025520,2, +0x202552c,1, +0x2025580,4, +0x20255a0,2, +0x20255ac,1, +0x2025600,4, +0x2025640,4, +0x2025680,4, +0x20256c0,4, +0x2025700,7, +0x2025720,7, +0x2025740,7, +0x2025760,7, +0x2025780,4, +0x202579c,11, +0x20257d0,2, +0x20257e0,2, +0x20257f0,2, +0x2025900,44, +0x2026000,7, +0x2026020,4, +0x2026040,4, +0x2026060,7, +0x2026080,7, +0x20260a0,4, +0x20260c0,4, +0x20260e0,7, +0x2026100,7, +0x2026120,4, +0x2026140,4, +0x2026160,7, +0x2026180,7, +0x20261a0,4, +0x20261c0,4, +0x20261e0,7, +0x2026200,32, +0x2026b00,1, +0x2026b20,1, +0x2026b28,4, +0x2026b40,1, +0x2026b60,1, +0x2026b68,4, +0x2026b80,1, +0x2026ba0,1, +0x2026ba8,4, +0x2026bc0,1, +0x2026be0,1, +0x2026be8,4, +0x2026c00,7, +0x2026c20,1, +0x2026c54,18, +0x2026ca0,1, +0x2026cd4,18, +0x2026d20,1, +0x2026d54,18, +0x2026da0,1, +0x2026dd4,12, +0x2026e08,6, +0x2027100,7, +0x2027120,7, +0x2027140,7, +0x2027160,7, +0x2027180,3, +0x2028000,10, +0x2028080,3, +0x20280c0,1, +0x2028100,21, +0x2028180,13, +0x20281c4,7, +0x20281e4,7, +0x2028204,7, +0x2028224,8, +0x2029000,7, +0x2029030,2, +0x2029040,7, +0x2029070,2, +0x2029100,2, +0x2029120,2, +0x2029140,2, +0x2029160,2, +0x2029180,9, +0x2029200,7, +0x2029230,2, +0x2029240,7, +0x2029270,2, +0x2029300,2, +0x2029320,2, +0x2029340,2, +0x2029360,2, +0x2029380,9, +0x2029400,11, +0x2029500,11, +0x202a000,3, +0x202a010,2, +0x202a01c,5, +0x202a040,8, +0x202a080,3, +0x202a090,2, +0x202a09c,5, +0x202a0c0,8, +0x202a100,3, +0x202a110,2, +0x202a11c,5, +0x202a140,8, +0x202a180,3, +0x202a190,2, +0x202a19c,5, +0x202a1c0,8, +0x202a200,7, +0x202a220,12, +0x202a280,7, +0x202a2a0,12, +0x202a300,3, +0x202a310,1, +0x202a400,3, +0x202a410,2, +0x202a41c,5, +0x202a440,8, +0x202a480,3, +0x202a490,2, +0x202a49c,5, +0x202a4c0,8, +0x202a500,3, +0x202a510,2, +0x202a51c,5, +0x202a540,8, +0x202a580,3, +0x202a590,2, +0x202a59c,5, +0x202a5c0,8, +0x202a600,7, +0x202a620,12, +0x202a680,7, +0x202a6a0,12, +0x202a700,3, +0x202a710,1, +0x202a804,1, +0x202a824,21, +0x202a880,16, +0x202a900,5, +0x202a920,11, +0x202a950,9, +0x202a980,22, +0x202aa00,22, +0x202aa80,22, +0x202ab00,22, +0x202ab80,22, +0x202ac00,22, +0x202ac80,22, +0x202ad00,22, +0x202ad80,3, +0x202c000,16, +0x202c080,11, +0x202c100,11, +0x202c204,1, +0x202c224,21, +0x202c280,16, +0x202c300,11, +0x202c340,11, +0x202c800,21, +0x202c860,5, +0x202c880,6, +0x202c8a0,5, +0x202c8c0,6, +0x202c900,21, +0x202c960,5, +0x202c980,6, +0x202c9a0,5, +0x202c9c0,6, +0x202ca00,21, +0x202ca60,5, +0x202ca80,6, +0x202caa0,5, +0x202cac0,6, +0x202cb00,21, +0x202cb60,5, +0x202cb80,6, +0x202cba0,5, +0x202cbc0,6, +0x202cc00,9, +0x202cc48,7, +0x202cc68,2, +0x202cc74,9, +0x202cc9c,2, +0x202cd00,14, +0x202cd40,14, +0x202cd80,28, +0x202ce00,19, +0x202ce50,3, +0x202ce60,25, +0x202cec8,1, +0x202ced0,2, +0x202cee0,7, +0x202cf00,1, +0x202cf08,2, +0x202cffc,20, +0x202d050,25, +0x202d100,19, +0x202d150,25, +0x202d200,19, +0x202d250,25, +0x202d300,19, +0x202d350,25, +0x202d400,19, +0x202d450,25, +0x202d500,19, +0x202d550,25, +0x202d600,19, +0x202d650,25, +0x202d700,19, +0x202d750,25, +0x202d800,19, +0x202d850,25, +0x202d904,1, +0x202d914,10, +0x202d948,11, +0x202d980,2, +0x202d9a0,6, +0x202d9c0,2, +0x202d9cc,2, +0x202e000,35, +0x202ea00,10, +0x202ea80,3, +0x202eb00,6, +0x202f000,1, +0x202f008,5, +0x202f038,1, +0x202f044,1, +0x202f050,2, +0x202f100,13, +0x202f140,11, +0x202f170,12, +0x202f1a4,1, +0x202f200,104, +0x202f400,104, +0x202f600,104, +0x202f800,104, +0x2030000,13, +0x2030040,2, +0x2030054,4, +0x2030080,27, +0x2030100,12, +0x2030140,14, +0x2030180,28, +0x2030200,6, +0x2030240,6, +0x203025c,3, +0x2030280,5, +0x20302a0,8, +0x2030400,14, +0x2030440,14, +0x2030480,14, +0x20304c0,14, +0x2030540,3, +0x2030600,7, +0x2030620,14, +0x2030680,5, +0x20306a0,7, +0x2030800,13, +0x2030840,2, +0x2030854,4, +0x2030880,27, +0x2030900,12, +0x2030940,14, +0x2030980,28, +0x2030a00,6, +0x2030a40,6, +0x2030a5c,3, +0x2030a80,5, +0x2030aa0,8, +0x2030c00,14, +0x2030c40,14, +0x2030c80,14, +0x2030cc0,14, +0x2030d40,3, +0x2030e00,7, +0x2030e20,14, +0x2030e80,5, +0x2030ea0,7, +0x2031000,13, +0x2031040,2, +0x2031054,4, +0x2031080,27, +0x2031100,12, +0x2031140,14, +0x2031180,28, +0x2031200,6, +0x2031240,6, +0x203125c,3, +0x2031280,5, +0x20312a0,8, +0x2031400,14, +0x2031440,14, +0x2031480,14, +0x20314c0,14, +0x2031540,3, +0x2031600,7, +0x2031620,14, +0x2031680,5, +0x20316a0,7, +0x2031800,13, +0x2031840,2, +0x2031854,4, +0x2031880,27, +0x2031900,12, +0x2031940,14, +0x2031980,28, +0x2031a00,6, +0x2031a40,6, +0x2031a5c,3, +0x2031a80,5, +0x2031aa0,8, +0x2031c00,14, +0x2031c40,14, +0x2031c80,14, +0x2031cc0,14, +0x2031d40,3, +0x2031e00,7, +0x2031e20,14, +0x2031e80,5, +0x2031ea0,7, +0x2032000,8, +0x2032040,8, +0x2032080,1, +0x2032098,6, +0x2032100,10, +0x2032140,3, +0x2032150,2, +0x2032180,2, +0x2032200,6, +0x2032220,18, +0x2032280,4, +0x2032300,8, +0x2032400,2, +0x2032480,2, +0x2032800,28, +0x20329f0,4, +0x2033000,40, +0x2033100,64, +0x2033800,56, +0x2033be0,8, +0x2034000,13, +0x2034040,2, +0x2034054,4, +0x2034080,27, +0x2034100,12, +0x2034140,14, +0x2034180,28, +0x2034200,6, +0x2034240,6, +0x203425c,3, +0x2034280,5, +0x20342a0,8, +0x2034400,14, +0x2034440,14, +0x2034480,14, +0x20344c0,14, +0x2034540,3, +0x2034600,7, +0x2034620,14, +0x2034680,5, +0x20346a0,7, +0x2034800,13, +0x2034840,2, +0x2034854,4, +0x2034880,27, +0x2034900,12, +0x2034940,14, +0x2034980,28, +0x2034a00,6, +0x2034a40,6, +0x2034a5c,3, +0x2034a80,5, +0x2034aa0,8, +0x2034c00,14, +0x2034c40,14, +0x2034c80,14, +0x2034cc0,14, +0x2034d40,3, +0x2034e00,7, +0x2034e20,14, +0x2034e80,5, +0x2034ea0,7, +0x2035000,13, +0x2035040,2, +0x2035054,4, +0x2035080,27, +0x2035100,12, +0x2035140,14, +0x2035180,28, +0x2035200,6, +0x2035240,6, +0x203525c,3, +0x2035280,5, +0x20352a0,8, +0x2035400,14, +0x2035440,14, +0x2035480,14, +0x20354c0,14, +0x2035540,3, +0x2035600,7, +0x2035620,14, +0x2035680,5, +0x20356a0,7, +0x2035800,13, +0x2035840,2, +0x2035854,4, +0x2035880,27, +0x2035900,12, +0x2035940,14, +0x2035980,28, +0x2035a00,6, +0x2035a40,6, +0x2035a5c,3, +0x2035a80,5, +0x2035aa0,8, +0x2035c00,14, +0x2035c40,14, +0x2035c80,14, +0x2035cc0,14, +0x2035d40,3, +0x2035e00,7, +0x2035e20,14, +0x2035e80,5, +0x2035ea0,7, +0x2036000,8, +0x2036040,8, +0x2036080,1, +0x2036098,6, +0x2036100,10, +0x2036140,3, +0x2036150,2, +0x2036180,2, +0x2036200,6, +0x2036220,18, +0x2036280,4, +0x2036300,8, +0x2036400,2, +0x2036480,2, +0x2036800,28, +0x20369f0,4, +0x2037000,40, +0x2037100,64, +0x2037800,56, +0x2037be0,8, +0x2038000,2, +0x203800c,2, +0x2038040,7, +0x2038100,3, +0x2038110,3, +0x2038120,5, +0x2038200,6, +0x2038240,5, +0x2038400,2, +0x203840c,2, +0x2038440,7, +0x2038500,3, +0x2038510,3, +0x2038520,5, +0x2038600,6, +0x2038640,5, +0x2038800,2, +0x203880c,2, +0x2038840,7, +0x2038900,3, +0x2038910,3, +0x2038920,5, +0x2038a00,6, +0x2038a40,5, +0x2038c00,2, +0x2038c0c,2, +0x2038c40,7, +0x2038d00,3, +0x2038d10,3, +0x2038d20,5, +0x2038e00,6, +0x2038e40,5, +0x2039000,2, +0x203900c,2, +0x2039040,7, +0x2039100,3, +0x2039110,3, +0x2039120,5, +0x2039200,6, +0x2039240,5, +0x2039400,2, +0x203940c,2, +0x2039440,7, +0x2039500,3, +0x2039510,3, +0x2039520,5, +0x2039600,6, +0x2039640,5, +0x2039800,2, +0x203980c,2, +0x2039840,7, +0x2039900,3, +0x2039910,3, +0x2039920,5, +0x2039a00,6, +0x2039a40,5, +0x2039c00,2, +0x2039c0c,2, +0x2039c40,7, +0x2039d00,3, +0x2039d10,3, +0x2039d20,5, +0x2039e00,6, +0x2039e40,5, +0x203a000,5, +0x203a040,9, +0x203a100,3, +0x203a200,1, +0x203a210,1, +0x203a220,1, +0x203a230,1, +0x203a240,1, +0x203a300,3, +0x203a314,1, +0x203a320,4, +0x203a400,5, +0x203a440,5, +0x203b000,80, +0x203b200,1, +0x2040004,5, +0x2040020,3, +0x2040030,3, +0x2040040,13, +0x2040078,4, +0x204009c,25, +0x2040104,5, +0x2040120,3, +0x2040130,3, +0x2040140,13, +0x2040178,4, +0x204019c,25, +0x2040204,5, +0x2040220,3, +0x2040230,3, +0x2040240,13, +0x2040278,4, +0x204029c,25, +0x2040304,5, +0x2040320,3, +0x2040330,3, +0x2040340,13, +0x2040378,4, +0x204039c,25, +0x2040600,4, +0x2040c00,24, +0x2040c80,24, +0x2040d00,24, +0x2040d80,24, +0x2040e00,4, +0x2040e20,4, +0x2040e40,4, +0x2040e60,4, +0x2040e80,39, +0x2040f20,7, +0x2040f40,7, +0x2040f60,7, +0x2041000,12, +0x2041200,1, +0x2041218,2, +0x204122c,1, +0x2041280,1, +0x2041298,2, +0x20412ac,1, +0x2041300,1, +0x2041318,2, +0x204132c,1, +0x2041380,1, +0x2041398,2, +0x20413ac,1, +0x2041400,4, +0x2041420,2, +0x204142c,1, +0x2041480,4, +0x20414a0,2, +0x20414ac,1, +0x2041500,4, +0x2041520,2, +0x204152c,1, +0x2041580,4, +0x20415a0,2, +0x20415ac,1, +0x2041600,4, +0x2041640,4, +0x2041680,4, +0x20416c0,4, +0x2041700,7, +0x2041720,7, +0x2041740,7, +0x2041760,7, +0x2041780,4, +0x204179c,11, +0x20417d0,2, +0x20417e0,2, +0x20417f0,2, +0x2041900,44, +0x2042000,7, +0x2042020,4, +0x2042040,4, +0x2042060,7, +0x2042080,7, +0x20420a0,4, +0x20420c0,4, +0x20420e0,7, +0x2042100,7, +0x2042120,4, +0x2042140,4, +0x2042160,7, +0x2042180,7, +0x20421a0,4, +0x20421c0,4, +0x20421e0,7, +0x2042200,32, +0x2042b00,1, +0x2042b20,1, +0x2042b28,4, +0x2042b40,1, +0x2042b60,1, +0x2042b68,4, +0x2042b80,1, +0x2042ba0,1, +0x2042ba8,4, +0x2042bc0,1, +0x2042be0,1, +0x2042be8,4, +0x2042c00,7, +0x2042c20,1, +0x2042c54,18, +0x2042ca0,1, +0x2042cd4,18, +0x2042d20,1, +0x2042d54,18, +0x2042da0,1, +0x2042dd4,12, +0x2042e08,6, +0x2043100,7, +0x2043120,7, +0x2043140,7, +0x2043160,7, +0x2043180,3, +0x2044004,5, +0x2044020,3, +0x2044030,3, +0x2044040,13, +0x2044078,4, +0x204409c,25, +0x2044104,5, +0x2044120,3, +0x2044130,3, +0x2044140,13, +0x2044178,4, +0x204419c,25, +0x2044204,5, +0x2044220,3, +0x2044230,3, +0x2044240,13, +0x2044278,4, +0x204429c,25, +0x2044304,5, +0x2044320,3, +0x2044330,3, +0x2044340,13, +0x2044378,4, +0x204439c,25, +0x2044600,4, +0x2044c00,24, +0x2044c80,24, +0x2044d00,24, +0x2044d80,24, +0x2044e00,4, +0x2044e20,4, +0x2044e40,4, +0x2044e60,4, +0x2044e80,39, +0x2044f20,7, +0x2044f40,7, +0x2044f60,7, +0x2045000,12, +0x2045200,1, +0x2045218,2, +0x204522c,1, +0x2045280,1, +0x2045298,2, +0x20452ac,1, +0x2045300,1, +0x2045318,2, +0x204532c,1, +0x2045380,1, +0x2045398,2, +0x20453ac,1, +0x2045400,4, +0x2045420,2, +0x204542c,1, +0x2045480,4, +0x20454a0,2, +0x20454ac,1, +0x2045500,4, +0x2045520,2, +0x204552c,1, +0x2045580,4, +0x20455a0,2, +0x20455ac,1, +0x2045600,4, +0x2045640,4, +0x2045680,4, +0x20456c0,4, +0x2045700,7, +0x2045720,7, +0x2045740,7, +0x2045760,7, +0x2045780,4, +0x204579c,11, +0x20457d0,2, +0x20457e0,2, +0x20457f0,2, +0x2045900,44, +0x2046000,7, +0x2046020,4, +0x2046040,4, +0x2046060,7, +0x2046080,7, +0x20460a0,4, +0x20460c0,4, +0x20460e0,7, +0x2046100,7, +0x2046120,4, +0x2046140,4, +0x2046160,7, +0x2046180,7, +0x20461a0,4, +0x20461c0,4, +0x20461e0,7, +0x2046200,32, +0x2046b00,1, +0x2046b20,1, +0x2046b28,4, +0x2046b40,1, +0x2046b60,1, +0x2046b68,4, +0x2046b80,1, +0x2046ba0,1, +0x2046ba8,4, +0x2046bc0,1, +0x2046be0,1, +0x2046be8,4, +0x2046c00,7, +0x2046c20,1, +0x2046c54,18, +0x2046ca0,1, +0x2046cd4,18, +0x2046d20,1, +0x2046d54,18, +0x2046da0,1, +0x2046dd4,12, +0x2046e08,6, +0x2047100,7, +0x2047120,7, +0x2047140,7, +0x2047160,7, +0x2047180,3, +0x2048000,10, +0x2048080,3, +0x20480c0,1, +0x2048100,21, +0x2048180,13, +0x20481c4,7, +0x20481e4,7, +0x2048204,7, +0x2048224,8, +0x2049000,7, +0x2049030,2, +0x2049040,7, +0x2049070,2, +0x2049100,2, +0x2049120,2, +0x2049140,2, +0x2049160,2, +0x2049180,9, +0x2049200,7, +0x2049230,2, +0x2049240,7, +0x2049270,2, +0x2049300,2, +0x2049320,2, +0x2049340,2, +0x2049360,2, +0x2049380,9, +0x2049400,11, +0x2049500,11, +0x204a000,3, +0x204a010,2, +0x204a01c,5, +0x204a040,8, +0x204a080,3, +0x204a090,2, +0x204a09c,5, +0x204a0c0,8, +0x204a100,3, +0x204a110,2, +0x204a11c,5, +0x204a140,8, +0x204a180,3, +0x204a190,2, +0x204a19c,5, +0x204a1c0,8, +0x204a200,7, +0x204a220,12, +0x204a280,7, +0x204a2a0,12, +0x204a300,3, +0x204a310,1, +0x204a400,3, +0x204a410,2, +0x204a41c,5, +0x204a440,8, +0x204a480,3, +0x204a490,2, +0x204a49c,5, +0x204a4c0,8, +0x204a500,3, +0x204a510,2, +0x204a51c,5, +0x204a540,8, +0x204a580,3, +0x204a590,2, +0x204a59c,5, +0x204a5c0,8, +0x204a600,7, +0x204a620,12, +0x204a680,7, +0x204a6a0,12, +0x204a700,3, +0x204a710,1, +0x204a804,1, +0x204a824,21, +0x204a880,16, +0x204a900,5, +0x204a920,11, +0x204a950,9, +0x204a980,22, +0x204aa00,22, +0x204aa80,22, +0x204ab00,22, +0x204ab80,22, +0x204ac00,22, +0x204ac80,22, +0x204ad00,22, +0x204ad80,3, +0x204c000,16, +0x204c080,11, +0x204c100,11, +0x204c204,1, +0x204c224,21, +0x204c280,16, +0x204c300,11, +0x204c340,11, +0x204c800,21, +0x204c860,5, +0x204c880,6, +0x204c8a0,5, +0x204c8c0,6, +0x204c900,21, +0x204c960,5, +0x204c980,6, +0x204c9a0,5, +0x204c9c0,6, +0x204ca00,21, +0x204ca60,5, +0x204ca80,6, +0x204caa0,5, +0x204cac0,6, +0x204cb00,21, +0x204cb60,5, +0x204cb80,6, +0x204cba0,5, +0x204cbc0,6, +0x204cc00,9, +0x204cc48,7, +0x204cc68,2, +0x204cc74,9, +0x204cc9c,2, +0x204cd00,14, +0x204cd40,14, +0x204cd80,28, +0x204ce00,19, +0x204ce50,3, +0x204ce60,25, +0x204cec8,1, +0x204ced0,2, +0x204cee0,7, +0x204cf00,1, +0x204cf08,2, +0x204cffc,20, +0x204d050,25, +0x204d100,19, +0x204d150,25, +0x204d200,19, +0x204d250,25, +0x204d300,19, +0x204d350,25, +0x204d400,19, +0x204d450,25, +0x204d500,19, +0x204d550,25, +0x204d600,19, +0x204d650,25, +0x204d700,19, +0x204d750,25, +0x204d800,19, +0x204d850,25, +0x204d904,1, +0x204d914,10, +0x204d948,11, +0x204d980,2, +0x204d9a0,6, +0x204d9c0,2, +0x204d9cc,2, +0x204e000,35, +0x204ea00,10, +0x204ea80,3, +0x204eb00,6, +0x204f000,1, +0x204f008,5, +0x204f038,1, +0x204f044,1, +0x204f050,2, +0x204f100,13, +0x204f140,11, +0x204f170,12, +0x204f1a4,1, +0x204f200,104, +0x204f400,104, +0x204f600,104, +0x204f800,104, +0x2050000,13, +0x2050040,2, +0x2050054,4, +0x2050080,27, +0x2050100,12, +0x2050140,14, +0x2050180,28, +0x2050200,6, +0x2050240,6, +0x205025c,3, +0x2050280,5, +0x20502a0,8, +0x2050400,14, +0x2050440,14, +0x2050480,14, +0x20504c0,14, +0x2050540,3, +0x2050600,7, +0x2050620,14, +0x2050680,5, +0x20506a0,7, +0x2050800,13, +0x2050840,2, +0x2050854,4, +0x2050880,27, +0x2050900,12, +0x2050940,14, +0x2050980,28, +0x2050a00,6, +0x2050a40,6, +0x2050a5c,3, +0x2050a80,5, +0x2050aa0,8, +0x2050c00,14, +0x2050c40,14, +0x2050c80,14, +0x2050cc0,14, +0x2050d40,3, +0x2050e00,7, +0x2050e20,14, +0x2050e80,5, +0x2050ea0,7, +0x2051000,13, +0x2051040,2, +0x2051054,4, +0x2051080,27, +0x2051100,12, +0x2051140,14, +0x2051180,28, +0x2051200,6, +0x2051240,6, +0x205125c,3, +0x2051280,5, +0x20512a0,8, +0x2051400,14, +0x2051440,14, +0x2051480,14, +0x20514c0,14, +0x2051540,3, +0x2051600,7, +0x2051620,14, +0x2051680,5, +0x20516a0,7, +0x2051800,13, +0x2051840,2, +0x2051854,4, +0x2051880,27, +0x2051900,12, +0x2051940,14, +0x2051980,28, +0x2051a00,6, +0x2051a40,6, +0x2051a5c,3, +0x2051a80,5, +0x2051aa0,8, +0x2051c00,14, +0x2051c40,14, +0x2051c80,14, +0x2051cc0,14, +0x2051d40,3, +0x2051e00,7, +0x2051e20,14, +0x2051e80,5, +0x2051ea0,7, +0x2052000,8, +0x2052040,8, +0x2052080,1, +0x2052098,6, +0x2052100,10, +0x2052140,3, +0x2052150,2, +0x2052180,2, +0x2052200,6, +0x2052220,18, +0x2052280,4, +0x2052300,8, +0x2052400,2, +0x2052480,2, +0x2052800,28, +0x20529f0,4, +0x2053000,40, +0x2053100,64, +0x2053800,56, +0x2053be0,8, +0x2054000,13, +0x2054040,2, +0x2054054,4, +0x2054080,27, +0x2054100,12, +0x2054140,14, +0x2054180,28, +0x2054200,6, +0x2054240,6, +0x205425c,3, +0x2054280,5, +0x20542a0,8, +0x2054400,14, +0x2054440,14, +0x2054480,14, +0x20544c0,14, +0x2054540,3, +0x2054600,7, +0x2054620,14, +0x2054680,5, +0x20546a0,7, +0x2054800,13, +0x2054840,2, +0x2054854,4, +0x2054880,27, +0x2054900,12, +0x2054940,14, +0x2054980,28, +0x2054a00,6, +0x2054a40,6, +0x2054a5c,3, +0x2054a80,5, +0x2054aa0,8, +0x2054c00,14, +0x2054c40,14, +0x2054c80,14, +0x2054cc0,14, +0x2054d40,3, +0x2054e00,7, +0x2054e20,14, +0x2054e80,5, +0x2054ea0,7, +0x2055000,13, +0x2055040,2, +0x2055054,4, +0x2055080,27, +0x2055100,12, +0x2055140,14, +0x2055180,28, +0x2055200,6, +0x2055240,6, +0x205525c,3, +0x2055280,5, +0x20552a0,8, +0x2055400,14, +0x2055440,14, +0x2055480,14, +0x20554c0,14, +0x2055540,3, +0x2055600,7, +0x2055620,14, +0x2055680,5, +0x20556a0,7, +0x2055800,13, +0x2055840,2, +0x2055854,4, +0x2055880,27, +0x2055900,12, +0x2055940,14, +0x2055980,28, +0x2055a00,6, +0x2055a40,6, +0x2055a5c,3, +0x2055a80,5, +0x2055aa0,8, +0x2055c00,14, +0x2055c40,14, +0x2055c80,14, +0x2055cc0,14, +0x2055d40,3, +0x2055e00,7, +0x2055e20,14, +0x2055e80,5, +0x2055ea0,7, +0x2056000,8, +0x2056040,8, +0x2056080,1, +0x2056098,6, +0x2056100,10, +0x2056140,3, +0x2056150,2, +0x2056180,2, +0x2056200,6, +0x2056220,18, +0x2056280,4, +0x2056300,8, +0x2056400,2, +0x2056480,2, +0x2056800,28, +0x20569f0,4, +0x2057000,40, +0x2057100,64, +0x2057800,56, +0x2057be0,8, +0x2058000,2, +0x205800c,2, +0x2058040,7, +0x2058100,3, +0x2058110,3, +0x2058120,5, +0x2058200,6, +0x2058240,5, +0x2058400,2, +0x205840c,2, +0x2058440,7, +0x2058500,3, +0x2058510,3, +0x2058520,5, +0x2058600,6, +0x2058640,5, +0x2058800,2, +0x205880c,2, +0x2058840,7, +0x2058900,3, +0x2058910,3, +0x2058920,5, +0x2058a00,6, +0x2058a40,5, +0x2058c00,2, +0x2058c0c,2, +0x2058c40,7, +0x2058d00,3, +0x2058d10,3, +0x2058d20,5, +0x2058e00,6, +0x2058e40,5, +0x2059000,2, +0x205900c,2, +0x2059040,7, +0x2059100,3, +0x2059110,3, +0x2059120,5, +0x2059200,6, +0x2059240,5, +0x2059400,2, +0x205940c,2, +0x2059440,7, +0x2059500,3, +0x2059510,3, +0x2059520,5, +0x2059600,6, +0x2059640,5, +0x2059800,2, +0x205980c,2, +0x2059840,7, +0x2059900,3, +0x2059910,3, +0x2059920,5, +0x2059a00,6, +0x2059a40,5, +0x2059c00,2, +0x2059c0c,2, +0x2059c40,7, +0x2059d00,3, +0x2059d10,3, +0x2059d20,5, +0x2059e00,6, +0x2059e40,5, +0x205a000,5, +0x205a040,9, +0x205a100,3, +0x205a200,1, +0x205a210,1, +0x205a220,1, +0x205a230,1, +0x205a240,1, +0x205a300,3, +0x205a314,1, +0x205a320,4, +0x205a400,5, +0x205a440,5, +0x205b000,80, +0x205b200,1, +0x2060004,5, +0x2060020,3, +0x2060030,3, +0x2060040,13, +0x2060078,4, +0x206009c,25, +0x2060104,5, +0x2060120,3, +0x2060130,3, +0x2060140,13, +0x2060178,4, +0x206019c,25, +0x2060204,5, +0x2060220,3, +0x2060230,3, +0x2060240,13, +0x2060278,4, +0x206029c,25, +0x2060304,5, +0x2060320,3, +0x2060330,3, +0x2060340,13, +0x2060378,4, +0x206039c,25, +0x2060600,4, +0x2060c00,24, +0x2060c80,24, +0x2060d00,24, +0x2060d80,24, +0x2060e00,4, +0x2060e20,4, +0x2060e40,4, +0x2060e60,4, +0x2060e80,39, +0x2060f20,7, +0x2060f40,7, +0x2060f60,7, +0x2061000,12, +0x2061200,1, +0x2061218,2, +0x206122c,1, +0x2061280,1, +0x2061298,2, +0x20612ac,1, +0x2061300,1, +0x2061318,2, +0x206132c,1, +0x2061380,1, +0x2061398,2, +0x20613ac,1, +0x2061400,4, +0x2061420,2, +0x206142c,1, +0x2061480,4, +0x20614a0,2, +0x20614ac,1, +0x2061500,4, +0x2061520,2, +0x206152c,1, +0x2061580,4, +0x20615a0,2, +0x20615ac,1, +0x2061600,4, +0x2061640,4, +0x2061680,4, +0x20616c0,4, +0x2061700,7, +0x2061720,7, +0x2061740,7, +0x2061760,7, +0x2061780,4, +0x206179c,11, +0x20617d0,2, +0x20617e0,2, +0x20617f0,2, +0x2061900,44, +0x2062000,7, +0x2062020,4, +0x2062040,4, +0x2062060,7, +0x2062080,7, +0x20620a0,4, +0x20620c0,4, +0x20620e0,7, +0x2062100,7, +0x2062120,4, +0x2062140,4, +0x2062160,7, +0x2062180,7, +0x20621a0,4, +0x20621c0,4, +0x20621e0,7, +0x2062200,32, +0x2062b00,1, +0x2062b20,1, +0x2062b28,4, +0x2062b40,1, +0x2062b60,1, +0x2062b68,4, +0x2062b80,1, +0x2062ba0,1, +0x2062ba8,4, +0x2062bc0,1, +0x2062be0,1, +0x2062be8,4, +0x2062c00,7, +0x2062c20,1, +0x2062c54,18, +0x2062ca0,1, +0x2062cd4,18, +0x2062d20,1, +0x2062d54,18, +0x2062da0,1, +0x2062dd4,12, +0x2062e08,6, +0x2063100,7, +0x2063120,7, +0x2063140,7, +0x2063160,7, +0x2063180,3, +0x2064004,5, +0x2064020,3, +0x2064030,3, +0x2064040,13, +0x2064078,4, +0x206409c,25, +0x2064104,5, +0x2064120,3, +0x2064130,3, +0x2064140,13, +0x2064178,4, +0x206419c,25, +0x2064204,5, +0x2064220,3, +0x2064230,3, +0x2064240,13, +0x2064278,4, +0x206429c,25, +0x2064304,5, +0x2064320,3, +0x2064330,3, +0x2064340,13, +0x2064378,4, +0x206439c,25, +0x2064600,4, +0x2064c00,24, +0x2064c80,24, +0x2064d00,24, +0x2064d80,24, +0x2064e00,4, +0x2064e20,4, +0x2064e40,4, +0x2064e60,4, +0x2064e80,39, +0x2064f20,7, +0x2064f40,7, +0x2064f60,7, +0x2065000,12, +0x2065200,1, +0x2065218,2, +0x206522c,1, +0x2065280,1, +0x2065298,2, +0x20652ac,1, +0x2065300,1, +0x2065318,2, +0x206532c,1, +0x2065380,1, +0x2065398,2, +0x20653ac,1, +0x2065400,4, +0x2065420,2, +0x206542c,1, +0x2065480,4, +0x20654a0,2, +0x20654ac,1, +0x2065500,4, +0x2065520,2, +0x206552c,1, +0x2065580,4, +0x20655a0,2, +0x20655ac,1, +0x2065600,4, +0x2065640,4, +0x2065680,4, +0x20656c0,4, +0x2065700,7, +0x2065720,7, +0x2065740,7, +0x2065760,7, +0x2065780,4, +0x206579c,11, +0x20657d0,2, +0x20657e0,2, +0x20657f0,2, +0x2065900,44, +0x2066000,7, +0x2066020,4, +0x2066040,4, +0x2066060,7, +0x2066080,7, +0x20660a0,4, +0x20660c0,4, +0x20660e0,7, +0x2066100,7, +0x2066120,4, +0x2066140,4, +0x2066160,7, +0x2066180,7, +0x20661a0,4, +0x20661c0,4, +0x20661e0,7, +0x2066200,32, +0x2066b00,1, +0x2066b20,1, +0x2066b28,4, +0x2066b40,1, +0x2066b60,1, +0x2066b68,4, +0x2066b80,1, +0x2066ba0,1, +0x2066ba8,4, +0x2066bc0,1, +0x2066be0,1, +0x2066be8,4, +0x2066c00,7, +0x2066c20,1, +0x2066c54,18, +0x2066ca0,1, +0x2066cd4,18, +0x2066d20,1, +0x2066d54,18, +0x2066da0,1, +0x2066dd4,12, +0x2066e08,6, +0x2067100,7, +0x2067120,7, +0x2067140,7, +0x2067160,7, +0x2067180,3, +0x2068000,10, +0x2068080,3, +0x20680c0,1, +0x2068100,21, +0x2068180,13, +0x20681c4,7, +0x20681e4,7, +0x2068204,7, +0x2068224,8, +0x2069000,7, +0x2069030,2, +0x2069040,7, +0x2069070,2, +0x2069100,2, +0x2069120,2, +0x2069140,2, +0x2069160,2, +0x2069180,9, +0x2069200,7, +0x2069230,2, +0x2069240,7, +0x2069270,2, +0x2069300,2, +0x2069320,2, +0x2069340,2, +0x2069360,2, +0x2069380,9, +0x2069400,11, +0x2069500,11, +0x206a000,3, +0x206a010,2, +0x206a01c,5, +0x206a040,8, +0x206a080,3, +0x206a090,2, +0x206a09c,5, +0x206a0c0,8, +0x206a100,3, +0x206a110,2, +0x206a11c,5, +0x206a140,8, +0x206a180,3, +0x206a190,2, +0x206a19c,5, +0x206a1c0,8, +0x206a200,7, +0x206a220,12, +0x206a280,7, +0x206a2a0,12, +0x206a300,3, +0x206a310,1, +0x206a400,3, +0x206a410,2, +0x206a41c,5, +0x206a440,8, +0x206a480,3, +0x206a490,2, +0x206a49c,5, +0x206a4c0,8, +0x206a500,3, +0x206a510,2, +0x206a51c,5, +0x206a540,8, +0x206a580,3, +0x206a590,2, +0x206a59c,5, +0x206a5c0,8, +0x206a600,7, +0x206a620,12, +0x206a680,7, +0x206a6a0,12, +0x206a700,3, +0x206a710,1, +0x206a804,1, +0x206a824,21, +0x206a880,16, +0x206a900,5, +0x206a920,11, +0x206a950,9, +0x206a980,22, +0x206aa00,22, +0x206aa80,22, +0x206ab00,22, +0x206ab80,22, +0x206ac00,22, +0x206ac80,22, +0x206ad00,22, +0x206ad80,3, +0x206c000,16, +0x206c080,11, +0x206c100,11, +0x206c204,1, +0x206c224,21, +0x206c280,16, +0x206c300,11, +0x206c340,11, +0x206c800,21, +0x206c860,5, +0x206c880,6, +0x206c8a0,5, +0x206c8c0,6, +0x206c900,21, +0x206c960,5, +0x206c980,6, +0x206c9a0,5, +0x206c9c0,6, +0x206ca00,21, +0x206ca60,5, +0x206ca80,6, +0x206caa0,5, +0x206cac0,6, +0x206cb00,21, +0x206cb60,5, +0x206cb80,6, +0x206cba0,5, +0x206cbc0,6, +0x206cc00,9, +0x206cc48,7, +0x206cc68,2, +0x206cc74,9, +0x206cc9c,2, +0x206cd00,14, +0x206cd40,14, +0x206cd80,28, +0x206ce00,19, +0x206ce50,3, +0x206ce60,25, +0x206cec8,1, +0x206ced0,2, +0x206cee0,7, +0x206cf00,1, +0x206cf08,2, +0x206cffc,20, +0x206d050,25, +0x206d100,19, +0x206d150,25, +0x206d200,19, +0x206d250,25, +0x206d300,19, +0x206d350,25, +0x206d400,19, +0x206d450,25, +0x206d500,19, +0x206d550,25, +0x206d600,19, +0x206d650,25, +0x206d700,19, +0x206d750,25, +0x206d800,19, +0x206d850,25, +0x206d904,1, +0x206d914,10, +0x206d948,11, +0x206d980,2, +0x206d9a0,6, +0x206d9c0,2, +0x206d9cc,2, +0x206e000,35, +0x206ea00,10, +0x206ea80,3, +0x206eb00,6, +0x206f000,1, +0x206f008,5, +0x206f038,1, +0x206f044,1, +0x206f050,2, +0x206f100,13, +0x206f140,11, +0x206f170,12, +0x206f1a4,1, +0x206f200,104, +0x206f400,104, +0x206f600,104, +0x206f800,104, +0x2070000,13, +0x2070040,2, +0x2070054,4, +0x2070080,27, +0x2070100,12, +0x2070140,14, +0x2070180,28, +0x2070200,6, +0x2070240,6, +0x207025c,3, +0x2070280,5, +0x20702a0,8, +0x2070400,14, +0x2070440,14, +0x2070480,14, +0x20704c0,14, +0x2070540,3, +0x2070600,7, +0x2070620,14, +0x2070680,5, +0x20706a0,7, +0x2070800,13, +0x2070840,2, +0x2070854,4, +0x2070880,27, +0x2070900,12, +0x2070940,14, +0x2070980,28, +0x2070a00,6, +0x2070a40,6, +0x2070a5c,3, +0x2070a80,5, +0x2070aa0,8, +0x2070c00,14, +0x2070c40,14, +0x2070c80,14, +0x2070cc0,14, +0x2070d40,3, +0x2070e00,7, +0x2070e20,14, +0x2070e80,5, +0x2070ea0,7, +0x2071000,13, +0x2071040,2, +0x2071054,4, +0x2071080,27, +0x2071100,12, +0x2071140,14, +0x2071180,28, +0x2071200,6, +0x2071240,6, +0x207125c,3, +0x2071280,5, +0x20712a0,8, +0x2071400,14, +0x2071440,14, +0x2071480,14, +0x20714c0,14, +0x2071540,3, +0x2071600,7, +0x2071620,14, +0x2071680,5, +0x20716a0,7, +0x2071800,13, +0x2071840,2, +0x2071854,4, +0x2071880,27, +0x2071900,12, +0x2071940,14, +0x2071980,28, +0x2071a00,6, +0x2071a40,6, +0x2071a5c,3, +0x2071a80,5, +0x2071aa0,8, +0x2071c00,14, +0x2071c40,14, +0x2071c80,14, +0x2071cc0,14, +0x2071d40,3, +0x2071e00,7, +0x2071e20,14, +0x2071e80,5, +0x2071ea0,7, +0x2072000,8, +0x2072040,8, +0x2072080,1, +0x2072098,6, +0x2072100,10, +0x2072140,3, +0x2072150,2, +0x2072180,2, +0x2072200,6, +0x2072220,18, +0x2072280,4, +0x2072300,8, +0x2072400,2, +0x2072480,2, +0x2072800,28, +0x20729f0,4, +0x2073000,40, +0x2073100,64, +0x2073800,56, +0x2073be0,8, +0x2074000,13, +0x2074040,2, +0x2074054,4, +0x2074080,27, +0x2074100,12, +0x2074140,14, +0x2074180,28, +0x2074200,6, +0x2074240,6, +0x207425c,3, +0x2074280,5, +0x20742a0,8, +0x2074400,14, +0x2074440,14, +0x2074480,14, +0x20744c0,14, +0x2074540,3, +0x2074600,7, +0x2074620,14, +0x2074680,5, +0x20746a0,7, +0x2074800,13, +0x2074840,2, +0x2074854,4, +0x2074880,27, +0x2074900,12, +0x2074940,14, +0x2074980,28, +0x2074a00,6, +0x2074a40,6, +0x2074a5c,3, +0x2074a80,5, +0x2074aa0,8, +0x2074c00,14, +0x2074c40,14, +0x2074c80,14, +0x2074cc0,14, +0x2074d40,3, +0x2074e00,7, +0x2074e20,14, +0x2074e80,5, +0x2074ea0,7, +0x2075000,13, +0x2075040,2, +0x2075054,4, +0x2075080,27, +0x2075100,12, +0x2075140,14, +0x2075180,28, +0x2075200,6, +0x2075240,6, +0x207525c,3, +0x2075280,5, +0x20752a0,8, +0x2075400,14, +0x2075440,14, +0x2075480,14, +0x20754c0,14, +0x2075540,3, +0x2075600,7, +0x2075620,14, +0x2075680,5, +0x20756a0,7, +0x2075800,13, +0x2075840,2, +0x2075854,4, +0x2075880,27, +0x2075900,12, +0x2075940,14, +0x2075980,28, +0x2075a00,6, +0x2075a40,6, +0x2075a5c,3, +0x2075a80,5, +0x2075aa0,8, +0x2075c00,14, +0x2075c40,14, +0x2075c80,14, +0x2075cc0,14, +0x2075d40,3, +0x2075e00,7, +0x2075e20,14, +0x2075e80,5, +0x2075ea0,7, +0x2076000,8, +0x2076040,8, +0x2076080,1, +0x2076098,6, +0x2076100,10, +0x2076140,3, +0x2076150,2, +0x2076180,2, +0x2076200,6, +0x2076220,18, +0x2076280,4, +0x2076300,8, +0x2076400,2, +0x2076480,2, +0x2076800,28, +0x20769f0,4, +0x2077000,40, +0x2077100,64, +0x2077800,56, +0x2077be0,8, +0x2078000,2, +0x207800c,2, +0x2078040,7, +0x2078100,3, +0x2078110,3, +0x2078120,5, +0x2078200,6, +0x2078240,5, +0x2078400,2, +0x207840c,2, +0x2078440,7, +0x2078500,3, +0x2078510,3, +0x2078520,5, +0x2078600,6, +0x2078640,5, +0x2078800,2, +0x207880c,2, +0x2078840,7, +0x2078900,3, +0x2078910,3, +0x2078920,5, +0x2078a00,6, +0x2078a40,5, +0x2078c00,2, +0x2078c0c,2, +0x2078c40,7, +0x2078d00,3, +0x2078d10,3, +0x2078d20,5, +0x2078e00,6, +0x2078e40,5, +0x2079000,2, +0x207900c,2, +0x2079040,7, +0x2079100,3, +0x2079110,3, +0x2079120,5, +0x2079200,6, +0x2079240,5, +0x2079400,2, +0x207940c,2, +0x2079440,7, +0x2079500,3, +0x2079510,3, +0x2079520,5, +0x2079600,6, +0x2079640,5, +0x2079800,2, +0x207980c,2, +0x2079840,7, +0x2079900,3, +0x2079910,3, +0x2079920,5, +0x2079a00,6, +0x2079a40,5, +0x2079c00,2, +0x2079c0c,2, +0x2079c40,7, +0x2079d00,3, +0x2079d10,3, +0x2079d20,5, +0x2079e00,6, +0x2079e40,5, +0x207a000,5, +0x207a040,9, +0x207a100,3, +0x207a200,1, +0x207a210,1, +0x207a220,1, +0x207a230,1, +0x207a240,1, +0x207a300,3, +0x207a314,1, +0x207a320,4, +0x207a400,5, +0x207a440,5, +0x207b000,80, +0x207b200,1, +0x2080000,3, +0x2080010,7, +0x2080030,10, +0x2080080,2, +0x2080100,6, +0x2080140,2, +0x2080180,2, +0x20801a0,1, +0x2080400,2, +0x2080440,4, +0x2080460,5, +0x2080478,1, +0x2080480,6, +0x20804a0,3, +0x20804b0,2, +0x2080500,5, +0x2080600,1, +0x2080800,5, +0x2080900,5, +0x2080a00,5, +0x2080b00,3, +0x2080c00,35, +0x2080d00,25, +0x2080d80,1, +0x2080dc0,3, +0x2080e00,2, +0x2080e20,2, +0x2090000,3, +0x209001c,6, +0x2090080,3, +0x2090090,2, +0x20900d4,4, +0x20900ec,27, +0x209015c,27, +0x20901cc,19, +0x2090224,120, +0x2090408,109, +0x20905f8,4, +0x2090610,27, +0x2090680,27, +0x20906f0,19, +0x2090748,120, +0x209092c,109, +0x2090b1c,4, +0x2090b34,27, +0x2090ba4,27, +0x2090c14,19, +0x2090c6c,120, +0x2090e50,109, +0x2091040,4, +0x2091058,27, +0x20910c8,27, +0x2091138,19, +0x2091190,120, +0x2091374,109, +0x2091564,4, +0x209157c,27, +0x20915ec,27, +0x209165c,19, +0x20916b4,120, +0x2091898,109, +0x2091a88,4, +0x2091aa0,27, +0x2091b10,27, +0x2091b80,19, +0x2091bd8,120, +0x2091dbc,109, +0x2091fac,4, +0x2091fc4,27, +0x2092034,27, +0x20920a4,19, +0x20920fc,120, +0x20922e0,109, +0x20924d0,4, +0x20924e8,27, +0x2092558,27, +0x20925c8,19, +0x2092620,120, +0x2092804,109, +0x20929f4,4, +0x2092a0c,27, +0x2092a7c,27, +0x2092aec,19, +0x2092b44,120, +0x2092d28,109, +0x2092f18,4, +0x2092f30,27, +0x2092fa0,27, +0x2093010,19, +0x2093068,120, +0x209324c,109, +0x209343c,4, +0x2093454,27, +0x20934c4,27, +0x2093534,19, +0x209358c,120, +0x2093770,109, +0x2093960,4, +0x2093978,27, +0x20939e8,27, +0x2093a58,19, +0x2093ab0,120, +0x2093c94,109, +0x2093e84,4, +0x2093e9c,27, +0x2093f0c,27, +0x2093f7c,19, +0x2093fd4,120, +0x20941b8,109, +0x20943a8,4, +0x20943c0,27, +0x2094430,27, +0x20944a0,19, +0x20944f8,120, +0x20946dc,109, +0x20948cc,4, +0x20948e4,27, +0x2094954,27, +0x20949c4,19, +0x2094a1c,120, +0x2094c00,109, +0x2094df0,4, +0x2094e08,27, +0x2094e78,27, +0x2094ee8,19, +0x2094f40,120, +0x2095124,109, +0x2095314,4, +0x209532c,27, +0x209539c,27, +0x209540c,19, +0x2095464,120, +0x2095648,109, +0x2095838,14, +0x2095940,13, +0x2095a44,13, +0x2095b48,16, +0x2095b90,42, +0x2095c40,2, +0x2095c90,54, +0x2095d70,58, +0x2095e60,58, +0x2095f50,58, +0x2096040,58, +0x2096130,58, +0x2096220,58, +0x2096310,58, +0x2096400,58, +0x20964f0,58, +0x20965e0,58, +0x20966d0,58, +0x20967c0,58, +0x20968b0,58, +0x20969a0,58, +0x2096a90,58, +0x2096b80,58, +0x2096c70,58, +0x2096d60,58, +0x2096e50,58, +0x2096f40,58, +0x2097030,58, +0x2097120,58, +0x2097210,58, +0x2097300,58, +0x20973f0,58, +0x20974e0,58, +0x20975d0,58, +0x20976c0,58, +0x20977b0,58, +0x20978a0,58, +0x2097990,58, +0x2097a80,101, +0x2097c90,49, +0x2097db0,18, +0x2097e00,11, +0x2097e30,4, +0x2097e54,45, +0x2097f58,9, +0x2097f88,4, +0x2097fa0,2, +0x2097fd8,14, +0x2098014,12, +0x2098158,3, +0x2098168,2, +0x2098174,68, +0x2098288,2, +0x2098294,68, +0x20983a8,1, +0x20983b0,2, +0x20983bc,68, +0x20984d0,2, +0x20984dc,68, +0x20985f0,1, +0x20985f8,4, +0x2098610,3, +0x2098624,12, +0x2098688,8, +0x20986dc,1, +0x20986e8,4, +0x2098700,3, +0x2098714,12, +0x2098778,8, +0x20987cc,1, +0x20987d8,4, +0x20987f0,3, +0x2098804,12, +0x2098868,8, +0x20988bc,1, +0x20988c8,4, +0x20988e0,3, +0x20988f4,12, +0x2098958,8, +0x20989ac,1, +0x20989b8,4, +0x20989d0,3, +0x20989e4,12, +0x2098a48,8, +0x2098a9c,1, +0x2098aa8,4, +0x2098ac0,3, +0x2098ad4,12, +0x2098b38,8, +0x2098b8c,1, +0x2098b98,4, +0x2098bb0,3, +0x2098bc4,12, +0x2098c28,8, +0x2098c7c,1, +0x2098c88,4, +0x2098ca0,3, +0x2098cb4,12, +0x2098d18,8, +0x2098d6c,1, +0x2098d78,4, +0x2098d90,3, +0x2098da4,12, +0x2098e08,8, +0x2098e5c,1, +0x2098e68,4, +0x2098e80,3, +0x2098e94,12, +0x2098ef8,8, +0x2098f4c,1, +0x2098f58,4, +0x2098f70,3, +0x2098f84,12, +0x2098fe8,8, +0x209903c,1, +0x2099048,4, +0x2099060,3, +0x2099074,12, +0x20990d8,8, +0x209912c,1, +0x2099138,4, +0x2099150,3, +0x2099164,12, +0x20991c8,8, +0x209921c,1, +0x2099228,4, +0x2099240,3, +0x2099254,12, +0x20992b8,8, +0x209930c,1, +0x2099318,4, +0x2099330,3, +0x2099344,12, +0x20993a8,8, +0x20993fc,1, +0x2099408,4, +0x2099420,3, +0x2099434,12, +0x2099498,8, +0x20994ec,1, +0x20994f8,4, +0x2099510,3, +0x2099524,12, +0x2099588,8, +0x20995dc,1, +0x20995e8,64, +0x2099748,5, +0x2099990,28, +0x2099a04,4, +0x2099a98,1, +0x2099be8,11, +0x2099c18,13, +0x2099c50,6, +0x209a000,15, +0x209a044,81, +0x209a18c,84, +0x209a2e0,84, +0x209a434,84, +0x209a588,84, +0x209a6dc,84, +0x209a830,84, +0x209a984,84, +0x209aad8,84, +0x209ac2c,84, +0x209ad80,84, +0x209aed4,84, +0x209b028,84, +0x209b17c,84, +0x209b2d0,84, +0x209b424,84, +0x209b578,84, +0x209b6cc,5, +0x209b760,4, +0x209b8e0,2414, +0x209dea4,88, +0x209e048,4, +0x209ebe0,1, +0x209ebf0,97, +0x209ed94,7, +0x209ee7c,1, +0x209eeac,9, +0x209eed4,5, +0x209eeec,11, +0x209ef2c,17, +0x209ef74,30, +0x209f034,3, +0x209f044,2, +0x209f054,17, +0x209fbe0,3, +0x209fbf0,1, +0x20a0000,3, +0x20a0018,2, +0x20a0024,14, +0x20a0060,27, +0x20a00d0,3, +0x20a00e0,3, +0x20a00f0,3, +0x20a0100,4, +0x20a0120,6, +0x20a0140,3, +0x20a0150,1, +0x20a015c,4, +0x20a0170,1, +0x20a0180,15, +0x20a01c0,1, +0x20a01c8,5, +0x20a01e0,1, +0x20a01f0,3, +0x20a0200,3, +0x20a0218,2, +0x20a0224,14, +0x20a0260,27, +0x20a02d0,3, +0x20a02e0,3, +0x20a02f0,3, +0x20a0300,4, +0x20a0320,6, +0x20a0340,3, +0x20a0350,1, +0x20a035c,4, +0x20a0370,1, +0x20a0380,15, +0x20a03c0,1, +0x20a03c8,5, +0x20a03e0,1, +0x20a03f0,3, +0x20a0400,3, +0x20a0418,2, +0x20a0424,14, +0x20a0460,27, +0x20a04d0,3, +0x20a04e0,3, +0x20a04f0,3, +0x20a0500,4, +0x20a0520,6, +0x20a0540,3, +0x20a0550,1, +0x20a055c,4, +0x20a0570,1, +0x20a0580,15, +0x20a05c0,1, +0x20a05c8,5, +0x20a05e0,1, +0x20a05f0,3, +0x20a0600,3, +0x20a0618,2, +0x20a0624,14, +0x20a0660,27, +0x20a06d0,3, +0x20a06e0,3, +0x20a06f0,3, +0x20a0700,4, +0x20a0720,6, +0x20a0740,3, +0x20a0750,1, +0x20a075c,4, +0x20a0770,1, +0x20a0780,15, +0x20a07c0,1, +0x20a07c8,5, +0x20a07e0,1, +0x20a07f0,3, +0x20a0800,3, +0x20a0818,2, +0x20a0824,14, +0x20a0860,27, +0x20a08d0,3, +0x20a08e0,3, +0x20a08f0,3, +0x20a0900,4, +0x20a0920,6, +0x20a0940,3, +0x20a0950,1, +0x20a095c,4, +0x20a0970,1, +0x20a0980,15, +0x20a09c0,1, +0x20a09c8,5, +0x20a09e0,1, +0x20a09f0,3, +0x20a1844,1, +0x20a1858,5, +0x20a1904,3, +0x20a1950,3, +0x20a1988,2, +0x20a19a0,7, +0x20a19c0,7, +0x20a19e0,4, +0x20a2000,24, +0x20a20f0,3, +0x20a2100,7, +0x20a2120,7, +0x20a2144,7, +0x20a2400,4, +0x20a2420,5, +0x20a25e0,3, +0x20a25f4,1, +0x20a25fc,4, +0x20a2620,3, +0x20a2680,8, +0x20a2700,19, +0x20a2800,99, +0x20a2a00,18, +0x20a2a80,8, +0x20a2b00,1, +0x20a3070,1, +0x20a3080,2, +0x20a308c,1, +0x20a3098,2, +0x20a3404,1, +0x20a3440,20, +0x20a3494,1, +0x20a349c,7, +0x20a34d0,4, +0x20a34e8,2, +0x20a34fc,8, +0x20a3520,7, +0x20a3540,7, +0x20a3560,7, +0x20a3580,7, +0x20a35a0,7, +0x20a35c0,7, +0x20a35e0,7, +0x20a3600,9, +0x20a363c,2, +0x20a3650,6, +0x20a3684,10, +0x20a3a00,10, +0x20a3a30,1, +0x20a3a40,8, +0x20a3a64,5, +0x20a4a04,3, +0x20a4b00,33, +0x20a4b90,3, +0x20a5000,8, +0x20a5040,8, +0x20a5104,1, +0x20a510c,3, +0x20a5124,1, +0x20a512c,3, +0x20a6000,13, +0x20a6200,14, +0x20a6240,1, +0x20a6248,1, +0x20a6258,1, +0x20a6260,8, +0x20a6284,1, +0x20a62a0,8, +0x20a6348,5, +0x20a67f0,1, +0x20a67f8,1, +0x20a6a10,12, +0x20a7000,19, +0x20a7a00,10, +0x20a7a80,3, +0x20a7b00,6, +0x20c0000,1, +0x20c000c,5, +0x20c0044,1, +0x20c0054,5, +0x20c0200,128, +0x20c0404,1, +0x20c0428,54, +0x20c0600,32, +0x20c0704,1, +0x20c0800,1, +0x20c0900,1, +0x20c0910,2, +0x20c0920,3, +0x20c0980,10, +0x20c0a00,19, +0x20c0b00,1, +0x20e0000,2, +0x20e000c,2, +0x20e0018,2, +0x20e0024,2, +0x20e0030,2, +0x20e003c,2, +0x20e0048,2, +0x20e0054,2, +0x20e0060,1, +0x20e0070,2, +0x20e007c,2, +0x20e0088,2, +0x20e0094,2, +0x20e00a0,2, +0x20e00ac,2, +0x20e00b8,2, +0x20e00c4,2, +0x20e00d0,1, +0x20e00e0,2, +0x20e00ec,2, +0x20e00f8,2, +0x20e0104,2, +0x20e0110,2, +0x20e011c,2, +0x20e0128,2, +0x20e0134,2, +0x20e0140,1, +0x20e0150,2, +0x20e015c,2, +0x20e0168,2, +0x20e0174,2, +0x20e0180,2, +0x20e018c,2, +0x20e0198,2, +0x20e01a4,2, +0x20e01b0,1, +0x20e01c0,57, +0x20e02b0,23, +0x20e0310,83, +0x20e0460,83, +0x20e05b0,83, +0x20e0700,83, +0x20e0850,83, +0x20e09a0,83, +0x20e0af0,83, +0x20e0c40,83, +0x20e0d90,83, +0x20e0ee0,83, +0x20e1030,83, +0x20e1180,83, +0x20e12d0,83, +0x20e1420,83, +0x20e1570,83, +0x20e16c0,83, +0x20e1810,83, +0x20e1960,83, +0x20e1ab0,83, +0x20e1c00,83, +0x20e1d50,83, +0x20e1ea0,83, +0x20e1ff0,83, +0x20e2140,83, +0x20e2290,83, +0x20e23e0,83, +0x20e2530,83, +0x20e2680,83, +0x20e27d0,83, +0x20e2920,83, +0x20e2a70,83, +0x20e2bc0,62, +0x20e2db4,3, +0x20e2df4,3, +0x20e2e34,3, +0x20e2e74,3, +0x20e2eb4,3, +0x20e2ef4,3, +0x20e2f34,3, +0x20e2f74,3, +0x20e2fb4,3, +0x20e2ff4,3, +0x20e3034,3, +0x20e3074,3, +0x20e30b4,3, +0x20e30f4,3, +0x20e3134,3, +0x20e3174,3, +0x20e31b4,3, +0x20f0000,4, +0x20f0014,2, +0x20f0020,8, +0x20f0044,2, +0x20f0050,13, +0x20f0088,20, +0x20f00dc,1, +0x20f0180,6, +0x20f0590,3, +0x20f05c0,2, +0x20f0a04,1, +0x20f0a0c,3, +0x20f0a20,1, +0x20f0ba0,4, +0x20f0c00,4, +0x20f0c20,3, +0x20f0c30,5, +0x20f0c50,52, +0x20f0d50,57, +0x20f0ec0,3, +0x20f0ffc,3, +0x20f1020,3, +0x20f1030,3, +0x20f1060,2, +0x20f1100,2, +0x20f1140,18, +0x20f11c0,30, +0x20f1240,14, +0x20f1280,28, +0x20f1300,2, +0x20f13a0,6, +0x20f1400,19, +0x20f1800,19, +0x20f1c00,19, +0x20f1c80,8, +0x20f1d00,3, +0x20f1d50,3, +0x20f1e00,3, +0x20f1e10,2, +0x20f1e20,6, +0x20f1e40,6, +0x20f1e60,6, +0x20f1e80,6, +0x20f1ea0,6, +0x20f1ec0,2, +0x20f1ecc,2, +0x20f1ee0,2, +0x20f1eec,2, +0x20f1f80,3, +0x20f1f90,60, +0x20f2100,32, +0x20f2200,32, +0x20f2300,32, +0x20f2400,32, +0x20f2500,32, +0x20f2600,32, +0x20f2700,32, +0x20f2800,32, +0x20f2900,32, +0x20f2a00,32, +0x20f2b00,32, +0x20f2c00,32, +0x20f2d00,32, +0x20f2e00,32, +0x20f2f00,32, +0x20f3000,32, +0x20f30c0,3, +0x20f4000,2, +0x20f4040,16, +0x20f4100,36, +0x20f4800,5, +0x20f4824,1, +0x20f482c,1, +0x20f4c04,1, +0x20f4cd8,74, +0x20f5000,7, +0x20f5020,4, +0x20f5204,1, +0x20f5280,35, +0x20f5310,4, +0x20f5404,1, +0x20f5480,34, +0x20f5510,10, +0x20f553c,3, +0x20f5800,7, +0x20f5820,4, +0x20f5a04,1, +0x20f5a80,35, +0x20f5b10,4, +0x20f5c04,1, +0x20f5c80,34, +0x20f5d10,10, +0x20f5d3c,3, +0x20fa000,5, +0x20fa01c,13, +0x20fa060,3, +0x20fa080,8, +0x20fa100,5, +0x20fa11c,13, +0x20fa160,3, +0x20fa180,8, +0x2200004,5, +0x2200020,3, +0x2200030,3, +0x2200040,13, +0x2200078,4, +0x220009c,25, +0x2200104,5, +0x2200120,3, +0x2200130,3, +0x2200140,13, +0x2200178,4, +0x220019c,25, +0x2200204,5, +0x2200220,3, +0x2200230,3, +0x2200240,13, +0x2200278,4, +0x220029c,25, +0x2200304,5, +0x2200320,3, +0x2200330,3, +0x2200340,13, +0x2200378,4, +0x220039c,25, +0x2200600,4, +0x2200c00,24, +0x2200c80,24, +0x2200d00,24, +0x2200d80,24, +0x2200e00,4, +0x2200e20,4, +0x2200e40,4, +0x2200e60,4, +0x2200e80,39, +0x2200f20,7, +0x2200f40,7, +0x2200f60,7, +0x2201000,12, +0x2201200,1, +0x2201218,2, +0x220122c,1, +0x2201280,1, +0x2201298,2, +0x22012ac,1, +0x2201300,1, +0x2201318,2, +0x220132c,1, +0x2201380,1, +0x2201398,2, +0x22013ac,1, +0x2201400,4, +0x2201420,2, +0x220142c,1, +0x2201480,4, +0x22014a0,2, +0x22014ac,1, +0x2201500,4, +0x2201520,2, +0x220152c,1, +0x2201580,4, +0x22015a0,2, +0x22015ac,1, +0x2201600,4, +0x2201640,4, +0x2201680,4, +0x22016c0,4, +0x2201700,7, +0x2201720,7, +0x2201740,7, +0x2201760,7, +0x2201780,4, +0x220179c,11, +0x22017d0,2, +0x22017e0,2, +0x22017f0,2, +0x2201900,44, +0x2202000,7, +0x2202020,4, +0x2202040,4, +0x2202060,7, +0x2202080,7, +0x22020a0,4, +0x22020c0,4, +0x22020e0,7, +0x2202100,7, +0x2202120,4, +0x2202140,4, +0x2202160,7, +0x2202180,7, +0x22021a0,4, +0x22021c0,4, +0x22021e0,7, +0x2202200,32, +0x2202b00,1, +0x2202b20,1, +0x2202b28,4, +0x2202b40,1, +0x2202b60,1, +0x2202b68,4, +0x2202b80,1, +0x2202ba0,1, +0x2202ba8,4, +0x2202bc0,1, +0x2202be0,1, +0x2202be8,4, +0x2202c00,7, +0x2202c20,1, +0x2202c54,18, +0x2202ca0,1, +0x2202cd4,18, +0x2202d20,1, +0x2202d54,18, +0x2202da0,1, +0x2202dd4,12, +0x2202e08,6, +0x2203100,7, +0x2203120,7, +0x2203140,7, +0x2203160,7, +0x2203180,3, +0x2204004,5, +0x2204020,3, +0x2204030,3, +0x2204040,13, +0x2204078,4, +0x220409c,25, +0x2204104,5, +0x2204120,3, +0x2204130,3, +0x2204140,13, +0x2204178,4, +0x220419c,25, +0x2204204,5, +0x2204220,3, +0x2204230,3, +0x2204240,13, +0x2204278,4, +0x220429c,25, +0x2204304,5, +0x2204320,3, +0x2204330,3, +0x2204340,13, +0x2204378,4, +0x220439c,25, +0x2204600,4, +0x2204c00,24, +0x2204c80,24, +0x2204d00,24, +0x2204d80,24, +0x2204e00,4, +0x2204e20,4, +0x2204e40,4, +0x2204e60,4, +0x2204e80,39, +0x2204f20,7, +0x2204f40,7, +0x2204f60,7, +0x2205000,12, +0x2205200,1, +0x2205218,2, +0x220522c,1, +0x2205280,1, +0x2205298,2, +0x22052ac,1, +0x2205300,1, +0x2205318,2, +0x220532c,1, +0x2205380,1, +0x2205398,2, +0x22053ac,1, +0x2205400,4, +0x2205420,2, +0x220542c,1, +0x2205480,4, +0x22054a0,2, +0x22054ac,1, +0x2205500,4, +0x2205520,2, +0x220552c,1, +0x2205580,4, +0x22055a0,2, +0x22055ac,1, +0x2205600,4, +0x2205640,4, +0x2205680,4, +0x22056c0,4, +0x2205700,7, +0x2205720,7, +0x2205740,7, +0x2205760,7, +0x2205780,4, +0x220579c,11, +0x22057d0,2, +0x22057e0,2, +0x22057f0,2, +0x2205900,44, +0x2206000,7, +0x2206020,4, +0x2206040,4, +0x2206060,7, +0x2206080,7, +0x22060a0,4, +0x22060c0,4, +0x22060e0,7, +0x2206100,7, +0x2206120,4, +0x2206140,4, +0x2206160,7, +0x2206180,7, +0x22061a0,4, +0x22061c0,4, +0x22061e0,7, +0x2206200,32, +0x2206b00,1, +0x2206b20,1, +0x2206b28,4, +0x2206b40,1, +0x2206b60,1, +0x2206b68,4, +0x2206b80,1, +0x2206ba0,1, +0x2206ba8,4, +0x2206bc0,1, +0x2206be0,1, +0x2206be8,4, +0x2206c00,7, +0x2206c20,1, +0x2206c54,18, +0x2206ca0,1, +0x2206cd4,18, +0x2206d20,1, +0x2206d54,18, +0x2206da0,1, +0x2206dd4,12, +0x2206e08,6, +0x2207100,7, +0x2207120,7, +0x2207140,7, +0x2207160,7, +0x2207180,3, +0x2208000,10, +0x2208080,3, +0x22080c0,1, +0x2208100,21, +0x2208180,13, +0x22081c4,7, +0x22081e4,7, +0x2208204,7, +0x2208224,8, +0x2209000,7, +0x2209030,2, +0x2209040,7, +0x2209070,2, +0x2209100,2, +0x2209120,2, +0x2209140,2, +0x2209160,2, +0x2209180,9, +0x2209200,7, +0x2209230,2, +0x2209240,7, +0x2209270,2, +0x2209300,2, +0x2209320,2, +0x2209340,2, +0x2209360,2, +0x2209380,9, +0x2209400,11, +0x2209500,11, +0x220a000,3, +0x220a010,2, +0x220a01c,5, +0x220a040,8, +0x220a080,3, +0x220a090,2, +0x220a09c,5, +0x220a0c0,8, +0x220a100,3, +0x220a110,2, +0x220a11c,5, +0x220a140,8, +0x220a180,3, +0x220a190,2, +0x220a19c,5, +0x220a1c0,8, +0x220a200,7, +0x220a220,12, +0x220a280,7, +0x220a2a0,12, +0x220a300,3, +0x220a310,1, +0x220a400,3, +0x220a410,2, +0x220a41c,5, +0x220a440,8, +0x220a480,3, +0x220a490,2, +0x220a49c,5, +0x220a4c0,8, +0x220a500,3, +0x220a510,2, +0x220a51c,5, +0x220a540,8, +0x220a580,3, +0x220a590,2, +0x220a59c,5, +0x220a5c0,8, +0x220a600,7, +0x220a620,12, +0x220a680,7, +0x220a6a0,12, +0x220a700,3, +0x220a710,1, +0x220a804,1, +0x220a824,21, +0x220a880,16, +0x220a900,5, +0x220a920,11, +0x220a950,9, +0x220a980,22, +0x220aa00,22, +0x220aa80,22, +0x220ab00,22, +0x220ab80,22, +0x220ac00,22, +0x220ac80,22, +0x220ad00,22, +0x220ad80,3, +0x220c000,16, +0x220c080,11, +0x220c100,11, +0x220c204,1, +0x220c224,21, +0x220c280,16, +0x220c300,11, +0x220c340,11, +0x220c800,21, +0x220c860,5, +0x220c880,6, +0x220c8a0,5, +0x220c8c0,6, +0x220c900,21, +0x220c960,5, +0x220c980,6, +0x220c9a0,5, +0x220c9c0,6, +0x220ca00,21, +0x220ca60,5, +0x220ca80,6, +0x220caa0,5, +0x220cac0,6, +0x220cb00,21, +0x220cb60,5, +0x220cb80,6, +0x220cba0,5, +0x220cbc0,6, +0x220cc00,9, +0x220cc48,7, +0x220cc68,2, +0x220cc74,9, +0x220cc9c,2, +0x220cd00,14, +0x220cd40,14, +0x220cd80,28, +0x220ce00,19, +0x220ce50,3, +0x220ce60,25, +0x220cec8,1, +0x220ced0,2, +0x220cee0,7, +0x220cf00,1, +0x220cf08,2, +0x220cffc,20, +0x220d050,25, +0x220d100,19, +0x220d150,25, +0x220d200,19, +0x220d250,25, +0x220d300,19, +0x220d350,25, +0x220d400,19, +0x220d450,25, +0x220d500,19, +0x220d550,25, +0x220d600,19, +0x220d650,25, +0x220d700,19, +0x220d750,25, +0x220d800,19, +0x220d850,25, +0x220d904,1, +0x220d914,10, +0x220d948,11, +0x220d980,2, +0x220d9a0,6, +0x220d9c0,2, +0x220d9cc,2, +0x220e000,35, +0x220ea00,10, +0x220ea80,3, +0x220eb00,6, +0x220f000,1, +0x220f008,5, +0x220f038,1, +0x220f044,1, +0x220f050,2, +0x220f100,13, +0x220f140,11, +0x220f170,12, +0x220f1a4,1, +0x220f200,104, +0x220f400,104, +0x220f600,104, +0x220f800,104, +0x2210000,13, +0x2210040,2, +0x2210054,4, +0x2210080,27, +0x2210100,12, +0x2210140,14, +0x2210180,28, +0x2210200,6, +0x2210240,6, +0x221025c,3, +0x2210280,5, +0x22102a0,8, +0x2210400,14, +0x2210440,14, +0x2210480,14, +0x22104c0,14, +0x2210540,3, +0x2210600,7, +0x2210620,14, +0x2210680,5, +0x22106a0,7, +0x2210800,13, +0x2210840,2, +0x2210854,4, +0x2210880,27, +0x2210900,12, +0x2210940,14, +0x2210980,28, +0x2210a00,6, +0x2210a40,6, +0x2210a5c,3, +0x2210a80,5, +0x2210aa0,8, +0x2210c00,14, +0x2210c40,14, +0x2210c80,14, +0x2210cc0,14, +0x2210d40,3, +0x2210e00,7, +0x2210e20,14, +0x2210e80,5, +0x2210ea0,7, +0x2211000,13, +0x2211040,2, +0x2211054,4, +0x2211080,27, +0x2211100,12, +0x2211140,14, +0x2211180,28, +0x2211200,6, +0x2211240,6, +0x221125c,3, +0x2211280,5, +0x22112a0,8, +0x2211400,14, +0x2211440,14, +0x2211480,14, +0x22114c0,14, +0x2211540,3, +0x2211600,7, +0x2211620,14, +0x2211680,5, +0x22116a0,7, +0x2211800,13, +0x2211840,2, +0x2211854,4, +0x2211880,27, +0x2211900,12, +0x2211940,14, +0x2211980,28, +0x2211a00,6, +0x2211a40,6, +0x2211a5c,3, +0x2211a80,5, +0x2211aa0,8, +0x2211c00,14, +0x2211c40,14, +0x2211c80,14, +0x2211cc0,14, +0x2211d40,3, +0x2211e00,7, +0x2211e20,14, +0x2211e80,5, +0x2211ea0,7, +0x2212000,8, +0x2212040,8, +0x2212080,1, +0x2212098,6, +0x2212100,10, +0x2212140,3, +0x2212150,2, +0x2212180,2, +0x2212200,6, +0x2212220,18, +0x2212280,4, +0x2212300,8, +0x2212400,2, +0x2212480,2, +0x2212800,28, +0x22129f0,4, +0x2213000,40, +0x2213100,64, +0x2213800,56, +0x2213be0,8, +0x2214000,13, +0x2214040,2, +0x2214054,4, +0x2214080,27, +0x2214100,12, +0x2214140,14, +0x2214180,28, +0x2214200,6, +0x2214240,6, +0x221425c,3, +0x2214280,5, +0x22142a0,8, +0x2214400,14, +0x2214440,14, +0x2214480,14, +0x22144c0,14, +0x2214540,3, +0x2214600,7, +0x2214620,14, +0x2214680,5, +0x22146a0,7, +0x2214800,13, +0x2214840,2, +0x2214854,4, +0x2214880,27, +0x2214900,12, +0x2214940,14, +0x2214980,28, +0x2214a00,6, +0x2214a40,6, +0x2214a5c,3, +0x2214a80,5, +0x2214aa0,8, +0x2214c00,14, +0x2214c40,14, +0x2214c80,14, +0x2214cc0,14, +0x2214d40,3, +0x2214e00,7, +0x2214e20,14, +0x2214e80,5, +0x2214ea0,7, +0x2215000,13, +0x2215040,2, +0x2215054,4, +0x2215080,27, +0x2215100,12, +0x2215140,14, +0x2215180,28, +0x2215200,6, +0x2215240,6, +0x221525c,3, +0x2215280,5, +0x22152a0,8, +0x2215400,14, +0x2215440,14, +0x2215480,14, +0x22154c0,14, +0x2215540,3, +0x2215600,7, +0x2215620,14, +0x2215680,5, +0x22156a0,7, +0x2215800,13, +0x2215840,2, +0x2215854,4, +0x2215880,27, +0x2215900,12, +0x2215940,14, +0x2215980,28, +0x2215a00,6, +0x2215a40,6, +0x2215a5c,3, +0x2215a80,5, +0x2215aa0,8, +0x2215c00,14, +0x2215c40,14, +0x2215c80,14, +0x2215cc0,14, +0x2215d40,3, +0x2215e00,7, +0x2215e20,14, +0x2215e80,5, +0x2215ea0,7, +0x2216000,8, +0x2216040,8, +0x2216080,1, +0x2216098,6, +0x2216100,10, +0x2216140,3, +0x2216150,2, +0x2216180,2, +0x2216200,6, +0x2216220,18, +0x2216280,4, +0x2216300,8, +0x2216400,2, +0x2216480,2, +0x2216800,28, +0x22169f0,4, +0x2217000,40, +0x2217100,64, +0x2217800,56, +0x2217be0,8, +0x2218000,2, +0x221800c,2, +0x2218040,7, +0x2218100,3, +0x2218110,3, +0x2218120,5, +0x2218200,6, +0x2218240,5, +0x2218400,2, +0x221840c,2, +0x2218440,7, +0x2218500,3, +0x2218510,3, +0x2218520,5, +0x2218600,6, +0x2218640,5, +0x2218800,2, +0x221880c,2, +0x2218840,7, +0x2218900,3, +0x2218910,3, +0x2218920,5, +0x2218a00,6, +0x2218a40,5, +0x2218c00,2, +0x2218c0c,2, +0x2218c40,7, +0x2218d00,3, +0x2218d10,3, +0x2218d20,5, +0x2218e00,6, +0x2218e40,5, +0x2219000,2, +0x221900c,2, +0x2219040,7, +0x2219100,3, +0x2219110,3, +0x2219120,5, +0x2219200,6, +0x2219240,5, +0x2219400,2, +0x221940c,2, +0x2219440,7, +0x2219500,3, +0x2219510,3, +0x2219520,5, +0x2219600,6, +0x2219640,5, +0x2219800,2, +0x221980c,2, +0x2219840,7, +0x2219900,3, +0x2219910,3, +0x2219920,5, +0x2219a00,6, +0x2219a40,5, +0x2219c00,2, +0x2219c0c,2, +0x2219c40,7, +0x2219d00,3, +0x2219d10,3, +0x2219d20,5, +0x2219e00,6, +0x2219e40,5, +0x221a000,5, +0x221a040,9, +0x221a100,3, +0x221a200,1, +0x221a210,1, +0x221a220,1, +0x221a230,1, +0x221a240,1, +0x221a300,3, +0x221a314,1, +0x221a320,4, +0x221a400,5, +0x221a440,5, +0x221b000,80, +0x221b200,1, +0x2220004,5, +0x2220020,3, +0x2220030,3, +0x2220040,13, +0x2220078,4, +0x222009c,25, +0x2220104,5, +0x2220120,3, +0x2220130,3, +0x2220140,13, +0x2220178,4, +0x222019c,25, +0x2220204,5, +0x2220220,3, +0x2220230,3, +0x2220240,13, +0x2220278,4, +0x222029c,25, +0x2220304,5, +0x2220320,3, +0x2220330,3, +0x2220340,13, +0x2220378,4, +0x222039c,25, +0x2220600,4, +0x2220c00,24, +0x2220c80,24, +0x2220d00,24, +0x2220d80,24, +0x2220e00,4, +0x2220e20,4, +0x2220e40,4, +0x2220e60,4, +0x2220e80,39, +0x2220f20,7, +0x2220f40,7, +0x2220f60,7, +0x2221000,12, +0x2221200,1, +0x2221218,2, +0x222122c,1, +0x2221280,1, +0x2221298,2, +0x22212ac,1, +0x2221300,1, +0x2221318,2, +0x222132c,1, +0x2221380,1, +0x2221398,2, +0x22213ac,1, +0x2221400,4, +0x2221420,2, +0x222142c,1, +0x2221480,4, +0x22214a0,2, +0x22214ac,1, +0x2221500,4, +0x2221520,2, +0x222152c,1, +0x2221580,4, +0x22215a0,2, +0x22215ac,1, +0x2221600,4, +0x2221640,4, +0x2221680,4, +0x22216c0,4, +0x2221700,7, +0x2221720,7, +0x2221740,7, +0x2221760,7, +0x2221780,4, +0x222179c,11, +0x22217d0,2, +0x22217e0,2, +0x22217f0,2, +0x2221900,44, +0x2222000,7, +0x2222020,4, +0x2222040,4, +0x2222060,7, +0x2222080,7, +0x22220a0,4, +0x22220c0,4, +0x22220e0,7, +0x2222100,7, +0x2222120,4, +0x2222140,4, +0x2222160,7, +0x2222180,7, +0x22221a0,4, +0x22221c0,4, +0x22221e0,7, +0x2222200,32, +0x2222b00,1, +0x2222b20,1, +0x2222b28,4, +0x2222b40,1, +0x2222b60,1, +0x2222b68,4, +0x2222b80,1, +0x2222ba0,1, +0x2222ba8,4, +0x2222bc0,1, +0x2222be0,1, +0x2222be8,4, +0x2222c00,7, +0x2222c20,1, +0x2222c54,18, +0x2222ca0,1, +0x2222cd4,18, +0x2222d20,1, +0x2222d54,18, +0x2222da0,1, +0x2222dd4,12, +0x2222e08,6, +0x2223100,7, +0x2223120,7, +0x2223140,7, +0x2223160,7, +0x2223180,3, +0x2224004,5, +0x2224020,3, +0x2224030,3, +0x2224040,13, +0x2224078,4, +0x222409c,25, +0x2224104,5, +0x2224120,3, +0x2224130,3, +0x2224140,13, +0x2224178,4, +0x222419c,25, +0x2224204,5, +0x2224220,3, +0x2224230,3, +0x2224240,13, +0x2224278,4, +0x222429c,25, +0x2224304,5, +0x2224320,3, +0x2224330,3, +0x2224340,13, +0x2224378,4, +0x222439c,25, +0x2224600,4, +0x2224c00,24, +0x2224c80,24, +0x2224d00,24, +0x2224d80,24, +0x2224e00,4, +0x2224e20,4, +0x2224e40,4, +0x2224e60,4, +0x2224e80,39, +0x2224f20,7, +0x2224f40,7, +0x2224f60,7, +0x2225000,12, +0x2225200,1, +0x2225218,2, +0x222522c,1, +0x2225280,1, +0x2225298,2, +0x22252ac,1, +0x2225300,1, +0x2225318,2, +0x222532c,1, +0x2225380,1, +0x2225398,2, +0x22253ac,1, +0x2225400,4, +0x2225420,2, +0x222542c,1, +0x2225480,4, +0x22254a0,2, +0x22254ac,1, +0x2225500,4, +0x2225520,2, +0x222552c,1, +0x2225580,4, +0x22255a0,2, +0x22255ac,1, +0x2225600,4, +0x2225640,4, +0x2225680,4, +0x22256c0,4, +0x2225700,7, +0x2225720,7, +0x2225740,7, +0x2225760,7, +0x2225780,4, +0x222579c,11, +0x22257d0,2, +0x22257e0,2, +0x22257f0,2, +0x2225900,44, +0x2226000,7, +0x2226020,4, +0x2226040,4, +0x2226060,7, +0x2226080,7, +0x22260a0,4, +0x22260c0,4, +0x22260e0,7, +0x2226100,7, +0x2226120,4, +0x2226140,4, +0x2226160,7, +0x2226180,7, +0x22261a0,4, +0x22261c0,4, +0x22261e0,7, +0x2226200,32, +0x2226b00,1, +0x2226b20,1, +0x2226b28,4, +0x2226b40,1, +0x2226b60,1, +0x2226b68,4, +0x2226b80,1, +0x2226ba0,1, +0x2226ba8,4, +0x2226bc0,1, +0x2226be0,1, +0x2226be8,4, +0x2226c00,7, +0x2226c20,1, +0x2226c54,18, +0x2226ca0,1, +0x2226cd4,18, +0x2226d20,1, +0x2226d54,18, +0x2226da0,1, +0x2226dd4,12, +0x2226e08,6, +0x2227100,7, +0x2227120,7, +0x2227140,7, +0x2227160,7, +0x2227180,3, +0x2228000,10, +0x2228080,3, +0x22280c0,1, +0x2228100,21, +0x2228180,13, +0x22281c4,7, +0x22281e4,7, +0x2228204,7, +0x2228224,8, +0x2229000,7, +0x2229030,2, +0x2229040,7, +0x2229070,2, +0x2229100,2, +0x2229120,2, +0x2229140,2, +0x2229160,2, +0x2229180,9, +0x2229200,7, +0x2229230,2, +0x2229240,7, +0x2229270,2, +0x2229300,2, +0x2229320,2, +0x2229340,2, +0x2229360,2, +0x2229380,9, +0x2229400,11, +0x2229500,11, +0x222a000,3, +0x222a010,2, +0x222a01c,5, +0x222a040,8, +0x222a080,3, +0x222a090,2, +0x222a09c,5, +0x222a0c0,8, +0x222a100,3, +0x222a110,2, +0x222a11c,5, +0x222a140,8, +0x222a180,3, +0x222a190,2, +0x222a19c,5, +0x222a1c0,8, +0x222a200,7, +0x222a220,12, +0x222a280,7, +0x222a2a0,12, +0x222a300,3, +0x222a310,1, +0x222a400,3, +0x222a410,2, +0x222a41c,5, +0x222a440,8, +0x222a480,3, +0x222a490,2, +0x222a49c,5, +0x222a4c0,8, +0x222a500,3, +0x222a510,2, +0x222a51c,5, +0x222a540,8, +0x222a580,3, +0x222a590,2, +0x222a59c,5, +0x222a5c0,8, +0x222a600,7, +0x222a620,12, +0x222a680,7, +0x222a6a0,12, +0x222a700,3, +0x222a710,1, +0x222a804,1, +0x222a824,21, +0x222a880,16, +0x222a900,5, +0x222a920,11, +0x222a950,9, +0x222a980,22, +0x222aa00,22, +0x222aa80,22, +0x222ab00,22, +0x222ab80,22, +0x222ac00,22, +0x222ac80,22, +0x222ad00,22, +0x222ad80,3, +0x222c000,16, +0x222c080,11, +0x222c100,11, +0x222c204,1, +0x222c224,21, +0x222c280,16, +0x222c300,11, +0x222c340,11, +0x222c800,21, +0x222c860,5, +0x222c880,6, +0x222c8a0,5, +0x222c8c0,6, +0x222c900,21, +0x222c960,5, +0x222c980,6, +0x222c9a0,5, +0x222c9c0,6, +0x222ca00,21, +0x222ca60,5, +0x222ca80,6, +0x222caa0,5, +0x222cac0,6, +0x222cb00,21, +0x222cb60,5, +0x222cb80,6, +0x222cba0,5, +0x222cbc0,6, +0x222cc00,9, +0x222cc48,7, +0x222cc68,2, +0x222cc74,9, +0x222cc9c,2, +0x222cd00,14, +0x222cd40,14, +0x222cd80,28, +0x222ce00,19, +0x222ce50,3, +0x222ce60,25, +0x222cec8,1, +0x222ced0,2, +0x222cee0,7, +0x222cf00,1, +0x222cf08,2, +0x222cffc,20, +0x222d050,25, +0x222d100,19, +0x222d150,25, +0x222d200,19, +0x222d250,25, +0x222d300,19, +0x222d350,25, +0x222d400,19, +0x222d450,25, +0x222d500,19, +0x222d550,25, +0x222d600,19, +0x222d650,25, +0x222d700,19, +0x222d750,25, +0x222d800,19, +0x222d850,25, +0x222d904,1, +0x222d914,10, +0x222d948,11, +0x222d980,2, +0x222d9a0,6, +0x222d9c0,2, +0x222d9cc,2, +0x222e000,35, +0x222ea00,10, +0x222ea80,3, +0x222eb00,6, +0x222f000,1, +0x222f008,5, +0x222f038,1, +0x222f044,1, +0x222f050,2, +0x222f100,13, +0x222f140,11, +0x222f170,12, +0x222f1a4,1, +0x222f200,104, +0x222f400,104, +0x222f600,104, +0x222f800,104, +0x2230000,13, +0x2230040,2, +0x2230054,4, +0x2230080,27, +0x2230100,12, +0x2230140,14, +0x2230180,28, +0x2230200,6, +0x2230240,6, +0x223025c,3, +0x2230280,5, +0x22302a0,8, +0x2230400,14, +0x2230440,14, +0x2230480,14, +0x22304c0,14, +0x2230540,3, +0x2230600,7, +0x2230620,14, +0x2230680,5, +0x22306a0,7, +0x2230800,13, +0x2230840,2, +0x2230854,4, +0x2230880,27, +0x2230900,12, +0x2230940,14, +0x2230980,28, +0x2230a00,6, +0x2230a40,6, +0x2230a5c,3, +0x2230a80,5, +0x2230aa0,8, +0x2230c00,14, +0x2230c40,14, +0x2230c80,14, +0x2230cc0,14, +0x2230d40,3, +0x2230e00,7, +0x2230e20,14, +0x2230e80,5, +0x2230ea0,7, +0x2231000,13, +0x2231040,2, +0x2231054,4, +0x2231080,27, +0x2231100,12, +0x2231140,14, +0x2231180,28, +0x2231200,6, +0x2231240,6, +0x223125c,3, +0x2231280,5, +0x22312a0,8, +0x2231400,14, +0x2231440,14, +0x2231480,14, +0x22314c0,14, +0x2231540,3, +0x2231600,7, +0x2231620,14, +0x2231680,5, +0x22316a0,7, +0x2231800,13, +0x2231840,2, +0x2231854,4, +0x2231880,27, +0x2231900,12, +0x2231940,14, +0x2231980,28, +0x2231a00,6, +0x2231a40,6, +0x2231a5c,3, +0x2231a80,5, +0x2231aa0,8, +0x2231c00,14, +0x2231c40,14, +0x2231c80,14, +0x2231cc0,14, +0x2231d40,3, +0x2231e00,7, +0x2231e20,14, +0x2231e80,5, +0x2231ea0,7, +0x2232000,8, +0x2232040,8, +0x2232080,1, +0x2232098,6, +0x2232100,10, +0x2232140,3, +0x2232150,2, +0x2232180,2, +0x2232200,6, +0x2232220,18, +0x2232280,4, +0x2232300,8, +0x2232400,2, +0x2232480,2, +0x2232800,28, +0x22329f0,4, +0x2233000,40, +0x2233100,64, +0x2233800,56, +0x2233be0,8, +0x2234000,13, +0x2234040,2, +0x2234054,4, +0x2234080,27, +0x2234100,12, +0x2234140,14, +0x2234180,28, +0x2234200,6, +0x2234240,6, +0x223425c,3, +0x2234280,5, +0x22342a0,8, +0x2234400,14, +0x2234440,14, +0x2234480,14, +0x22344c0,14, +0x2234540,3, +0x2234600,7, +0x2234620,14, +0x2234680,5, +0x22346a0,7, +0x2234800,13, +0x2234840,2, +0x2234854,4, +0x2234880,27, +0x2234900,12, +0x2234940,14, +0x2234980,28, +0x2234a00,6, +0x2234a40,6, +0x2234a5c,3, +0x2234a80,5, +0x2234aa0,8, +0x2234c00,14, +0x2234c40,14, +0x2234c80,14, +0x2234cc0,14, +0x2234d40,3, +0x2234e00,7, +0x2234e20,14, +0x2234e80,5, +0x2234ea0,7, +0x2235000,13, +0x2235040,2, +0x2235054,4, +0x2235080,27, +0x2235100,12, +0x2235140,14, +0x2235180,28, +0x2235200,6, +0x2235240,6, +0x223525c,3, +0x2235280,5, +0x22352a0,8, +0x2235400,14, +0x2235440,14, +0x2235480,14, +0x22354c0,14, +0x2235540,3, +0x2235600,7, +0x2235620,14, +0x2235680,5, +0x22356a0,7, +0x2235800,13, +0x2235840,2, +0x2235854,4, +0x2235880,27, +0x2235900,12, +0x2235940,14, +0x2235980,28, +0x2235a00,6, +0x2235a40,6, +0x2235a5c,3, +0x2235a80,5, +0x2235aa0,8, +0x2235c00,14, +0x2235c40,14, +0x2235c80,14, +0x2235cc0,14, +0x2235d40,3, +0x2235e00,7, +0x2235e20,14, +0x2235e80,5, +0x2235ea0,7, +0x2236000,8, +0x2236040,8, +0x2236080,1, +0x2236098,6, +0x2236100,10, +0x2236140,3, +0x2236150,2, +0x2236180,2, +0x2236200,6, +0x2236220,18, +0x2236280,4, +0x2236300,8, +0x2236400,2, +0x2236480,2, +0x2236800,28, +0x22369f0,4, +0x2237000,40, +0x2237100,64, +0x2237800,56, +0x2237be0,8, +0x2238000,2, +0x223800c,2, +0x2238040,7, +0x2238100,3, +0x2238110,3, +0x2238120,5, +0x2238200,6, +0x2238240,5, +0x2238400,2, +0x223840c,2, +0x2238440,7, +0x2238500,3, +0x2238510,3, +0x2238520,5, +0x2238600,6, +0x2238640,5, +0x2238800,2, +0x223880c,2, +0x2238840,7, +0x2238900,3, +0x2238910,3, +0x2238920,5, +0x2238a00,6, +0x2238a40,5, +0x2238c00,2, +0x2238c0c,2, +0x2238c40,7, +0x2238d00,3, +0x2238d10,3, +0x2238d20,5, +0x2238e00,6, +0x2238e40,5, +0x2239000,2, +0x223900c,2, +0x2239040,7, +0x2239100,3, +0x2239110,3, +0x2239120,5, +0x2239200,6, +0x2239240,5, +0x2239400,2, +0x223940c,2, +0x2239440,7, +0x2239500,3, +0x2239510,3, +0x2239520,5, +0x2239600,6, +0x2239640,5, +0x2239800,2, +0x223980c,2, +0x2239840,7, +0x2239900,3, +0x2239910,3, +0x2239920,5, +0x2239a00,6, +0x2239a40,5, +0x2239c00,2, +0x2239c0c,2, +0x2239c40,7, +0x2239d00,3, +0x2239d10,3, +0x2239d20,5, +0x2239e00,6, +0x2239e40,5, +0x223a000,5, +0x223a040,9, +0x223a100,3, +0x223a200,1, +0x223a210,1, +0x223a220,1, +0x223a230,1, +0x223a240,1, +0x223a300,3, +0x223a314,1, +0x223a320,4, +0x223a400,5, +0x223a440,5, +0x223b000,80, +0x223b200,1, +0x2240004,5, +0x2240020,3, +0x2240030,3, +0x2240040,13, +0x2240078,4, +0x224009c,25, +0x2240104,5, +0x2240120,3, +0x2240130,3, +0x2240140,13, +0x2240178,4, +0x224019c,25, +0x2240204,5, +0x2240220,3, +0x2240230,3, +0x2240240,13, +0x2240278,4, +0x224029c,25, +0x2240304,5, +0x2240320,3, +0x2240330,3, +0x2240340,13, +0x2240378,4, +0x224039c,25, +0x2240600,4, +0x2240c00,24, +0x2240c80,24, +0x2240d00,24, +0x2240d80,24, +0x2240e00,4, +0x2240e20,4, +0x2240e40,4, +0x2240e60,4, +0x2240e80,39, +0x2240f20,7, +0x2240f40,7, +0x2240f60,7, +0x2241000,12, +0x2241200,1, +0x2241218,2, +0x224122c,1, +0x2241280,1, +0x2241298,2, +0x22412ac,1, +0x2241300,1, +0x2241318,2, +0x224132c,1, +0x2241380,1, +0x2241398,2, +0x22413ac,1, +0x2241400,4, +0x2241420,2, +0x224142c,1, +0x2241480,4, +0x22414a0,2, +0x22414ac,1, +0x2241500,4, +0x2241520,2, +0x224152c,1, +0x2241580,4, +0x22415a0,2, +0x22415ac,1, +0x2241600,4, +0x2241640,4, +0x2241680,4, +0x22416c0,4, +0x2241700,7, +0x2241720,7, +0x2241740,7, +0x2241760,7, +0x2241780,4, +0x224179c,11, +0x22417d0,2, +0x22417e0,2, +0x22417f0,2, +0x2241900,44, +0x2242000,7, +0x2242020,4, +0x2242040,4, +0x2242060,7, +0x2242080,7, +0x22420a0,4, +0x22420c0,4, +0x22420e0,7, +0x2242100,7, +0x2242120,4, +0x2242140,4, +0x2242160,7, +0x2242180,7, +0x22421a0,4, +0x22421c0,4, +0x22421e0,7, +0x2242200,32, +0x2242b00,1, +0x2242b20,1, +0x2242b28,4, +0x2242b40,1, +0x2242b60,1, +0x2242b68,4, +0x2242b80,1, +0x2242ba0,1, +0x2242ba8,4, +0x2242bc0,1, +0x2242be0,1, +0x2242be8,4, +0x2242c00,7, +0x2242c20,1, +0x2242c54,18, +0x2242ca0,1, +0x2242cd4,18, +0x2242d20,1, +0x2242d54,18, +0x2242da0,1, +0x2242dd4,12, +0x2242e08,6, +0x2243100,7, +0x2243120,7, +0x2243140,7, +0x2243160,7, +0x2243180,3, +0x2244004,5, +0x2244020,3, +0x2244030,3, +0x2244040,13, +0x2244078,4, +0x224409c,25, +0x2244104,5, +0x2244120,3, +0x2244130,3, +0x2244140,13, +0x2244178,4, +0x224419c,25, +0x2244204,5, +0x2244220,3, +0x2244230,3, +0x2244240,13, +0x2244278,4, +0x224429c,25, +0x2244304,5, +0x2244320,3, +0x2244330,3, +0x2244340,13, +0x2244378,4, +0x224439c,25, +0x2244600,4, +0x2244c00,24, +0x2244c80,24, +0x2244d00,24, +0x2244d80,24, +0x2244e00,4, +0x2244e20,4, +0x2244e40,4, +0x2244e60,4, +0x2244e80,39, +0x2244f20,7, +0x2244f40,7, +0x2244f60,7, +0x2245000,12, +0x2245200,1, +0x2245218,2, +0x224522c,1, +0x2245280,1, +0x2245298,2, +0x22452ac,1, +0x2245300,1, +0x2245318,2, +0x224532c,1, +0x2245380,1, +0x2245398,2, +0x22453ac,1, +0x2245400,4, +0x2245420,2, +0x224542c,1, +0x2245480,4, +0x22454a0,2, +0x22454ac,1, +0x2245500,4, +0x2245520,2, +0x224552c,1, +0x2245580,4, +0x22455a0,2, +0x22455ac,1, +0x2245600,4, +0x2245640,4, +0x2245680,4, +0x22456c0,4, +0x2245700,7, +0x2245720,7, +0x2245740,7, +0x2245760,7, +0x2245780,4, +0x224579c,11, +0x22457d0,2, +0x22457e0,2, +0x22457f0,2, +0x2245900,44, +0x2246000,7, +0x2246020,4, +0x2246040,4, +0x2246060,7, +0x2246080,7, +0x22460a0,4, +0x22460c0,4, +0x22460e0,7, +0x2246100,7, +0x2246120,4, +0x2246140,4, +0x2246160,7, +0x2246180,7, +0x22461a0,4, +0x22461c0,4, +0x22461e0,7, +0x2246200,32, +0x2246b00,1, +0x2246b20,1, +0x2246b28,4, +0x2246b40,1, +0x2246b60,1, +0x2246b68,4, +0x2246b80,1, +0x2246ba0,1, +0x2246ba8,4, +0x2246bc0,1, +0x2246be0,1, +0x2246be8,4, +0x2246c00,7, +0x2246c20,1, +0x2246c54,18, +0x2246ca0,1, +0x2246cd4,18, +0x2246d20,1, +0x2246d54,18, +0x2246da0,1, +0x2246dd4,12, +0x2246e08,6, +0x2247100,7, +0x2247120,7, +0x2247140,7, +0x2247160,7, +0x2247180,3, +0x2248000,10, +0x2248080,3, +0x22480c0,1, +0x2248100,21, +0x2248180,13, +0x22481c4,7, +0x22481e4,7, +0x2248204,7, +0x2248224,8, +0x2249000,7, +0x2249030,2, +0x2249040,7, +0x2249070,2, +0x2249100,2, +0x2249120,2, +0x2249140,2, +0x2249160,2, +0x2249180,9, +0x2249200,7, +0x2249230,2, +0x2249240,7, +0x2249270,2, +0x2249300,2, +0x2249320,2, +0x2249340,2, +0x2249360,2, +0x2249380,9, +0x2249400,11, +0x2249500,11, +0x224a000,3, +0x224a010,2, +0x224a01c,5, +0x224a040,8, +0x224a080,3, +0x224a090,2, +0x224a09c,5, +0x224a0c0,8, +0x224a100,3, +0x224a110,2, +0x224a11c,5, +0x224a140,8, +0x224a180,3, +0x224a190,2, +0x224a19c,5, +0x224a1c0,8, +0x224a200,7, +0x224a220,12, +0x224a280,7, +0x224a2a0,12, +0x224a300,3, +0x224a310,1, +0x224a400,3, +0x224a410,2, +0x224a41c,5, +0x224a440,8, +0x224a480,3, +0x224a490,2, +0x224a49c,5, +0x224a4c0,8, +0x224a500,3, +0x224a510,2, +0x224a51c,5, +0x224a540,8, +0x224a580,3, +0x224a590,2, +0x224a59c,5, +0x224a5c0,8, +0x224a600,7, +0x224a620,12, +0x224a680,7, +0x224a6a0,12, +0x224a700,3, +0x224a710,1, +0x224a804,1, +0x224a824,21, +0x224a880,16, +0x224a900,5, +0x224a920,11, +0x224a950,9, +0x224a980,22, +0x224aa00,22, +0x224aa80,22, +0x224ab00,22, +0x224ab80,22, +0x224ac00,22, +0x224ac80,22, +0x224ad00,22, +0x224ad80,3, +0x224c000,16, +0x224c080,11, +0x224c100,11, +0x224c204,1, +0x224c224,21, +0x224c280,16, +0x224c300,11, +0x224c340,11, +0x224c800,21, +0x224c860,5, +0x224c880,6, +0x224c8a0,5, +0x224c8c0,6, +0x224c900,21, +0x224c960,5, +0x224c980,6, +0x224c9a0,5, +0x224c9c0,6, +0x224ca00,21, +0x224ca60,5, +0x224ca80,6, +0x224caa0,5, +0x224cac0,6, +0x224cb00,21, +0x224cb60,5, +0x224cb80,6, +0x224cba0,5, +0x224cbc0,6, +0x224cc00,9, +0x224cc48,7, +0x224cc68,2, +0x224cc74,9, +0x224cc9c,2, +0x224cd00,14, +0x224cd40,14, +0x224cd80,28, +0x224ce00,19, +0x224ce50,3, +0x224ce60,25, +0x224cec8,1, +0x224ced0,2, +0x224cee0,7, +0x224cf00,1, +0x224cf08,2, +0x224cffc,20, +0x224d050,25, +0x224d100,19, +0x224d150,25, +0x224d200,19, +0x224d250,25, +0x224d300,19, +0x224d350,25, +0x224d400,19, +0x224d450,25, +0x224d500,19, +0x224d550,25, +0x224d600,19, +0x224d650,25, +0x224d700,19, +0x224d750,25, +0x224d800,19, +0x224d850,25, +0x224d904,1, +0x224d914,10, +0x224d948,11, +0x224d980,2, +0x224d9a0,6, +0x224d9c0,2, +0x224d9cc,2, +0x224e000,35, +0x224ea00,10, +0x224ea80,3, +0x224eb00,6, +0x224f000,1, +0x224f008,5, +0x224f038,1, +0x224f044,1, +0x224f050,2, +0x224f100,13, +0x224f140,11, +0x224f170,12, +0x224f1a4,1, +0x224f200,104, +0x224f400,104, +0x224f600,104, +0x224f800,104, +0x2250000,13, +0x2250040,2, +0x2250054,4, +0x2250080,27, +0x2250100,12, +0x2250140,14, +0x2250180,28, +0x2250200,6, +0x2250240,6, +0x225025c,3, +0x2250280,5, +0x22502a0,8, +0x2250400,14, +0x2250440,14, +0x2250480,14, +0x22504c0,14, +0x2250540,3, +0x2250600,7, +0x2250620,14, +0x2250680,5, +0x22506a0,7, +0x2250800,13, +0x2250840,2, +0x2250854,4, +0x2250880,27, +0x2250900,12, +0x2250940,14, +0x2250980,28, +0x2250a00,6, +0x2250a40,6, +0x2250a5c,3, +0x2250a80,5, +0x2250aa0,8, +0x2250c00,14, +0x2250c40,14, +0x2250c80,14, +0x2250cc0,14, +0x2250d40,3, +0x2250e00,7, +0x2250e20,14, +0x2250e80,5, +0x2250ea0,7, +0x2251000,13, +0x2251040,2, +0x2251054,4, +0x2251080,27, +0x2251100,12, +0x2251140,14, +0x2251180,28, +0x2251200,6, +0x2251240,6, +0x225125c,3, +0x2251280,5, +0x22512a0,8, +0x2251400,14, +0x2251440,14, +0x2251480,14, +0x22514c0,14, +0x2251540,3, +0x2251600,7, +0x2251620,14, +0x2251680,5, +0x22516a0,7, +0x2251800,13, +0x2251840,2, +0x2251854,4, +0x2251880,27, +0x2251900,12, +0x2251940,14, +0x2251980,28, +0x2251a00,6, +0x2251a40,6, +0x2251a5c,3, +0x2251a80,5, +0x2251aa0,8, +0x2251c00,14, +0x2251c40,14, +0x2251c80,14, +0x2251cc0,14, +0x2251d40,3, +0x2251e00,7, +0x2251e20,14, +0x2251e80,5, +0x2251ea0,7, +0x2252000,8, +0x2252040,8, +0x2252080,1, +0x2252098,6, +0x2252100,10, +0x2252140,3, +0x2252150,2, +0x2252180,2, +0x2252200,6, +0x2252220,18, +0x2252280,4, +0x2252300,8, +0x2252400,2, +0x2252480,2, +0x2252800,28, +0x22529f0,4, +0x2253000,40, +0x2253100,64, +0x2253800,56, +0x2253be0,8, +0x2254000,13, +0x2254040,2, +0x2254054,4, +0x2254080,27, +0x2254100,12, +0x2254140,14, +0x2254180,28, +0x2254200,6, +0x2254240,6, +0x225425c,3, +0x2254280,5, +0x22542a0,8, +0x2254400,14, +0x2254440,14, +0x2254480,14, +0x22544c0,14, +0x2254540,3, +0x2254600,7, +0x2254620,14, +0x2254680,5, +0x22546a0,7, +0x2254800,13, +0x2254840,2, +0x2254854,4, +0x2254880,27, +0x2254900,12, +0x2254940,14, +0x2254980,28, +0x2254a00,6, +0x2254a40,6, +0x2254a5c,3, +0x2254a80,5, +0x2254aa0,8, +0x2254c00,14, +0x2254c40,14, +0x2254c80,14, +0x2254cc0,14, +0x2254d40,3, +0x2254e00,7, +0x2254e20,14, +0x2254e80,5, +0x2254ea0,7, +0x2255000,13, +0x2255040,2, +0x2255054,4, +0x2255080,27, +0x2255100,12, +0x2255140,14, +0x2255180,28, +0x2255200,6, +0x2255240,6, +0x225525c,3, +0x2255280,5, +0x22552a0,8, +0x2255400,14, +0x2255440,14, +0x2255480,14, +0x22554c0,14, +0x2255540,3, +0x2255600,7, +0x2255620,14, +0x2255680,5, +0x22556a0,7, +0x2255800,13, +0x2255840,2, +0x2255854,4, +0x2255880,27, +0x2255900,12, +0x2255940,14, +0x2255980,28, +0x2255a00,6, +0x2255a40,6, +0x2255a5c,3, +0x2255a80,5, +0x2255aa0,8, +0x2255c00,14, +0x2255c40,14, +0x2255c80,14, +0x2255cc0,14, +0x2255d40,3, +0x2255e00,7, +0x2255e20,14, +0x2255e80,5, +0x2255ea0,7, +0x2256000,8, +0x2256040,8, +0x2256080,1, +0x2256098,6, +0x2256100,10, +0x2256140,3, +0x2256150,2, +0x2256180,2, +0x2256200,6, +0x2256220,18, +0x2256280,4, +0x2256300,8, +0x2256400,2, +0x2256480,2, +0x2256800,28, +0x22569f0,4, +0x2257000,40, +0x2257100,64, +0x2257800,56, +0x2257be0,8, +0x2258000,2, +0x225800c,2, +0x2258040,7, +0x2258100,3, +0x2258110,3, +0x2258120,5, +0x2258200,6, +0x2258240,5, +0x2258400,2, +0x225840c,2, +0x2258440,7, +0x2258500,3, +0x2258510,3, +0x2258520,5, +0x2258600,6, +0x2258640,5, +0x2258800,2, +0x225880c,2, +0x2258840,7, +0x2258900,3, +0x2258910,3, +0x2258920,5, +0x2258a00,6, +0x2258a40,5, +0x2258c00,2, +0x2258c0c,2, +0x2258c40,7, +0x2258d00,3, +0x2258d10,3, +0x2258d20,5, +0x2258e00,6, +0x2258e40,5, +0x2259000,2, +0x225900c,2, +0x2259040,7, +0x2259100,3, +0x2259110,3, +0x2259120,5, +0x2259200,6, +0x2259240,5, +0x2259400,2, +0x225940c,2, +0x2259440,7, +0x2259500,3, +0x2259510,3, +0x2259520,5, +0x2259600,6, +0x2259640,5, +0x2259800,2, +0x225980c,2, +0x2259840,7, +0x2259900,3, +0x2259910,3, +0x2259920,5, +0x2259a00,6, +0x2259a40,5, +0x2259c00,2, +0x2259c0c,2, +0x2259c40,7, +0x2259d00,3, +0x2259d10,3, +0x2259d20,5, +0x2259e00,6, +0x2259e40,5, +0x225a000,5, +0x225a040,9, +0x225a100,3, +0x225a200,1, +0x225a210,1, +0x225a220,1, +0x225a230,1, +0x225a240,1, +0x225a300,3, +0x225a314,1, +0x225a320,4, +0x225a400,5, +0x225a440,5, +0x225b000,80, +0x225b200,1, +0x2260004,5, +0x2260020,3, +0x2260030,3, +0x2260040,13, +0x2260078,4, +0x226009c,25, +0x2260104,5, +0x2260120,3, +0x2260130,3, +0x2260140,13, +0x2260178,4, +0x226019c,25, +0x2260204,5, +0x2260220,3, +0x2260230,3, +0x2260240,13, +0x2260278,4, +0x226029c,25, +0x2260304,5, +0x2260320,3, +0x2260330,3, +0x2260340,13, +0x2260378,4, +0x226039c,25, +0x2260600,4, +0x2260c00,24, +0x2260c80,24, +0x2260d00,24, +0x2260d80,24, +0x2260e00,4, +0x2260e20,4, +0x2260e40,4, +0x2260e60,4, +0x2260e80,39, +0x2260f20,7, +0x2260f40,7, +0x2260f60,7, +0x2261000,12, +0x2261200,1, +0x2261218,2, +0x226122c,1, +0x2261280,1, +0x2261298,2, +0x22612ac,1, +0x2261300,1, +0x2261318,2, +0x226132c,1, +0x2261380,1, +0x2261398,2, +0x22613ac,1, +0x2261400,4, +0x2261420,2, +0x226142c,1, +0x2261480,4, +0x22614a0,2, +0x22614ac,1, +0x2261500,4, +0x2261520,2, +0x226152c,1, +0x2261580,4, +0x22615a0,2, +0x22615ac,1, +0x2261600,4, +0x2261640,4, +0x2261680,4, +0x22616c0,4, +0x2261700,7, +0x2261720,7, +0x2261740,7, +0x2261760,7, +0x2261780,4, +0x226179c,11, +0x22617d0,2, +0x22617e0,2, +0x22617f0,2, +0x2261900,44, +0x2262000,7, +0x2262020,4, +0x2262040,4, +0x2262060,7, +0x2262080,7, +0x22620a0,4, +0x22620c0,4, +0x22620e0,7, +0x2262100,7, +0x2262120,4, +0x2262140,4, +0x2262160,7, +0x2262180,7, +0x22621a0,4, +0x22621c0,4, +0x22621e0,7, +0x2262200,32, +0x2262b00,1, +0x2262b20,1, +0x2262b28,4, +0x2262b40,1, +0x2262b60,1, +0x2262b68,4, +0x2262b80,1, +0x2262ba0,1, +0x2262ba8,4, +0x2262bc0,1, +0x2262be0,1, +0x2262be8,4, +0x2262c00,7, +0x2262c20,1, +0x2262c54,18, +0x2262ca0,1, +0x2262cd4,18, +0x2262d20,1, +0x2262d54,18, +0x2262da0,1, +0x2262dd4,12, +0x2262e08,6, +0x2263100,7, +0x2263120,7, +0x2263140,7, +0x2263160,7, +0x2263180,3, +0x2264004,5, +0x2264020,3, +0x2264030,3, +0x2264040,13, +0x2264078,4, +0x226409c,25, +0x2264104,5, +0x2264120,3, +0x2264130,3, +0x2264140,13, +0x2264178,4, +0x226419c,25, +0x2264204,5, +0x2264220,3, +0x2264230,3, +0x2264240,13, +0x2264278,4, +0x226429c,25, +0x2264304,5, +0x2264320,3, +0x2264330,3, +0x2264340,13, +0x2264378,4, +0x226439c,25, +0x2264600,4, +0x2264c00,24, +0x2264c80,24, +0x2264d00,24, +0x2264d80,24, +0x2264e00,4, +0x2264e20,4, +0x2264e40,4, +0x2264e60,4, +0x2264e80,39, +0x2264f20,7, +0x2264f40,7, +0x2264f60,7, +0x2265000,12, +0x2265200,1, +0x2265218,2, +0x226522c,1, +0x2265280,1, +0x2265298,2, +0x22652ac,1, +0x2265300,1, +0x2265318,2, +0x226532c,1, +0x2265380,1, +0x2265398,2, +0x22653ac,1, +0x2265400,4, +0x2265420,2, +0x226542c,1, +0x2265480,4, +0x22654a0,2, +0x22654ac,1, +0x2265500,4, +0x2265520,2, +0x226552c,1, +0x2265580,4, +0x22655a0,2, +0x22655ac,1, +0x2265600,4, +0x2265640,4, +0x2265680,4, +0x22656c0,4, +0x2265700,7, +0x2265720,7, +0x2265740,7, +0x2265760,7, +0x2265780,4, +0x226579c,11, +0x22657d0,2, +0x22657e0,2, +0x22657f0,2, +0x2265900,44, +0x2266000,7, +0x2266020,4, +0x2266040,4, +0x2266060,7, +0x2266080,7, +0x22660a0,4, +0x22660c0,4, +0x22660e0,7, +0x2266100,7, +0x2266120,4, +0x2266140,4, +0x2266160,7, +0x2266180,7, +0x22661a0,4, +0x22661c0,4, +0x22661e0,7, +0x2266200,32, +0x2266b00,1, +0x2266b20,1, +0x2266b28,4, +0x2266b40,1, +0x2266b60,1, +0x2266b68,4, +0x2266b80,1, +0x2266ba0,1, +0x2266ba8,4, +0x2266bc0,1, +0x2266be0,1, +0x2266be8,4, +0x2266c00,7, +0x2266c20,1, +0x2266c54,18, +0x2266ca0,1, +0x2266cd4,18, +0x2266d20,1, +0x2266d54,18, +0x2266da0,1, +0x2266dd4,12, +0x2266e08,6, +0x2267100,7, +0x2267120,7, +0x2267140,7, +0x2267160,7, +0x2267180,3, +0x2268000,10, +0x2268080,3, +0x22680c0,1, +0x2268100,21, +0x2268180,13, +0x22681c4,7, +0x22681e4,7, +0x2268204,7, +0x2268224,8, +0x2269000,7, +0x2269030,2, +0x2269040,7, +0x2269070,2, +0x2269100,2, +0x2269120,2, +0x2269140,2, +0x2269160,2, +0x2269180,9, +0x2269200,7, +0x2269230,2, +0x2269240,7, +0x2269270,2, +0x2269300,2, +0x2269320,2, +0x2269340,2, +0x2269360,2, +0x2269380,9, +0x2269400,11, +0x2269500,11, +0x226a000,3, +0x226a010,2, +0x226a01c,5, +0x226a040,8, +0x226a080,3, +0x226a090,2, +0x226a09c,5, +0x226a0c0,8, +0x226a100,3, +0x226a110,2, +0x226a11c,5, +0x226a140,8, +0x226a180,3, +0x226a190,2, +0x226a19c,5, +0x226a1c0,8, +0x226a200,7, +0x226a220,12, +0x226a280,7, +0x226a2a0,12, +0x226a300,3, +0x226a310,1, +0x226a400,3, +0x226a410,2, +0x226a41c,5, +0x226a440,8, +0x226a480,3, +0x226a490,2, +0x226a49c,5, +0x226a4c0,8, +0x226a500,3, +0x226a510,2, +0x226a51c,5, +0x226a540,8, +0x226a580,3, +0x226a590,2, +0x226a59c,5, +0x226a5c0,8, +0x226a600,7, +0x226a620,12, +0x226a680,7, +0x226a6a0,12, +0x226a700,3, +0x226a710,1, +0x226a804,1, +0x226a824,21, +0x226a880,16, +0x226a900,5, +0x226a920,11, +0x226a950,9, +0x226a980,22, +0x226aa00,22, +0x226aa80,22, +0x226ab00,22, +0x226ab80,22, +0x226ac00,22, +0x226ac80,22, +0x226ad00,22, +0x226ad80,3, +0x226c000,16, +0x226c080,11, +0x226c100,11, +0x226c204,1, +0x226c224,21, +0x226c280,16, +0x226c300,11, +0x226c340,11, +0x226c800,21, +0x226c860,5, +0x226c880,6, +0x226c8a0,5, +0x226c8c0,6, +0x226c900,21, +0x226c960,5, +0x226c980,6, +0x226c9a0,5, +0x226c9c0,6, +0x226ca00,21, +0x226ca60,5, +0x226ca80,6, +0x226caa0,5, +0x226cac0,6, +0x226cb00,21, +0x226cb60,5, +0x226cb80,6, +0x226cba0,5, +0x226cbc0,6, +0x226cc00,9, +0x226cc48,7, +0x226cc68,2, +0x226cc74,9, +0x226cc9c,2, +0x226cd00,14, +0x226cd40,14, +0x226cd80,28, +0x226ce00,19, +0x226ce50,3, +0x226ce60,25, +0x226cec8,1, +0x226ced0,2, +0x226cee0,7, +0x226cf00,1, +0x226cf08,2, +0x226cffc,20, +0x226d050,25, +0x226d100,19, +0x226d150,25, +0x226d200,19, +0x226d250,25, +0x226d300,19, +0x226d350,25, +0x226d400,19, +0x226d450,25, +0x226d500,19, +0x226d550,25, +0x226d600,19, +0x226d650,25, +0x226d700,19, +0x226d750,25, +0x226d800,19, +0x226d850,25, +0x226d904,1, +0x226d914,10, +0x226d948,11, +0x226d980,2, +0x226d9a0,6, +0x226d9c0,2, +0x226d9cc,2, +0x226e000,35, +0x226ea00,10, +0x226ea80,3, +0x226eb00,6, +0x226f000,1, +0x226f008,5, +0x226f038,1, +0x226f044,1, +0x226f050,2, +0x226f100,13, +0x226f140,11, +0x226f170,12, +0x226f1a4,1, +0x226f200,104, +0x226f400,104, +0x226f600,104, +0x226f800,104, +0x2270000,13, +0x2270040,2, +0x2270054,4, +0x2270080,27, +0x2270100,12, +0x2270140,14, +0x2270180,28, +0x2270200,6, +0x2270240,6, +0x227025c,3, +0x2270280,5, +0x22702a0,8, +0x2270400,14, +0x2270440,14, +0x2270480,14, +0x22704c0,14, +0x2270540,3, +0x2270600,7, +0x2270620,14, +0x2270680,5, +0x22706a0,7, +0x2270800,13, +0x2270840,2, +0x2270854,4, +0x2270880,27, +0x2270900,12, +0x2270940,14, +0x2270980,28, +0x2270a00,6, +0x2270a40,6, +0x2270a5c,3, +0x2270a80,5, +0x2270aa0,8, +0x2270c00,14, +0x2270c40,14, +0x2270c80,14, +0x2270cc0,14, +0x2270d40,3, +0x2270e00,7, +0x2270e20,14, +0x2270e80,5, +0x2270ea0,7, +0x2271000,13, +0x2271040,2, +0x2271054,4, +0x2271080,27, +0x2271100,12, +0x2271140,14, +0x2271180,28, +0x2271200,6, +0x2271240,6, +0x227125c,3, +0x2271280,5, +0x22712a0,8, +0x2271400,14, +0x2271440,14, +0x2271480,14, +0x22714c0,14, +0x2271540,3, +0x2271600,7, +0x2271620,14, +0x2271680,5, +0x22716a0,7, +0x2271800,13, +0x2271840,2, +0x2271854,4, +0x2271880,27, +0x2271900,12, +0x2271940,14, +0x2271980,28, +0x2271a00,6, +0x2271a40,6, +0x2271a5c,3, +0x2271a80,5, +0x2271aa0,8, +0x2271c00,14, +0x2271c40,14, +0x2271c80,14, +0x2271cc0,14, +0x2271d40,3, +0x2271e00,7, +0x2271e20,14, +0x2271e80,5, +0x2271ea0,7, +0x2272000,8, +0x2272040,8, +0x2272080,1, +0x2272098,6, +0x2272100,10, +0x2272140,3, +0x2272150,2, +0x2272180,2, +0x2272200,6, +0x2272220,18, +0x2272280,4, +0x2272300,8, +0x2272400,2, +0x2272480,2, +0x2272800,28, +0x22729f0,4, +0x2273000,40, +0x2273100,64, +0x2273800,56, +0x2273be0,8, +0x2274000,13, +0x2274040,2, +0x2274054,4, +0x2274080,27, +0x2274100,12, +0x2274140,14, +0x2274180,28, +0x2274200,6, +0x2274240,6, +0x227425c,3, +0x2274280,5, +0x22742a0,8, +0x2274400,14, +0x2274440,14, +0x2274480,14, +0x22744c0,14, +0x2274540,3, +0x2274600,7, +0x2274620,14, +0x2274680,5, +0x22746a0,7, +0x2274800,13, +0x2274840,2, +0x2274854,4, +0x2274880,27, +0x2274900,12, +0x2274940,14, +0x2274980,28, +0x2274a00,6, +0x2274a40,6, +0x2274a5c,3, +0x2274a80,5, +0x2274aa0,8, +0x2274c00,14, +0x2274c40,14, +0x2274c80,14, +0x2274cc0,14, +0x2274d40,3, +0x2274e00,7, +0x2274e20,14, +0x2274e80,5, +0x2274ea0,7, +0x2275000,13, +0x2275040,2, +0x2275054,4, +0x2275080,27, +0x2275100,12, +0x2275140,14, +0x2275180,28, +0x2275200,6, +0x2275240,6, +0x227525c,3, +0x2275280,5, +0x22752a0,8, +0x2275400,14, +0x2275440,14, +0x2275480,14, +0x22754c0,14, +0x2275540,3, +0x2275600,7, +0x2275620,14, +0x2275680,5, +0x22756a0,7, +0x2275800,13, +0x2275840,2, +0x2275854,4, +0x2275880,27, +0x2275900,12, +0x2275940,14, +0x2275980,28, +0x2275a00,6, +0x2275a40,6, +0x2275a5c,3, +0x2275a80,5, +0x2275aa0,8, +0x2275c00,14, +0x2275c40,14, +0x2275c80,14, +0x2275cc0,14, +0x2275d40,3, +0x2275e00,7, +0x2275e20,14, +0x2275e80,5, +0x2275ea0,7, +0x2276000,8, +0x2276040,8, +0x2276080,1, +0x2276098,6, +0x2276100,10, +0x2276140,3, +0x2276150,2, +0x2276180,2, +0x2276200,6, +0x2276220,18, +0x2276280,4, +0x2276300,8, +0x2276400,2, +0x2276480,2, +0x2276800,28, +0x22769f0,4, +0x2277000,40, +0x2277100,64, +0x2277800,56, +0x2277be0,8, +0x2278000,2, +0x227800c,2, +0x2278040,7, +0x2278100,3, +0x2278110,3, +0x2278120,5, +0x2278200,6, +0x2278240,5, +0x2278400,2, +0x227840c,2, +0x2278440,7, +0x2278500,3, +0x2278510,3, +0x2278520,5, +0x2278600,6, +0x2278640,5, +0x2278800,2, +0x227880c,2, +0x2278840,7, +0x2278900,3, +0x2278910,3, +0x2278920,5, +0x2278a00,6, +0x2278a40,5, +0x2278c00,2, +0x2278c0c,2, +0x2278c40,7, +0x2278d00,3, +0x2278d10,3, +0x2278d20,5, +0x2278e00,6, +0x2278e40,5, +0x2279000,2, +0x227900c,2, +0x2279040,7, +0x2279100,3, +0x2279110,3, +0x2279120,5, +0x2279200,6, +0x2279240,5, +0x2279400,2, +0x227940c,2, +0x2279440,7, +0x2279500,3, +0x2279510,3, +0x2279520,5, +0x2279600,6, +0x2279640,5, +0x2279800,2, +0x227980c,2, +0x2279840,7, +0x2279900,3, +0x2279910,3, +0x2279920,5, +0x2279a00,6, +0x2279a40,5, +0x2279c00,2, +0x2279c0c,2, +0x2279c40,7, +0x2279d00,3, +0x2279d10,3, +0x2279d20,5, +0x2279e00,6, +0x2279e40,5, +0x227a000,5, +0x227a040,9, +0x227a100,3, +0x227a200,1, +0x227a210,1, +0x227a220,1, +0x227a230,1, +0x227a240,1, +0x227a300,3, +0x227a314,1, +0x227a320,4, +0x227a400,5, +0x227a440,5, +0x227b000,80, +0x227b200,1, +0x2280000,3, +0x2280010,7, +0x2280030,10, +0x2280080,2, +0x2280100,6, +0x2280140,2, +0x2280180,2, +0x22801a0,1, +0x2280400,2, +0x2280440,4, +0x2280460,5, +0x2280478,1, +0x2280480,6, +0x22804a0,3, +0x22804b0,2, +0x2280500,5, +0x2280600,1, +0x2280800,5, +0x2280900,5, +0x2280a00,5, +0x2280b00,3, +0x2280c00,35, +0x2280d00,25, +0x2280d80,1, +0x2280dc0,3, +0x2280e00,2, +0x2280e20,2, +0x2290000,3, +0x229001c,6, +0x2290080,3, +0x2290090,2, +0x22900d4,4, +0x22900ec,27, +0x229015c,27, +0x22901cc,19, +0x2290224,120, +0x2290408,109, +0x22905f8,4, +0x2290610,27, +0x2290680,27, +0x22906f0,19, +0x2290748,120, +0x229092c,109, +0x2290b1c,4, +0x2290b34,27, +0x2290ba4,27, +0x2290c14,19, +0x2290c6c,120, +0x2290e50,109, +0x2291040,4, +0x2291058,27, +0x22910c8,27, +0x2291138,19, +0x2291190,120, +0x2291374,109, +0x2291564,4, +0x229157c,27, +0x22915ec,27, +0x229165c,19, +0x22916b4,120, +0x2291898,109, +0x2291a88,4, +0x2291aa0,27, +0x2291b10,27, +0x2291b80,19, +0x2291bd8,120, +0x2291dbc,109, +0x2291fac,4, +0x2291fc4,27, +0x2292034,27, +0x22920a4,19, +0x22920fc,120, +0x22922e0,109, +0x22924d0,4, +0x22924e8,27, +0x2292558,27, +0x22925c8,19, +0x2292620,120, +0x2292804,109, +0x22929f4,4, +0x2292a0c,27, +0x2292a7c,27, +0x2292aec,19, +0x2292b44,120, +0x2292d28,109, +0x2292f18,4, +0x2292f30,27, +0x2292fa0,27, +0x2293010,19, +0x2293068,120, +0x229324c,109, +0x229343c,4, +0x2293454,27, +0x22934c4,27, +0x2293534,19, +0x229358c,120, +0x2293770,109, +0x2293960,4, +0x2293978,27, +0x22939e8,27, +0x2293a58,19, +0x2293ab0,120, +0x2293c94,109, +0x2293e84,4, +0x2293e9c,27, +0x2293f0c,27, +0x2293f7c,19, +0x2293fd4,120, +0x22941b8,109, +0x22943a8,4, +0x22943c0,27, +0x2294430,27, +0x22944a0,19, +0x22944f8,120, +0x22946dc,109, +0x22948cc,4, +0x22948e4,27, +0x2294954,27, +0x22949c4,19, +0x2294a1c,120, +0x2294c00,109, +0x2294df0,4, +0x2294e08,27, +0x2294e78,27, +0x2294ee8,19, +0x2294f40,120, +0x2295124,109, +0x2295314,4, +0x229532c,27, +0x229539c,27, +0x229540c,19, +0x2295464,120, +0x2295648,109, +0x2295838,14, +0x2295940,13, +0x2295a44,13, +0x2295b48,16, +0x2295b90,42, +0x2295c40,2, +0x2295c90,54, +0x2295d70,58, +0x2295e60,58, +0x2295f50,58, +0x2296040,58, +0x2296130,58, +0x2296220,58, +0x2296310,58, +0x2296400,58, +0x22964f0,58, +0x22965e0,58, +0x22966d0,58, +0x22967c0,58, +0x22968b0,58, +0x22969a0,58, +0x2296a90,58, +0x2296b80,58, +0x2296c70,58, +0x2296d60,58, +0x2296e50,58, +0x2296f40,58, +0x2297030,58, +0x2297120,58, +0x2297210,58, +0x2297300,58, +0x22973f0,58, +0x22974e0,58, +0x22975d0,58, +0x22976c0,58, +0x22977b0,58, +0x22978a0,58, +0x2297990,58, +0x2297a80,101, +0x2297c90,49, +0x2297db0,18, +0x2297e00,11, +0x2297e30,4, +0x2297e54,45, +0x2297f58,9, +0x2297f88,4, +0x2297fa0,2, +0x2297fd8,14, +0x2298014,12, +0x2298158,3, +0x2298168,2, +0x2298174,68, +0x2298288,2, +0x2298294,68, +0x22983a8,1, +0x22983b0,2, +0x22983bc,68, +0x22984d0,2, +0x22984dc,68, +0x22985f0,1, +0x22985f8,4, +0x2298610,3, +0x2298624,12, +0x2298688,8, +0x22986dc,1, +0x22986e8,4, +0x2298700,3, +0x2298714,12, +0x2298778,8, +0x22987cc,1, +0x22987d8,4, +0x22987f0,3, +0x2298804,12, +0x2298868,8, +0x22988bc,1, +0x22988c8,4, +0x22988e0,3, +0x22988f4,12, +0x2298958,8, +0x22989ac,1, +0x22989b8,4, +0x22989d0,3, +0x22989e4,12, +0x2298a48,8, +0x2298a9c,1, +0x2298aa8,4, +0x2298ac0,3, +0x2298ad4,12, +0x2298b38,8, +0x2298b8c,1, +0x2298b98,4, +0x2298bb0,3, +0x2298bc4,12, +0x2298c28,8, +0x2298c7c,1, +0x2298c88,4, +0x2298ca0,3, +0x2298cb4,12, +0x2298d18,8, +0x2298d6c,1, +0x2298d78,4, +0x2298d90,3, +0x2298da4,12, +0x2298e08,8, +0x2298e5c,1, +0x2298e68,4, +0x2298e80,3, +0x2298e94,12, +0x2298ef8,8, +0x2298f4c,1, +0x2298f58,4, +0x2298f70,3, +0x2298f84,12, +0x2298fe8,8, +0x229903c,1, +0x2299048,4, +0x2299060,3, +0x2299074,12, +0x22990d8,8, +0x229912c,1, +0x2299138,4, +0x2299150,3, +0x2299164,12, +0x22991c8,8, +0x229921c,1, +0x2299228,4, +0x2299240,3, +0x2299254,12, +0x22992b8,8, +0x229930c,1, +0x2299318,4, +0x2299330,3, +0x2299344,12, +0x22993a8,8, +0x22993fc,1, +0x2299408,4, +0x2299420,3, +0x2299434,12, +0x2299498,8, +0x22994ec,1, +0x22994f8,4, +0x2299510,3, +0x2299524,12, +0x2299588,8, +0x22995dc,1, +0x22995e8,64, +0x2299748,5, +0x2299990,28, +0x2299a04,4, +0x2299a98,1, +0x2299be8,11, +0x2299c18,13, +0x2299c50,6, +0x229a000,15, +0x229a044,81, +0x229a18c,84, +0x229a2e0,84, +0x229a434,84, +0x229a588,84, +0x229a6dc,84, +0x229a830,84, +0x229a984,84, +0x229aad8,84, +0x229ac2c,84, +0x229ad80,84, +0x229aed4,84, +0x229b028,84, +0x229b17c,84, +0x229b2d0,84, +0x229b424,84, +0x229b578,84, +0x229b6cc,5, +0x229b760,4, +0x229b8e0,2414, +0x229dea4,88, +0x229e048,4, +0x229ebe0,1, +0x229ebf0,97, +0x229ed94,7, +0x229ee7c,1, +0x229eeac,9, +0x229eed4,5, +0x229eeec,11, +0x229ef2c,17, +0x229ef74,30, +0x229f034,3, +0x229f044,2, +0x229f054,17, +0x229fbe0,3, +0x229fbf0,1, +0x22a0000,3, +0x22a0018,2, +0x22a0024,14, +0x22a0060,27, +0x22a00d0,3, +0x22a00e0,3, +0x22a00f0,3, +0x22a0100,4, +0x22a0120,6, +0x22a0140,3, +0x22a0150,1, +0x22a015c,4, +0x22a0170,1, +0x22a0180,15, +0x22a01c0,1, +0x22a01c8,5, +0x22a01e0,1, +0x22a01f0,3, +0x22a0200,3, +0x22a0218,2, +0x22a0224,14, +0x22a0260,27, +0x22a02d0,3, +0x22a02e0,3, +0x22a02f0,3, +0x22a0300,4, +0x22a0320,6, +0x22a0340,3, +0x22a0350,1, +0x22a035c,4, +0x22a0370,1, +0x22a0380,15, +0x22a03c0,1, +0x22a03c8,5, +0x22a03e0,1, +0x22a03f0,3, +0x22a0400,3, +0x22a0418,2, +0x22a0424,14, +0x22a0460,27, +0x22a04d0,3, +0x22a04e0,3, +0x22a04f0,3, +0x22a0500,4, +0x22a0520,6, +0x22a0540,3, +0x22a0550,1, +0x22a055c,4, +0x22a0570,1, +0x22a0580,15, +0x22a05c0,1, +0x22a05c8,5, +0x22a05e0,1, +0x22a05f0,3, +0x22a0600,3, +0x22a0618,2, +0x22a0624,14, +0x22a0660,27, +0x22a06d0,3, +0x22a06e0,3, +0x22a06f0,3, +0x22a0700,4, +0x22a0720,6, +0x22a0740,3, +0x22a0750,1, +0x22a075c,4, +0x22a0770,1, +0x22a0780,15, +0x22a07c0,1, +0x22a07c8,5, +0x22a07e0,1, +0x22a07f0,3, +0x22a0800,3, +0x22a0818,2, +0x22a0824,14, +0x22a0860,27, +0x22a08d0,3, +0x22a08e0,3, +0x22a08f0,3, +0x22a0900,4, +0x22a0920,6, +0x22a0940,3, +0x22a0950,1, +0x22a095c,4, +0x22a0970,1, +0x22a0980,15, +0x22a09c0,1, +0x22a09c8,5, +0x22a09e0,1, +0x22a09f0,3, +0x22a1844,1, +0x22a1858,5, +0x22a1904,3, +0x22a1950,3, +0x22a1988,2, +0x22a19a0,7, +0x22a19c0,7, +0x22a19e0,4, +0x22a2000,24, +0x22a20f0,3, +0x22a2100,7, +0x22a2120,7, +0x22a2144,7, +0x22a2400,4, +0x22a2420,5, +0x22a25e0,3, +0x22a25f4,1, +0x22a25fc,4, +0x22a2620,3, +0x22a2680,8, +0x22a2700,19, +0x22a2800,99, +0x22a2a00,18, +0x22a2a80,8, +0x22a2b00,1, +0x22a3070,1, +0x22a3080,2, +0x22a308c,1, +0x22a3098,2, +0x22a3404,1, +0x22a3440,20, +0x22a3494,1, +0x22a349c,7, +0x22a34d0,4, +0x22a34e8,2, +0x22a34fc,8, +0x22a3520,7, +0x22a3540,7, +0x22a3560,7, +0x22a3580,7, +0x22a35a0,7, +0x22a35c0,7, +0x22a35e0,7, +0x22a3600,9, +0x22a363c,2, +0x22a3650,6, +0x22a3684,10, +0x22a3a00,10, +0x22a3a30,1, +0x22a3a40,8, +0x22a3a64,5, +0x22a4a04,3, +0x22a4b00,33, +0x22a4b90,3, +0x22a5000,8, +0x22a5040,8, +0x22a5104,1, +0x22a510c,3, +0x22a5124,1, +0x22a512c,3, +0x22a6000,13, +0x22a6200,14, +0x22a6240,1, +0x22a6248,1, +0x22a6258,1, +0x22a6260,8, +0x22a6284,1, +0x22a62a0,8, +0x22a6348,5, +0x22a67f0,1, +0x22a67f8,1, +0x22a6a10,12, +0x22a7000,19, +0x22a7a00,10, +0x22a7a80,3, +0x22a7b00,6, +0x22c0000,1, +0x22c000c,5, +0x22c0044,1, +0x22c0054,5, +0x22c0200,128, +0x22c0404,1, +0x22c0428,54, +0x22c0600,32, +0x22c0704,1, +0x22c0800,1, +0x22c0900,1, +0x22c0910,2, +0x22c0920,3, +0x22c0980,10, +0x22c0a00,19, +0x22c0b00,1, +0x22e0000,2, +0x22e000c,2, +0x22e0018,2, +0x22e0024,2, +0x22e0030,2, +0x22e003c,2, +0x22e0048,2, +0x22e0054,2, +0x22e0060,1, +0x22e0070,2, +0x22e007c,2, +0x22e0088,2, +0x22e0094,2, +0x22e00a0,2, +0x22e00ac,2, +0x22e00b8,2, +0x22e00c4,2, +0x22e00d0,1, +0x22e00e0,2, +0x22e00ec,2, +0x22e00f8,2, +0x22e0104,2, +0x22e0110,2, +0x22e011c,2, +0x22e0128,2, +0x22e0134,2, +0x22e0140,1, +0x22e0150,2, +0x22e015c,2, +0x22e0168,2, +0x22e0174,2, +0x22e0180,2, +0x22e018c,2, +0x22e0198,2, +0x22e01a4,2, +0x22e01b0,1, +0x22e01c0,57, +0x22e02b0,23, +0x22e0310,83, +0x22e0460,83, +0x22e05b0,83, +0x22e0700,83, +0x22e0850,83, +0x22e09a0,83, +0x22e0af0,83, +0x22e0c40,83, +0x22e0d90,83, +0x22e0ee0,83, +0x22e1030,83, +0x22e1180,83, +0x22e12d0,83, +0x22e1420,83, +0x22e1570,83, +0x22e16c0,83, +0x22e1810,83, +0x22e1960,83, +0x22e1ab0,83, +0x22e1c00,83, +0x22e1d50,83, +0x22e1ea0,83, +0x22e1ff0,83, +0x22e2140,83, +0x22e2290,83, +0x22e23e0,83, +0x22e2530,83, +0x22e2680,83, +0x22e27d0,83, +0x22e2920,83, +0x22e2a70,83, +0x22e2bc0,62, +0x22e2db4,3, +0x22e2df4,3, +0x22e2e34,3, +0x22e2e74,3, +0x22e2eb4,3, +0x22e2ef4,3, +0x22e2f34,3, +0x22e2f74,3, +0x22e2fb4,3, +0x22e2ff4,3, +0x22e3034,3, +0x22e3074,3, +0x22e30b4,3, +0x22e30f4,3, +0x22e3134,3, +0x22e3174,3, +0x22e31b4,3, +0x22f0000,4, +0x22f0014,2, +0x22f0020,8, +0x22f0044,2, +0x22f0050,13, +0x22f0088,20, +0x22f00dc,1, +0x22f0180,6, +0x22f0590,3, +0x22f05c0,2, +0x22f0a04,1, +0x22f0a0c,3, +0x22f0a20,1, +0x22f0ba0,4, +0x22f0c00,4, +0x22f0c20,3, +0x22f0c30,5, +0x22f0c50,52, +0x22f0d50,57, +0x22f0ec0,3, +0x22f0ffc,3, +0x22f1020,3, +0x22f1030,3, +0x22f1060,2, +0x22f1100,2, +0x22f1140,18, +0x22f11c0,30, +0x22f1240,14, +0x22f1280,28, +0x22f1300,2, +0x22f13a0,6, +0x22f1400,19, +0x22f1800,19, +0x22f1c00,19, +0x22f1c80,8, +0x22f1d00,3, +0x22f1d50,3, +0x22f1e00,3, +0x22f1e10,2, +0x22f1e20,6, +0x22f1e40,6, +0x22f1e60,6, +0x22f1e80,6, +0x22f1ea0,6, +0x22f1ec0,2, +0x22f1ecc,2, +0x22f1ee0,2, +0x22f1eec,2, +0x22f1f80,3, +0x22f1f90,60, +0x22f2100,32, +0x22f2200,32, +0x22f2300,32, +0x22f2400,32, +0x22f2500,32, +0x22f2600,32, +0x22f2700,32, +0x22f2800,32, +0x22f2900,32, +0x22f2a00,32, +0x22f2b00,32, +0x22f2c00,32, +0x22f2d00,32, +0x22f2e00,32, +0x22f2f00,32, +0x22f3000,32, +0x22f30c0,3, +0x22f4000,2, +0x22f4040,16, +0x22f4100,36, +0x22f4800,5, +0x22f4824,1, +0x22f482c,1, +0x22f4c04,1, +0x22f4cd8,74, +0x22f5000,7, +0x22f5020,4, +0x22f5204,1, +0x22f5280,35, +0x22f5310,4, +0x22f5404,1, +0x22f5480,34, +0x22f5510,10, +0x22f553c,3, +0x22f5800,7, +0x22f5820,4, +0x22f5a04,1, +0x22f5a80,35, +0x22f5b10,4, +0x22f5c04,1, +0x22f5c80,34, +0x22f5d10,10, +0x22f5d3c,3, +0x22fa000,5, +0x22fa01c,13, +0x22fa060,3, +0x22fa080,8, +0x22fa100,5, +0x22fa11c,13, +0x22fa160,3, +0x22fa180,8, +0x2400004,5, +0x2400020,3, +0x2400030,3, +0x2400040,13, +0x2400078,4, +0x240009c,25, +0x2400104,5, +0x2400120,3, +0x2400130,3, +0x2400140,13, +0x2400178,4, +0x240019c,25, +0x2400204,5, +0x2400220,3, +0x2400230,3, +0x2400240,13, +0x2400278,4, +0x240029c,25, +0x2400304,5, +0x2400320,3, +0x2400330,3, +0x2400340,13, +0x2400378,4, +0x240039c,25, +0x2400600,4, +0x2400c00,24, +0x2400c80,24, +0x2400d00,24, +0x2400d80,24, +0x2400e00,4, +0x2400e20,4, +0x2400e40,4, +0x2400e60,4, +0x2400e80,39, +0x2400f20,7, +0x2400f40,7, +0x2400f60,7, +0x2401000,12, +0x2401200,1, +0x2401218,2, +0x240122c,1, +0x2401280,1, +0x2401298,2, +0x24012ac,1, +0x2401300,1, +0x2401318,2, +0x240132c,1, +0x2401380,1, +0x2401398,2, +0x24013ac,1, +0x2401400,4, +0x2401420,2, +0x240142c,1, +0x2401480,4, +0x24014a0,2, +0x24014ac,1, +0x2401500,4, +0x2401520,2, +0x240152c,1, +0x2401580,4, +0x24015a0,2, +0x24015ac,1, +0x2401600,4, +0x2401640,4, +0x2401680,4, +0x24016c0,4, +0x2401700,7, +0x2401720,7, +0x2401740,7, +0x2401760,7, +0x2401780,4, +0x240179c,11, +0x24017d0,2, +0x24017e0,2, +0x24017f0,2, +0x2401900,44, +0x2402000,7, +0x2402020,4, +0x2402040,4, +0x2402060,7, +0x2402080,7, +0x24020a0,4, +0x24020c0,4, +0x24020e0,7, +0x2402100,7, +0x2402120,4, +0x2402140,4, +0x2402160,7, +0x2402180,7, +0x24021a0,4, +0x24021c0,4, +0x24021e0,7, +0x2402200,32, +0x2402b00,1, +0x2402b20,1, +0x2402b28,4, +0x2402b40,1, +0x2402b60,1, +0x2402b68,4, +0x2402b80,1, +0x2402ba0,1, +0x2402ba8,4, +0x2402bc0,1, +0x2402be0,1, +0x2402be8,4, +0x2402c00,7, +0x2402c20,1, +0x2402c54,18, +0x2402ca0,1, +0x2402cd4,18, +0x2402d20,1, +0x2402d54,18, +0x2402da0,1, +0x2402dd4,12, +0x2402e08,6, +0x2403100,7, +0x2403120,7, +0x2403140,7, +0x2403160,7, +0x2403180,3, +0x2404004,5, +0x2404020,3, +0x2404030,3, +0x2404040,13, +0x2404078,4, +0x240409c,25, +0x2404104,5, +0x2404120,3, +0x2404130,3, +0x2404140,13, +0x2404178,4, +0x240419c,25, +0x2404204,5, +0x2404220,3, +0x2404230,3, +0x2404240,13, +0x2404278,4, +0x240429c,25, +0x2404304,5, +0x2404320,3, +0x2404330,3, +0x2404340,13, +0x2404378,4, +0x240439c,25, +0x2404600,4, +0x2404c00,24, +0x2404c80,24, +0x2404d00,24, +0x2404d80,24, +0x2404e00,4, +0x2404e20,4, +0x2404e40,4, +0x2404e60,4, +0x2404e80,39, +0x2404f20,7, +0x2404f40,7, +0x2404f60,7, +0x2405000,12, +0x2405200,1, +0x2405218,2, +0x240522c,1, +0x2405280,1, +0x2405298,2, +0x24052ac,1, +0x2405300,1, +0x2405318,2, +0x240532c,1, +0x2405380,1, +0x2405398,2, +0x24053ac,1, +0x2405400,4, +0x2405420,2, +0x240542c,1, +0x2405480,4, +0x24054a0,2, +0x24054ac,1, +0x2405500,4, +0x2405520,2, +0x240552c,1, +0x2405580,4, +0x24055a0,2, +0x24055ac,1, +0x2405600,4, +0x2405640,4, +0x2405680,4, +0x24056c0,4, +0x2405700,7, +0x2405720,7, +0x2405740,7, +0x2405760,7, +0x2405780,4, +0x240579c,11, +0x24057d0,2, +0x24057e0,2, +0x24057f0,2, +0x2405900,44, +0x2406000,7, +0x2406020,4, +0x2406040,4, +0x2406060,7, +0x2406080,7, +0x24060a0,4, +0x24060c0,4, +0x24060e0,7, +0x2406100,7, +0x2406120,4, +0x2406140,4, +0x2406160,7, +0x2406180,7, +0x24061a0,4, +0x24061c0,4, +0x24061e0,7, +0x2406200,32, +0x2406b00,1, +0x2406b20,1, +0x2406b28,4, +0x2406b40,1, +0x2406b60,1, +0x2406b68,4, +0x2406b80,1, +0x2406ba0,1, +0x2406ba8,4, +0x2406bc0,1, +0x2406be0,1, +0x2406be8,4, +0x2406c00,7, +0x2406c20,1, +0x2406c54,18, +0x2406ca0,1, +0x2406cd4,18, +0x2406d20,1, +0x2406d54,18, +0x2406da0,1, +0x2406dd4,12, +0x2406e08,6, +0x2407100,7, +0x2407120,7, +0x2407140,7, +0x2407160,7, +0x2407180,3, +0x2408000,10, +0x2408080,3, +0x24080c0,1, +0x2408100,21, +0x2408180,13, +0x24081c4,7, +0x24081e4,7, +0x2408204,7, +0x2408224,8, +0x2409000,7, +0x2409030,2, +0x2409040,7, +0x2409070,2, +0x2409100,2, +0x2409120,2, +0x2409140,2, +0x2409160,2, +0x2409180,9, +0x2409200,7, +0x2409230,2, +0x2409240,7, +0x2409270,2, +0x2409300,2, +0x2409320,2, +0x2409340,2, +0x2409360,2, +0x2409380,9, +0x2409400,11, +0x2409500,11, +0x240a000,3, +0x240a010,2, +0x240a01c,5, +0x240a040,8, +0x240a080,3, +0x240a090,2, +0x240a09c,5, +0x240a0c0,8, +0x240a100,3, +0x240a110,2, +0x240a11c,5, +0x240a140,8, +0x240a180,3, +0x240a190,2, +0x240a19c,5, +0x240a1c0,8, +0x240a200,7, +0x240a220,12, +0x240a280,7, +0x240a2a0,12, +0x240a300,3, +0x240a310,1, +0x240a400,3, +0x240a410,2, +0x240a41c,5, +0x240a440,8, +0x240a480,3, +0x240a490,2, +0x240a49c,5, +0x240a4c0,8, +0x240a500,3, +0x240a510,2, +0x240a51c,5, +0x240a540,8, +0x240a580,3, +0x240a590,2, +0x240a59c,5, +0x240a5c0,8, +0x240a600,7, +0x240a620,12, +0x240a680,7, +0x240a6a0,12, +0x240a700,3, +0x240a710,1, +0x240a804,1, +0x240a824,21, +0x240a880,16, +0x240a900,5, +0x240a920,11, +0x240a950,9, +0x240a980,22, +0x240aa00,22, +0x240aa80,22, +0x240ab00,22, +0x240ab80,22, +0x240ac00,22, +0x240ac80,22, +0x240ad00,22, +0x240ad80,3, +0x240c000,16, +0x240c080,11, +0x240c100,11, +0x240c204,1, +0x240c224,21, +0x240c280,16, +0x240c300,11, +0x240c340,11, +0x240c800,21, +0x240c860,5, +0x240c880,6, +0x240c8a0,5, +0x240c8c0,6, +0x240c900,21, +0x240c960,5, +0x240c980,6, +0x240c9a0,5, +0x240c9c0,6, +0x240ca00,21, +0x240ca60,5, +0x240ca80,6, +0x240caa0,5, +0x240cac0,6, +0x240cb00,21, +0x240cb60,5, +0x240cb80,6, +0x240cba0,5, +0x240cbc0,6, +0x240cc00,9, +0x240cc48,7, +0x240cc68,2, +0x240cc74,9, +0x240cc9c,2, +0x240cd00,14, +0x240cd40,14, +0x240cd80,28, +0x240ce00,19, +0x240ce50,3, +0x240ce60,25, +0x240cec8,1, +0x240ced0,2, +0x240cee0,7, +0x240cf00,1, +0x240cf08,2, +0x240cffc,20, +0x240d050,25, +0x240d100,19, +0x240d150,25, +0x240d200,19, +0x240d250,25, +0x240d300,19, +0x240d350,25, +0x240d400,19, +0x240d450,25, +0x240d500,19, +0x240d550,25, +0x240d600,19, +0x240d650,25, +0x240d700,19, +0x240d750,25, +0x240d800,19, +0x240d850,25, +0x240d904,1, +0x240d914,10, +0x240d948,11, +0x240d980,2, +0x240d9a0,6, +0x240d9c0,2, +0x240d9cc,2, +0x240e000,35, +0x240ea00,10, +0x240ea80,3, +0x240eb00,6, +0x240f000,1, +0x240f008,5, +0x240f038,1, +0x240f044,1, +0x240f050,2, +0x240f100,13, +0x240f140,11, +0x240f170,12, +0x240f1a4,1, +0x240f200,104, +0x240f400,104, +0x240f600,104, +0x240f800,104, +0x2410000,13, +0x2410040,2, +0x2410054,4, +0x2410080,27, +0x2410100,12, +0x2410140,14, +0x2410180,28, +0x2410200,6, +0x2410240,6, +0x241025c,3, +0x2410280,5, +0x24102a0,8, +0x2410400,14, +0x2410440,14, +0x2410480,14, +0x24104c0,14, +0x2410540,3, +0x2410600,7, +0x2410620,14, +0x2410680,5, +0x24106a0,7, +0x2410800,13, +0x2410840,2, +0x2410854,4, +0x2410880,27, +0x2410900,12, +0x2410940,14, +0x2410980,28, +0x2410a00,6, +0x2410a40,6, +0x2410a5c,3, +0x2410a80,5, +0x2410aa0,8, +0x2410c00,14, +0x2410c40,14, +0x2410c80,14, +0x2410cc0,14, +0x2410d40,3, +0x2410e00,7, +0x2410e20,14, +0x2410e80,5, +0x2410ea0,7, +0x2411000,13, +0x2411040,2, +0x2411054,4, +0x2411080,27, +0x2411100,12, +0x2411140,14, +0x2411180,28, +0x2411200,6, +0x2411240,6, +0x241125c,3, +0x2411280,5, +0x24112a0,8, +0x2411400,14, +0x2411440,14, +0x2411480,14, +0x24114c0,14, +0x2411540,3, +0x2411600,7, +0x2411620,14, +0x2411680,5, +0x24116a0,7, +0x2411800,13, +0x2411840,2, +0x2411854,4, +0x2411880,27, +0x2411900,12, +0x2411940,14, +0x2411980,28, +0x2411a00,6, +0x2411a40,6, +0x2411a5c,3, +0x2411a80,5, +0x2411aa0,8, +0x2411c00,14, +0x2411c40,14, +0x2411c80,14, +0x2411cc0,14, +0x2411d40,3, +0x2411e00,7, +0x2411e20,14, +0x2411e80,5, +0x2411ea0,7, +0x2412000,8, +0x2412040,8, +0x2412080,1, +0x2412098,6, +0x2412100,10, +0x2412140,3, +0x2412150,2, +0x2412180,2, +0x2412200,6, +0x2412220,18, +0x2412280,4, +0x2412300,8, +0x2412400,2, +0x2412480,2, +0x2412800,28, +0x24129f0,4, +0x2413000,40, +0x2413100,64, +0x2413800,56, +0x2413be0,8, +0x2414000,13, +0x2414040,2, +0x2414054,4, +0x2414080,27, +0x2414100,12, +0x2414140,14, +0x2414180,28, +0x2414200,6, +0x2414240,6, +0x241425c,3, +0x2414280,5, +0x24142a0,8, +0x2414400,14, +0x2414440,14, +0x2414480,14, +0x24144c0,14, +0x2414540,3, +0x2414600,7, +0x2414620,14, +0x2414680,5, +0x24146a0,7, +0x2414800,13, +0x2414840,2, +0x2414854,4, +0x2414880,27, +0x2414900,12, +0x2414940,14, +0x2414980,28, +0x2414a00,6, +0x2414a40,6, +0x2414a5c,3, +0x2414a80,5, +0x2414aa0,8, +0x2414c00,14, +0x2414c40,14, +0x2414c80,14, +0x2414cc0,14, +0x2414d40,3, +0x2414e00,7, +0x2414e20,14, +0x2414e80,5, +0x2414ea0,7, +0x2415000,13, +0x2415040,2, +0x2415054,4, +0x2415080,27, +0x2415100,12, +0x2415140,14, +0x2415180,28, +0x2415200,6, +0x2415240,6, +0x241525c,3, +0x2415280,5, +0x24152a0,8, +0x2415400,14, +0x2415440,14, +0x2415480,14, +0x24154c0,14, +0x2415540,3, +0x2415600,7, +0x2415620,14, +0x2415680,5, +0x24156a0,7, +0x2415800,13, +0x2415840,2, +0x2415854,4, +0x2415880,27, +0x2415900,12, +0x2415940,14, +0x2415980,28, +0x2415a00,6, +0x2415a40,6, +0x2415a5c,3, +0x2415a80,5, +0x2415aa0,8, +0x2415c00,14, +0x2415c40,14, +0x2415c80,14, +0x2415cc0,14, +0x2415d40,3, +0x2415e00,7, +0x2415e20,14, +0x2415e80,5, +0x2415ea0,7, +0x2416000,8, +0x2416040,8, +0x2416080,1, +0x2416098,6, +0x2416100,10, +0x2416140,3, +0x2416150,2, +0x2416180,2, +0x2416200,6, +0x2416220,18, +0x2416280,4, +0x2416300,8, +0x2416400,2, +0x2416480,2, +0x2416800,28, +0x24169f0,4, +0x2417000,40, +0x2417100,64, +0x2417800,56, +0x2417be0,8, +0x2418000,2, +0x241800c,2, +0x2418040,7, +0x2418100,3, +0x2418110,3, +0x2418120,5, +0x2418200,6, +0x2418240,5, +0x2418400,2, +0x241840c,2, +0x2418440,7, +0x2418500,3, +0x2418510,3, +0x2418520,5, +0x2418600,6, +0x2418640,5, +0x2418800,2, +0x241880c,2, +0x2418840,7, +0x2418900,3, +0x2418910,3, +0x2418920,5, +0x2418a00,6, +0x2418a40,5, +0x2418c00,2, +0x2418c0c,2, +0x2418c40,7, +0x2418d00,3, +0x2418d10,3, +0x2418d20,5, +0x2418e00,6, +0x2418e40,5, +0x2419000,2, +0x241900c,2, +0x2419040,7, +0x2419100,3, +0x2419110,3, +0x2419120,5, +0x2419200,6, +0x2419240,5, +0x2419400,2, +0x241940c,2, +0x2419440,7, +0x2419500,3, +0x2419510,3, +0x2419520,5, +0x2419600,6, +0x2419640,5, +0x2419800,2, +0x241980c,2, +0x2419840,7, +0x2419900,3, +0x2419910,3, +0x2419920,5, +0x2419a00,6, +0x2419a40,5, +0x2419c00,2, +0x2419c0c,2, +0x2419c40,7, +0x2419d00,3, +0x2419d10,3, +0x2419d20,5, +0x2419e00,6, +0x2419e40,5, +0x241a000,5, +0x241a040,9, +0x241a100,3, +0x241a200,1, +0x241a210,1, +0x241a220,1, +0x241a230,1, +0x241a240,1, +0x241a300,3, +0x241a314,1, +0x241a320,4, +0x241a400,5, +0x241a440,5, +0x241b000,80, +0x241b200,1, +0x2420004,5, +0x2420020,3, +0x2420030,3, +0x2420040,13, +0x2420078,4, +0x242009c,25, +0x2420104,5, +0x2420120,3, +0x2420130,3, +0x2420140,13, +0x2420178,4, +0x242019c,25, +0x2420204,5, +0x2420220,3, +0x2420230,3, +0x2420240,13, +0x2420278,4, +0x242029c,25, +0x2420304,5, +0x2420320,3, +0x2420330,3, +0x2420340,13, +0x2420378,4, +0x242039c,25, +0x2420600,4, +0x2420c00,24, +0x2420c80,24, +0x2420d00,24, +0x2420d80,24, +0x2420e00,4, +0x2420e20,4, +0x2420e40,4, +0x2420e60,4, +0x2420e80,39, +0x2420f20,7, +0x2420f40,7, +0x2420f60,7, +0x2421000,12, +0x2421200,1, +0x2421218,2, +0x242122c,1, +0x2421280,1, +0x2421298,2, +0x24212ac,1, +0x2421300,1, +0x2421318,2, +0x242132c,1, +0x2421380,1, +0x2421398,2, +0x24213ac,1, +0x2421400,4, +0x2421420,2, +0x242142c,1, +0x2421480,4, +0x24214a0,2, +0x24214ac,1, +0x2421500,4, +0x2421520,2, +0x242152c,1, +0x2421580,4, +0x24215a0,2, +0x24215ac,1, +0x2421600,4, +0x2421640,4, +0x2421680,4, +0x24216c0,4, +0x2421700,7, +0x2421720,7, +0x2421740,7, +0x2421760,7, +0x2421780,4, +0x242179c,11, +0x24217d0,2, +0x24217e0,2, +0x24217f0,2, +0x2421900,44, +0x2422000,7, +0x2422020,4, +0x2422040,4, +0x2422060,7, +0x2422080,7, +0x24220a0,4, +0x24220c0,4, +0x24220e0,7, +0x2422100,7, +0x2422120,4, +0x2422140,4, +0x2422160,7, +0x2422180,7, +0x24221a0,4, +0x24221c0,4, +0x24221e0,7, +0x2422200,32, +0x2422b00,1, +0x2422b20,1, +0x2422b28,4, +0x2422b40,1, +0x2422b60,1, +0x2422b68,4, +0x2422b80,1, +0x2422ba0,1, +0x2422ba8,4, +0x2422bc0,1, +0x2422be0,1, +0x2422be8,4, +0x2422c00,7, +0x2422c20,1, +0x2422c54,18, +0x2422ca0,1, +0x2422cd4,18, +0x2422d20,1, +0x2422d54,18, +0x2422da0,1, +0x2422dd4,12, +0x2422e08,6, +0x2423100,7, +0x2423120,7, +0x2423140,7, +0x2423160,7, +0x2423180,3, +0x2424004,5, +0x2424020,3, +0x2424030,3, +0x2424040,13, +0x2424078,4, +0x242409c,25, +0x2424104,5, +0x2424120,3, +0x2424130,3, +0x2424140,13, +0x2424178,4, +0x242419c,25, +0x2424204,5, +0x2424220,3, +0x2424230,3, +0x2424240,13, +0x2424278,4, +0x242429c,25, +0x2424304,5, +0x2424320,3, +0x2424330,3, +0x2424340,13, +0x2424378,4, +0x242439c,25, +0x2424600,4, +0x2424c00,24, +0x2424c80,24, +0x2424d00,24, +0x2424d80,24, +0x2424e00,4, +0x2424e20,4, +0x2424e40,4, +0x2424e60,4, +0x2424e80,39, +0x2424f20,7, +0x2424f40,7, +0x2424f60,7, +0x2425000,12, +0x2425200,1, +0x2425218,2, +0x242522c,1, +0x2425280,1, +0x2425298,2, +0x24252ac,1, +0x2425300,1, +0x2425318,2, +0x242532c,1, +0x2425380,1, +0x2425398,2, +0x24253ac,1, +0x2425400,4, +0x2425420,2, +0x242542c,1, +0x2425480,4, +0x24254a0,2, +0x24254ac,1, +0x2425500,4, +0x2425520,2, +0x242552c,1, +0x2425580,4, +0x24255a0,2, +0x24255ac,1, +0x2425600,4, +0x2425640,4, +0x2425680,4, +0x24256c0,4, +0x2425700,7, +0x2425720,7, +0x2425740,7, +0x2425760,7, +0x2425780,4, +0x242579c,11, +0x24257d0,2, +0x24257e0,2, +0x24257f0,2, +0x2425900,44, +0x2426000,7, +0x2426020,4, +0x2426040,4, +0x2426060,7, +0x2426080,7, +0x24260a0,4, +0x24260c0,4, +0x24260e0,7, +0x2426100,7, +0x2426120,4, +0x2426140,4, +0x2426160,7, +0x2426180,7, +0x24261a0,4, +0x24261c0,4, +0x24261e0,7, +0x2426200,32, +0x2426b00,1, +0x2426b20,1, +0x2426b28,4, +0x2426b40,1, +0x2426b60,1, +0x2426b68,4, +0x2426b80,1, +0x2426ba0,1, +0x2426ba8,4, +0x2426bc0,1, +0x2426be0,1, +0x2426be8,4, +0x2426c00,7, +0x2426c20,1, +0x2426c54,18, +0x2426ca0,1, +0x2426cd4,18, +0x2426d20,1, +0x2426d54,18, +0x2426da0,1, +0x2426dd4,12, +0x2426e08,6, +0x2427100,7, +0x2427120,7, +0x2427140,7, +0x2427160,7, +0x2427180,3, +0x2428000,10, +0x2428080,3, +0x24280c0,1, +0x2428100,21, +0x2428180,13, +0x24281c4,7, +0x24281e4,7, +0x2428204,7, +0x2428224,8, +0x2429000,7, +0x2429030,2, +0x2429040,7, +0x2429070,2, +0x2429100,2, +0x2429120,2, +0x2429140,2, +0x2429160,2, +0x2429180,9, +0x2429200,7, +0x2429230,2, +0x2429240,7, +0x2429270,2, +0x2429300,2, +0x2429320,2, +0x2429340,2, +0x2429360,2, +0x2429380,9, +0x2429400,11, +0x2429500,11, +0x242a000,3, +0x242a010,2, +0x242a01c,5, +0x242a040,8, +0x242a080,3, +0x242a090,2, +0x242a09c,5, +0x242a0c0,8, +0x242a100,3, +0x242a110,2, +0x242a11c,5, +0x242a140,8, +0x242a180,3, +0x242a190,2, +0x242a19c,5, +0x242a1c0,8, +0x242a200,7, +0x242a220,12, +0x242a280,7, +0x242a2a0,12, +0x242a300,3, +0x242a310,1, +0x242a400,3, +0x242a410,2, +0x242a41c,5, +0x242a440,8, +0x242a480,3, +0x242a490,2, +0x242a49c,5, +0x242a4c0,8, +0x242a500,3, +0x242a510,2, +0x242a51c,5, +0x242a540,8, +0x242a580,3, +0x242a590,2, +0x242a59c,5, +0x242a5c0,8, +0x242a600,7, +0x242a620,12, +0x242a680,7, +0x242a6a0,12, +0x242a700,3, +0x242a710,1, +0x242a804,1, +0x242a824,21, +0x242a880,16, +0x242a900,5, +0x242a920,11, +0x242a950,9, +0x242a980,22, +0x242aa00,22, +0x242aa80,22, +0x242ab00,22, +0x242ab80,22, +0x242ac00,22, +0x242ac80,22, +0x242ad00,22, +0x242ad80,3, +0x242c000,16, +0x242c080,11, +0x242c100,11, +0x242c204,1, +0x242c224,21, +0x242c280,16, +0x242c300,11, +0x242c340,11, +0x242c800,21, +0x242c860,5, +0x242c880,6, +0x242c8a0,5, +0x242c8c0,6, +0x242c900,21, +0x242c960,5, +0x242c980,6, +0x242c9a0,5, +0x242c9c0,6, +0x242ca00,21, +0x242ca60,5, +0x242ca80,6, +0x242caa0,5, +0x242cac0,6, +0x242cb00,21, +0x242cb60,5, +0x242cb80,6, +0x242cba0,5, +0x242cbc0,6, +0x242cc00,9, +0x242cc48,7, +0x242cc68,2, +0x242cc74,9, +0x242cc9c,2, +0x242cd00,14, +0x242cd40,14, +0x242cd80,28, +0x242ce00,19, +0x242ce50,3, +0x242ce60,25, +0x242cec8,1, +0x242ced0,2, +0x242cee0,7, +0x242cf00,1, +0x242cf08,2, +0x242cffc,20, +0x242d050,25, +0x242d100,19, +0x242d150,25, +0x242d200,19, +0x242d250,25, +0x242d300,19, +0x242d350,25, +0x242d400,19, +0x242d450,25, +0x242d500,19, +0x242d550,25, +0x242d600,19, +0x242d650,25, +0x242d700,19, +0x242d750,25, +0x242d800,19, +0x242d850,25, +0x242d904,1, +0x242d914,10, +0x242d948,11, +0x242d980,2, +0x242d9a0,6, +0x242d9c0,2, +0x242d9cc,2, +0x242e000,35, +0x242ea00,10, +0x242ea80,3, +0x242eb00,6, +0x242f000,1, +0x242f008,5, +0x242f038,1, +0x242f044,1, +0x242f050,2, +0x242f100,13, +0x242f140,11, +0x242f170,12, +0x242f1a4,1, +0x242f200,104, +0x242f400,104, +0x242f600,104, +0x242f800,104, +0x2430000,13, +0x2430040,2, +0x2430054,4, +0x2430080,27, +0x2430100,12, +0x2430140,14, +0x2430180,28, +0x2430200,6, +0x2430240,6, +0x243025c,3, +0x2430280,5, +0x24302a0,8, +0x2430400,14, +0x2430440,14, +0x2430480,14, +0x24304c0,14, +0x2430540,3, +0x2430600,7, +0x2430620,14, +0x2430680,5, +0x24306a0,7, +0x2430800,13, +0x2430840,2, +0x2430854,4, +0x2430880,27, +0x2430900,12, +0x2430940,14, +0x2430980,28, +0x2430a00,6, +0x2430a40,6, +0x2430a5c,3, +0x2430a80,5, +0x2430aa0,8, +0x2430c00,14, +0x2430c40,14, +0x2430c80,14, +0x2430cc0,14, +0x2430d40,3, +0x2430e00,7, +0x2430e20,14, +0x2430e80,5, +0x2430ea0,7, +0x2431000,13, +0x2431040,2, +0x2431054,4, +0x2431080,27, +0x2431100,12, +0x2431140,14, +0x2431180,28, +0x2431200,6, +0x2431240,6, +0x243125c,3, +0x2431280,5, +0x24312a0,8, +0x2431400,14, +0x2431440,14, +0x2431480,14, +0x24314c0,14, +0x2431540,3, +0x2431600,7, +0x2431620,14, +0x2431680,5, +0x24316a0,7, +0x2431800,13, +0x2431840,2, +0x2431854,4, +0x2431880,27, +0x2431900,12, +0x2431940,14, +0x2431980,28, +0x2431a00,6, +0x2431a40,6, +0x2431a5c,3, +0x2431a80,5, +0x2431aa0,8, +0x2431c00,14, +0x2431c40,14, +0x2431c80,14, +0x2431cc0,14, +0x2431d40,3, +0x2431e00,7, +0x2431e20,14, +0x2431e80,5, +0x2431ea0,7, +0x2432000,8, +0x2432040,8, +0x2432080,1, +0x2432098,6, +0x2432100,10, +0x2432140,3, +0x2432150,2, +0x2432180,2, +0x2432200,6, +0x2432220,18, +0x2432280,4, +0x2432300,8, +0x2432400,2, +0x2432480,2, +0x2432800,28, +0x24329f0,4, +0x2433000,40, +0x2433100,64, +0x2433800,56, +0x2433be0,8, +0x2434000,13, +0x2434040,2, +0x2434054,4, +0x2434080,27, +0x2434100,12, +0x2434140,14, +0x2434180,28, +0x2434200,6, +0x2434240,6, +0x243425c,3, +0x2434280,5, +0x24342a0,8, +0x2434400,14, +0x2434440,14, +0x2434480,14, +0x24344c0,14, +0x2434540,3, +0x2434600,7, +0x2434620,14, +0x2434680,5, +0x24346a0,7, +0x2434800,13, +0x2434840,2, +0x2434854,4, +0x2434880,27, +0x2434900,12, +0x2434940,14, +0x2434980,28, +0x2434a00,6, +0x2434a40,6, +0x2434a5c,3, +0x2434a80,5, +0x2434aa0,8, +0x2434c00,14, +0x2434c40,14, +0x2434c80,14, +0x2434cc0,14, +0x2434d40,3, +0x2434e00,7, +0x2434e20,14, +0x2434e80,5, +0x2434ea0,7, +0x2435000,13, +0x2435040,2, +0x2435054,4, +0x2435080,27, +0x2435100,12, +0x2435140,14, +0x2435180,28, +0x2435200,6, +0x2435240,6, +0x243525c,3, +0x2435280,5, +0x24352a0,8, +0x2435400,14, +0x2435440,14, +0x2435480,14, +0x24354c0,14, +0x2435540,3, +0x2435600,7, +0x2435620,14, +0x2435680,5, +0x24356a0,7, +0x2435800,13, +0x2435840,2, +0x2435854,4, +0x2435880,27, +0x2435900,12, +0x2435940,14, +0x2435980,28, +0x2435a00,6, +0x2435a40,6, +0x2435a5c,3, +0x2435a80,5, +0x2435aa0,8, +0x2435c00,14, +0x2435c40,14, +0x2435c80,14, +0x2435cc0,14, +0x2435d40,3, +0x2435e00,7, +0x2435e20,14, +0x2435e80,5, +0x2435ea0,7, +0x2436000,8, +0x2436040,8, +0x2436080,1, +0x2436098,6, +0x2436100,10, +0x2436140,3, +0x2436150,2, +0x2436180,2, +0x2436200,6, +0x2436220,18, +0x2436280,4, +0x2436300,8, +0x2436400,2, +0x2436480,2, +0x2436800,28, +0x24369f0,4, +0x2437000,40, +0x2437100,64, +0x2437800,56, +0x2437be0,8, +0x2438000,2, +0x243800c,2, +0x2438040,7, +0x2438100,3, +0x2438110,3, +0x2438120,5, +0x2438200,6, +0x2438240,5, +0x2438400,2, +0x243840c,2, +0x2438440,7, +0x2438500,3, +0x2438510,3, +0x2438520,5, +0x2438600,6, +0x2438640,5, +0x2438800,2, +0x243880c,2, +0x2438840,7, +0x2438900,3, +0x2438910,3, +0x2438920,5, +0x2438a00,6, +0x2438a40,5, +0x2438c00,2, +0x2438c0c,2, +0x2438c40,7, +0x2438d00,3, +0x2438d10,3, +0x2438d20,5, +0x2438e00,6, +0x2438e40,5, +0x2439000,2, +0x243900c,2, +0x2439040,7, +0x2439100,3, +0x2439110,3, +0x2439120,5, +0x2439200,6, +0x2439240,5, +0x2439400,2, +0x243940c,2, +0x2439440,7, +0x2439500,3, +0x2439510,3, +0x2439520,5, +0x2439600,6, +0x2439640,5, +0x2439800,2, +0x243980c,2, +0x2439840,7, +0x2439900,3, +0x2439910,3, +0x2439920,5, +0x2439a00,6, +0x2439a40,5, +0x2439c00,2, +0x2439c0c,2, +0x2439c40,7, +0x2439d00,3, +0x2439d10,3, +0x2439d20,5, +0x2439e00,6, +0x2439e40,5, +0x243a000,5, +0x243a040,9, +0x243a100,3, +0x243a200,1, +0x243a210,1, +0x243a220,1, +0x243a230,1, +0x243a240,1, +0x243a300,3, +0x243a314,1, +0x243a320,4, +0x243a400,5, +0x243a440,5, +0x243b000,80, +0x243b200,1, +0x2440004,5, +0x2440020,3, +0x2440030,3, +0x2440040,13, +0x2440078,4, +0x244009c,25, +0x2440104,5, +0x2440120,3, +0x2440130,3, +0x2440140,13, +0x2440178,4, +0x244019c,25, +0x2440204,5, +0x2440220,3, +0x2440230,3, +0x2440240,13, +0x2440278,4, +0x244029c,25, +0x2440304,5, +0x2440320,3, +0x2440330,3, +0x2440340,13, +0x2440378,4, +0x244039c,25, +0x2440600,4, +0x2440c00,24, +0x2440c80,24, +0x2440d00,24, +0x2440d80,24, +0x2440e00,4, +0x2440e20,4, +0x2440e40,4, +0x2440e60,4, +0x2440e80,39, +0x2440f20,7, +0x2440f40,7, +0x2440f60,7, +0x2441000,12, +0x2441200,1, +0x2441218,2, +0x244122c,1, +0x2441280,1, +0x2441298,2, +0x24412ac,1, +0x2441300,1, +0x2441318,2, +0x244132c,1, +0x2441380,1, +0x2441398,2, +0x24413ac,1, +0x2441400,4, +0x2441420,2, +0x244142c,1, +0x2441480,4, +0x24414a0,2, +0x24414ac,1, +0x2441500,4, +0x2441520,2, +0x244152c,1, +0x2441580,4, +0x24415a0,2, +0x24415ac,1, +0x2441600,4, +0x2441640,4, +0x2441680,4, +0x24416c0,4, +0x2441700,7, +0x2441720,7, +0x2441740,7, +0x2441760,7, +0x2441780,4, +0x244179c,11, +0x24417d0,2, +0x24417e0,2, +0x24417f0,2, +0x2441900,44, +0x2442000,7, +0x2442020,4, +0x2442040,4, +0x2442060,7, +0x2442080,7, +0x24420a0,4, +0x24420c0,4, +0x24420e0,7, +0x2442100,7, +0x2442120,4, +0x2442140,4, +0x2442160,7, +0x2442180,7, +0x24421a0,4, +0x24421c0,4, +0x24421e0,7, +0x2442200,32, +0x2442b00,1, +0x2442b20,1, +0x2442b28,4, +0x2442b40,1, +0x2442b60,1, +0x2442b68,4, +0x2442b80,1, +0x2442ba0,1, +0x2442ba8,4, +0x2442bc0,1, +0x2442be0,1, +0x2442be8,4, +0x2442c00,7, +0x2442c20,1, +0x2442c54,18, +0x2442ca0,1, +0x2442cd4,18, +0x2442d20,1, +0x2442d54,18, +0x2442da0,1, +0x2442dd4,12, +0x2442e08,6, +0x2443100,7, +0x2443120,7, +0x2443140,7, +0x2443160,7, +0x2443180,3, +0x2444004,5, +0x2444020,3, +0x2444030,3, +0x2444040,13, +0x2444078,4, +0x244409c,25, +0x2444104,5, +0x2444120,3, +0x2444130,3, +0x2444140,13, +0x2444178,4, +0x244419c,25, +0x2444204,5, +0x2444220,3, +0x2444230,3, +0x2444240,13, +0x2444278,4, +0x244429c,25, +0x2444304,5, +0x2444320,3, +0x2444330,3, +0x2444340,13, +0x2444378,4, +0x244439c,25, +0x2444600,4, +0x2444c00,24, +0x2444c80,24, +0x2444d00,24, +0x2444d80,24, +0x2444e00,4, +0x2444e20,4, +0x2444e40,4, +0x2444e60,4, +0x2444e80,39, +0x2444f20,7, +0x2444f40,7, +0x2444f60,7, +0x2445000,12, +0x2445200,1, +0x2445218,2, +0x244522c,1, +0x2445280,1, +0x2445298,2, +0x24452ac,1, +0x2445300,1, +0x2445318,2, +0x244532c,1, +0x2445380,1, +0x2445398,2, +0x24453ac,1, +0x2445400,4, +0x2445420,2, +0x244542c,1, +0x2445480,4, +0x24454a0,2, +0x24454ac,1, +0x2445500,4, +0x2445520,2, +0x244552c,1, +0x2445580,4, +0x24455a0,2, +0x24455ac,1, +0x2445600,4, +0x2445640,4, +0x2445680,4, +0x24456c0,4, +0x2445700,7, +0x2445720,7, +0x2445740,7, +0x2445760,7, +0x2445780,4, +0x244579c,11, +0x24457d0,2, +0x24457e0,2, +0x24457f0,2, +0x2445900,44, +0x2446000,7, +0x2446020,4, +0x2446040,4, +0x2446060,7, +0x2446080,7, +0x24460a0,4, +0x24460c0,4, +0x24460e0,7, +0x2446100,7, +0x2446120,4, +0x2446140,4, +0x2446160,7, +0x2446180,7, +0x24461a0,4, +0x24461c0,4, +0x24461e0,7, +0x2446200,32, +0x2446b00,1, +0x2446b20,1, +0x2446b28,4, +0x2446b40,1, +0x2446b60,1, +0x2446b68,4, +0x2446b80,1, +0x2446ba0,1, +0x2446ba8,4, +0x2446bc0,1, +0x2446be0,1, +0x2446be8,4, +0x2446c00,7, +0x2446c20,1, +0x2446c54,18, +0x2446ca0,1, +0x2446cd4,18, +0x2446d20,1, +0x2446d54,18, +0x2446da0,1, +0x2446dd4,12, +0x2446e08,6, +0x2447100,7, +0x2447120,7, +0x2447140,7, +0x2447160,7, +0x2447180,3, +0x2448000,10, +0x2448080,3, +0x24480c0,1, +0x2448100,21, +0x2448180,13, +0x24481c4,7, +0x24481e4,7, +0x2448204,7, +0x2448224,8, +0x2449000,7, +0x2449030,2, +0x2449040,7, +0x2449070,2, +0x2449100,2, +0x2449120,2, +0x2449140,2, +0x2449160,2, +0x2449180,9, +0x2449200,7, +0x2449230,2, +0x2449240,7, +0x2449270,2, +0x2449300,2, +0x2449320,2, +0x2449340,2, +0x2449360,2, +0x2449380,9, +0x2449400,11, +0x2449500,11, +0x244a000,3, +0x244a010,2, +0x244a01c,5, +0x244a040,8, +0x244a080,3, +0x244a090,2, +0x244a09c,5, +0x244a0c0,8, +0x244a100,3, +0x244a110,2, +0x244a11c,5, +0x244a140,8, +0x244a180,3, +0x244a190,2, +0x244a19c,5, +0x244a1c0,8, +0x244a200,7, +0x244a220,12, +0x244a280,7, +0x244a2a0,12, +0x244a300,3, +0x244a310,1, +0x244a400,3, +0x244a410,2, +0x244a41c,5, +0x244a440,8, +0x244a480,3, +0x244a490,2, +0x244a49c,5, +0x244a4c0,8, +0x244a500,3, +0x244a510,2, +0x244a51c,5, +0x244a540,8, +0x244a580,3, +0x244a590,2, +0x244a59c,5, +0x244a5c0,8, +0x244a600,7, +0x244a620,12, +0x244a680,7, +0x244a6a0,12, +0x244a700,3, +0x244a710,1, +0x244a804,1, +0x244a824,21, +0x244a880,16, +0x244a900,5, +0x244a920,11, +0x244a950,9, +0x244a980,22, +0x244aa00,22, +0x244aa80,22, +0x244ab00,22, +0x244ab80,22, +0x244ac00,22, +0x244ac80,22, +0x244ad00,22, +0x244ad80,3, +0x244c000,16, +0x244c080,11, +0x244c100,11, +0x244c204,1, +0x244c224,21, +0x244c280,16, +0x244c300,11, +0x244c340,11, +0x244c800,21, +0x244c860,5, +0x244c880,6, +0x244c8a0,5, +0x244c8c0,6, +0x244c900,21, +0x244c960,5, +0x244c980,6, +0x244c9a0,5, +0x244c9c0,6, +0x244ca00,21, +0x244ca60,5, +0x244ca80,6, +0x244caa0,5, +0x244cac0,6, +0x244cb00,21, +0x244cb60,5, +0x244cb80,6, +0x244cba0,5, +0x244cbc0,6, +0x244cc00,9, +0x244cc48,7, +0x244cc68,2, +0x244cc74,9, +0x244cc9c,2, +0x244cd00,14, +0x244cd40,14, +0x244cd80,28, +0x244ce00,19, +0x244ce50,3, +0x244ce60,25, +0x244cec8,1, +0x244ced0,2, +0x244cee0,7, +0x244cf00,1, +0x244cf08,2, +0x244cffc,20, +0x244d050,25, +0x244d100,19, +0x244d150,25, +0x244d200,19, +0x244d250,25, +0x244d300,19, +0x244d350,25, +0x244d400,19, +0x244d450,25, +0x244d500,19, +0x244d550,25, +0x244d600,19, +0x244d650,25, +0x244d700,19, +0x244d750,25, +0x244d800,19, +0x244d850,25, +0x244d904,1, +0x244d914,10, +0x244d948,11, +0x244d980,2, +0x244d9a0,6, +0x244d9c0,2, +0x244d9cc,2, +0x244e000,35, +0x244ea00,10, +0x244ea80,3, +0x244eb00,6, +0x244f000,1, +0x244f008,5, +0x244f038,1, +0x244f044,1, +0x244f050,2, +0x244f100,13, +0x244f140,11, +0x244f170,12, +0x244f1a4,1, +0x244f200,104, +0x244f400,104, +0x244f600,104, +0x244f800,104, +0x2450000,13, +0x2450040,2, +0x2450054,4, +0x2450080,27, +0x2450100,12, +0x2450140,14, +0x2450180,28, +0x2450200,6, +0x2450240,6, +0x245025c,3, +0x2450280,5, +0x24502a0,8, +0x2450400,14, +0x2450440,14, +0x2450480,14, +0x24504c0,14, +0x2450540,3, +0x2450600,7, +0x2450620,14, +0x2450680,5, +0x24506a0,7, +0x2450800,13, +0x2450840,2, +0x2450854,4, +0x2450880,27, +0x2450900,12, +0x2450940,14, +0x2450980,28, +0x2450a00,6, +0x2450a40,6, +0x2450a5c,3, +0x2450a80,5, +0x2450aa0,8, +0x2450c00,14, +0x2450c40,14, +0x2450c80,14, +0x2450cc0,14, +0x2450d40,3, +0x2450e00,7, +0x2450e20,14, +0x2450e80,5, +0x2450ea0,7, +0x2451000,13, +0x2451040,2, +0x2451054,4, +0x2451080,27, +0x2451100,12, +0x2451140,14, +0x2451180,28, +0x2451200,6, +0x2451240,6, +0x245125c,3, +0x2451280,5, +0x24512a0,8, +0x2451400,14, +0x2451440,14, +0x2451480,14, +0x24514c0,14, +0x2451540,3, +0x2451600,7, +0x2451620,14, +0x2451680,5, +0x24516a0,7, +0x2451800,13, +0x2451840,2, +0x2451854,4, +0x2451880,27, +0x2451900,12, +0x2451940,14, +0x2451980,28, +0x2451a00,6, +0x2451a40,6, +0x2451a5c,3, +0x2451a80,5, +0x2451aa0,8, +0x2451c00,14, +0x2451c40,14, +0x2451c80,14, +0x2451cc0,14, +0x2451d40,3, +0x2451e00,7, +0x2451e20,14, +0x2451e80,5, +0x2451ea0,7, +0x2452000,8, +0x2452040,8, +0x2452080,1, +0x2452098,6, +0x2452100,10, +0x2452140,3, +0x2452150,2, +0x2452180,2, +0x2452200,6, +0x2452220,18, +0x2452280,4, +0x2452300,8, +0x2452400,2, +0x2452480,2, +0x2452800,28, +0x24529f0,4, +0x2453000,40, +0x2453100,64, +0x2453800,56, +0x2453be0,8, +0x2454000,13, +0x2454040,2, +0x2454054,4, +0x2454080,27, +0x2454100,12, +0x2454140,14, +0x2454180,28, +0x2454200,6, +0x2454240,6, +0x245425c,3, +0x2454280,5, +0x24542a0,8, +0x2454400,14, +0x2454440,14, +0x2454480,14, +0x24544c0,14, +0x2454540,3, +0x2454600,7, +0x2454620,14, +0x2454680,5, +0x24546a0,7, +0x2454800,13, +0x2454840,2, +0x2454854,4, +0x2454880,27, +0x2454900,12, +0x2454940,14, +0x2454980,28, +0x2454a00,6, +0x2454a40,6, +0x2454a5c,3, +0x2454a80,5, +0x2454aa0,8, +0x2454c00,14, +0x2454c40,14, +0x2454c80,14, +0x2454cc0,14, +0x2454d40,3, +0x2454e00,7, +0x2454e20,14, +0x2454e80,5, +0x2454ea0,7, +0x2455000,13, +0x2455040,2, +0x2455054,4, +0x2455080,27, +0x2455100,12, +0x2455140,14, +0x2455180,28, +0x2455200,6, +0x2455240,6, +0x245525c,3, +0x2455280,5, +0x24552a0,8, +0x2455400,14, +0x2455440,14, +0x2455480,14, +0x24554c0,14, +0x2455540,3, +0x2455600,7, +0x2455620,14, +0x2455680,5, +0x24556a0,7, +0x2455800,13, +0x2455840,2, +0x2455854,4, +0x2455880,27, +0x2455900,12, +0x2455940,14, +0x2455980,28, +0x2455a00,6, +0x2455a40,6, +0x2455a5c,3, +0x2455a80,5, +0x2455aa0,8, +0x2455c00,14, +0x2455c40,14, +0x2455c80,14, +0x2455cc0,14, +0x2455d40,3, +0x2455e00,7, +0x2455e20,14, +0x2455e80,5, +0x2455ea0,7, +0x2456000,8, +0x2456040,8, +0x2456080,1, +0x2456098,6, +0x2456100,10, +0x2456140,3, +0x2456150,2, +0x2456180,2, +0x2456200,6, +0x2456220,18, +0x2456280,4, +0x2456300,8, +0x2456400,2, +0x2456480,2, +0x2456800,28, +0x24569f0,4, +0x2457000,40, +0x2457100,64, +0x2457800,56, +0x2457be0,8, +0x2458000,2, +0x245800c,2, +0x2458040,7, +0x2458100,3, +0x2458110,3, +0x2458120,5, +0x2458200,6, +0x2458240,5, +0x2458400,2, +0x245840c,2, +0x2458440,7, +0x2458500,3, +0x2458510,3, +0x2458520,5, +0x2458600,6, +0x2458640,5, +0x2458800,2, +0x245880c,2, +0x2458840,7, +0x2458900,3, +0x2458910,3, +0x2458920,5, +0x2458a00,6, +0x2458a40,5, +0x2458c00,2, +0x2458c0c,2, +0x2458c40,7, +0x2458d00,3, +0x2458d10,3, +0x2458d20,5, +0x2458e00,6, +0x2458e40,5, +0x2459000,2, +0x245900c,2, +0x2459040,7, +0x2459100,3, +0x2459110,3, +0x2459120,5, +0x2459200,6, +0x2459240,5, +0x2459400,2, +0x245940c,2, +0x2459440,7, +0x2459500,3, +0x2459510,3, +0x2459520,5, +0x2459600,6, +0x2459640,5, +0x2459800,2, +0x245980c,2, +0x2459840,7, +0x2459900,3, +0x2459910,3, +0x2459920,5, +0x2459a00,6, +0x2459a40,5, +0x2459c00,2, +0x2459c0c,2, +0x2459c40,7, +0x2459d00,3, +0x2459d10,3, +0x2459d20,5, +0x2459e00,6, +0x2459e40,5, +0x245a000,5, +0x245a040,9, +0x245a100,3, +0x245a200,1, +0x245a210,1, +0x245a220,1, +0x245a230,1, +0x245a240,1, +0x245a300,3, +0x245a314,1, +0x245a320,4, +0x245a400,5, +0x245a440,5, +0x245b000,80, +0x245b200,1, +0x2460004,5, +0x2460020,3, +0x2460030,3, +0x2460040,13, +0x2460078,4, +0x246009c,25, +0x2460104,5, +0x2460120,3, +0x2460130,3, +0x2460140,13, +0x2460178,4, +0x246019c,25, +0x2460204,5, +0x2460220,3, +0x2460230,3, +0x2460240,13, +0x2460278,4, +0x246029c,25, +0x2460304,5, +0x2460320,3, +0x2460330,3, +0x2460340,13, +0x2460378,4, +0x246039c,25, +0x2460600,4, +0x2460c00,24, +0x2460c80,24, +0x2460d00,24, +0x2460d80,24, +0x2460e00,4, +0x2460e20,4, +0x2460e40,4, +0x2460e60,4, +0x2460e80,39, +0x2460f20,7, +0x2460f40,7, +0x2460f60,7, +0x2461000,12, +0x2461200,1, +0x2461218,2, +0x246122c,1, +0x2461280,1, +0x2461298,2, +0x24612ac,1, +0x2461300,1, +0x2461318,2, +0x246132c,1, +0x2461380,1, +0x2461398,2, +0x24613ac,1, +0x2461400,4, +0x2461420,2, +0x246142c,1, +0x2461480,4, +0x24614a0,2, +0x24614ac,1, +0x2461500,4, +0x2461520,2, +0x246152c,1, +0x2461580,4, +0x24615a0,2, +0x24615ac,1, +0x2461600,4, +0x2461640,4, +0x2461680,4, +0x24616c0,4, +0x2461700,7, +0x2461720,7, +0x2461740,7, +0x2461760,7, +0x2461780,4, +0x246179c,11, +0x24617d0,2, +0x24617e0,2, +0x24617f0,2, +0x2461900,44, +0x2462000,7, +0x2462020,4, +0x2462040,4, +0x2462060,7, +0x2462080,7, +0x24620a0,4, +0x24620c0,4, +0x24620e0,7, +0x2462100,7, +0x2462120,4, +0x2462140,4, +0x2462160,7, +0x2462180,7, +0x24621a0,4, +0x24621c0,4, +0x24621e0,7, +0x2462200,32, +0x2462b00,1, +0x2462b20,1, +0x2462b28,4, +0x2462b40,1, +0x2462b60,1, +0x2462b68,4, +0x2462b80,1, +0x2462ba0,1, +0x2462ba8,4, +0x2462bc0,1, +0x2462be0,1, +0x2462be8,4, +0x2462c00,7, +0x2462c20,1, +0x2462c54,18, +0x2462ca0,1, +0x2462cd4,18, +0x2462d20,1, +0x2462d54,18, +0x2462da0,1, +0x2462dd4,12, +0x2462e08,6, +0x2463100,7, +0x2463120,7, +0x2463140,7, +0x2463160,7, +0x2463180,3, +0x2464004,5, +0x2464020,3, +0x2464030,3, +0x2464040,13, +0x2464078,4, +0x246409c,25, +0x2464104,5, +0x2464120,3, +0x2464130,3, +0x2464140,13, +0x2464178,4, +0x246419c,25, +0x2464204,5, +0x2464220,3, +0x2464230,3, +0x2464240,13, +0x2464278,4, +0x246429c,25, +0x2464304,5, +0x2464320,3, +0x2464330,3, +0x2464340,13, +0x2464378,4, +0x246439c,25, +0x2464600,4, +0x2464c00,24, +0x2464c80,24, +0x2464d00,24, +0x2464d80,24, +0x2464e00,4, +0x2464e20,4, +0x2464e40,4, +0x2464e60,4, +0x2464e80,39, +0x2464f20,7, +0x2464f40,7, +0x2464f60,7, +0x2465000,12, +0x2465200,1, +0x2465218,2, +0x246522c,1, +0x2465280,1, +0x2465298,2, +0x24652ac,1, +0x2465300,1, +0x2465318,2, +0x246532c,1, +0x2465380,1, +0x2465398,2, +0x24653ac,1, +0x2465400,4, +0x2465420,2, +0x246542c,1, +0x2465480,4, +0x24654a0,2, +0x24654ac,1, +0x2465500,4, +0x2465520,2, +0x246552c,1, +0x2465580,4, +0x24655a0,2, +0x24655ac,1, +0x2465600,4, +0x2465640,4, +0x2465680,4, +0x24656c0,4, +0x2465700,7, +0x2465720,7, +0x2465740,7, +0x2465760,7, +0x2465780,4, +0x246579c,11, +0x24657d0,2, +0x24657e0,2, +0x24657f0,2, +0x2465900,44, +0x2466000,7, +0x2466020,4, +0x2466040,4, +0x2466060,7, +0x2466080,7, +0x24660a0,4, +0x24660c0,4, +0x24660e0,7, +0x2466100,7, +0x2466120,4, +0x2466140,4, +0x2466160,7, +0x2466180,7, +0x24661a0,4, +0x24661c0,4, +0x24661e0,7, +0x2466200,32, +0x2466b00,1, +0x2466b20,1, +0x2466b28,4, +0x2466b40,1, +0x2466b60,1, +0x2466b68,4, +0x2466b80,1, +0x2466ba0,1, +0x2466ba8,4, +0x2466bc0,1, +0x2466be0,1, +0x2466be8,4, +0x2466c00,7, +0x2466c20,1, +0x2466c54,18, +0x2466ca0,1, +0x2466cd4,18, +0x2466d20,1, +0x2466d54,18, +0x2466da0,1, +0x2466dd4,12, +0x2466e08,6, +0x2467100,7, +0x2467120,7, +0x2467140,7, +0x2467160,7, +0x2467180,3, +0x2468000,10, +0x2468080,3, +0x24680c0,1, +0x2468100,21, +0x2468180,13, +0x24681c4,7, +0x24681e4,7, +0x2468204,7, +0x2468224,8, +0x2469000,7, +0x2469030,2, +0x2469040,7, +0x2469070,2, +0x2469100,2, +0x2469120,2, +0x2469140,2, +0x2469160,2, +0x2469180,9, +0x2469200,7, +0x2469230,2, +0x2469240,7, +0x2469270,2, +0x2469300,2, +0x2469320,2, +0x2469340,2, +0x2469360,2, +0x2469380,9, +0x2469400,11, +0x2469500,11, +0x246a000,3, +0x246a010,2, +0x246a01c,5, +0x246a040,8, +0x246a080,3, +0x246a090,2, +0x246a09c,5, +0x246a0c0,8, +0x246a100,3, +0x246a110,2, +0x246a11c,5, +0x246a140,8, +0x246a180,3, +0x246a190,2, +0x246a19c,5, +0x246a1c0,8, +0x246a200,7, +0x246a220,12, +0x246a280,7, +0x246a2a0,12, +0x246a300,3, +0x246a310,1, +0x246a400,3, +0x246a410,2, +0x246a41c,5, +0x246a440,8, +0x246a480,3, +0x246a490,2, +0x246a49c,5, +0x246a4c0,8, +0x246a500,3, +0x246a510,2, +0x246a51c,5, +0x246a540,8, +0x246a580,3, +0x246a590,2, +0x246a59c,5, +0x246a5c0,8, +0x246a600,7, +0x246a620,12, +0x246a680,7, +0x246a6a0,12, +0x246a700,3, +0x246a710,1, +0x246a804,1, +0x246a824,21, +0x246a880,16, +0x246a900,5, +0x246a920,11, +0x246a950,9, +0x246a980,22, +0x246aa00,22, +0x246aa80,22, +0x246ab00,22, +0x246ab80,22, +0x246ac00,22, +0x246ac80,22, +0x246ad00,22, +0x246ad80,3, +0x246c000,16, +0x246c080,11, +0x246c100,11, +0x246c204,1, +0x246c224,21, +0x246c280,16, +0x246c300,11, +0x246c340,11, +0x246c800,21, +0x246c860,5, +0x246c880,6, +0x246c8a0,5, +0x246c8c0,6, +0x246c900,21, +0x246c960,5, +0x246c980,6, +0x246c9a0,5, +0x246c9c0,6, +0x246ca00,21, +0x246ca60,5, +0x246ca80,6, +0x246caa0,5, +0x246cac0,6, +0x246cb00,21, +0x246cb60,5, +0x246cb80,6, +0x246cba0,5, +0x246cbc0,6, +0x246cc00,9, +0x246cc48,7, +0x246cc68,2, +0x246cc74,9, +0x246cc9c,2, +0x246cd00,14, +0x246cd40,14, +0x246cd80,28, +0x246ce00,19, +0x246ce50,3, +0x246ce60,25, +0x246cec8,1, +0x246ced0,2, +0x246cee0,7, +0x246cf00,1, +0x246cf08,2, +0x246cffc,20, +0x246d050,25, +0x246d100,19, +0x246d150,25, +0x246d200,19, +0x246d250,25, +0x246d300,19, +0x246d350,25, +0x246d400,19, +0x246d450,25, +0x246d500,19, +0x246d550,25, +0x246d600,19, +0x246d650,25, +0x246d700,19, +0x246d750,25, +0x246d800,19, +0x246d850,25, +0x246d904,1, +0x246d914,10, +0x246d948,11, +0x246d980,2, +0x246d9a0,6, +0x246d9c0,2, +0x246d9cc,2, +0x246e000,35, +0x246ea00,10, +0x246ea80,3, +0x246eb00,6, +0x246f000,1, +0x246f008,5, +0x246f038,1, +0x246f044,1, +0x246f050,2, +0x246f100,13, +0x246f140,11, +0x246f170,12, +0x246f1a4,1, +0x246f200,104, +0x246f400,104, +0x246f600,104, +0x246f800,104, +0x2470000,13, +0x2470040,2, +0x2470054,4, +0x2470080,27, +0x2470100,12, +0x2470140,14, +0x2470180,28, +0x2470200,6, +0x2470240,6, +0x247025c,3, +0x2470280,5, +0x24702a0,8, +0x2470400,14, +0x2470440,14, +0x2470480,14, +0x24704c0,14, +0x2470540,3, +0x2470600,7, +0x2470620,14, +0x2470680,5, +0x24706a0,7, +0x2470800,13, +0x2470840,2, +0x2470854,4, +0x2470880,27, +0x2470900,12, +0x2470940,14, +0x2470980,28, +0x2470a00,6, +0x2470a40,6, +0x2470a5c,3, +0x2470a80,5, +0x2470aa0,8, +0x2470c00,14, +0x2470c40,14, +0x2470c80,14, +0x2470cc0,14, +0x2470d40,3, +0x2470e00,7, +0x2470e20,14, +0x2470e80,5, +0x2470ea0,7, +0x2471000,13, +0x2471040,2, +0x2471054,4, +0x2471080,27, +0x2471100,12, +0x2471140,14, +0x2471180,28, +0x2471200,6, +0x2471240,6, +0x247125c,3, +0x2471280,5, +0x24712a0,8, +0x2471400,14, +0x2471440,14, +0x2471480,14, +0x24714c0,14, +0x2471540,3, +0x2471600,7, +0x2471620,14, +0x2471680,5, +0x24716a0,7, +0x2471800,13, +0x2471840,2, +0x2471854,4, +0x2471880,27, +0x2471900,12, +0x2471940,14, +0x2471980,28, +0x2471a00,6, +0x2471a40,6, +0x2471a5c,3, +0x2471a80,5, +0x2471aa0,8, +0x2471c00,14, +0x2471c40,14, +0x2471c80,14, +0x2471cc0,14, +0x2471d40,3, +0x2471e00,7, +0x2471e20,14, +0x2471e80,5, +0x2471ea0,7, +0x2472000,8, +0x2472040,8, +0x2472080,1, +0x2472098,6, +0x2472100,10, +0x2472140,3, +0x2472150,2, +0x2472180,2, +0x2472200,6, +0x2472220,18, +0x2472280,4, +0x2472300,8, +0x2472400,2, +0x2472480,2, +0x2472800,28, +0x24729f0,4, +0x2473000,40, +0x2473100,64, +0x2473800,56, +0x2473be0,8, +0x2474000,13, +0x2474040,2, +0x2474054,4, +0x2474080,27, +0x2474100,12, +0x2474140,14, +0x2474180,28, +0x2474200,6, +0x2474240,6, +0x247425c,3, +0x2474280,5, +0x24742a0,8, +0x2474400,14, +0x2474440,14, +0x2474480,14, +0x24744c0,14, +0x2474540,3, +0x2474600,7, +0x2474620,14, +0x2474680,5, +0x24746a0,7, +0x2474800,13, +0x2474840,2, +0x2474854,4, +0x2474880,27, +0x2474900,12, +0x2474940,14, +0x2474980,28, +0x2474a00,6, +0x2474a40,6, +0x2474a5c,3, +0x2474a80,5, +0x2474aa0,8, +0x2474c00,14, +0x2474c40,14, +0x2474c80,14, +0x2474cc0,14, +0x2474d40,3, +0x2474e00,7, +0x2474e20,14, +0x2474e80,5, +0x2474ea0,7, +0x2475000,13, +0x2475040,2, +0x2475054,4, +0x2475080,27, +0x2475100,12, +0x2475140,14, +0x2475180,28, +0x2475200,6, +0x2475240,6, +0x247525c,3, +0x2475280,5, +0x24752a0,8, +0x2475400,14, +0x2475440,14, +0x2475480,14, +0x24754c0,14, +0x2475540,3, +0x2475600,7, +0x2475620,14, +0x2475680,5, +0x24756a0,7, +0x2475800,13, +0x2475840,2, +0x2475854,4, +0x2475880,27, +0x2475900,12, +0x2475940,14, +0x2475980,28, +0x2475a00,6, +0x2475a40,6, +0x2475a5c,3, +0x2475a80,5, +0x2475aa0,8, +0x2475c00,14, +0x2475c40,14, +0x2475c80,14, +0x2475cc0,14, +0x2475d40,3, +0x2475e00,7, +0x2475e20,14, +0x2475e80,5, +0x2475ea0,7, +0x2476000,8, +0x2476040,8, +0x2476080,1, +0x2476098,6, +0x2476100,10, +0x2476140,3, +0x2476150,2, +0x2476180,2, +0x2476200,6, +0x2476220,18, +0x2476280,4, +0x2476300,8, +0x2476400,2, +0x2476480,2, +0x2476800,28, +0x24769f0,4, +0x2477000,40, +0x2477100,64, +0x2477800,56, +0x2477be0,8, +0x2478000,2, +0x247800c,2, +0x2478040,7, +0x2478100,3, +0x2478110,3, +0x2478120,5, +0x2478200,6, +0x2478240,5, +0x2478400,2, +0x247840c,2, +0x2478440,7, +0x2478500,3, +0x2478510,3, +0x2478520,5, +0x2478600,6, +0x2478640,5, +0x2478800,2, +0x247880c,2, +0x2478840,7, +0x2478900,3, +0x2478910,3, +0x2478920,5, +0x2478a00,6, +0x2478a40,5, +0x2478c00,2, +0x2478c0c,2, +0x2478c40,7, +0x2478d00,3, +0x2478d10,3, +0x2478d20,5, +0x2478e00,6, +0x2478e40,5, +0x2479000,2, +0x247900c,2, +0x2479040,7, +0x2479100,3, +0x2479110,3, +0x2479120,5, +0x2479200,6, +0x2479240,5, +0x2479400,2, +0x247940c,2, +0x2479440,7, +0x2479500,3, +0x2479510,3, +0x2479520,5, +0x2479600,6, +0x2479640,5, +0x2479800,2, +0x247980c,2, +0x2479840,7, +0x2479900,3, +0x2479910,3, +0x2479920,5, +0x2479a00,6, +0x2479a40,5, +0x2479c00,2, +0x2479c0c,2, +0x2479c40,7, +0x2479d00,3, +0x2479d10,3, +0x2479d20,5, +0x2479e00,6, +0x2479e40,5, +0x247a000,5, +0x247a040,9, +0x247a100,3, +0x247a200,1, +0x247a210,1, +0x247a220,1, +0x247a230,1, +0x247a240,1, +0x247a300,3, +0x247a314,1, +0x247a320,4, +0x247a400,5, +0x247a440,5, +0x247b000,80, +0x247b200,1, +0x2480000,3, +0x2480010,7, +0x2480030,10, +0x2480080,2, +0x2480100,6, +0x2480140,2, +0x2480180,2, +0x24801a0,1, +0x2480400,2, +0x2480440,4, +0x2480460,5, +0x2480478,1, +0x2480480,6, +0x24804a0,3, +0x24804b0,2, +0x2480500,5, +0x2480600,1, +0x2480800,5, +0x2480900,5, +0x2480a00,5, +0x2480b00,3, +0x2480c00,35, +0x2480d00,25, +0x2480d80,1, +0x2480dc0,3, +0x2480e00,2, +0x2480e20,2, +0x2490000,3, +0x249001c,6, +0x2490080,3, +0x2490090,2, +0x24900d4,4, +0x24900ec,27, +0x249015c,27, +0x24901cc,19, +0x2490224,120, +0x2490408,109, +0x24905f8,4, +0x2490610,27, +0x2490680,27, +0x24906f0,19, +0x2490748,120, +0x249092c,109, +0x2490b1c,4, +0x2490b34,27, +0x2490ba4,27, +0x2490c14,19, +0x2490c6c,120, +0x2490e50,109, +0x2491040,4, +0x2491058,27, +0x24910c8,27, +0x2491138,19, +0x2491190,120, +0x2491374,109, +0x2491564,4, +0x249157c,27, +0x24915ec,27, +0x249165c,19, +0x24916b4,120, +0x2491898,109, +0x2491a88,4, +0x2491aa0,27, +0x2491b10,27, +0x2491b80,19, +0x2491bd8,120, +0x2491dbc,109, +0x2491fac,4, +0x2491fc4,27, +0x2492034,27, +0x24920a4,19, +0x24920fc,120, +0x24922e0,109, +0x24924d0,4, +0x24924e8,27, +0x2492558,27, +0x24925c8,19, +0x2492620,120, +0x2492804,109, +0x24929f4,4, +0x2492a0c,27, +0x2492a7c,27, +0x2492aec,19, +0x2492b44,120, +0x2492d28,109, +0x2492f18,4, +0x2492f30,27, +0x2492fa0,27, +0x2493010,19, +0x2493068,120, +0x249324c,109, +0x249343c,4, +0x2493454,27, +0x24934c4,27, +0x2493534,19, +0x249358c,120, +0x2493770,109, +0x2493960,4, +0x2493978,27, +0x24939e8,27, +0x2493a58,19, +0x2493ab0,120, +0x2493c94,109, +0x2493e84,4, +0x2493e9c,27, +0x2493f0c,27, +0x2493f7c,19, +0x2493fd4,120, +0x24941b8,109, +0x24943a8,4, +0x24943c0,27, +0x2494430,27, +0x24944a0,19, +0x24944f8,120, +0x24946dc,109, +0x24948cc,4, +0x24948e4,27, +0x2494954,27, +0x24949c4,19, +0x2494a1c,120, +0x2494c00,109, +0x2494df0,4, +0x2494e08,27, +0x2494e78,27, +0x2494ee8,19, +0x2494f40,120, +0x2495124,109, +0x2495314,4, +0x249532c,27, +0x249539c,27, +0x249540c,19, +0x2495464,120, +0x2495648,109, +0x2495838,14, +0x2495940,13, +0x2495a44,13, +0x2495b48,16, +0x2495b90,42, +0x2495c40,2, +0x2495c90,54, +0x2495d70,58, +0x2495e60,58, +0x2495f50,58, +0x2496040,58, +0x2496130,58, +0x2496220,58, +0x2496310,58, +0x2496400,58, +0x24964f0,58, +0x24965e0,58, +0x24966d0,58, +0x24967c0,58, +0x24968b0,58, +0x24969a0,58, +0x2496a90,58, +0x2496b80,58, +0x2496c70,58, +0x2496d60,58, +0x2496e50,58, +0x2496f40,58, +0x2497030,58, +0x2497120,58, +0x2497210,58, +0x2497300,58, +0x24973f0,58, +0x24974e0,58, +0x24975d0,58, +0x24976c0,58, +0x24977b0,58, +0x24978a0,58, +0x2497990,58, +0x2497a80,101, +0x2497c90,49, +0x2497db0,18, +0x2497e00,11, +0x2497e30,4, +0x2497e54,45, +0x2497f58,9, +0x2497f88,4, +0x2497fa0,2, +0x2497fd8,14, +0x2498014,12, +0x2498158,3, +0x2498168,2, +0x2498174,68, +0x2498288,2, +0x2498294,68, +0x24983a8,1, +0x24983b0,2, +0x24983bc,68, +0x24984d0,2, +0x24984dc,68, +0x24985f0,1, +0x24985f8,4, +0x2498610,3, +0x2498624,12, +0x2498688,8, +0x24986dc,1, +0x24986e8,4, +0x2498700,3, +0x2498714,12, +0x2498778,8, +0x24987cc,1, +0x24987d8,4, +0x24987f0,3, +0x2498804,12, +0x2498868,8, +0x24988bc,1, +0x24988c8,4, +0x24988e0,3, +0x24988f4,12, +0x2498958,8, +0x24989ac,1, +0x24989b8,4, +0x24989d0,3, +0x24989e4,12, +0x2498a48,8, +0x2498a9c,1, +0x2498aa8,4, +0x2498ac0,3, +0x2498ad4,12, +0x2498b38,8, +0x2498b8c,1, +0x2498b98,4, +0x2498bb0,3, +0x2498bc4,12, +0x2498c28,8, +0x2498c7c,1, +0x2498c88,4, +0x2498ca0,3, +0x2498cb4,12, +0x2498d18,8, +0x2498d6c,1, +0x2498d78,4, +0x2498d90,3, +0x2498da4,12, +0x2498e08,8, +0x2498e5c,1, +0x2498e68,4, +0x2498e80,3, +0x2498e94,12, +0x2498ef8,8, +0x2498f4c,1, +0x2498f58,4, +0x2498f70,3, +0x2498f84,12, +0x2498fe8,8, +0x249903c,1, +0x2499048,4, +0x2499060,3, +0x2499074,12, +0x24990d8,8, +0x249912c,1, +0x2499138,4, +0x2499150,3, +0x2499164,12, +0x24991c8,8, +0x249921c,1, +0x2499228,4, +0x2499240,3, +0x2499254,12, +0x24992b8,8, +0x249930c,1, +0x2499318,4, +0x2499330,3, +0x2499344,12, +0x24993a8,8, +0x24993fc,1, +0x2499408,4, +0x2499420,3, +0x2499434,12, +0x2499498,8, +0x24994ec,1, +0x24994f8,4, +0x2499510,3, +0x2499524,12, +0x2499588,8, +0x24995dc,1, +0x24995e8,64, +0x2499748,5, +0x2499990,28, +0x2499a04,4, +0x2499a98,1, +0x2499be8,11, +0x2499c18,13, +0x2499c50,6, +0x249a000,15, +0x249a044,81, +0x249a18c,84, +0x249a2e0,84, +0x249a434,84, +0x249a588,84, +0x249a6dc,84, +0x249a830,84, +0x249a984,84, +0x249aad8,84, +0x249ac2c,84, +0x249ad80,84, +0x249aed4,84, +0x249b028,84, +0x249b17c,84, +0x249b2d0,84, +0x249b424,84, +0x249b578,84, +0x249b6cc,5, +0x249b760,4, +0x249b8e0,2414, +0x249dea4,88, +0x249e048,4, +0x249ebe0,1, +0x249ebf0,97, +0x249ed94,7, +0x249ee7c,1, +0x249eeac,9, +0x249eed4,5, +0x249eeec,11, +0x249ef2c,17, +0x249ef74,30, +0x249f034,3, +0x249f044,2, +0x249f054,17, +0x249fbe0,3, +0x249fbf0,1, +0x24a0000,3, +0x24a0018,2, +0x24a0024,14, +0x24a0060,27, +0x24a00d0,3, +0x24a00e0,3, +0x24a00f0,3, +0x24a0100,4, +0x24a0120,6, +0x24a0140,3, +0x24a0150,1, +0x24a015c,4, +0x24a0170,1, +0x24a0180,15, +0x24a01c0,1, +0x24a01c8,5, +0x24a01e0,1, +0x24a01f0,3, +0x24a0200,3, +0x24a0218,2, +0x24a0224,14, +0x24a0260,27, +0x24a02d0,3, +0x24a02e0,3, +0x24a02f0,3, +0x24a0300,4, +0x24a0320,6, +0x24a0340,3, +0x24a0350,1, +0x24a035c,4, +0x24a0370,1, +0x24a0380,15, +0x24a03c0,1, +0x24a03c8,5, +0x24a03e0,1, +0x24a03f0,3, +0x24a0400,3, +0x24a0418,2, +0x24a0424,14, +0x24a0460,27, +0x24a04d0,3, +0x24a04e0,3, +0x24a04f0,3, +0x24a0500,4, +0x24a0520,6, +0x24a0540,3, +0x24a0550,1, +0x24a055c,4, +0x24a0570,1, +0x24a0580,15, +0x24a05c0,1, +0x24a05c8,5, +0x24a05e0,1, +0x24a05f0,3, +0x24a0600,3, +0x24a0618,2, +0x24a0624,14, +0x24a0660,27, +0x24a06d0,3, +0x24a06e0,3, +0x24a06f0,3, +0x24a0700,4, +0x24a0720,6, +0x24a0740,3, +0x24a0750,1, +0x24a075c,4, +0x24a0770,1, +0x24a0780,15, +0x24a07c0,1, +0x24a07c8,5, +0x24a07e0,1, +0x24a07f0,3, +0x24a0800,3, +0x24a0818,2, +0x24a0824,14, +0x24a0860,27, +0x24a08d0,3, +0x24a08e0,3, +0x24a08f0,3, +0x24a0900,4, +0x24a0920,6, +0x24a0940,3, +0x24a0950,1, +0x24a095c,4, +0x24a0970,1, +0x24a0980,15, +0x24a09c0,1, +0x24a09c8,5, +0x24a09e0,1, +0x24a09f0,3, +0x24a1844,1, +0x24a1858,5, +0x24a1904,3, +0x24a1950,3, +0x24a1988,2, +0x24a19a0,7, +0x24a19c0,7, +0x24a19e0,4, +0x24a2000,24, +0x24a20f0,3, +0x24a2100,7, +0x24a2120,7, +0x24a2144,7, +0x24a2400,4, +0x24a2420,5, +0x24a25e0,3, +0x24a25f4,1, +0x24a25fc,4, +0x24a2620,3, +0x24a2680,8, +0x24a2700,19, +0x24a2800,99, +0x24a2a00,18, +0x24a2a80,8, +0x24a2b00,1, +0x24a3070,1, +0x24a3080,2, +0x24a308c,1, +0x24a3098,2, +0x24a3404,1, +0x24a3440,20, +0x24a3494,1, +0x24a349c,7, +0x24a34d0,4, +0x24a34e8,2, +0x24a34fc,8, +0x24a3520,7, +0x24a3540,7, +0x24a3560,7, +0x24a3580,7, +0x24a35a0,7, +0x24a35c0,7, +0x24a35e0,7, +0x24a3600,9, +0x24a363c,2, +0x24a3650,6, +0x24a3684,10, +0x24a3a00,10, +0x24a3a30,1, +0x24a3a40,8, +0x24a3a64,5, +0x24a4a04,3, +0x24a4b00,33, +0x24a4b90,3, +0x24a5000,8, +0x24a5040,8, +0x24a5104,1, +0x24a510c,3, +0x24a5124,1, +0x24a512c,3, +0x24a6000,13, +0x24a6200,14, +0x24a6240,1, +0x24a6248,1, +0x24a6258,1, +0x24a6260,8, +0x24a6284,1, +0x24a62a0,8, +0x24a6348,5, +0x24a67f0,1, +0x24a67f8,1, +0x24a6a10,12, +0x24a7000,19, +0x24a7a00,10, +0x24a7a80,3, +0x24a7b00,6, +0x24c0000,1, +0x24c000c,5, +0x24c0044,1, +0x24c0054,5, +0x24c0200,128, +0x24c0404,1, +0x24c0428,54, +0x24c0600,32, +0x24c0704,1, +0x24c0800,1, +0x24c0900,1, +0x24c0910,2, +0x24c0920,3, +0x24c0980,10, +0x24c0a00,19, +0x24c0b00,1, +0x24e0000,2, +0x24e000c,2, +0x24e0018,2, +0x24e0024,2, +0x24e0030,2, +0x24e003c,2, +0x24e0048,2, +0x24e0054,2, +0x24e0060,1, +0x24e0070,2, +0x24e007c,2, +0x24e0088,2, +0x24e0094,2, +0x24e00a0,2, +0x24e00ac,2, +0x24e00b8,2, +0x24e00c4,2, +0x24e00d0,1, +0x24e00e0,2, +0x24e00ec,2, +0x24e00f8,2, +0x24e0104,2, +0x24e0110,2, +0x24e011c,2, +0x24e0128,2, +0x24e0134,2, +0x24e0140,1, +0x24e0150,2, +0x24e015c,2, +0x24e0168,2, +0x24e0174,2, +0x24e0180,2, +0x24e018c,2, +0x24e0198,2, +0x24e01a4,2, +0x24e01b0,1, +0x24e01c0,57, +0x24e02b0,23, +0x24e0310,83, +0x24e0460,83, +0x24e05b0,83, +0x24e0700,83, +0x24e0850,83, +0x24e09a0,83, +0x24e0af0,83, +0x24e0c40,83, +0x24e0d90,83, +0x24e0ee0,83, +0x24e1030,83, +0x24e1180,83, +0x24e12d0,83, +0x24e1420,83, +0x24e1570,83, +0x24e16c0,83, +0x24e1810,83, +0x24e1960,83, +0x24e1ab0,83, +0x24e1c00,83, +0x24e1d50,83, +0x24e1ea0,83, +0x24e1ff0,83, +0x24e2140,83, +0x24e2290,83, +0x24e23e0,83, +0x24e2530,83, +0x24e2680,83, +0x24e27d0,83, +0x24e2920,83, +0x24e2a70,83, +0x24e2bc0,62, +0x24e2db4,3, +0x24e2df4,3, +0x24e2e34,3, +0x24e2e74,3, +0x24e2eb4,3, +0x24e2ef4,3, +0x24e2f34,3, +0x24e2f74,3, +0x24e2fb4,3, +0x24e2ff4,3, +0x24e3034,3, +0x24e3074,3, +0x24e30b4,3, +0x24e30f4,3, +0x24e3134,3, +0x24e3174,3, +0x24e31b4,3, +0x24f0000,4, +0x24f0014,2, +0x24f0020,8, +0x24f0044,2, +0x24f0050,13, +0x24f0088,20, +0x24f00dc,1, +0x24f0180,6, +0x24f0590,3, +0x24f05c0,2, +0x24f0a04,1, +0x24f0a0c,3, +0x24f0a20,1, +0x24f0ba0,4, +0x24f0c00,4, +0x24f0c20,3, +0x24f0c30,5, +0x24f0c50,52, +0x24f0d50,57, +0x24f0ec0,3, +0x24f0ffc,3, +0x24f1020,3, +0x24f1030,3, +0x24f1060,2, +0x24f1100,2, +0x24f1140,18, +0x24f11c0,30, +0x24f1240,14, +0x24f1280,28, +0x24f1300,2, +0x24f13a0,6, +0x24f1400,19, +0x24f1800,19, +0x24f1c00,19, +0x24f1c80,8, +0x24f1d00,3, +0x24f1d50,3, +0x24f1e00,3, +0x24f1e10,2, +0x24f1e20,6, +0x24f1e40,6, +0x24f1e60,6, +0x24f1e80,6, +0x24f1ea0,6, +0x24f1ec0,2, +0x24f1ecc,2, +0x24f1ee0,2, +0x24f1eec,2, +0x24f1f80,3, +0x24f1f90,60, +0x24f2100,32, +0x24f2200,32, +0x24f2300,32, +0x24f2400,32, +0x24f2500,32, +0x24f2600,32, +0x24f2700,32, +0x24f2800,32, +0x24f2900,32, +0x24f2a00,32, +0x24f2b00,32, +0x24f2c00,32, +0x24f2d00,32, +0x24f2e00,32, +0x24f2f00,32, +0x24f3000,32, +0x24f30c0,3, +0x24f4000,2, +0x24f4040,16, +0x24f4100,36, +0x24f4800,5, +0x24f4824,1, +0x24f482c,1, +0x24f4c04,1, +0x24f4cd8,74, +0x24f5000,7, +0x24f5020,4, +0x24f5204,1, +0x24f5280,35, +0x24f5310,4, +0x24f5404,1, +0x24f5480,34, +0x24f5510,10, +0x24f553c,3, +0x24f5800,7, +0x24f5820,4, +0x24f5a04,1, +0x24f5a80,35, +0x24f5b10,4, +0x24f5c04,1, +0x24f5c80,34, +0x24f5d10,10, +0x24f5d3c,3, +0x24fa000,5, +0x24fa01c,13, +0x24fa060,3, +0x24fa080,8, +0x24fa100,5, +0x24fa11c,13, +0x24fa160,3, +0x24fa180,8, +0x2600004,5, +0x2600020,3, +0x2600030,3, +0x2600040,13, +0x2600078,4, +0x260009c,25, +0x2600104,5, +0x2600120,3, +0x2600130,3, +0x2600140,13, +0x2600178,4, +0x260019c,25, +0x2600204,5, +0x2600220,3, +0x2600230,3, +0x2600240,13, +0x2600278,4, +0x260029c,25, +0x2600304,5, +0x2600320,3, +0x2600330,3, +0x2600340,13, +0x2600378,4, +0x260039c,25, +0x2600600,4, +0x2600c00,24, +0x2600c80,24, +0x2600d00,24, +0x2600d80,24, +0x2600e00,4, +0x2600e20,4, +0x2600e40,4, +0x2600e60,4, +0x2600e80,39, +0x2600f20,7, +0x2600f40,7, +0x2600f60,7, +0x2601000,12, +0x2601200,1, +0x2601218,2, +0x260122c,1, +0x2601280,1, +0x2601298,2, +0x26012ac,1, +0x2601300,1, +0x2601318,2, +0x260132c,1, +0x2601380,1, +0x2601398,2, +0x26013ac,1, +0x2601400,4, +0x2601420,2, +0x260142c,1, +0x2601480,4, +0x26014a0,2, +0x26014ac,1, +0x2601500,4, +0x2601520,2, +0x260152c,1, +0x2601580,4, +0x26015a0,2, +0x26015ac,1, +0x2601600,4, +0x2601640,4, +0x2601680,4, +0x26016c0,4, +0x2601700,7, +0x2601720,7, +0x2601740,7, +0x2601760,7, +0x2601780,4, +0x260179c,11, +0x26017d0,2, +0x26017e0,2, +0x26017f0,2, +0x2601900,44, +0x2602000,7, +0x2602020,4, +0x2602040,4, +0x2602060,7, +0x2602080,7, +0x26020a0,4, +0x26020c0,4, +0x26020e0,7, +0x2602100,7, +0x2602120,4, +0x2602140,4, +0x2602160,7, +0x2602180,7, +0x26021a0,4, +0x26021c0,4, +0x26021e0,7, +0x2602200,32, +0x2602b00,1, +0x2602b20,1, +0x2602b28,4, +0x2602b40,1, +0x2602b60,1, +0x2602b68,4, +0x2602b80,1, +0x2602ba0,1, +0x2602ba8,4, +0x2602bc0,1, +0x2602be0,1, +0x2602be8,4, +0x2602c00,7, +0x2602c20,1, +0x2602c54,18, +0x2602ca0,1, +0x2602cd4,18, +0x2602d20,1, +0x2602d54,18, +0x2602da0,1, +0x2602dd4,12, +0x2602e08,6, +0x2603100,7, +0x2603120,7, +0x2603140,7, +0x2603160,7, +0x2603180,3, +0x2604004,5, +0x2604020,3, +0x2604030,3, +0x2604040,13, +0x2604078,4, +0x260409c,25, +0x2604104,5, +0x2604120,3, +0x2604130,3, +0x2604140,13, +0x2604178,4, +0x260419c,25, +0x2604204,5, +0x2604220,3, +0x2604230,3, +0x2604240,13, +0x2604278,4, +0x260429c,25, +0x2604304,5, +0x2604320,3, +0x2604330,3, +0x2604340,13, +0x2604378,4, +0x260439c,25, +0x2604600,4, +0x2604c00,24, +0x2604c80,24, +0x2604d00,24, +0x2604d80,24, +0x2604e00,4, +0x2604e20,4, +0x2604e40,4, +0x2604e60,4, +0x2604e80,39, +0x2604f20,7, +0x2604f40,7, +0x2604f60,7, +0x2605000,12, +0x2605200,1, +0x2605218,2, +0x260522c,1, +0x2605280,1, +0x2605298,2, +0x26052ac,1, +0x2605300,1, +0x2605318,2, +0x260532c,1, +0x2605380,1, +0x2605398,2, +0x26053ac,1, +0x2605400,4, +0x2605420,2, +0x260542c,1, +0x2605480,4, +0x26054a0,2, +0x26054ac,1, +0x2605500,4, +0x2605520,2, +0x260552c,1, +0x2605580,4, +0x26055a0,2, +0x26055ac,1, +0x2605600,4, +0x2605640,4, +0x2605680,4, +0x26056c0,4, +0x2605700,7, +0x2605720,7, +0x2605740,7, +0x2605760,7, +0x2605780,4, +0x260579c,11, +0x26057d0,2, +0x26057e0,2, +0x26057f0,2, +0x2605900,44, +0x2606000,7, +0x2606020,4, +0x2606040,4, +0x2606060,7, +0x2606080,7, +0x26060a0,4, +0x26060c0,4, +0x26060e0,7, +0x2606100,7, +0x2606120,4, +0x2606140,4, +0x2606160,7, +0x2606180,7, +0x26061a0,4, +0x26061c0,4, +0x26061e0,7, +0x2606200,32, +0x2606b00,1, +0x2606b20,1, +0x2606b28,4, +0x2606b40,1, +0x2606b60,1, +0x2606b68,4, +0x2606b80,1, +0x2606ba0,1, +0x2606ba8,4, +0x2606bc0,1, +0x2606be0,1, +0x2606be8,4, +0x2606c00,7, +0x2606c20,1, +0x2606c54,18, +0x2606ca0,1, +0x2606cd4,18, +0x2606d20,1, +0x2606d54,18, +0x2606da0,1, +0x2606dd4,12, +0x2606e08,6, +0x2607100,7, +0x2607120,7, +0x2607140,7, +0x2607160,7, +0x2607180,3, +0x2608000,10, +0x2608080,3, +0x26080c0,1, +0x2608100,21, +0x2608180,13, +0x26081c4,7, +0x26081e4,7, +0x2608204,7, +0x2608224,8, +0x2609000,7, +0x2609030,2, +0x2609040,7, +0x2609070,2, +0x2609100,2, +0x2609120,2, +0x2609140,2, +0x2609160,2, +0x2609180,9, +0x2609200,7, +0x2609230,2, +0x2609240,7, +0x2609270,2, +0x2609300,2, +0x2609320,2, +0x2609340,2, +0x2609360,2, +0x2609380,9, +0x2609400,11, +0x2609500,11, +0x260a000,3, +0x260a010,2, +0x260a01c,5, +0x260a040,8, +0x260a080,3, +0x260a090,2, +0x260a09c,5, +0x260a0c0,8, +0x260a100,3, +0x260a110,2, +0x260a11c,5, +0x260a140,8, +0x260a180,3, +0x260a190,2, +0x260a19c,5, +0x260a1c0,8, +0x260a200,7, +0x260a220,12, +0x260a280,7, +0x260a2a0,12, +0x260a300,3, +0x260a310,1, +0x260a400,3, +0x260a410,2, +0x260a41c,5, +0x260a440,8, +0x260a480,3, +0x260a490,2, +0x260a49c,5, +0x260a4c0,8, +0x260a500,3, +0x260a510,2, +0x260a51c,5, +0x260a540,8, +0x260a580,3, +0x260a590,2, +0x260a59c,5, +0x260a5c0,8, +0x260a600,7, +0x260a620,12, +0x260a680,7, +0x260a6a0,12, +0x260a700,3, +0x260a710,1, +0x260a804,1, +0x260a824,21, +0x260a880,16, +0x260a900,5, +0x260a920,11, +0x260a950,9, +0x260a980,22, +0x260aa00,22, +0x260aa80,22, +0x260ab00,22, +0x260ab80,22, +0x260ac00,22, +0x260ac80,22, +0x260ad00,22, +0x260ad80,3, +0x260c000,16, +0x260c080,11, +0x260c100,11, +0x260c204,1, +0x260c224,21, +0x260c280,16, +0x260c300,11, +0x260c340,11, +0x260c800,21, +0x260c860,5, +0x260c880,6, +0x260c8a0,5, +0x260c8c0,6, +0x260c900,21, +0x260c960,5, +0x260c980,6, +0x260c9a0,5, +0x260c9c0,6, +0x260ca00,21, +0x260ca60,5, +0x260ca80,6, +0x260caa0,5, +0x260cac0,6, +0x260cb00,21, +0x260cb60,5, +0x260cb80,6, +0x260cba0,5, +0x260cbc0,6, +0x260cc00,9, +0x260cc48,7, +0x260cc68,2, +0x260cc74,9, +0x260cc9c,2, +0x260cd00,14, +0x260cd40,14, +0x260cd80,28, +0x260ce00,19, +0x260ce50,3, +0x260ce60,25, +0x260cec8,1, +0x260ced0,2, +0x260cee0,7, +0x260cf00,1, +0x260cf08,2, +0x260cffc,20, +0x260d050,25, +0x260d100,19, +0x260d150,25, +0x260d200,19, +0x260d250,25, +0x260d300,19, +0x260d350,25, +0x260d400,19, +0x260d450,25, +0x260d500,19, +0x260d550,25, +0x260d600,19, +0x260d650,25, +0x260d700,19, +0x260d750,25, +0x260d800,19, +0x260d850,25, +0x260d904,1, +0x260d914,10, +0x260d948,11, +0x260d980,2, +0x260d9a0,6, +0x260d9c0,2, +0x260d9cc,2, +0x260e000,35, +0x260ea00,10, +0x260ea80,3, +0x260eb00,6, +0x260f000,1, +0x260f008,5, +0x260f038,1, +0x260f044,1, +0x260f050,2, +0x260f100,13, +0x260f140,11, +0x260f170,12, +0x260f1a4,1, +0x260f200,104, +0x260f400,104, +0x260f600,104, +0x260f800,104, +0x2610000,13, +0x2610040,2, +0x2610054,4, +0x2610080,27, +0x2610100,12, +0x2610140,14, +0x2610180,28, +0x2610200,6, +0x2610240,6, +0x261025c,3, +0x2610280,5, +0x26102a0,8, +0x2610400,14, +0x2610440,14, +0x2610480,14, +0x26104c0,14, +0x2610540,3, +0x2610600,7, +0x2610620,14, +0x2610680,5, +0x26106a0,7, +0x2610800,13, +0x2610840,2, +0x2610854,4, +0x2610880,27, +0x2610900,12, +0x2610940,14, +0x2610980,28, +0x2610a00,6, +0x2610a40,6, +0x2610a5c,3, +0x2610a80,5, +0x2610aa0,8, +0x2610c00,14, +0x2610c40,14, +0x2610c80,14, +0x2610cc0,14, +0x2610d40,3, +0x2610e00,7, +0x2610e20,14, +0x2610e80,5, +0x2610ea0,7, +0x2611000,13, +0x2611040,2, +0x2611054,4, +0x2611080,27, +0x2611100,12, +0x2611140,14, +0x2611180,28, +0x2611200,6, +0x2611240,6, +0x261125c,3, +0x2611280,5, +0x26112a0,8, +0x2611400,14, +0x2611440,14, +0x2611480,14, +0x26114c0,14, +0x2611540,3, +0x2611600,7, +0x2611620,14, +0x2611680,5, +0x26116a0,7, +0x2611800,13, +0x2611840,2, +0x2611854,4, +0x2611880,27, +0x2611900,12, +0x2611940,14, +0x2611980,28, +0x2611a00,6, +0x2611a40,6, +0x2611a5c,3, +0x2611a80,5, +0x2611aa0,8, +0x2611c00,14, +0x2611c40,14, +0x2611c80,14, +0x2611cc0,14, +0x2611d40,3, +0x2611e00,7, +0x2611e20,14, +0x2611e80,5, +0x2611ea0,7, +0x2612000,8, +0x2612040,8, +0x2612080,1, +0x2612098,6, +0x2612100,10, +0x2612140,3, +0x2612150,2, +0x2612180,2, +0x2612200,6, +0x2612220,18, +0x2612280,4, +0x2612300,8, +0x2612400,2, +0x2612480,2, +0x2612800,28, +0x26129f0,4, +0x2613000,40, +0x2613100,64, +0x2613800,56, +0x2613be0,8, +0x2614000,13, +0x2614040,2, +0x2614054,4, +0x2614080,27, +0x2614100,12, +0x2614140,14, +0x2614180,28, +0x2614200,6, +0x2614240,6, +0x261425c,3, +0x2614280,5, +0x26142a0,8, +0x2614400,14, +0x2614440,14, +0x2614480,14, +0x26144c0,14, +0x2614540,3, +0x2614600,7, +0x2614620,14, +0x2614680,5, +0x26146a0,7, +0x2614800,13, +0x2614840,2, +0x2614854,4, +0x2614880,27, +0x2614900,12, +0x2614940,14, +0x2614980,28, +0x2614a00,6, +0x2614a40,6, +0x2614a5c,3, +0x2614a80,5, +0x2614aa0,8, +0x2614c00,14, +0x2614c40,14, +0x2614c80,14, +0x2614cc0,14, +0x2614d40,3, +0x2614e00,7, +0x2614e20,14, +0x2614e80,5, +0x2614ea0,7, +0x2615000,13, +0x2615040,2, +0x2615054,4, +0x2615080,27, +0x2615100,12, +0x2615140,14, +0x2615180,28, +0x2615200,6, +0x2615240,6, +0x261525c,3, +0x2615280,5, +0x26152a0,8, +0x2615400,14, +0x2615440,14, +0x2615480,14, +0x26154c0,14, +0x2615540,3, +0x2615600,7, +0x2615620,14, +0x2615680,5, +0x26156a0,7, +0x2615800,13, +0x2615840,2, +0x2615854,4, +0x2615880,27, +0x2615900,12, +0x2615940,14, +0x2615980,28, +0x2615a00,6, +0x2615a40,6, +0x2615a5c,3, +0x2615a80,5, +0x2615aa0,8, +0x2615c00,14, +0x2615c40,14, +0x2615c80,14, +0x2615cc0,14, +0x2615d40,3, +0x2615e00,7, +0x2615e20,14, +0x2615e80,5, +0x2615ea0,7, +0x2616000,8, +0x2616040,8, +0x2616080,1, +0x2616098,6, +0x2616100,10, +0x2616140,3, +0x2616150,2, +0x2616180,2, +0x2616200,6, +0x2616220,18, +0x2616280,4, +0x2616300,8, +0x2616400,2, +0x2616480,2, +0x2616800,28, +0x26169f0,4, +0x2617000,40, +0x2617100,64, +0x2617800,56, +0x2617be0,8, +0x2618000,2, +0x261800c,2, +0x2618040,7, +0x2618100,3, +0x2618110,3, +0x2618120,5, +0x2618200,6, +0x2618240,5, +0x2618400,2, +0x261840c,2, +0x2618440,7, +0x2618500,3, +0x2618510,3, +0x2618520,5, +0x2618600,6, +0x2618640,5, +0x2618800,2, +0x261880c,2, +0x2618840,7, +0x2618900,3, +0x2618910,3, +0x2618920,5, +0x2618a00,6, +0x2618a40,5, +0x2618c00,2, +0x2618c0c,2, +0x2618c40,7, +0x2618d00,3, +0x2618d10,3, +0x2618d20,5, +0x2618e00,6, +0x2618e40,5, +0x2619000,2, +0x261900c,2, +0x2619040,7, +0x2619100,3, +0x2619110,3, +0x2619120,5, +0x2619200,6, +0x2619240,5, +0x2619400,2, +0x261940c,2, +0x2619440,7, +0x2619500,3, +0x2619510,3, +0x2619520,5, +0x2619600,6, +0x2619640,5, +0x2619800,2, +0x261980c,2, +0x2619840,7, +0x2619900,3, +0x2619910,3, +0x2619920,5, +0x2619a00,6, +0x2619a40,5, +0x2619c00,2, +0x2619c0c,2, +0x2619c40,7, +0x2619d00,3, +0x2619d10,3, +0x2619d20,5, +0x2619e00,6, +0x2619e40,5, +0x261a000,5, +0x261a040,9, +0x261a100,3, +0x261a200,1, +0x261a210,1, +0x261a220,1, +0x261a230,1, +0x261a240,1, +0x261a300,3, +0x261a314,1, +0x261a320,4, +0x261a400,5, +0x261a440,5, +0x261b000,80, +0x261b200,1, +0x2620004,5, +0x2620020,3, +0x2620030,3, +0x2620040,13, +0x2620078,4, +0x262009c,25, +0x2620104,5, +0x2620120,3, +0x2620130,3, +0x2620140,13, +0x2620178,4, +0x262019c,25, +0x2620204,5, +0x2620220,3, +0x2620230,3, +0x2620240,13, +0x2620278,4, +0x262029c,25, +0x2620304,5, +0x2620320,3, +0x2620330,3, +0x2620340,13, +0x2620378,4, +0x262039c,25, +0x2620600,4, +0x2620c00,24, +0x2620c80,24, +0x2620d00,24, +0x2620d80,24, +0x2620e00,4, +0x2620e20,4, +0x2620e40,4, +0x2620e60,4, +0x2620e80,39, +0x2620f20,7, +0x2620f40,7, +0x2620f60,7, +0x2621000,12, +0x2621200,1, +0x2621218,2, +0x262122c,1, +0x2621280,1, +0x2621298,2, +0x26212ac,1, +0x2621300,1, +0x2621318,2, +0x262132c,1, +0x2621380,1, +0x2621398,2, +0x26213ac,1, +0x2621400,4, +0x2621420,2, +0x262142c,1, +0x2621480,4, +0x26214a0,2, +0x26214ac,1, +0x2621500,4, +0x2621520,2, +0x262152c,1, +0x2621580,4, +0x26215a0,2, +0x26215ac,1, +0x2621600,4, +0x2621640,4, +0x2621680,4, +0x26216c0,4, +0x2621700,7, +0x2621720,7, +0x2621740,7, +0x2621760,7, +0x2621780,4, +0x262179c,11, +0x26217d0,2, +0x26217e0,2, +0x26217f0,2, +0x2621900,44, +0x2622000,7, +0x2622020,4, +0x2622040,4, +0x2622060,7, +0x2622080,7, +0x26220a0,4, +0x26220c0,4, +0x26220e0,7, +0x2622100,7, +0x2622120,4, +0x2622140,4, +0x2622160,7, +0x2622180,7, +0x26221a0,4, +0x26221c0,4, +0x26221e0,7, +0x2622200,32, +0x2622b00,1, +0x2622b20,1, +0x2622b28,4, +0x2622b40,1, +0x2622b60,1, +0x2622b68,4, +0x2622b80,1, +0x2622ba0,1, +0x2622ba8,4, +0x2622bc0,1, +0x2622be0,1, +0x2622be8,4, +0x2622c00,7, +0x2622c20,1, +0x2622c54,18, +0x2622ca0,1, +0x2622cd4,18, +0x2622d20,1, +0x2622d54,18, +0x2622da0,1, +0x2622dd4,12, +0x2622e08,6, +0x2623100,7, +0x2623120,7, +0x2623140,7, +0x2623160,7, +0x2623180,3, +0x2624004,5, +0x2624020,3, +0x2624030,3, +0x2624040,13, +0x2624078,4, +0x262409c,25, +0x2624104,5, +0x2624120,3, +0x2624130,3, +0x2624140,13, +0x2624178,4, +0x262419c,25, +0x2624204,5, +0x2624220,3, +0x2624230,3, +0x2624240,13, +0x2624278,4, +0x262429c,25, +0x2624304,5, +0x2624320,3, +0x2624330,3, +0x2624340,13, +0x2624378,4, +0x262439c,25, +0x2624600,4, +0x2624c00,24, +0x2624c80,24, +0x2624d00,24, +0x2624d80,24, +0x2624e00,4, +0x2624e20,4, +0x2624e40,4, +0x2624e60,4, +0x2624e80,39, +0x2624f20,7, +0x2624f40,7, +0x2624f60,7, +0x2625000,12, +0x2625200,1, +0x2625218,2, +0x262522c,1, +0x2625280,1, +0x2625298,2, +0x26252ac,1, +0x2625300,1, +0x2625318,2, +0x262532c,1, +0x2625380,1, +0x2625398,2, +0x26253ac,1, +0x2625400,4, +0x2625420,2, +0x262542c,1, +0x2625480,4, +0x26254a0,2, +0x26254ac,1, +0x2625500,4, +0x2625520,2, +0x262552c,1, +0x2625580,4, +0x26255a0,2, +0x26255ac,1, +0x2625600,4, +0x2625640,4, +0x2625680,4, +0x26256c0,4, +0x2625700,7, +0x2625720,7, +0x2625740,7, +0x2625760,7, +0x2625780,4, +0x262579c,11, +0x26257d0,2, +0x26257e0,2, +0x26257f0,2, +0x2625900,44, +0x2626000,7, +0x2626020,4, +0x2626040,4, +0x2626060,7, +0x2626080,7, +0x26260a0,4, +0x26260c0,4, +0x26260e0,7, +0x2626100,7, +0x2626120,4, +0x2626140,4, +0x2626160,7, +0x2626180,7, +0x26261a0,4, +0x26261c0,4, +0x26261e0,7, +0x2626200,32, +0x2626b00,1, +0x2626b20,1, +0x2626b28,4, +0x2626b40,1, +0x2626b60,1, +0x2626b68,4, +0x2626b80,1, +0x2626ba0,1, +0x2626ba8,4, +0x2626bc0,1, +0x2626be0,1, +0x2626be8,4, +0x2626c00,7, +0x2626c20,1, +0x2626c54,18, +0x2626ca0,1, +0x2626cd4,18, +0x2626d20,1, +0x2626d54,18, +0x2626da0,1, +0x2626dd4,12, +0x2626e08,6, +0x2627100,7, +0x2627120,7, +0x2627140,7, +0x2627160,7, +0x2627180,3, +0x2628000,10, +0x2628080,3, +0x26280c0,1, +0x2628100,21, +0x2628180,13, +0x26281c4,7, +0x26281e4,7, +0x2628204,7, +0x2628224,8, +0x2629000,7, +0x2629030,2, +0x2629040,7, +0x2629070,2, +0x2629100,2, +0x2629120,2, +0x2629140,2, +0x2629160,2, +0x2629180,9, +0x2629200,7, +0x2629230,2, +0x2629240,7, +0x2629270,2, +0x2629300,2, +0x2629320,2, +0x2629340,2, +0x2629360,2, +0x2629380,9, +0x2629400,11, +0x2629500,11, +0x262a000,3, +0x262a010,2, +0x262a01c,5, +0x262a040,8, +0x262a080,3, +0x262a090,2, +0x262a09c,5, +0x262a0c0,8, +0x262a100,3, +0x262a110,2, +0x262a11c,5, +0x262a140,8, +0x262a180,3, +0x262a190,2, +0x262a19c,5, +0x262a1c0,8, +0x262a200,7, +0x262a220,12, +0x262a280,7, +0x262a2a0,12, +0x262a300,3, +0x262a310,1, +0x262a400,3, +0x262a410,2, +0x262a41c,5, +0x262a440,8, +0x262a480,3, +0x262a490,2, +0x262a49c,5, +0x262a4c0,8, +0x262a500,3, +0x262a510,2, +0x262a51c,5, +0x262a540,8, +0x262a580,3, +0x262a590,2, +0x262a59c,5, +0x262a5c0,8, +0x262a600,7, +0x262a620,12, +0x262a680,7, +0x262a6a0,12, +0x262a700,3, +0x262a710,1, +0x262a804,1, +0x262a824,21, +0x262a880,16, +0x262a900,5, +0x262a920,11, +0x262a950,9, +0x262a980,22, +0x262aa00,22, +0x262aa80,22, +0x262ab00,22, +0x262ab80,22, +0x262ac00,22, +0x262ac80,22, +0x262ad00,22, +0x262ad80,3, +0x262c000,16, +0x262c080,11, +0x262c100,11, +0x262c204,1, +0x262c224,21, +0x262c280,16, +0x262c300,11, +0x262c340,11, +0x262c800,21, +0x262c860,5, +0x262c880,6, +0x262c8a0,5, +0x262c8c0,6, +0x262c900,21, +0x262c960,5, +0x262c980,6, +0x262c9a0,5, +0x262c9c0,6, +0x262ca00,21, +0x262ca60,5, +0x262ca80,6, +0x262caa0,5, +0x262cac0,6, +0x262cb00,21, +0x262cb60,5, +0x262cb80,6, +0x262cba0,5, +0x262cbc0,6, +0x262cc00,9, +0x262cc48,7, +0x262cc68,2, +0x262cc74,9, +0x262cc9c,2, +0x262cd00,14, +0x262cd40,14, +0x262cd80,28, +0x262ce00,19, +0x262ce50,3, +0x262ce60,25, +0x262cec8,1, +0x262ced0,2, +0x262cee0,7, +0x262cf00,1, +0x262cf08,2, +0x262cffc,20, +0x262d050,25, +0x262d100,19, +0x262d150,25, +0x262d200,19, +0x262d250,25, +0x262d300,19, +0x262d350,25, +0x262d400,19, +0x262d450,25, +0x262d500,19, +0x262d550,25, +0x262d600,19, +0x262d650,25, +0x262d700,19, +0x262d750,25, +0x262d800,19, +0x262d850,25, +0x262d904,1, +0x262d914,10, +0x262d948,11, +0x262d980,2, +0x262d9a0,6, +0x262d9c0,2, +0x262d9cc,2, +0x262e000,35, +0x262ea00,10, +0x262ea80,3, +0x262eb00,6, +0x262f000,1, +0x262f008,5, +0x262f038,1, +0x262f044,1, +0x262f050,2, +0x262f100,13, +0x262f140,11, +0x262f170,12, +0x262f1a4,1, +0x262f200,104, +0x262f400,104, +0x262f600,104, +0x262f800,104, +0x2630000,13, +0x2630040,2, +0x2630054,4, +0x2630080,27, +0x2630100,12, +0x2630140,14, +0x2630180,28, +0x2630200,6, +0x2630240,6, +0x263025c,3, +0x2630280,5, +0x26302a0,8, +0x2630400,14, +0x2630440,14, +0x2630480,14, +0x26304c0,14, +0x2630540,3, +0x2630600,7, +0x2630620,14, +0x2630680,5, +0x26306a0,7, +0x2630800,13, +0x2630840,2, +0x2630854,4, +0x2630880,27, +0x2630900,12, +0x2630940,14, +0x2630980,28, +0x2630a00,6, +0x2630a40,6, +0x2630a5c,3, +0x2630a80,5, +0x2630aa0,8, +0x2630c00,14, +0x2630c40,14, +0x2630c80,14, +0x2630cc0,14, +0x2630d40,3, +0x2630e00,7, +0x2630e20,14, +0x2630e80,5, +0x2630ea0,7, +0x2631000,13, +0x2631040,2, +0x2631054,4, +0x2631080,27, +0x2631100,12, +0x2631140,14, +0x2631180,28, +0x2631200,6, +0x2631240,6, +0x263125c,3, +0x2631280,5, +0x26312a0,8, +0x2631400,14, +0x2631440,14, +0x2631480,14, +0x26314c0,14, +0x2631540,3, +0x2631600,7, +0x2631620,14, +0x2631680,5, +0x26316a0,7, +0x2631800,13, +0x2631840,2, +0x2631854,4, +0x2631880,27, +0x2631900,12, +0x2631940,14, +0x2631980,28, +0x2631a00,6, +0x2631a40,6, +0x2631a5c,3, +0x2631a80,5, +0x2631aa0,8, +0x2631c00,14, +0x2631c40,14, +0x2631c80,14, +0x2631cc0,14, +0x2631d40,3, +0x2631e00,7, +0x2631e20,14, +0x2631e80,5, +0x2631ea0,7, +0x2632000,8, +0x2632040,8, +0x2632080,1, +0x2632098,6, +0x2632100,10, +0x2632140,3, +0x2632150,2, +0x2632180,2, +0x2632200,6, +0x2632220,18, +0x2632280,4, +0x2632300,8, +0x2632400,2, +0x2632480,2, +0x2632800,28, +0x26329f0,4, +0x2633000,40, +0x2633100,64, +0x2633800,56, +0x2633be0,8, +0x2634000,13, +0x2634040,2, +0x2634054,4, +0x2634080,27, +0x2634100,12, +0x2634140,14, +0x2634180,28, +0x2634200,6, +0x2634240,6, +0x263425c,3, +0x2634280,5, +0x26342a0,8, +0x2634400,14, +0x2634440,14, +0x2634480,14, +0x26344c0,14, +0x2634540,3, +0x2634600,7, +0x2634620,14, +0x2634680,5, +0x26346a0,7, +0x2634800,13, +0x2634840,2, +0x2634854,4, +0x2634880,27, +0x2634900,12, +0x2634940,14, +0x2634980,28, +0x2634a00,6, +0x2634a40,6, +0x2634a5c,3, +0x2634a80,5, +0x2634aa0,8, +0x2634c00,14, +0x2634c40,14, +0x2634c80,14, +0x2634cc0,14, +0x2634d40,3, +0x2634e00,7, +0x2634e20,14, +0x2634e80,5, +0x2634ea0,7, +0x2635000,13, +0x2635040,2, +0x2635054,4, +0x2635080,27, +0x2635100,12, +0x2635140,14, +0x2635180,28, +0x2635200,6, +0x2635240,6, +0x263525c,3, +0x2635280,5, +0x26352a0,8, +0x2635400,14, +0x2635440,14, +0x2635480,14, +0x26354c0,14, +0x2635540,3, +0x2635600,7, +0x2635620,14, +0x2635680,5, +0x26356a0,7, +0x2635800,13, +0x2635840,2, +0x2635854,4, +0x2635880,27, +0x2635900,12, +0x2635940,14, +0x2635980,28, +0x2635a00,6, +0x2635a40,6, +0x2635a5c,3, +0x2635a80,5, +0x2635aa0,8, +0x2635c00,14, +0x2635c40,14, +0x2635c80,14, +0x2635cc0,14, +0x2635d40,3, +0x2635e00,7, +0x2635e20,14, +0x2635e80,5, +0x2635ea0,7, +0x2636000,8, +0x2636040,8, +0x2636080,1, +0x2636098,6, +0x2636100,10, +0x2636140,3, +0x2636150,2, +0x2636180,2, +0x2636200,6, +0x2636220,18, +0x2636280,4, +0x2636300,8, +0x2636400,2, +0x2636480,2, +0x2636800,28, +0x26369f0,4, +0x2637000,40, +0x2637100,64, +0x2637800,56, +0x2637be0,8, +0x2638000,2, +0x263800c,2, +0x2638040,7, +0x2638100,3, +0x2638110,3, +0x2638120,5, +0x2638200,6, +0x2638240,5, +0x2638400,2, +0x263840c,2, +0x2638440,7, +0x2638500,3, +0x2638510,3, +0x2638520,5, +0x2638600,6, +0x2638640,5, +0x2638800,2, +0x263880c,2, +0x2638840,7, +0x2638900,3, +0x2638910,3, +0x2638920,5, +0x2638a00,6, +0x2638a40,5, +0x2638c00,2, +0x2638c0c,2, +0x2638c40,7, +0x2638d00,3, +0x2638d10,3, +0x2638d20,5, +0x2638e00,6, +0x2638e40,5, +0x2639000,2, +0x263900c,2, +0x2639040,7, +0x2639100,3, +0x2639110,3, +0x2639120,5, +0x2639200,6, +0x2639240,5, +0x2639400,2, +0x263940c,2, +0x2639440,7, +0x2639500,3, +0x2639510,3, +0x2639520,5, +0x2639600,6, +0x2639640,5, +0x2639800,2, +0x263980c,2, +0x2639840,7, +0x2639900,3, +0x2639910,3, +0x2639920,5, +0x2639a00,6, +0x2639a40,5, +0x2639c00,2, +0x2639c0c,2, +0x2639c40,7, +0x2639d00,3, +0x2639d10,3, +0x2639d20,5, +0x2639e00,6, +0x2639e40,5, +0x263a000,5, +0x263a040,9, +0x263a100,3, +0x263a200,1, +0x263a210,1, +0x263a220,1, +0x263a230,1, +0x263a240,1, +0x263a300,3, +0x263a314,1, +0x263a320,4, +0x263a400,5, +0x263a440,5, +0x263b000,80, +0x263b200,1, +0x2640004,5, +0x2640020,3, +0x2640030,3, +0x2640040,13, +0x2640078,4, +0x264009c,25, +0x2640104,5, +0x2640120,3, +0x2640130,3, +0x2640140,13, +0x2640178,4, +0x264019c,25, +0x2640204,5, +0x2640220,3, +0x2640230,3, +0x2640240,13, +0x2640278,4, +0x264029c,25, +0x2640304,5, +0x2640320,3, +0x2640330,3, +0x2640340,13, +0x2640378,4, +0x264039c,25, +0x2640600,4, +0x2640c00,24, +0x2640c80,24, +0x2640d00,24, +0x2640d80,24, +0x2640e00,4, +0x2640e20,4, +0x2640e40,4, +0x2640e60,4, +0x2640e80,39, +0x2640f20,7, +0x2640f40,7, +0x2640f60,7, +0x2641000,12, +0x2641200,1, +0x2641218,2, +0x264122c,1, +0x2641280,1, +0x2641298,2, +0x26412ac,1, +0x2641300,1, +0x2641318,2, +0x264132c,1, +0x2641380,1, +0x2641398,2, +0x26413ac,1, +0x2641400,4, +0x2641420,2, +0x264142c,1, +0x2641480,4, +0x26414a0,2, +0x26414ac,1, +0x2641500,4, +0x2641520,2, +0x264152c,1, +0x2641580,4, +0x26415a0,2, +0x26415ac,1, +0x2641600,4, +0x2641640,4, +0x2641680,4, +0x26416c0,4, +0x2641700,7, +0x2641720,7, +0x2641740,7, +0x2641760,7, +0x2641780,4, +0x264179c,11, +0x26417d0,2, +0x26417e0,2, +0x26417f0,2, +0x2641900,44, +0x2642000,7, +0x2642020,4, +0x2642040,4, +0x2642060,7, +0x2642080,7, +0x26420a0,4, +0x26420c0,4, +0x26420e0,7, +0x2642100,7, +0x2642120,4, +0x2642140,4, +0x2642160,7, +0x2642180,7, +0x26421a0,4, +0x26421c0,4, +0x26421e0,7, +0x2642200,32, +0x2642b00,1, +0x2642b20,1, +0x2642b28,4, +0x2642b40,1, +0x2642b60,1, +0x2642b68,4, +0x2642b80,1, +0x2642ba0,1, +0x2642ba8,4, +0x2642bc0,1, +0x2642be0,1, +0x2642be8,4, +0x2642c00,7, +0x2642c20,1, +0x2642c54,18, +0x2642ca0,1, +0x2642cd4,18, +0x2642d20,1, +0x2642d54,18, +0x2642da0,1, +0x2642dd4,12, +0x2642e08,6, +0x2643100,7, +0x2643120,7, +0x2643140,7, +0x2643160,7, +0x2643180,3, +0x2644004,5, +0x2644020,3, +0x2644030,3, +0x2644040,13, +0x2644078,4, +0x264409c,25, +0x2644104,5, +0x2644120,3, +0x2644130,3, +0x2644140,13, +0x2644178,4, +0x264419c,25, +0x2644204,5, +0x2644220,3, +0x2644230,3, +0x2644240,13, +0x2644278,4, +0x264429c,25, +0x2644304,5, +0x2644320,3, +0x2644330,3, +0x2644340,13, +0x2644378,4, +0x264439c,25, +0x2644600,4, +0x2644c00,24, +0x2644c80,24, +0x2644d00,24, +0x2644d80,24, +0x2644e00,4, +0x2644e20,4, +0x2644e40,4, +0x2644e60,4, +0x2644e80,39, +0x2644f20,7, +0x2644f40,7, +0x2644f60,7, +0x2645000,12, +0x2645200,1, +0x2645218,2, +0x264522c,1, +0x2645280,1, +0x2645298,2, +0x26452ac,1, +0x2645300,1, +0x2645318,2, +0x264532c,1, +0x2645380,1, +0x2645398,2, +0x26453ac,1, +0x2645400,4, +0x2645420,2, +0x264542c,1, +0x2645480,4, +0x26454a0,2, +0x26454ac,1, +0x2645500,4, +0x2645520,2, +0x264552c,1, +0x2645580,4, +0x26455a0,2, +0x26455ac,1, +0x2645600,4, +0x2645640,4, +0x2645680,4, +0x26456c0,4, +0x2645700,7, +0x2645720,7, +0x2645740,7, +0x2645760,7, +0x2645780,4, +0x264579c,11, +0x26457d0,2, +0x26457e0,2, +0x26457f0,2, +0x2645900,44, +0x2646000,7, +0x2646020,4, +0x2646040,4, +0x2646060,7, +0x2646080,7, +0x26460a0,4, +0x26460c0,4, +0x26460e0,7, +0x2646100,7, +0x2646120,4, +0x2646140,4, +0x2646160,7, +0x2646180,7, +0x26461a0,4, +0x26461c0,4, +0x26461e0,7, +0x2646200,32, +0x2646b00,1, +0x2646b20,1, +0x2646b28,4, +0x2646b40,1, +0x2646b60,1, +0x2646b68,4, +0x2646b80,1, +0x2646ba0,1, +0x2646ba8,4, +0x2646bc0,1, +0x2646be0,1, +0x2646be8,4, +0x2646c00,7, +0x2646c20,1, +0x2646c54,18, +0x2646ca0,1, +0x2646cd4,18, +0x2646d20,1, +0x2646d54,18, +0x2646da0,1, +0x2646dd4,12, +0x2646e08,6, +0x2647100,7, +0x2647120,7, +0x2647140,7, +0x2647160,7, +0x2647180,3, +0x2648000,10, +0x2648080,3, +0x26480c0,1, +0x2648100,21, +0x2648180,13, +0x26481c4,7, +0x26481e4,7, +0x2648204,7, +0x2648224,8, +0x2649000,7, +0x2649030,2, +0x2649040,7, +0x2649070,2, +0x2649100,2, +0x2649120,2, +0x2649140,2, +0x2649160,2, +0x2649180,9, +0x2649200,7, +0x2649230,2, +0x2649240,7, +0x2649270,2, +0x2649300,2, +0x2649320,2, +0x2649340,2, +0x2649360,2, +0x2649380,9, +0x2649400,11, +0x2649500,11, +0x264a000,3, +0x264a010,2, +0x264a01c,5, +0x264a040,8, +0x264a080,3, +0x264a090,2, +0x264a09c,5, +0x264a0c0,8, +0x264a100,3, +0x264a110,2, +0x264a11c,5, +0x264a140,8, +0x264a180,3, +0x264a190,2, +0x264a19c,5, +0x264a1c0,8, +0x264a200,7, +0x264a220,12, +0x264a280,7, +0x264a2a0,12, +0x264a300,3, +0x264a310,1, +0x264a400,3, +0x264a410,2, +0x264a41c,5, +0x264a440,8, +0x264a480,3, +0x264a490,2, +0x264a49c,5, +0x264a4c0,8, +0x264a500,3, +0x264a510,2, +0x264a51c,5, +0x264a540,8, +0x264a580,3, +0x264a590,2, +0x264a59c,5, +0x264a5c0,8, +0x264a600,7, +0x264a620,12, +0x264a680,7, +0x264a6a0,12, +0x264a700,3, +0x264a710,1, +0x264a804,1, +0x264a824,21, +0x264a880,16, +0x264a900,5, +0x264a920,11, +0x264a950,9, +0x264a980,22, +0x264aa00,22, +0x264aa80,22, +0x264ab00,22, +0x264ab80,22, +0x264ac00,22, +0x264ac80,22, +0x264ad00,22, +0x264ad80,3, +0x264c000,16, +0x264c080,11, +0x264c100,11, +0x264c204,1, +0x264c224,21, +0x264c280,16, +0x264c300,11, +0x264c340,11, +0x264c800,21, +0x264c860,5, +0x264c880,6, +0x264c8a0,5, +0x264c8c0,6, +0x264c900,21, +0x264c960,5, +0x264c980,6, +0x264c9a0,5, +0x264c9c0,6, +0x264ca00,21, +0x264ca60,5, +0x264ca80,6, +0x264caa0,5, +0x264cac0,6, +0x264cb00,21, +0x264cb60,5, +0x264cb80,6, +0x264cba0,5, +0x264cbc0,6, +0x264cc00,9, +0x264cc48,7, +0x264cc68,2, +0x264cc74,9, +0x264cc9c,2, +0x264cd00,14, +0x264cd40,14, +0x264cd80,28, +0x264ce00,19, +0x264ce50,3, +0x264ce60,25, +0x264cec8,1, +0x264ced0,2, +0x264cee0,7, +0x264cf00,1, +0x264cf08,2, +0x264cffc,20, +0x264d050,25, +0x264d100,19, +0x264d150,25, +0x264d200,19, +0x264d250,25, +0x264d300,19, +0x264d350,25, +0x264d400,19, +0x264d450,25, +0x264d500,19, +0x264d550,25, +0x264d600,19, +0x264d650,25, +0x264d700,19, +0x264d750,25, +0x264d800,19, +0x264d850,25, +0x264d904,1, +0x264d914,10, +0x264d948,11, +0x264d980,2, +0x264d9a0,6, +0x264d9c0,2, +0x264d9cc,2, +0x264e000,35, +0x264ea00,10, +0x264ea80,3, +0x264eb00,6, +0x264f000,1, +0x264f008,5, +0x264f038,1, +0x264f044,1, +0x264f050,2, +0x264f100,13, +0x264f140,11, +0x264f170,12, +0x264f1a4,1, +0x264f200,104, +0x264f400,104, +0x264f600,104, +0x264f800,104, +0x2650000,13, +0x2650040,2, +0x2650054,4, +0x2650080,27, +0x2650100,12, +0x2650140,14, +0x2650180,28, +0x2650200,6, +0x2650240,6, +0x265025c,3, +0x2650280,5, +0x26502a0,8, +0x2650400,14, +0x2650440,14, +0x2650480,14, +0x26504c0,14, +0x2650540,3, +0x2650600,7, +0x2650620,14, +0x2650680,5, +0x26506a0,7, +0x2650800,13, +0x2650840,2, +0x2650854,4, +0x2650880,27, +0x2650900,12, +0x2650940,14, +0x2650980,28, +0x2650a00,6, +0x2650a40,6, +0x2650a5c,3, +0x2650a80,5, +0x2650aa0,8, +0x2650c00,14, +0x2650c40,14, +0x2650c80,14, +0x2650cc0,14, +0x2650d40,3, +0x2650e00,7, +0x2650e20,14, +0x2650e80,5, +0x2650ea0,7, +0x2651000,13, +0x2651040,2, +0x2651054,4, +0x2651080,27, +0x2651100,12, +0x2651140,14, +0x2651180,28, +0x2651200,6, +0x2651240,6, +0x265125c,3, +0x2651280,5, +0x26512a0,8, +0x2651400,14, +0x2651440,14, +0x2651480,14, +0x26514c0,14, +0x2651540,3, +0x2651600,7, +0x2651620,14, +0x2651680,5, +0x26516a0,7, +0x2651800,13, +0x2651840,2, +0x2651854,4, +0x2651880,27, +0x2651900,12, +0x2651940,14, +0x2651980,28, +0x2651a00,6, +0x2651a40,6, +0x2651a5c,3, +0x2651a80,5, +0x2651aa0,8, +0x2651c00,14, +0x2651c40,14, +0x2651c80,14, +0x2651cc0,14, +0x2651d40,3, +0x2651e00,7, +0x2651e20,14, +0x2651e80,5, +0x2651ea0,7, +0x2652000,8, +0x2652040,8, +0x2652080,1, +0x2652098,6, +0x2652100,10, +0x2652140,3, +0x2652150,2, +0x2652180,2, +0x2652200,6, +0x2652220,18, +0x2652280,4, +0x2652300,8, +0x2652400,2, +0x2652480,2, +0x2652800,28, +0x26529f0,4, +0x2653000,40, +0x2653100,64, +0x2653800,56, +0x2653be0,8, +0x2654000,13, +0x2654040,2, +0x2654054,4, +0x2654080,27, +0x2654100,12, +0x2654140,14, +0x2654180,28, +0x2654200,6, +0x2654240,6, +0x265425c,3, +0x2654280,5, +0x26542a0,8, +0x2654400,14, +0x2654440,14, +0x2654480,14, +0x26544c0,14, +0x2654540,3, +0x2654600,7, +0x2654620,14, +0x2654680,5, +0x26546a0,7, +0x2654800,13, +0x2654840,2, +0x2654854,4, +0x2654880,27, +0x2654900,12, +0x2654940,14, +0x2654980,28, +0x2654a00,6, +0x2654a40,6, +0x2654a5c,3, +0x2654a80,5, +0x2654aa0,8, +0x2654c00,14, +0x2654c40,14, +0x2654c80,14, +0x2654cc0,14, +0x2654d40,3, +0x2654e00,7, +0x2654e20,14, +0x2654e80,5, +0x2654ea0,7, +0x2655000,13, +0x2655040,2, +0x2655054,4, +0x2655080,27, +0x2655100,12, +0x2655140,14, +0x2655180,28, +0x2655200,6, +0x2655240,6, +0x265525c,3, +0x2655280,5, +0x26552a0,8, +0x2655400,14, +0x2655440,14, +0x2655480,14, +0x26554c0,14, +0x2655540,3, +0x2655600,7, +0x2655620,14, +0x2655680,5, +0x26556a0,7, +0x2655800,13, +0x2655840,2, +0x2655854,4, +0x2655880,27, +0x2655900,12, +0x2655940,14, +0x2655980,28, +0x2655a00,6, +0x2655a40,6, +0x2655a5c,3, +0x2655a80,5, +0x2655aa0,8, +0x2655c00,14, +0x2655c40,14, +0x2655c80,14, +0x2655cc0,14, +0x2655d40,3, +0x2655e00,7, +0x2655e20,14, +0x2655e80,5, +0x2655ea0,7, +0x2656000,8, +0x2656040,8, +0x2656080,1, +0x2656098,6, +0x2656100,10, +0x2656140,3, +0x2656150,2, +0x2656180,2, +0x2656200,6, +0x2656220,18, +0x2656280,4, +0x2656300,8, +0x2656400,2, +0x2656480,2, +0x2656800,28, +0x26569f0,4, +0x2657000,40, +0x2657100,64, +0x2657800,56, +0x2657be0,8, +0x2658000,2, +0x265800c,2, +0x2658040,7, +0x2658100,3, +0x2658110,3, +0x2658120,5, +0x2658200,6, +0x2658240,5, +0x2658400,2, +0x265840c,2, +0x2658440,7, +0x2658500,3, +0x2658510,3, +0x2658520,5, +0x2658600,6, +0x2658640,5, +0x2658800,2, +0x265880c,2, +0x2658840,7, +0x2658900,3, +0x2658910,3, +0x2658920,5, +0x2658a00,6, +0x2658a40,5, +0x2658c00,2, +0x2658c0c,2, +0x2658c40,7, +0x2658d00,3, +0x2658d10,3, +0x2658d20,5, +0x2658e00,6, +0x2658e40,5, +0x2659000,2, +0x265900c,2, +0x2659040,7, +0x2659100,3, +0x2659110,3, +0x2659120,5, +0x2659200,6, +0x2659240,5, +0x2659400,2, +0x265940c,2, +0x2659440,7, +0x2659500,3, +0x2659510,3, +0x2659520,5, +0x2659600,6, +0x2659640,5, +0x2659800,2, +0x265980c,2, +0x2659840,7, +0x2659900,3, +0x2659910,3, +0x2659920,5, +0x2659a00,6, +0x2659a40,5, +0x2659c00,2, +0x2659c0c,2, +0x2659c40,7, +0x2659d00,3, +0x2659d10,3, +0x2659d20,5, +0x2659e00,6, +0x2659e40,5, +0x265a000,5, +0x265a040,9, +0x265a100,3, +0x265a200,1, +0x265a210,1, +0x265a220,1, +0x265a230,1, +0x265a240,1, +0x265a300,3, +0x265a314,1, +0x265a320,4, +0x265a400,5, +0x265a440,5, +0x265b000,80, +0x265b200,1, +0x2660004,5, +0x2660020,3, +0x2660030,3, +0x2660040,13, +0x2660078,4, +0x266009c,25, +0x2660104,5, +0x2660120,3, +0x2660130,3, +0x2660140,13, +0x2660178,4, +0x266019c,25, +0x2660204,5, +0x2660220,3, +0x2660230,3, +0x2660240,13, +0x2660278,4, +0x266029c,25, +0x2660304,5, +0x2660320,3, +0x2660330,3, +0x2660340,13, +0x2660378,4, +0x266039c,25, +0x2660600,4, +0x2660c00,24, +0x2660c80,24, +0x2660d00,24, +0x2660d80,24, +0x2660e00,4, +0x2660e20,4, +0x2660e40,4, +0x2660e60,4, +0x2660e80,39, +0x2660f20,7, +0x2660f40,7, +0x2660f60,7, +0x2661000,12, +0x2661200,1, +0x2661218,2, +0x266122c,1, +0x2661280,1, +0x2661298,2, +0x26612ac,1, +0x2661300,1, +0x2661318,2, +0x266132c,1, +0x2661380,1, +0x2661398,2, +0x26613ac,1, +0x2661400,4, +0x2661420,2, +0x266142c,1, +0x2661480,4, +0x26614a0,2, +0x26614ac,1, +0x2661500,4, +0x2661520,2, +0x266152c,1, +0x2661580,4, +0x26615a0,2, +0x26615ac,1, +0x2661600,4, +0x2661640,4, +0x2661680,4, +0x26616c0,4, +0x2661700,7, +0x2661720,7, +0x2661740,7, +0x2661760,7, +0x2661780,4, +0x266179c,11, +0x26617d0,2, +0x26617e0,2, +0x26617f0,2, +0x2661900,44, +0x2662000,7, +0x2662020,4, +0x2662040,4, +0x2662060,7, +0x2662080,7, +0x26620a0,4, +0x26620c0,4, +0x26620e0,7, +0x2662100,7, +0x2662120,4, +0x2662140,4, +0x2662160,7, +0x2662180,7, +0x26621a0,4, +0x26621c0,4, +0x26621e0,7, +0x2662200,32, +0x2662b00,1, +0x2662b20,1, +0x2662b28,4, +0x2662b40,1, +0x2662b60,1, +0x2662b68,4, +0x2662b80,1, +0x2662ba0,1, +0x2662ba8,4, +0x2662bc0,1, +0x2662be0,1, +0x2662be8,4, +0x2662c00,7, +0x2662c20,1, +0x2662c54,18, +0x2662ca0,1, +0x2662cd4,18, +0x2662d20,1, +0x2662d54,18, +0x2662da0,1, +0x2662dd4,12, +0x2662e08,6, +0x2663100,7, +0x2663120,7, +0x2663140,7, +0x2663160,7, +0x2663180,3, +0x2664004,5, +0x2664020,3, +0x2664030,3, +0x2664040,13, +0x2664078,4, +0x266409c,25, +0x2664104,5, +0x2664120,3, +0x2664130,3, +0x2664140,13, +0x2664178,4, +0x266419c,25, +0x2664204,5, +0x2664220,3, +0x2664230,3, +0x2664240,13, +0x2664278,4, +0x266429c,25, +0x2664304,5, +0x2664320,3, +0x2664330,3, +0x2664340,13, +0x2664378,4, +0x266439c,25, +0x2664600,4, +0x2664c00,24, +0x2664c80,24, +0x2664d00,24, +0x2664d80,24, +0x2664e00,4, +0x2664e20,4, +0x2664e40,4, +0x2664e60,4, +0x2664e80,39, +0x2664f20,7, +0x2664f40,7, +0x2664f60,7, +0x2665000,12, +0x2665200,1, +0x2665218,2, +0x266522c,1, +0x2665280,1, +0x2665298,2, +0x26652ac,1, +0x2665300,1, +0x2665318,2, +0x266532c,1, +0x2665380,1, +0x2665398,2, +0x26653ac,1, +0x2665400,4, +0x2665420,2, +0x266542c,1, +0x2665480,4, +0x26654a0,2, +0x26654ac,1, +0x2665500,4, +0x2665520,2, +0x266552c,1, +0x2665580,4, +0x26655a0,2, +0x26655ac,1, +0x2665600,4, +0x2665640,4, +0x2665680,4, +0x26656c0,4, +0x2665700,7, +0x2665720,7, +0x2665740,7, +0x2665760,7, +0x2665780,4, +0x266579c,11, +0x26657d0,2, +0x26657e0,2, +0x26657f0,2, +0x2665900,44, +0x2666000,7, +0x2666020,4, +0x2666040,4, +0x2666060,7, +0x2666080,7, +0x26660a0,4, +0x26660c0,4, +0x26660e0,7, +0x2666100,7, +0x2666120,4, +0x2666140,4, +0x2666160,7, +0x2666180,7, +0x26661a0,4, +0x26661c0,4, +0x26661e0,7, +0x2666200,32, +0x2666b00,1, +0x2666b20,1, +0x2666b28,4, +0x2666b40,1, +0x2666b60,1, +0x2666b68,4, +0x2666b80,1, +0x2666ba0,1, +0x2666ba8,4, +0x2666bc0,1, +0x2666be0,1, +0x2666be8,4, +0x2666c00,7, +0x2666c20,1, +0x2666c54,18, +0x2666ca0,1, +0x2666cd4,18, +0x2666d20,1, +0x2666d54,18, +0x2666da0,1, +0x2666dd4,12, +0x2666e08,6, +0x2667100,7, +0x2667120,7, +0x2667140,7, +0x2667160,7, +0x2667180,3, +0x2668000,10, +0x2668080,3, +0x26680c0,1, +0x2668100,21, +0x2668180,13, +0x26681c4,7, +0x26681e4,7, +0x2668204,7, +0x2668224,8, +0x2669000,7, +0x2669030,2, +0x2669040,7, +0x2669070,2, +0x2669100,2, +0x2669120,2, +0x2669140,2, +0x2669160,2, +0x2669180,9, +0x2669200,7, +0x2669230,2, +0x2669240,7, +0x2669270,2, +0x2669300,2, +0x2669320,2, +0x2669340,2, +0x2669360,2, +0x2669380,9, +0x2669400,11, +0x2669500,11, +0x266a000,3, +0x266a010,2, +0x266a01c,5, +0x266a040,8, +0x266a080,3, +0x266a090,2, +0x266a09c,5, +0x266a0c0,8, +0x266a100,3, +0x266a110,2, +0x266a11c,5, +0x266a140,8, +0x266a180,3, +0x266a190,2, +0x266a19c,5, +0x266a1c0,8, +0x266a200,7, +0x266a220,12, +0x266a280,7, +0x266a2a0,12, +0x266a300,3, +0x266a310,1, +0x266a400,3, +0x266a410,2, +0x266a41c,5, +0x266a440,8, +0x266a480,3, +0x266a490,2, +0x266a49c,5, +0x266a4c0,8, +0x266a500,3, +0x266a510,2, +0x266a51c,5, +0x266a540,8, +0x266a580,3, +0x266a590,2, +0x266a59c,5, +0x266a5c0,8, +0x266a600,7, +0x266a620,12, +0x266a680,7, +0x266a6a0,12, +0x266a700,3, +0x266a710,1, +0x266a804,1, +0x266a824,21, +0x266a880,16, +0x266a900,5, +0x266a920,11, +0x266a950,9, +0x266a980,22, +0x266aa00,22, +0x266aa80,22, +0x266ab00,22, +0x266ab80,22, +0x266ac00,22, +0x266ac80,22, +0x266ad00,22, +0x266ad80,3, +0x266c000,16, +0x266c080,11, +0x266c100,11, +0x266c204,1, +0x266c224,21, +0x266c280,16, +0x266c300,11, +0x266c340,11, +0x266c800,21, +0x266c860,5, +0x266c880,6, +0x266c8a0,5, +0x266c8c0,6, +0x266c900,21, +0x266c960,5, +0x266c980,6, +0x266c9a0,5, +0x266c9c0,6, +0x266ca00,21, +0x266ca60,5, +0x266ca80,6, +0x266caa0,5, +0x266cac0,6, +0x266cb00,21, +0x266cb60,5, +0x266cb80,6, +0x266cba0,5, +0x266cbc0,6, +0x266cc00,9, +0x266cc48,7, +0x266cc68,2, +0x266cc74,9, +0x266cc9c,2, +0x266cd00,14, +0x266cd40,14, +0x266cd80,28, +0x266ce00,19, +0x266ce50,3, +0x266ce60,25, +0x266cec8,1, +0x266ced0,2, +0x266cee0,7, +0x266cf00,1, +0x266cf08,2, +0x266cffc,20, +0x266d050,25, +0x266d100,19, +0x266d150,25, +0x266d200,19, +0x266d250,25, +0x266d300,19, +0x266d350,25, +0x266d400,19, +0x266d450,25, +0x266d500,19, +0x266d550,25, +0x266d600,19, +0x266d650,25, +0x266d700,19, +0x266d750,25, +0x266d800,19, +0x266d850,25, +0x266d904,1, +0x266d914,10, +0x266d948,11, +0x266d980,2, +0x266d9a0,6, +0x266d9c0,2, +0x266d9cc,2, +0x266e000,35, +0x266ea00,10, +0x266ea80,3, +0x266eb00,6, +0x266f000,1, +0x266f008,5, +0x266f038,1, +0x266f044,1, +0x266f050,2, +0x266f100,13, +0x266f140,11, +0x266f170,12, +0x266f1a4,1, +0x266f200,104, +0x266f400,104, +0x266f600,104, +0x266f800,104, +0x2670000,13, +0x2670040,2, +0x2670054,4, +0x2670080,27, +0x2670100,12, +0x2670140,14, +0x2670180,28, +0x2670200,6, +0x2670240,6, +0x267025c,3, +0x2670280,5, +0x26702a0,8, +0x2670400,14, +0x2670440,14, +0x2670480,14, +0x26704c0,14, +0x2670540,3, +0x2670600,7, +0x2670620,14, +0x2670680,5, +0x26706a0,7, +0x2670800,13, +0x2670840,2, +0x2670854,4, +0x2670880,27, +0x2670900,12, +0x2670940,14, +0x2670980,28, +0x2670a00,6, +0x2670a40,6, +0x2670a5c,3, +0x2670a80,5, +0x2670aa0,8, +0x2670c00,14, +0x2670c40,14, +0x2670c80,14, +0x2670cc0,14, +0x2670d40,3, +0x2670e00,7, +0x2670e20,14, +0x2670e80,5, +0x2670ea0,7, +0x2671000,13, +0x2671040,2, +0x2671054,4, +0x2671080,27, +0x2671100,12, +0x2671140,14, +0x2671180,28, +0x2671200,6, +0x2671240,6, +0x267125c,3, +0x2671280,5, +0x26712a0,8, +0x2671400,14, +0x2671440,14, +0x2671480,14, +0x26714c0,14, +0x2671540,3, +0x2671600,7, +0x2671620,14, +0x2671680,5, +0x26716a0,7, +0x2671800,13, +0x2671840,2, +0x2671854,4, +0x2671880,27, +0x2671900,12, +0x2671940,14, +0x2671980,28, +0x2671a00,6, +0x2671a40,6, +0x2671a5c,3, +0x2671a80,5, +0x2671aa0,8, +0x2671c00,14, +0x2671c40,14, +0x2671c80,14, +0x2671cc0,14, +0x2671d40,3, +0x2671e00,7, +0x2671e20,14, +0x2671e80,5, +0x2671ea0,7, +0x2672000,8, +0x2672040,8, +0x2672080,1, +0x2672098,6, +0x2672100,10, +0x2672140,3, +0x2672150,2, +0x2672180,2, +0x2672200,6, +0x2672220,18, +0x2672280,4, +0x2672300,8, +0x2672400,2, +0x2672480,2, +0x2672800,28, +0x26729f0,4, +0x2673000,40, +0x2673100,64, +0x2673800,56, +0x2673be0,8, +0x2674000,13, +0x2674040,2, +0x2674054,4, +0x2674080,27, +0x2674100,12, +0x2674140,14, +0x2674180,28, +0x2674200,6, +0x2674240,6, +0x267425c,3, +0x2674280,5, +0x26742a0,8, +0x2674400,14, +0x2674440,14, +0x2674480,14, +0x26744c0,14, +0x2674540,3, +0x2674600,7, +0x2674620,14, +0x2674680,5, +0x26746a0,7, +0x2674800,13, +0x2674840,2, +0x2674854,4, +0x2674880,27, +0x2674900,12, +0x2674940,14, +0x2674980,28, +0x2674a00,6, +0x2674a40,6, +0x2674a5c,3, +0x2674a80,5, +0x2674aa0,8, +0x2674c00,14, +0x2674c40,14, +0x2674c80,14, +0x2674cc0,14, +0x2674d40,3, +0x2674e00,7, +0x2674e20,14, +0x2674e80,5, +0x2674ea0,7, +0x2675000,13, +0x2675040,2, +0x2675054,4, +0x2675080,27, +0x2675100,12, +0x2675140,14, +0x2675180,28, +0x2675200,6, +0x2675240,6, +0x267525c,3, +0x2675280,5, +0x26752a0,8, +0x2675400,14, +0x2675440,14, +0x2675480,14, +0x26754c0,14, +0x2675540,3, +0x2675600,7, +0x2675620,14, +0x2675680,5, +0x26756a0,7, +0x2675800,13, +0x2675840,2, +0x2675854,4, +0x2675880,27, +0x2675900,12, +0x2675940,14, +0x2675980,28, +0x2675a00,6, +0x2675a40,6, +0x2675a5c,3, +0x2675a80,5, +0x2675aa0,8, +0x2675c00,14, +0x2675c40,14, +0x2675c80,14, +0x2675cc0,14, +0x2675d40,3, +0x2675e00,7, +0x2675e20,14, +0x2675e80,5, +0x2675ea0,7, +0x2676000,8, +0x2676040,8, +0x2676080,1, +0x2676098,6, +0x2676100,10, +0x2676140,3, +0x2676150,2, +0x2676180,2, +0x2676200,6, +0x2676220,18, +0x2676280,4, +0x2676300,8, +0x2676400,2, +0x2676480,2, +0x2676800,28, +0x26769f0,4, +0x2677000,40, +0x2677100,64, +0x2677800,56, +0x2677be0,8, +0x2678000,2, +0x267800c,2, +0x2678040,7, +0x2678100,3, +0x2678110,3, +0x2678120,5, +0x2678200,6, +0x2678240,5, +0x2678400,2, +0x267840c,2, +0x2678440,7, +0x2678500,3, +0x2678510,3, +0x2678520,5, +0x2678600,6, +0x2678640,5, +0x2678800,2, +0x267880c,2, +0x2678840,7, +0x2678900,3, +0x2678910,3, +0x2678920,5, +0x2678a00,6, +0x2678a40,5, +0x2678c00,2, +0x2678c0c,2, +0x2678c40,7, +0x2678d00,3, +0x2678d10,3, +0x2678d20,5, +0x2678e00,6, +0x2678e40,5, +0x2679000,2, +0x267900c,2, +0x2679040,7, +0x2679100,3, +0x2679110,3, +0x2679120,5, +0x2679200,6, +0x2679240,5, +0x2679400,2, +0x267940c,2, +0x2679440,7, +0x2679500,3, +0x2679510,3, +0x2679520,5, +0x2679600,6, +0x2679640,5, +0x2679800,2, +0x267980c,2, +0x2679840,7, +0x2679900,3, +0x2679910,3, +0x2679920,5, +0x2679a00,6, +0x2679a40,5, +0x2679c00,2, +0x2679c0c,2, +0x2679c40,7, +0x2679d00,3, +0x2679d10,3, +0x2679d20,5, +0x2679e00,6, +0x2679e40,5, +0x267a000,5, +0x267a040,9, +0x267a100,3, +0x267a200,1, +0x267a210,1, +0x267a220,1, +0x267a230,1, +0x267a240,1, +0x267a300,3, +0x267a314,1, +0x267a320,4, +0x267a400,5, +0x267a440,5, +0x267b000,80, +0x267b200,1, +0x2680000,3, +0x2680010,7, +0x2680030,10, +0x2680080,2, +0x2680100,6, +0x2680140,2, +0x2680180,2, +0x26801a0,1, +0x2680400,2, +0x2680440,4, +0x2680460,5, +0x2680478,1, +0x2680480,6, +0x26804a0,3, +0x26804b0,2, +0x2680500,5, +0x2680600,1, +0x2680800,5, +0x2680900,5, +0x2680a00,5, +0x2680b00,3, +0x2680c00,35, +0x2680d00,25, +0x2680d80,1, +0x2680dc0,3, +0x2680e00,2, +0x2680e20,2, +0x2690000,3, +0x269001c,6, +0x2690080,3, +0x2690090,2, +0x26900d4,4, +0x26900ec,27, +0x269015c,27, +0x26901cc,19, +0x2690224,120, +0x2690408,109, +0x26905f8,4, +0x2690610,27, +0x2690680,27, +0x26906f0,19, +0x2690748,120, +0x269092c,109, +0x2690b1c,4, +0x2690b34,27, +0x2690ba4,27, +0x2690c14,19, +0x2690c6c,120, +0x2690e50,109, +0x2691040,4, +0x2691058,27, +0x26910c8,27, +0x2691138,19, +0x2691190,120, +0x2691374,109, +0x2691564,4, +0x269157c,27, +0x26915ec,27, +0x269165c,19, +0x26916b4,120, +0x2691898,109, +0x2691a88,4, +0x2691aa0,27, +0x2691b10,27, +0x2691b80,19, +0x2691bd8,120, +0x2691dbc,109, +0x2691fac,4, +0x2691fc4,27, +0x2692034,27, +0x26920a4,19, +0x26920fc,120, +0x26922e0,109, +0x26924d0,4, +0x26924e8,27, +0x2692558,27, +0x26925c8,19, +0x2692620,120, +0x2692804,109, +0x26929f4,4, +0x2692a0c,27, +0x2692a7c,27, +0x2692aec,19, +0x2692b44,120, +0x2692d28,109, +0x2692f18,4, +0x2692f30,27, +0x2692fa0,27, +0x2693010,19, +0x2693068,120, +0x269324c,109, +0x269343c,4, +0x2693454,27, +0x26934c4,27, +0x2693534,19, +0x269358c,120, +0x2693770,109, +0x2693960,4, +0x2693978,27, +0x26939e8,27, +0x2693a58,19, +0x2693ab0,120, +0x2693c94,109, +0x2693e84,4, +0x2693e9c,27, +0x2693f0c,27, +0x2693f7c,19, +0x2693fd4,120, +0x26941b8,109, +0x26943a8,4, +0x26943c0,27, +0x2694430,27, +0x26944a0,19, +0x26944f8,120, +0x26946dc,109, +0x26948cc,4, +0x26948e4,27, +0x2694954,27, +0x26949c4,19, +0x2694a1c,120, +0x2694c00,109, +0x2694df0,4, +0x2694e08,27, +0x2694e78,27, +0x2694ee8,19, +0x2694f40,120, +0x2695124,109, +0x2695314,4, +0x269532c,27, +0x269539c,27, +0x269540c,19, +0x2695464,120, +0x2695648,109, +0x2695838,14, +0x2695940,13, +0x2695a44,13, +0x2695b48,16, +0x2695b90,42, +0x2695c40,2, +0x2695c90,54, +0x2695d70,58, +0x2695e60,58, +0x2695f50,58, +0x2696040,58, +0x2696130,58, +0x2696220,58, +0x2696310,58, +0x2696400,58, +0x26964f0,58, +0x26965e0,58, +0x26966d0,58, +0x26967c0,58, +0x26968b0,58, +0x26969a0,58, +0x2696a90,58, +0x2696b80,58, +0x2696c70,58, +0x2696d60,58, +0x2696e50,58, +0x2696f40,58, +0x2697030,58, +0x2697120,58, +0x2697210,58, +0x2697300,58, +0x26973f0,58, +0x26974e0,58, +0x26975d0,58, +0x26976c0,58, +0x26977b0,58, +0x26978a0,58, +0x2697990,58, +0x2697a80,101, +0x2697c90,49, +0x2697db0,18, +0x2697e00,11, +0x2697e30,4, +0x2697e54,45, +0x2697f58,9, +0x2697f88,4, +0x2697fa0,2, +0x2697fd8,14, +0x2698014,12, +0x2698158,3, +0x2698168,2, +0x2698174,68, +0x2698288,2, +0x2698294,68, +0x26983a8,1, +0x26983b0,2, +0x26983bc,68, +0x26984d0,2, +0x26984dc,68, +0x26985f0,1, +0x26985f8,4, +0x2698610,3, +0x2698624,12, +0x2698688,8, +0x26986dc,1, +0x26986e8,4, +0x2698700,3, +0x2698714,12, +0x2698778,8, +0x26987cc,1, +0x26987d8,4, +0x26987f0,3, +0x2698804,12, +0x2698868,8, +0x26988bc,1, +0x26988c8,4, +0x26988e0,3, +0x26988f4,12, +0x2698958,8, +0x26989ac,1, +0x26989b8,4, +0x26989d0,3, +0x26989e4,12, +0x2698a48,8, +0x2698a9c,1, +0x2698aa8,4, +0x2698ac0,3, +0x2698ad4,12, +0x2698b38,8, +0x2698b8c,1, +0x2698b98,4, +0x2698bb0,3, +0x2698bc4,12, +0x2698c28,8, +0x2698c7c,1, +0x2698c88,4, +0x2698ca0,3, +0x2698cb4,12, +0x2698d18,8, +0x2698d6c,1, +0x2698d78,4, +0x2698d90,3, +0x2698da4,12, +0x2698e08,8, +0x2698e5c,1, +0x2698e68,4, +0x2698e80,3, +0x2698e94,12, +0x2698ef8,8, +0x2698f4c,1, +0x2698f58,4, +0x2698f70,3, +0x2698f84,12, +0x2698fe8,8, +0x269903c,1, +0x2699048,4, +0x2699060,3, +0x2699074,12, +0x26990d8,8, +0x269912c,1, +0x2699138,4, +0x2699150,3, +0x2699164,12, +0x26991c8,8, +0x269921c,1, +0x2699228,4, +0x2699240,3, +0x2699254,12, +0x26992b8,8, +0x269930c,1, +0x2699318,4, +0x2699330,3, +0x2699344,12, +0x26993a8,8, +0x26993fc,1, +0x2699408,4, +0x2699420,3, +0x2699434,12, +0x2699498,8, +0x26994ec,1, +0x26994f8,4, +0x2699510,3, +0x2699524,12, +0x2699588,8, +0x26995dc,1, +0x26995e8,64, +0x2699748,5, +0x2699990,28, +0x2699a04,4, +0x2699a98,1, +0x2699be8,11, +0x2699c18,13, +0x2699c50,6, +0x269a000,15, +0x269a044,81, +0x269a18c,84, +0x269a2e0,84, +0x269a434,84, +0x269a588,84, +0x269a6dc,84, +0x269a830,84, +0x269a984,84, +0x269aad8,84, +0x269ac2c,84, +0x269ad80,84, +0x269aed4,84, +0x269b028,84, +0x269b17c,84, +0x269b2d0,84, +0x269b424,84, +0x269b578,84, +0x269b6cc,5, +0x269b760,4, +0x269b8e0,2414, +0x269dea4,88, +0x269e048,4, +0x269ebe0,1, +0x269ebf0,97, +0x269ed94,7, +0x269ee7c,1, +0x269eeac,9, +0x269eed4,5, +0x269eeec,11, +0x269ef2c,17, +0x269ef74,30, +0x269f034,3, +0x269f044,2, +0x269f054,17, +0x269fbe0,3, +0x269fbf0,1, +0x26a0000,3, +0x26a0018,2, +0x26a0024,14, +0x26a0060,27, +0x26a00d0,3, +0x26a00e0,3, +0x26a00f0,3, +0x26a0100,4, +0x26a0120,6, +0x26a0140,3, +0x26a0150,1, +0x26a015c,4, +0x26a0170,1, +0x26a0180,15, +0x26a01c0,1, +0x26a01c8,5, +0x26a01e0,1, +0x26a01f0,3, +0x26a0200,3, +0x26a0218,2, +0x26a0224,14, +0x26a0260,27, +0x26a02d0,3, +0x26a02e0,3, +0x26a02f0,3, +0x26a0300,4, +0x26a0320,6, +0x26a0340,3, +0x26a0350,1, +0x26a035c,4, +0x26a0370,1, +0x26a0380,15, +0x26a03c0,1, +0x26a03c8,5, +0x26a03e0,1, +0x26a03f0,3, +0x26a0400,3, +0x26a0418,2, +0x26a0424,14, +0x26a0460,27, +0x26a04d0,3, +0x26a04e0,3, +0x26a04f0,3, +0x26a0500,4, +0x26a0520,6, +0x26a0540,3, +0x26a0550,1, +0x26a055c,4, +0x26a0570,1, +0x26a0580,15, +0x26a05c0,1, +0x26a05c8,5, +0x26a05e0,1, +0x26a05f0,3, +0x26a0600,3, +0x26a0618,2, +0x26a0624,14, +0x26a0660,27, +0x26a06d0,3, +0x26a06e0,3, +0x26a06f0,3, +0x26a0700,4, +0x26a0720,6, +0x26a0740,3, +0x26a0750,1, +0x26a075c,4, +0x26a0770,1, +0x26a0780,15, +0x26a07c0,1, +0x26a07c8,5, +0x26a07e0,1, +0x26a07f0,3, +0x26a0800,3, +0x26a0818,2, +0x26a0824,14, +0x26a0860,27, +0x26a08d0,3, +0x26a08e0,3, +0x26a08f0,3, +0x26a0900,4, +0x26a0920,6, +0x26a0940,3, +0x26a0950,1, +0x26a095c,4, +0x26a0970,1, +0x26a0980,15, +0x26a09c0,1, +0x26a09c8,5, +0x26a09e0,1, +0x26a09f0,3, +0x26a1844,1, +0x26a1858,5, +0x26a1904,3, +0x26a1950,3, +0x26a1988,2, +0x26a19a0,7, +0x26a19c0,7, +0x26a19e0,4, +0x26a2000,24, +0x26a20f0,3, +0x26a2100,7, +0x26a2120,7, +0x26a2144,7, +0x26a2400,4, +0x26a2420,5, +0x26a25e0,3, +0x26a25f4,1, +0x26a25fc,4, +0x26a2620,3, +0x26a2680,8, +0x26a2700,19, +0x26a2800,99, +0x26a2a00,18, +0x26a2a80,8, +0x26a2b00,1, +0x26a3070,1, +0x26a3080,2, +0x26a308c,1, +0x26a3098,2, +0x26a3404,1, +0x26a3440,20, +0x26a3494,1, +0x26a349c,7, +0x26a34d0,4, +0x26a34e8,2, +0x26a34fc,8, +0x26a3520,7, +0x26a3540,7, +0x26a3560,7, +0x26a3580,7, +0x26a35a0,7, +0x26a35c0,7, +0x26a35e0,7, +0x26a3600,9, +0x26a363c,2, +0x26a3650,6, +0x26a3684,10, +0x26a3a00,10, +0x26a3a30,1, +0x26a3a40,8, +0x26a3a64,5, +0x26a4a04,3, +0x26a4b00,33, +0x26a4b90,3, +0x26a5000,8, +0x26a5040,8, +0x26a5104,1, +0x26a510c,3, +0x26a5124,1, +0x26a512c,3, +0x26a6000,13, +0x26a6200,14, +0x26a6240,1, +0x26a6248,1, +0x26a6258,1, +0x26a6260,8, +0x26a6284,1, +0x26a62a0,8, +0x26a6348,5, +0x26a67f0,1, +0x26a67f8,1, +0x26a6a10,12, +0x26a7000,19, +0x26a7a00,10, +0x26a7a80,3, +0x26a7b00,6, +0x26c0000,1, +0x26c000c,5, +0x26c0044,1, +0x26c0054,5, +0x26c0200,128, +0x26c0404,1, +0x26c0428,54, +0x26c0600,32, +0x26c0704,1, +0x26c0800,1, +0x26c0900,1, +0x26c0910,2, +0x26c0920,3, +0x26c0980,10, +0x26c0a00,19, +0x26c0b00,1, +0x26e0000,2, +0x26e000c,2, +0x26e0018,2, +0x26e0024,2, +0x26e0030,2, +0x26e003c,2, +0x26e0048,2, +0x26e0054,2, +0x26e0060,1, +0x26e0070,2, +0x26e007c,2, +0x26e0088,2, +0x26e0094,2, +0x26e00a0,2, +0x26e00ac,2, +0x26e00b8,2, +0x26e00c4,2, +0x26e00d0,1, +0x26e00e0,2, +0x26e00ec,2, +0x26e00f8,2, +0x26e0104,2, +0x26e0110,2, +0x26e011c,2, +0x26e0128,2, +0x26e0134,2, +0x26e0140,1, +0x26e0150,2, +0x26e015c,2, +0x26e0168,2, +0x26e0174,2, +0x26e0180,2, +0x26e018c,2, +0x26e0198,2, +0x26e01a4,2, +0x26e01b0,1, +0x26e01c0,57, +0x26e02b0,23, +0x26e0310,83, +0x26e0460,83, +0x26e05b0,83, +0x26e0700,83, +0x26e0850,83, +0x26e09a0,83, +0x26e0af0,83, +0x26e0c40,83, +0x26e0d90,83, +0x26e0ee0,83, +0x26e1030,83, +0x26e1180,83, +0x26e12d0,83, +0x26e1420,83, +0x26e1570,83, +0x26e16c0,83, +0x26e1810,83, +0x26e1960,83, +0x26e1ab0,83, +0x26e1c00,83, +0x26e1d50,83, +0x26e1ea0,83, +0x26e1ff0,83, +0x26e2140,83, +0x26e2290,83, +0x26e23e0,83, +0x26e2530,83, +0x26e2680,83, +0x26e27d0,83, +0x26e2920,83, +0x26e2a70,83, +0x26e2bc0,62, +0x26e2db4,3, +0x26e2df4,3, +0x26e2e34,3, +0x26e2e74,3, +0x26e2eb4,3, +0x26e2ef4,3, +0x26e2f34,3, +0x26e2f74,3, +0x26e2fb4,3, +0x26e2ff4,3, +0x26e3034,3, +0x26e3074,3, +0x26e30b4,3, +0x26e30f4,3, +0x26e3134,3, +0x26e3174,3, +0x26e31b4,3, +0x26f0000,4, +0x26f0014,2, +0x26f0020,8, +0x26f0044,2, +0x26f0050,13, +0x26f0088,20, +0x26f00dc,1, +0x26f0180,6, +0x26f0590,3, +0x26f05c0,2, +0x26f0a04,1, +0x26f0a0c,3, +0x26f0a20,1, +0x26f0ba0,4, +0x26f0c00,4, +0x26f0c20,3, +0x26f0c30,5, +0x26f0c50,52, +0x26f0d50,57, +0x26f0ec0,3, +0x26f0ffc,3, +0x26f1020,3, +0x26f1030,3, +0x26f1060,2, +0x26f1100,2, +0x26f1140,18, +0x26f11c0,30, +0x26f1240,14, +0x26f1280,28, +0x26f1300,2, +0x26f13a0,6, +0x26f1400,19, +0x26f1800,19, +0x26f1c00,19, +0x26f1c80,8, +0x26f1d00,3, +0x26f1d50,3, +0x26f1e00,3, +0x26f1e10,2, +0x26f1e20,6, +0x26f1e40,6, +0x26f1e60,6, +0x26f1e80,6, +0x26f1ea0,6, +0x26f1ec0,2, +0x26f1ecc,2, +0x26f1ee0,2, +0x26f1eec,2, +0x26f1f80,3, +0x26f1f90,60, +0x26f2100,32, +0x26f2200,32, +0x26f2300,32, +0x26f2400,32, +0x26f2500,32, +0x26f2600,32, +0x26f2700,32, +0x26f2800,32, +0x26f2900,32, +0x26f2a00,32, +0x26f2b00,32, +0x26f2c00,32, +0x26f2d00,32, +0x26f2e00,32, +0x26f2f00,32, +0x26f3000,32, +0x26f30c0,3, +0x26f4000,2, +0x26f4040,16, +0x26f4100,36, +0x26f4800,5, +0x26f4824,1, +0x26f482c,1, +0x26f4c04,1, +0x26f4cd8,74, +0x26f5000,7, +0x26f5020,4, +0x26f5204,1, +0x26f5280,35, +0x26f5310,4, +0x26f5404,1, +0x26f5480,34, +0x26f5510,10, +0x26f553c,3, +0x26f5800,7, +0x26f5820,4, +0x26f5a04,1, +0x26f5a80,35, +0x26f5b10,4, +0x26f5c04,1, +0x26f5c80,34, +0x26f5d10,10, +0x26f5d3c,3, +0x26fa000,5, +0x26fa01c,13, +0x26fa060,3, +0x26fa080,8, +0x26fa100,5, +0x26fa11c,13, +0x26fa160,3, +0x26fa180,8, +0x2800004,5, +0x2800020,3, +0x2800030,3, +0x2800040,13, +0x2800078,4, +0x280009c,25, +0x2800104,5, +0x2800120,3, +0x2800130,3, +0x2800140,13, +0x2800178,4, +0x280019c,25, +0x2800204,5, +0x2800220,3, +0x2800230,3, +0x2800240,13, +0x2800278,4, +0x280029c,25, +0x2800304,5, +0x2800320,3, +0x2800330,3, +0x2800340,13, +0x2800378,4, +0x280039c,25, +0x2800600,4, +0x2800c00,24, +0x2800c80,24, +0x2800d00,24, +0x2800d80,24, +0x2800e00,4, +0x2800e20,4, +0x2800e40,4, +0x2800e60,4, +0x2800e80,39, +0x2800f20,7, +0x2800f40,7, +0x2800f60,7, +0x2801000,12, +0x2801200,1, +0x2801218,2, +0x280122c,1, +0x2801280,1, +0x2801298,2, +0x28012ac,1, +0x2801300,1, +0x2801318,2, +0x280132c,1, +0x2801380,1, +0x2801398,2, +0x28013ac,1, +0x2801400,4, +0x2801420,2, +0x280142c,1, +0x2801480,4, +0x28014a0,2, +0x28014ac,1, +0x2801500,4, +0x2801520,2, +0x280152c,1, +0x2801580,4, +0x28015a0,2, +0x28015ac,1, +0x2801600,4, +0x2801640,4, +0x2801680,4, +0x28016c0,4, +0x2801700,7, +0x2801720,7, +0x2801740,7, +0x2801760,7, +0x2801780,4, +0x280179c,11, +0x28017d0,2, +0x28017e0,2, +0x28017f0,2, +0x2801900,44, +0x2802000,7, +0x2802020,4, +0x2802040,4, +0x2802060,7, +0x2802080,7, +0x28020a0,4, +0x28020c0,4, +0x28020e0,7, +0x2802100,7, +0x2802120,4, +0x2802140,4, +0x2802160,7, +0x2802180,7, +0x28021a0,4, +0x28021c0,4, +0x28021e0,7, +0x2802200,32, +0x2802b00,1, +0x2802b20,1, +0x2802b28,4, +0x2802b40,1, +0x2802b60,1, +0x2802b68,4, +0x2802b80,1, +0x2802ba0,1, +0x2802ba8,4, +0x2802bc0,1, +0x2802be0,1, +0x2802be8,4, +0x2802c00,7, +0x2802c20,1, +0x2802c54,18, +0x2802ca0,1, +0x2802cd4,18, +0x2802d20,1, +0x2802d54,18, +0x2802da0,1, +0x2802dd4,12, +0x2802e08,6, +0x2803100,7, +0x2803120,7, +0x2803140,7, +0x2803160,7, +0x2803180,3, +0x2804004,5, +0x2804020,3, +0x2804030,3, +0x2804040,13, +0x2804078,4, +0x280409c,25, +0x2804104,5, +0x2804120,3, +0x2804130,3, +0x2804140,13, +0x2804178,4, +0x280419c,25, +0x2804204,5, +0x2804220,3, +0x2804230,3, +0x2804240,13, +0x2804278,4, +0x280429c,25, +0x2804304,5, +0x2804320,3, +0x2804330,3, +0x2804340,13, +0x2804378,4, +0x280439c,25, +0x2804600,4, +0x2804c00,24, +0x2804c80,24, +0x2804d00,24, +0x2804d80,24, +0x2804e00,4, +0x2804e20,4, +0x2804e40,4, +0x2804e60,4, +0x2804e80,39, +0x2804f20,7, +0x2804f40,7, +0x2804f60,7, +0x2805000,12, +0x2805200,1, +0x2805218,2, +0x280522c,1, +0x2805280,1, +0x2805298,2, +0x28052ac,1, +0x2805300,1, +0x2805318,2, +0x280532c,1, +0x2805380,1, +0x2805398,2, +0x28053ac,1, +0x2805400,4, +0x2805420,2, +0x280542c,1, +0x2805480,4, +0x28054a0,2, +0x28054ac,1, +0x2805500,4, +0x2805520,2, +0x280552c,1, +0x2805580,4, +0x28055a0,2, +0x28055ac,1, +0x2805600,4, +0x2805640,4, +0x2805680,4, +0x28056c0,4, +0x2805700,7, +0x2805720,7, +0x2805740,7, +0x2805760,7, +0x2805780,4, +0x280579c,11, +0x28057d0,2, +0x28057e0,2, +0x28057f0,2, +0x2805900,44, +0x2806000,7, +0x2806020,4, +0x2806040,4, +0x2806060,7, +0x2806080,7, +0x28060a0,4, +0x28060c0,4, +0x28060e0,7, +0x2806100,7, +0x2806120,4, +0x2806140,4, +0x2806160,7, +0x2806180,7, +0x28061a0,4, +0x28061c0,4, +0x28061e0,7, +0x2806200,32, +0x2806b00,1, +0x2806b20,1, +0x2806b28,4, +0x2806b40,1, +0x2806b60,1, +0x2806b68,4, +0x2806b80,1, +0x2806ba0,1, +0x2806ba8,4, +0x2806bc0,1, +0x2806be0,1, +0x2806be8,4, +0x2806c00,7, +0x2806c20,1, +0x2806c54,18, +0x2806ca0,1, +0x2806cd4,18, +0x2806d20,1, +0x2806d54,18, +0x2806da0,1, +0x2806dd4,12, +0x2806e08,6, +0x2807100,7, +0x2807120,7, +0x2807140,7, +0x2807160,7, +0x2807180,3, +0x2808000,10, +0x2808080,3, +0x28080c0,1, +0x2808100,21, +0x2808180,13, +0x28081c4,7, +0x28081e4,7, +0x2808204,7, +0x2808224,8, +0x2809000,7, +0x2809030,2, +0x2809040,7, +0x2809070,2, +0x2809100,2, +0x2809120,2, +0x2809140,2, +0x2809160,2, +0x2809180,9, +0x2809200,7, +0x2809230,2, +0x2809240,7, +0x2809270,2, +0x2809300,2, +0x2809320,2, +0x2809340,2, +0x2809360,2, +0x2809380,9, +0x2809400,11, +0x2809500,11, +0x280a000,3, +0x280a010,2, +0x280a01c,5, +0x280a040,8, +0x280a080,3, +0x280a090,2, +0x280a09c,5, +0x280a0c0,8, +0x280a100,3, +0x280a110,2, +0x280a11c,5, +0x280a140,8, +0x280a180,3, +0x280a190,2, +0x280a19c,5, +0x280a1c0,8, +0x280a200,7, +0x280a220,12, +0x280a280,7, +0x280a2a0,12, +0x280a300,3, +0x280a310,1, +0x280a400,3, +0x280a410,2, +0x280a41c,5, +0x280a440,8, +0x280a480,3, +0x280a490,2, +0x280a49c,5, +0x280a4c0,8, +0x280a500,3, +0x280a510,2, +0x280a51c,5, +0x280a540,8, +0x280a580,3, +0x280a590,2, +0x280a59c,5, +0x280a5c0,8, +0x280a600,7, +0x280a620,12, +0x280a680,7, +0x280a6a0,12, +0x280a700,3, +0x280a710,1, +0x280a804,1, +0x280a824,21, +0x280a880,16, +0x280a900,5, +0x280a920,11, +0x280a950,9, +0x280a980,22, +0x280aa00,22, +0x280aa80,22, +0x280ab00,22, +0x280ab80,22, +0x280ac00,22, +0x280ac80,22, +0x280ad00,22, +0x280ad80,3, +0x280c000,16, +0x280c080,11, +0x280c100,11, +0x280c204,1, +0x280c224,21, +0x280c280,16, +0x280c300,11, +0x280c340,11, +0x280c800,21, +0x280c860,5, +0x280c880,6, +0x280c8a0,5, +0x280c8c0,6, +0x280c900,21, +0x280c960,5, +0x280c980,6, +0x280c9a0,5, +0x280c9c0,6, +0x280ca00,21, +0x280ca60,5, +0x280ca80,6, +0x280caa0,5, +0x280cac0,6, +0x280cb00,21, +0x280cb60,5, +0x280cb80,6, +0x280cba0,5, +0x280cbc0,6, +0x280cc00,9, +0x280cc48,7, +0x280cc68,2, +0x280cc74,9, +0x280cc9c,2, +0x280cd00,14, +0x280cd40,14, +0x280cd80,28, +0x280ce00,19, +0x280ce50,3, +0x280ce60,25, +0x280cec8,1, +0x280ced0,2, +0x280cee0,7, +0x280cf00,1, +0x280cf08,2, +0x280cffc,20, +0x280d050,25, +0x280d100,19, +0x280d150,25, +0x280d200,19, +0x280d250,25, +0x280d300,19, +0x280d350,25, +0x280d400,19, +0x280d450,25, +0x280d500,19, +0x280d550,25, +0x280d600,19, +0x280d650,25, +0x280d700,19, +0x280d750,25, +0x280d800,19, +0x280d850,25, +0x280d904,1, +0x280d914,10, +0x280d948,11, +0x280d980,2, +0x280d9a0,6, +0x280d9c0,2, +0x280d9cc,2, +0x280e000,35, +0x280ea00,10, +0x280ea80,3, +0x280eb00,6, +0x280f000,1, +0x280f008,5, +0x280f038,1, +0x280f044,1, +0x280f050,2, +0x280f100,13, +0x280f140,11, +0x280f170,12, +0x280f1a4,1, +0x280f200,104, +0x280f400,104, +0x280f600,104, +0x280f800,104, +0x2810000,13, +0x2810040,2, +0x2810054,4, +0x2810080,27, +0x2810100,12, +0x2810140,14, +0x2810180,28, +0x2810200,6, +0x2810240,6, +0x281025c,3, +0x2810280,5, +0x28102a0,8, +0x2810400,14, +0x2810440,14, +0x2810480,14, +0x28104c0,14, +0x2810540,3, +0x2810600,7, +0x2810620,14, +0x2810680,5, +0x28106a0,7, +0x2810800,13, +0x2810840,2, +0x2810854,4, +0x2810880,27, +0x2810900,12, +0x2810940,14, +0x2810980,28, +0x2810a00,6, +0x2810a40,6, +0x2810a5c,3, +0x2810a80,5, +0x2810aa0,8, +0x2810c00,14, +0x2810c40,14, +0x2810c80,14, +0x2810cc0,14, +0x2810d40,3, +0x2810e00,7, +0x2810e20,14, +0x2810e80,5, +0x2810ea0,7, +0x2811000,13, +0x2811040,2, +0x2811054,4, +0x2811080,27, +0x2811100,12, +0x2811140,14, +0x2811180,28, +0x2811200,6, +0x2811240,6, +0x281125c,3, +0x2811280,5, +0x28112a0,8, +0x2811400,14, +0x2811440,14, +0x2811480,14, +0x28114c0,14, +0x2811540,3, +0x2811600,7, +0x2811620,14, +0x2811680,5, +0x28116a0,7, +0x2811800,13, +0x2811840,2, +0x2811854,4, +0x2811880,27, +0x2811900,12, +0x2811940,14, +0x2811980,28, +0x2811a00,6, +0x2811a40,6, +0x2811a5c,3, +0x2811a80,5, +0x2811aa0,8, +0x2811c00,14, +0x2811c40,14, +0x2811c80,14, +0x2811cc0,14, +0x2811d40,3, +0x2811e00,7, +0x2811e20,14, +0x2811e80,5, +0x2811ea0,7, +0x2812000,8, +0x2812040,8, +0x2812080,1, +0x2812098,6, +0x2812100,10, +0x2812140,3, +0x2812150,2, +0x2812180,2, +0x2812200,6, +0x2812220,18, +0x2812280,4, +0x2812300,8, +0x2812400,2, +0x2812480,2, +0x2812800,28, +0x28129f0,4, +0x2813000,40, +0x2813100,64, +0x2813800,56, +0x2813be0,8, +0x2814000,13, +0x2814040,2, +0x2814054,4, +0x2814080,27, +0x2814100,12, +0x2814140,14, +0x2814180,28, +0x2814200,6, +0x2814240,6, +0x281425c,3, +0x2814280,5, +0x28142a0,8, +0x2814400,14, +0x2814440,14, +0x2814480,14, +0x28144c0,14, +0x2814540,3, +0x2814600,7, +0x2814620,14, +0x2814680,5, +0x28146a0,7, +0x2814800,13, +0x2814840,2, +0x2814854,4, +0x2814880,27, +0x2814900,12, +0x2814940,14, +0x2814980,28, +0x2814a00,6, +0x2814a40,6, +0x2814a5c,3, +0x2814a80,5, +0x2814aa0,8, +0x2814c00,14, +0x2814c40,14, +0x2814c80,14, +0x2814cc0,14, +0x2814d40,3, +0x2814e00,7, +0x2814e20,14, +0x2814e80,5, +0x2814ea0,7, +0x2815000,13, +0x2815040,2, +0x2815054,4, +0x2815080,27, +0x2815100,12, +0x2815140,14, +0x2815180,28, +0x2815200,6, +0x2815240,6, +0x281525c,3, +0x2815280,5, +0x28152a0,8, +0x2815400,14, +0x2815440,14, +0x2815480,14, +0x28154c0,14, +0x2815540,3, +0x2815600,7, +0x2815620,14, +0x2815680,5, +0x28156a0,7, +0x2815800,13, +0x2815840,2, +0x2815854,4, +0x2815880,27, +0x2815900,12, +0x2815940,14, +0x2815980,28, +0x2815a00,6, +0x2815a40,6, +0x2815a5c,3, +0x2815a80,5, +0x2815aa0,8, +0x2815c00,14, +0x2815c40,14, +0x2815c80,14, +0x2815cc0,14, +0x2815d40,3, +0x2815e00,7, +0x2815e20,14, +0x2815e80,5, +0x2815ea0,7, +0x2816000,8, +0x2816040,8, +0x2816080,1, +0x2816098,6, +0x2816100,10, +0x2816140,3, +0x2816150,2, +0x2816180,2, +0x2816200,6, +0x2816220,18, +0x2816280,4, +0x2816300,8, +0x2816400,2, +0x2816480,2, +0x2816800,28, +0x28169f0,4, +0x2817000,40, +0x2817100,64, +0x2817800,56, +0x2817be0,8, +0x2818000,2, +0x281800c,2, +0x2818040,7, +0x2818100,3, +0x2818110,3, +0x2818120,5, +0x2818200,6, +0x2818240,5, +0x2818400,2, +0x281840c,2, +0x2818440,7, +0x2818500,3, +0x2818510,3, +0x2818520,5, +0x2818600,6, +0x2818640,5, +0x2818800,2, +0x281880c,2, +0x2818840,7, +0x2818900,3, +0x2818910,3, +0x2818920,5, +0x2818a00,6, +0x2818a40,5, +0x2818c00,2, +0x2818c0c,2, +0x2818c40,7, +0x2818d00,3, +0x2818d10,3, +0x2818d20,5, +0x2818e00,6, +0x2818e40,5, +0x2819000,2, +0x281900c,2, +0x2819040,7, +0x2819100,3, +0x2819110,3, +0x2819120,5, +0x2819200,6, +0x2819240,5, +0x2819400,2, +0x281940c,2, +0x2819440,7, +0x2819500,3, +0x2819510,3, +0x2819520,5, +0x2819600,6, +0x2819640,5, +0x2819800,2, +0x281980c,2, +0x2819840,7, +0x2819900,3, +0x2819910,3, +0x2819920,5, +0x2819a00,6, +0x2819a40,5, +0x2819c00,2, +0x2819c0c,2, +0x2819c40,7, +0x2819d00,3, +0x2819d10,3, +0x2819d20,5, +0x2819e00,6, +0x2819e40,5, +0x281a000,5, +0x281a040,9, +0x281a100,3, +0x281a200,1, +0x281a210,1, +0x281a220,1, +0x281a230,1, +0x281a240,1, +0x281a300,3, +0x281a314,1, +0x281a320,4, +0x281a400,5, +0x281a440,5, +0x281b000,80, +0x281b200,1, +0x2820004,5, +0x2820020,3, +0x2820030,3, +0x2820040,13, +0x2820078,4, +0x282009c,25, +0x2820104,5, +0x2820120,3, +0x2820130,3, +0x2820140,13, +0x2820178,4, +0x282019c,25, +0x2820204,5, +0x2820220,3, +0x2820230,3, +0x2820240,13, +0x2820278,4, +0x282029c,25, +0x2820304,5, +0x2820320,3, +0x2820330,3, +0x2820340,13, +0x2820378,4, +0x282039c,25, +0x2820600,4, +0x2820c00,24, +0x2820c80,24, +0x2820d00,24, +0x2820d80,24, +0x2820e00,4, +0x2820e20,4, +0x2820e40,4, +0x2820e60,4, +0x2820e80,39, +0x2820f20,7, +0x2820f40,7, +0x2820f60,7, +0x2821000,12, +0x2821200,1, +0x2821218,2, +0x282122c,1, +0x2821280,1, +0x2821298,2, +0x28212ac,1, +0x2821300,1, +0x2821318,2, +0x282132c,1, +0x2821380,1, +0x2821398,2, +0x28213ac,1, +0x2821400,4, +0x2821420,2, +0x282142c,1, +0x2821480,4, +0x28214a0,2, +0x28214ac,1, +0x2821500,4, +0x2821520,2, +0x282152c,1, +0x2821580,4, +0x28215a0,2, +0x28215ac,1, +0x2821600,4, +0x2821640,4, +0x2821680,4, +0x28216c0,4, +0x2821700,7, +0x2821720,7, +0x2821740,7, +0x2821760,7, +0x2821780,4, +0x282179c,11, +0x28217d0,2, +0x28217e0,2, +0x28217f0,2, +0x2821900,44, +0x2822000,7, +0x2822020,4, +0x2822040,4, +0x2822060,7, +0x2822080,7, +0x28220a0,4, +0x28220c0,4, +0x28220e0,7, +0x2822100,7, +0x2822120,4, +0x2822140,4, +0x2822160,7, +0x2822180,7, +0x28221a0,4, +0x28221c0,4, +0x28221e0,7, +0x2822200,32, +0x2822b00,1, +0x2822b20,1, +0x2822b28,4, +0x2822b40,1, +0x2822b60,1, +0x2822b68,4, +0x2822b80,1, +0x2822ba0,1, +0x2822ba8,4, +0x2822bc0,1, +0x2822be0,1, +0x2822be8,4, +0x2822c00,7, +0x2822c20,1, +0x2822c54,18, +0x2822ca0,1, +0x2822cd4,18, +0x2822d20,1, +0x2822d54,18, +0x2822da0,1, +0x2822dd4,12, +0x2822e08,6, +0x2823100,7, +0x2823120,7, +0x2823140,7, +0x2823160,7, +0x2823180,3, +0x2824004,5, +0x2824020,3, +0x2824030,3, +0x2824040,13, +0x2824078,4, +0x282409c,25, +0x2824104,5, +0x2824120,3, +0x2824130,3, +0x2824140,13, +0x2824178,4, +0x282419c,25, +0x2824204,5, +0x2824220,3, +0x2824230,3, +0x2824240,13, +0x2824278,4, +0x282429c,25, +0x2824304,5, +0x2824320,3, +0x2824330,3, +0x2824340,13, +0x2824378,4, +0x282439c,25, +0x2824600,4, +0x2824c00,24, +0x2824c80,24, +0x2824d00,24, +0x2824d80,24, +0x2824e00,4, +0x2824e20,4, +0x2824e40,4, +0x2824e60,4, +0x2824e80,39, +0x2824f20,7, +0x2824f40,7, +0x2824f60,7, +0x2825000,12, +0x2825200,1, +0x2825218,2, +0x282522c,1, +0x2825280,1, +0x2825298,2, +0x28252ac,1, +0x2825300,1, +0x2825318,2, +0x282532c,1, +0x2825380,1, +0x2825398,2, +0x28253ac,1, +0x2825400,4, +0x2825420,2, +0x282542c,1, +0x2825480,4, +0x28254a0,2, +0x28254ac,1, +0x2825500,4, +0x2825520,2, +0x282552c,1, +0x2825580,4, +0x28255a0,2, +0x28255ac,1, +0x2825600,4, +0x2825640,4, +0x2825680,4, +0x28256c0,4, +0x2825700,7, +0x2825720,7, +0x2825740,7, +0x2825760,7, +0x2825780,4, +0x282579c,11, +0x28257d0,2, +0x28257e0,2, +0x28257f0,2, +0x2825900,44, +0x2826000,7, +0x2826020,4, +0x2826040,4, +0x2826060,7, +0x2826080,7, +0x28260a0,4, +0x28260c0,4, +0x28260e0,7, +0x2826100,7, +0x2826120,4, +0x2826140,4, +0x2826160,7, +0x2826180,7, +0x28261a0,4, +0x28261c0,4, +0x28261e0,7, +0x2826200,32, +0x2826b00,1, +0x2826b20,1, +0x2826b28,4, +0x2826b40,1, +0x2826b60,1, +0x2826b68,4, +0x2826b80,1, +0x2826ba0,1, +0x2826ba8,4, +0x2826bc0,1, +0x2826be0,1, +0x2826be8,4, +0x2826c00,7, +0x2826c20,1, +0x2826c54,18, +0x2826ca0,1, +0x2826cd4,18, +0x2826d20,1, +0x2826d54,18, +0x2826da0,1, +0x2826dd4,12, +0x2826e08,6, +0x2827100,7, +0x2827120,7, +0x2827140,7, +0x2827160,7, +0x2827180,3, +0x2828000,10, +0x2828080,3, +0x28280c0,1, +0x2828100,21, +0x2828180,13, +0x28281c4,7, +0x28281e4,7, +0x2828204,7, +0x2828224,8, +0x2829000,7, +0x2829030,2, +0x2829040,7, +0x2829070,2, +0x2829100,2, +0x2829120,2, +0x2829140,2, +0x2829160,2, +0x2829180,9, +0x2829200,7, +0x2829230,2, +0x2829240,7, +0x2829270,2, +0x2829300,2, +0x2829320,2, +0x2829340,2, +0x2829360,2, +0x2829380,9, +0x2829400,11, +0x2829500,11, +0x282a000,3, +0x282a010,2, +0x282a01c,5, +0x282a040,8, +0x282a080,3, +0x282a090,2, +0x282a09c,5, +0x282a0c0,8, +0x282a100,3, +0x282a110,2, +0x282a11c,5, +0x282a140,8, +0x282a180,3, +0x282a190,2, +0x282a19c,5, +0x282a1c0,8, +0x282a200,7, +0x282a220,12, +0x282a280,7, +0x282a2a0,12, +0x282a300,3, +0x282a310,1, +0x282a400,3, +0x282a410,2, +0x282a41c,5, +0x282a440,8, +0x282a480,3, +0x282a490,2, +0x282a49c,5, +0x282a4c0,8, +0x282a500,3, +0x282a510,2, +0x282a51c,5, +0x282a540,8, +0x282a580,3, +0x282a590,2, +0x282a59c,5, +0x282a5c0,8, +0x282a600,7, +0x282a620,12, +0x282a680,7, +0x282a6a0,12, +0x282a700,3, +0x282a710,1, +0x282a804,1, +0x282a824,21, +0x282a880,16, +0x282a900,5, +0x282a920,11, +0x282a950,9, +0x282a980,22, +0x282aa00,22, +0x282aa80,22, +0x282ab00,22, +0x282ab80,22, +0x282ac00,22, +0x282ac80,22, +0x282ad00,22, +0x282ad80,3, +0x282c000,16, +0x282c080,11, +0x282c100,11, +0x282c204,1, +0x282c224,21, +0x282c280,16, +0x282c300,11, +0x282c340,11, +0x282c800,21, +0x282c860,5, +0x282c880,6, +0x282c8a0,5, +0x282c8c0,6, +0x282c900,21, +0x282c960,5, +0x282c980,6, +0x282c9a0,5, +0x282c9c0,6, +0x282ca00,21, +0x282ca60,5, +0x282ca80,6, +0x282caa0,5, +0x282cac0,6, +0x282cb00,21, +0x282cb60,5, +0x282cb80,6, +0x282cba0,5, +0x282cbc0,6, +0x282cc00,9, +0x282cc48,7, +0x282cc68,2, +0x282cc74,9, +0x282cc9c,2, +0x282cd00,14, +0x282cd40,14, +0x282cd80,28, +0x282ce00,19, +0x282ce50,3, +0x282ce60,25, +0x282cec8,1, +0x282ced0,2, +0x282cee0,7, +0x282cf00,1, +0x282cf08,2, +0x282cffc,20, +0x282d050,25, +0x282d100,19, +0x282d150,25, +0x282d200,19, +0x282d250,25, +0x282d300,19, +0x282d350,25, +0x282d400,19, +0x282d450,25, +0x282d500,19, +0x282d550,25, +0x282d600,19, +0x282d650,25, +0x282d700,19, +0x282d750,25, +0x282d800,19, +0x282d850,25, +0x282d904,1, +0x282d914,10, +0x282d948,11, +0x282d980,2, +0x282d9a0,6, +0x282d9c0,2, +0x282d9cc,2, +0x282e000,35, +0x282ea00,10, +0x282ea80,3, +0x282eb00,6, +0x282f000,1, +0x282f008,5, +0x282f038,1, +0x282f044,1, +0x282f050,2, +0x282f100,13, +0x282f140,11, +0x282f170,12, +0x282f1a4,1, +0x282f200,104, +0x282f400,104, +0x282f600,104, +0x282f800,104, +0x2830000,13, +0x2830040,2, +0x2830054,4, +0x2830080,27, +0x2830100,12, +0x2830140,14, +0x2830180,28, +0x2830200,6, +0x2830240,6, +0x283025c,3, +0x2830280,5, +0x28302a0,8, +0x2830400,14, +0x2830440,14, +0x2830480,14, +0x28304c0,14, +0x2830540,3, +0x2830600,7, +0x2830620,14, +0x2830680,5, +0x28306a0,7, +0x2830800,13, +0x2830840,2, +0x2830854,4, +0x2830880,27, +0x2830900,12, +0x2830940,14, +0x2830980,28, +0x2830a00,6, +0x2830a40,6, +0x2830a5c,3, +0x2830a80,5, +0x2830aa0,8, +0x2830c00,14, +0x2830c40,14, +0x2830c80,14, +0x2830cc0,14, +0x2830d40,3, +0x2830e00,7, +0x2830e20,14, +0x2830e80,5, +0x2830ea0,7, +0x2831000,13, +0x2831040,2, +0x2831054,4, +0x2831080,27, +0x2831100,12, +0x2831140,14, +0x2831180,28, +0x2831200,6, +0x2831240,6, +0x283125c,3, +0x2831280,5, +0x28312a0,8, +0x2831400,14, +0x2831440,14, +0x2831480,14, +0x28314c0,14, +0x2831540,3, +0x2831600,7, +0x2831620,14, +0x2831680,5, +0x28316a0,7, +0x2831800,13, +0x2831840,2, +0x2831854,4, +0x2831880,27, +0x2831900,12, +0x2831940,14, +0x2831980,28, +0x2831a00,6, +0x2831a40,6, +0x2831a5c,3, +0x2831a80,5, +0x2831aa0,8, +0x2831c00,14, +0x2831c40,14, +0x2831c80,14, +0x2831cc0,14, +0x2831d40,3, +0x2831e00,7, +0x2831e20,14, +0x2831e80,5, +0x2831ea0,7, +0x2832000,8, +0x2832040,8, +0x2832080,1, +0x2832098,6, +0x2832100,10, +0x2832140,3, +0x2832150,2, +0x2832180,2, +0x2832200,6, +0x2832220,18, +0x2832280,4, +0x2832300,8, +0x2832400,2, +0x2832480,2, +0x2832800,28, +0x28329f0,4, +0x2833000,40, +0x2833100,64, +0x2833800,56, +0x2833be0,8, +0x2834000,13, +0x2834040,2, +0x2834054,4, +0x2834080,27, +0x2834100,12, +0x2834140,14, +0x2834180,28, +0x2834200,6, +0x2834240,6, +0x283425c,3, +0x2834280,5, +0x28342a0,8, +0x2834400,14, +0x2834440,14, +0x2834480,14, +0x28344c0,14, +0x2834540,3, +0x2834600,7, +0x2834620,14, +0x2834680,5, +0x28346a0,7, +0x2834800,13, +0x2834840,2, +0x2834854,4, +0x2834880,27, +0x2834900,12, +0x2834940,14, +0x2834980,28, +0x2834a00,6, +0x2834a40,6, +0x2834a5c,3, +0x2834a80,5, +0x2834aa0,8, +0x2834c00,14, +0x2834c40,14, +0x2834c80,14, +0x2834cc0,14, +0x2834d40,3, +0x2834e00,7, +0x2834e20,14, +0x2834e80,5, +0x2834ea0,7, +0x2835000,13, +0x2835040,2, +0x2835054,4, +0x2835080,27, +0x2835100,12, +0x2835140,14, +0x2835180,28, +0x2835200,6, +0x2835240,6, +0x283525c,3, +0x2835280,5, +0x28352a0,8, +0x2835400,14, +0x2835440,14, +0x2835480,14, +0x28354c0,14, +0x2835540,3, +0x2835600,7, +0x2835620,14, +0x2835680,5, +0x28356a0,7, +0x2835800,13, +0x2835840,2, +0x2835854,4, +0x2835880,27, +0x2835900,12, +0x2835940,14, +0x2835980,28, +0x2835a00,6, +0x2835a40,6, +0x2835a5c,3, +0x2835a80,5, +0x2835aa0,8, +0x2835c00,14, +0x2835c40,14, +0x2835c80,14, +0x2835cc0,14, +0x2835d40,3, +0x2835e00,7, +0x2835e20,14, +0x2835e80,5, +0x2835ea0,7, +0x2836000,8, +0x2836040,8, +0x2836080,1, +0x2836098,6, +0x2836100,10, +0x2836140,3, +0x2836150,2, +0x2836180,2, +0x2836200,6, +0x2836220,18, +0x2836280,4, +0x2836300,8, +0x2836400,2, +0x2836480,2, +0x2836800,28, +0x28369f0,4, +0x2837000,40, +0x2837100,64, +0x2837800,56, +0x2837be0,8, +0x2838000,2, +0x283800c,2, +0x2838040,7, +0x2838100,3, +0x2838110,3, +0x2838120,5, +0x2838200,6, +0x2838240,5, +0x2838400,2, +0x283840c,2, +0x2838440,7, +0x2838500,3, +0x2838510,3, +0x2838520,5, +0x2838600,6, +0x2838640,5, +0x2838800,2, +0x283880c,2, +0x2838840,7, +0x2838900,3, +0x2838910,3, +0x2838920,5, +0x2838a00,6, +0x2838a40,5, +0x2838c00,2, +0x2838c0c,2, +0x2838c40,7, +0x2838d00,3, +0x2838d10,3, +0x2838d20,5, +0x2838e00,6, +0x2838e40,5, +0x2839000,2, +0x283900c,2, +0x2839040,7, +0x2839100,3, +0x2839110,3, +0x2839120,5, +0x2839200,6, +0x2839240,5, +0x2839400,2, +0x283940c,2, +0x2839440,7, +0x2839500,3, +0x2839510,3, +0x2839520,5, +0x2839600,6, +0x2839640,5, +0x2839800,2, +0x283980c,2, +0x2839840,7, +0x2839900,3, +0x2839910,3, +0x2839920,5, +0x2839a00,6, +0x2839a40,5, +0x2839c00,2, +0x2839c0c,2, +0x2839c40,7, +0x2839d00,3, +0x2839d10,3, +0x2839d20,5, +0x2839e00,6, +0x2839e40,5, +0x283a000,5, +0x283a040,9, +0x283a100,3, +0x283a200,1, +0x283a210,1, +0x283a220,1, +0x283a230,1, +0x283a240,1, +0x283a300,3, +0x283a314,1, +0x283a320,4, +0x283a400,5, +0x283a440,5, +0x283b000,80, +0x283b200,1, +0x2840004,5, +0x2840020,3, +0x2840030,3, +0x2840040,13, +0x2840078,4, +0x284009c,25, +0x2840104,5, +0x2840120,3, +0x2840130,3, +0x2840140,13, +0x2840178,4, +0x284019c,25, +0x2840204,5, +0x2840220,3, +0x2840230,3, +0x2840240,13, +0x2840278,4, +0x284029c,25, +0x2840304,5, +0x2840320,3, +0x2840330,3, +0x2840340,13, +0x2840378,4, +0x284039c,25, +0x2840600,4, +0x2840c00,24, +0x2840c80,24, +0x2840d00,24, +0x2840d80,24, +0x2840e00,4, +0x2840e20,4, +0x2840e40,4, +0x2840e60,4, +0x2840e80,39, +0x2840f20,7, +0x2840f40,7, +0x2840f60,7, +0x2841000,12, +0x2841200,1, +0x2841218,2, +0x284122c,1, +0x2841280,1, +0x2841298,2, +0x28412ac,1, +0x2841300,1, +0x2841318,2, +0x284132c,1, +0x2841380,1, +0x2841398,2, +0x28413ac,1, +0x2841400,4, +0x2841420,2, +0x284142c,1, +0x2841480,4, +0x28414a0,2, +0x28414ac,1, +0x2841500,4, +0x2841520,2, +0x284152c,1, +0x2841580,4, +0x28415a0,2, +0x28415ac,1, +0x2841600,4, +0x2841640,4, +0x2841680,4, +0x28416c0,4, +0x2841700,7, +0x2841720,7, +0x2841740,7, +0x2841760,7, +0x2841780,4, +0x284179c,11, +0x28417d0,2, +0x28417e0,2, +0x28417f0,2, +0x2841900,44, +0x2842000,7, +0x2842020,4, +0x2842040,4, +0x2842060,7, +0x2842080,7, +0x28420a0,4, +0x28420c0,4, +0x28420e0,7, +0x2842100,7, +0x2842120,4, +0x2842140,4, +0x2842160,7, +0x2842180,7, +0x28421a0,4, +0x28421c0,4, +0x28421e0,7, +0x2842200,32, +0x2842b00,1, +0x2842b20,1, +0x2842b28,4, +0x2842b40,1, +0x2842b60,1, +0x2842b68,4, +0x2842b80,1, +0x2842ba0,1, +0x2842ba8,4, +0x2842bc0,1, +0x2842be0,1, +0x2842be8,4, +0x2842c00,7, +0x2842c20,1, +0x2842c54,18, +0x2842ca0,1, +0x2842cd4,18, +0x2842d20,1, +0x2842d54,18, +0x2842da0,1, +0x2842dd4,12, +0x2842e08,6, +0x2843100,7, +0x2843120,7, +0x2843140,7, +0x2843160,7, +0x2843180,3, +0x2844004,5, +0x2844020,3, +0x2844030,3, +0x2844040,13, +0x2844078,4, +0x284409c,25, +0x2844104,5, +0x2844120,3, +0x2844130,3, +0x2844140,13, +0x2844178,4, +0x284419c,25, +0x2844204,5, +0x2844220,3, +0x2844230,3, +0x2844240,13, +0x2844278,4, +0x284429c,25, +0x2844304,5, +0x2844320,3, +0x2844330,3, +0x2844340,13, +0x2844378,4, +0x284439c,25, +0x2844600,4, +0x2844c00,24, +0x2844c80,24, +0x2844d00,24, +0x2844d80,24, +0x2844e00,4, +0x2844e20,4, +0x2844e40,4, +0x2844e60,4, +0x2844e80,39, +0x2844f20,7, +0x2844f40,7, +0x2844f60,7, +0x2845000,12, +0x2845200,1, +0x2845218,2, +0x284522c,1, +0x2845280,1, +0x2845298,2, +0x28452ac,1, +0x2845300,1, +0x2845318,2, +0x284532c,1, +0x2845380,1, +0x2845398,2, +0x28453ac,1, +0x2845400,4, +0x2845420,2, +0x284542c,1, +0x2845480,4, +0x28454a0,2, +0x28454ac,1, +0x2845500,4, +0x2845520,2, +0x284552c,1, +0x2845580,4, +0x28455a0,2, +0x28455ac,1, +0x2845600,4, +0x2845640,4, +0x2845680,4, +0x28456c0,4, +0x2845700,7, +0x2845720,7, +0x2845740,7, +0x2845760,7, +0x2845780,4, +0x284579c,11, +0x28457d0,2, +0x28457e0,2, +0x28457f0,2, +0x2845900,44, +0x2846000,7, +0x2846020,4, +0x2846040,4, +0x2846060,7, +0x2846080,7, +0x28460a0,4, +0x28460c0,4, +0x28460e0,7, +0x2846100,7, +0x2846120,4, +0x2846140,4, +0x2846160,7, +0x2846180,7, +0x28461a0,4, +0x28461c0,4, +0x28461e0,7, +0x2846200,32, +0x2846b00,1, +0x2846b20,1, +0x2846b28,4, +0x2846b40,1, +0x2846b60,1, +0x2846b68,4, +0x2846b80,1, +0x2846ba0,1, +0x2846ba8,4, +0x2846bc0,1, +0x2846be0,1, +0x2846be8,4, +0x2846c00,7, +0x2846c20,1, +0x2846c54,18, +0x2846ca0,1, +0x2846cd4,18, +0x2846d20,1, +0x2846d54,18, +0x2846da0,1, +0x2846dd4,12, +0x2846e08,6, +0x2847100,7, +0x2847120,7, +0x2847140,7, +0x2847160,7, +0x2847180,3, +0x2848000,10, +0x2848080,3, +0x28480c0,1, +0x2848100,21, +0x2848180,13, +0x28481c4,7, +0x28481e4,7, +0x2848204,7, +0x2848224,8, +0x2849000,7, +0x2849030,2, +0x2849040,7, +0x2849070,2, +0x2849100,2, +0x2849120,2, +0x2849140,2, +0x2849160,2, +0x2849180,9, +0x2849200,7, +0x2849230,2, +0x2849240,7, +0x2849270,2, +0x2849300,2, +0x2849320,2, +0x2849340,2, +0x2849360,2, +0x2849380,9, +0x2849400,11, +0x2849500,11, +0x284a000,3, +0x284a010,2, +0x284a01c,5, +0x284a040,8, +0x284a080,3, +0x284a090,2, +0x284a09c,5, +0x284a0c0,8, +0x284a100,3, +0x284a110,2, +0x284a11c,5, +0x284a140,8, +0x284a180,3, +0x284a190,2, +0x284a19c,5, +0x284a1c0,8, +0x284a200,7, +0x284a220,12, +0x284a280,7, +0x284a2a0,12, +0x284a300,3, +0x284a310,1, +0x284a400,3, +0x284a410,2, +0x284a41c,5, +0x284a440,8, +0x284a480,3, +0x284a490,2, +0x284a49c,5, +0x284a4c0,8, +0x284a500,3, +0x284a510,2, +0x284a51c,5, +0x284a540,8, +0x284a580,3, +0x284a590,2, +0x284a59c,5, +0x284a5c0,8, +0x284a600,7, +0x284a620,12, +0x284a680,7, +0x284a6a0,12, +0x284a700,3, +0x284a710,1, +0x284a804,1, +0x284a824,21, +0x284a880,16, +0x284a900,5, +0x284a920,11, +0x284a950,9, +0x284a980,22, +0x284aa00,22, +0x284aa80,22, +0x284ab00,22, +0x284ab80,22, +0x284ac00,22, +0x284ac80,22, +0x284ad00,22, +0x284ad80,3, +0x284c000,16, +0x284c080,11, +0x284c100,11, +0x284c204,1, +0x284c224,21, +0x284c280,16, +0x284c300,11, +0x284c340,11, +0x284c800,21, +0x284c860,5, +0x284c880,6, +0x284c8a0,5, +0x284c8c0,6, +0x284c900,21, +0x284c960,5, +0x284c980,6, +0x284c9a0,5, +0x284c9c0,6, +0x284ca00,21, +0x284ca60,5, +0x284ca80,6, +0x284caa0,5, +0x284cac0,6, +0x284cb00,21, +0x284cb60,5, +0x284cb80,6, +0x284cba0,5, +0x284cbc0,6, +0x284cc00,9, +0x284cc48,7, +0x284cc68,2, +0x284cc74,9, +0x284cc9c,2, +0x284cd00,14, +0x284cd40,14, +0x284cd80,28, +0x284ce00,19, +0x284ce50,3, +0x284ce60,25, +0x284cec8,1, +0x284ced0,2, +0x284cee0,7, +0x284cf00,1, +0x284cf08,2, +0x284cffc,20, +0x284d050,25, +0x284d100,19, +0x284d150,25, +0x284d200,19, +0x284d250,25, +0x284d300,19, +0x284d350,25, +0x284d400,19, +0x284d450,25, +0x284d500,19, +0x284d550,25, +0x284d600,19, +0x284d650,25, +0x284d700,19, +0x284d750,25, +0x284d800,19, +0x284d850,25, +0x284d904,1, +0x284d914,10, +0x284d948,11, +0x284d980,2, +0x284d9a0,6, +0x284d9c0,2, +0x284d9cc,2, +0x284e000,35, +0x284ea00,10, +0x284ea80,3, +0x284eb00,6, +0x284f000,1, +0x284f008,5, +0x284f038,1, +0x284f044,1, +0x284f050,2, +0x284f100,13, +0x284f140,11, +0x284f170,12, +0x284f1a4,1, +0x284f200,104, +0x284f400,104, +0x284f600,104, +0x284f800,104, +0x2850000,13, +0x2850040,2, +0x2850054,4, +0x2850080,27, +0x2850100,12, +0x2850140,14, +0x2850180,28, +0x2850200,6, +0x2850240,6, +0x285025c,3, +0x2850280,5, +0x28502a0,8, +0x2850400,14, +0x2850440,14, +0x2850480,14, +0x28504c0,14, +0x2850540,3, +0x2850600,7, +0x2850620,14, +0x2850680,5, +0x28506a0,7, +0x2850800,13, +0x2850840,2, +0x2850854,4, +0x2850880,27, +0x2850900,12, +0x2850940,14, +0x2850980,28, +0x2850a00,6, +0x2850a40,6, +0x2850a5c,3, +0x2850a80,5, +0x2850aa0,8, +0x2850c00,14, +0x2850c40,14, +0x2850c80,14, +0x2850cc0,14, +0x2850d40,3, +0x2850e00,7, +0x2850e20,14, +0x2850e80,5, +0x2850ea0,7, +0x2851000,13, +0x2851040,2, +0x2851054,4, +0x2851080,27, +0x2851100,12, +0x2851140,14, +0x2851180,28, +0x2851200,6, +0x2851240,6, +0x285125c,3, +0x2851280,5, +0x28512a0,8, +0x2851400,14, +0x2851440,14, +0x2851480,14, +0x28514c0,14, +0x2851540,3, +0x2851600,7, +0x2851620,14, +0x2851680,5, +0x28516a0,7, +0x2851800,13, +0x2851840,2, +0x2851854,4, +0x2851880,27, +0x2851900,12, +0x2851940,14, +0x2851980,28, +0x2851a00,6, +0x2851a40,6, +0x2851a5c,3, +0x2851a80,5, +0x2851aa0,8, +0x2851c00,14, +0x2851c40,14, +0x2851c80,14, +0x2851cc0,14, +0x2851d40,3, +0x2851e00,7, +0x2851e20,14, +0x2851e80,5, +0x2851ea0,7, +0x2852000,8, +0x2852040,8, +0x2852080,1, +0x2852098,6, +0x2852100,10, +0x2852140,3, +0x2852150,2, +0x2852180,2, +0x2852200,6, +0x2852220,18, +0x2852280,4, +0x2852300,8, +0x2852400,2, +0x2852480,2, +0x2852800,28, +0x28529f0,4, +0x2853000,40, +0x2853100,64, +0x2853800,56, +0x2853be0,8, +0x2854000,13, +0x2854040,2, +0x2854054,4, +0x2854080,27, +0x2854100,12, +0x2854140,14, +0x2854180,28, +0x2854200,6, +0x2854240,6, +0x285425c,3, +0x2854280,5, +0x28542a0,8, +0x2854400,14, +0x2854440,14, +0x2854480,14, +0x28544c0,14, +0x2854540,3, +0x2854600,7, +0x2854620,14, +0x2854680,5, +0x28546a0,7, +0x2854800,13, +0x2854840,2, +0x2854854,4, +0x2854880,27, +0x2854900,12, +0x2854940,14, +0x2854980,28, +0x2854a00,6, +0x2854a40,6, +0x2854a5c,3, +0x2854a80,5, +0x2854aa0,8, +0x2854c00,14, +0x2854c40,14, +0x2854c80,14, +0x2854cc0,14, +0x2854d40,3, +0x2854e00,7, +0x2854e20,14, +0x2854e80,5, +0x2854ea0,7, +0x2855000,13, +0x2855040,2, +0x2855054,4, +0x2855080,27, +0x2855100,12, +0x2855140,14, +0x2855180,28, +0x2855200,6, +0x2855240,6, +0x285525c,3, +0x2855280,5, +0x28552a0,8, +0x2855400,14, +0x2855440,14, +0x2855480,14, +0x28554c0,14, +0x2855540,3, +0x2855600,7, +0x2855620,14, +0x2855680,5, +0x28556a0,7, +0x2855800,13, +0x2855840,2, +0x2855854,4, +0x2855880,27, +0x2855900,12, +0x2855940,14, +0x2855980,28, +0x2855a00,6, +0x2855a40,6, +0x2855a5c,3, +0x2855a80,5, +0x2855aa0,8, +0x2855c00,14, +0x2855c40,14, +0x2855c80,14, +0x2855cc0,14, +0x2855d40,3, +0x2855e00,7, +0x2855e20,14, +0x2855e80,5, +0x2855ea0,7, +0x2856000,8, +0x2856040,8, +0x2856080,1, +0x2856098,6, +0x2856100,10, +0x2856140,3, +0x2856150,2, +0x2856180,2, +0x2856200,6, +0x2856220,18, +0x2856280,4, +0x2856300,8, +0x2856400,2, +0x2856480,2, +0x2856800,28, +0x28569f0,4, +0x2857000,40, +0x2857100,64, +0x2857800,56, +0x2857be0,8, +0x2858000,2, +0x285800c,2, +0x2858040,7, +0x2858100,3, +0x2858110,3, +0x2858120,5, +0x2858200,6, +0x2858240,5, +0x2858400,2, +0x285840c,2, +0x2858440,7, +0x2858500,3, +0x2858510,3, +0x2858520,5, +0x2858600,6, +0x2858640,5, +0x2858800,2, +0x285880c,2, +0x2858840,7, +0x2858900,3, +0x2858910,3, +0x2858920,5, +0x2858a00,6, +0x2858a40,5, +0x2858c00,2, +0x2858c0c,2, +0x2858c40,7, +0x2858d00,3, +0x2858d10,3, +0x2858d20,5, +0x2858e00,6, +0x2858e40,5, +0x2859000,2, +0x285900c,2, +0x2859040,7, +0x2859100,3, +0x2859110,3, +0x2859120,5, +0x2859200,6, +0x2859240,5, +0x2859400,2, +0x285940c,2, +0x2859440,7, +0x2859500,3, +0x2859510,3, +0x2859520,5, +0x2859600,6, +0x2859640,5, +0x2859800,2, +0x285980c,2, +0x2859840,7, +0x2859900,3, +0x2859910,3, +0x2859920,5, +0x2859a00,6, +0x2859a40,5, +0x2859c00,2, +0x2859c0c,2, +0x2859c40,7, +0x2859d00,3, +0x2859d10,3, +0x2859d20,5, +0x2859e00,6, +0x2859e40,5, +0x285a000,5, +0x285a040,9, +0x285a100,3, +0x285a200,1, +0x285a210,1, +0x285a220,1, +0x285a230,1, +0x285a240,1, +0x285a300,3, +0x285a314,1, +0x285a320,4, +0x285a400,5, +0x285a440,5, +0x285b000,80, +0x285b200,1, +0x2860004,5, +0x2860020,3, +0x2860030,3, +0x2860040,13, +0x2860078,4, +0x286009c,25, +0x2860104,5, +0x2860120,3, +0x2860130,3, +0x2860140,13, +0x2860178,4, +0x286019c,25, +0x2860204,5, +0x2860220,3, +0x2860230,3, +0x2860240,13, +0x2860278,4, +0x286029c,25, +0x2860304,5, +0x2860320,3, +0x2860330,3, +0x2860340,13, +0x2860378,4, +0x286039c,25, +0x2860600,4, +0x2860c00,24, +0x2860c80,24, +0x2860d00,24, +0x2860d80,24, +0x2860e00,4, +0x2860e20,4, +0x2860e40,4, +0x2860e60,4, +0x2860e80,39, +0x2860f20,7, +0x2860f40,7, +0x2860f60,7, +0x2861000,12, +0x2861200,1, +0x2861218,2, +0x286122c,1, +0x2861280,1, +0x2861298,2, +0x28612ac,1, +0x2861300,1, +0x2861318,2, +0x286132c,1, +0x2861380,1, +0x2861398,2, +0x28613ac,1, +0x2861400,4, +0x2861420,2, +0x286142c,1, +0x2861480,4, +0x28614a0,2, +0x28614ac,1, +0x2861500,4, +0x2861520,2, +0x286152c,1, +0x2861580,4, +0x28615a0,2, +0x28615ac,1, +0x2861600,4, +0x2861640,4, +0x2861680,4, +0x28616c0,4, +0x2861700,7, +0x2861720,7, +0x2861740,7, +0x2861760,7, +0x2861780,4, +0x286179c,11, +0x28617d0,2, +0x28617e0,2, +0x28617f0,2, +0x2861900,44, +0x2862000,7, +0x2862020,4, +0x2862040,4, +0x2862060,7, +0x2862080,7, +0x28620a0,4, +0x28620c0,4, +0x28620e0,7, +0x2862100,7, +0x2862120,4, +0x2862140,4, +0x2862160,7, +0x2862180,7, +0x28621a0,4, +0x28621c0,4, +0x28621e0,7, +0x2862200,32, +0x2862b00,1, +0x2862b20,1, +0x2862b28,4, +0x2862b40,1, +0x2862b60,1, +0x2862b68,4, +0x2862b80,1, +0x2862ba0,1, +0x2862ba8,4, +0x2862bc0,1, +0x2862be0,1, +0x2862be8,4, +0x2862c00,7, +0x2862c20,1, +0x2862c54,18, +0x2862ca0,1, +0x2862cd4,18, +0x2862d20,1, +0x2862d54,18, +0x2862da0,1, +0x2862dd4,12, +0x2862e08,6, +0x2863100,7, +0x2863120,7, +0x2863140,7, +0x2863160,7, +0x2863180,3, +0x2864004,5, +0x2864020,3, +0x2864030,3, +0x2864040,13, +0x2864078,4, +0x286409c,25, +0x2864104,5, +0x2864120,3, +0x2864130,3, +0x2864140,13, +0x2864178,4, +0x286419c,25, +0x2864204,5, +0x2864220,3, +0x2864230,3, +0x2864240,13, +0x2864278,4, +0x286429c,25, +0x2864304,5, +0x2864320,3, +0x2864330,3, +0x2864340,13, +0x2864378,4, +0x286439c,25, +0x2864600,4, +0x2864c00,24, +0x2864c80,24, +0x2864d00,24, +0x2864d80,24, +0x2864e00,4, +0x2864e20,4, +0x2864e40,4, +0x2864e60,4, +0x2864e80,39, +0x2864f20,7, +0x2864f40,7, +0x2864f60,7, +0x2865000,12, +0x2865200,1, +0x2865218,2, +0x286522c,1, +0x2865280,1, +0x2865298,2, +0x28652ac,1, +0x2865300,1, +0x2865318,2, +0x286532c,1, +0x2865380,1, +0x2865398,2, +0x28653ac,1, +0x2865400,4, +0x2865420,2, +0x286542c,1, +0x2865480,4, +0x28654a0,2, +0x28654ac,1, +0x2865500,4, +0x2865520,2, +0x286552c,1, +0x2865580,4, +0x28655a0,2, +0x28655ac,1, +0x2865600,4, +0x2865640,4, +0x2865680,4, +0x28656c0,4, +0x2865700,7, +0x2865720,7, +0x2865740,7, +0x2865760,7, +0x2865780,4, +0x286579c,11, +0x28657d0,2, +0x28657e0,2, +0x28657f0,2, +0x2865900,44, +0x2866000,7, +0x2866020,4, +0x2866040,4, +0x2866060,7, +0x2866080,7, +0x28660a0,4, +0x28660c0,4, +0x28660e0,7, +0x2866100,7, +0x2866120,4, +0x2866140,4, +0x2866160,7, +0x2866180,7, +0x28661a0,4, +0x28661c0,4, +0x28661e0,7, +0x2866200,32, +0x2866b00,1, +0x2866b20,1, +0x2866b28,4, +0x2866b40,1, +0x2866b60,1, +0x2866b68,4, +0x2866b80,1, +0x2866ba0,1, +0x2866ba8,4, +0x2866bc0,1, +0x2866be0,1, +0x2866be8,4, +0x2866c00,7, +0x2866c20,1, +0x2866c54,18, +0x2866ca0,1, +0x2866cd4,18, +0x2866d20,1, +0x2866d54,18, +0x2866da0,1, +0x2866dd4,12, +0x2866e08,6, +0x2867100,7, +0x2867120,7, +0x2867140,7, +0x2867160,7, +0x2867180,3, +0x2868000,10, +0x2868080,3, +0x28680c0,1, +0x2868100,21, +0x2868180,13, +0x28681c4,7, +0x28681e4,7, +0x2868204,7, +0x2868224,8, +0x2869000,7, +0x2869030,2, +0x2869040,7, +0x2869070,2, +0x2869100,2, +0x2869120,2, +0x2869140,2, +0x2869160,2, +0x2869180,9, +0x2869200,7, +0x2869230,2, +0x2869240,7, +0x2869270,2, +0x2869300,2, +0x2869320,2, +0x2869340,2, +0x2869360,2, +0x2869380,9, +0x2869400,11, +0x2869500,11, +0x286a000,3, +0x286a010,2, +0x286a01c,5, +0x286a040,8, +0x286a080,3, +0x286a090,2, +0x286a09c,5, +0x286a0c0,8, +0x286a100,3, +0x286a110,2, +0x286a11c,5, +0x286a140,8, +0x286a180,3, +0x286a190,2, +0x286a19c,5, +0x286a1c0,8, +0x286a200,7, +0x286a220,12, +0x286a280,7, +0x286a2a0,12, +0x286a300,3, +0x286a310,1, +0x286a400,3, +0x286a410,2, +0x286a41c,5, +0x286a440,8, +0x286a480,3, +0x286a490,2, +0x286a49c,5, +0x286a4c0,8, +0x286a500,3, +0x286a510,2, +0x286a51c,5, +0x286a540,8, +0x286a580,3, +0x286a590,2, +0x286a59c,5, +0x286a5c0,8, +0x286a600,7, +0x286a620,12, +0x286a680,7, +0x286a6a0,12, +0x286a700,3, +0x286a710,1, +0x286a804,1, +0x286a824,21, +0x286a880,16, +0x286a900,5, +0x286a920,11, +0x286a950,9, +0x286a980,22, +0x286aa00,22, +0x286aa80,22, +0x286ab00,22, +0x286ab80,22, +0x286ac00,22, +0x286ac80,22, +0x286ad00,22, +0x286ad80,3, +0x286c000,16, +0x286c080,11, +0x286c100,11, +0x286c204,1, +0x286c224,21, +0x286c280,16, +0x286c300,11, +0x286c340,11, +0x286c800,21, +0x286c860,5, +0x286c880,6, +0x286c8a0,5, +0x286c8c0,6, +0x286c900,21, +0x286c960,5, +0x286c980,6, +0x286c9a0,5, +0x286c9c0,6, +0x286ca00,21, +0x286ca60,5, +0x286ca80,6, +0x286caa0,5, +0x286cac0,6, +0x286cb00,21, +0x286cb60,5, +0x286cb80,6, +0x286cba0,5, +0x286cbc0,6, +0x286cc00,9, +0x286cc48,7, +0x286cc68,2, +0x286cc74,9, +0x286cc9c,2, +0x286cd00,14, +0x286cd40,14, +0x286cd80,28, +0x286ce00,19, +0x286ce50,3, +0x286ce60,25, +0x286cec8,1, +0x286ced0,2, +0x286cee0,7, +0x286cf00,1, +0x286cf08,2, +0x286cffc,20, +0x286d050,25, +0x286d100,19, +0x286d150,25, +0x286d200,19, +0x286d250,25, +0x286d300,19, +0x286d350,25, +0x286d400,19, +0x286d450,25, +0x286d500,19, +0x286d550,25, +0x286d600,19, +0x286d650,25, +0x286d700,19, +0x286d750,25, +0x286d800,19, +0x286d850,25, +0x286d904,1, +0x286d914,10, +0x286d948,11, +0x286d980,2, +0x286d9a0,6, +0x286d9c0,2, +0x286d9cc,2, +0x286e000,35, +0x286ea00,10, +0x286ea80,3, +0x286eb00,6, +0x286f000,1, +0x286f008,5, +0x286f038,1, +0x286f044,1, +0x286f050,2, +0x286f100,13, +0x286f140,11, +0x286f170,12, +0x286f1a4,1, +0x286f200,104, +0x286f400,104, +0x286f600,104, +0x286f800,104, +0x2870000,13, +0x2870040,2, +0x2870054,4, +0x2870080,27, +0x2870100,12, +0x2870140,14, +0x2870180,28, +0x2870200,6, +0x2870240,6, +0x287025c,3, +0x2870280,5, +0x28702a0,8, +0x2870400,14, +0x2870440,14, +0x2870480,14, +0x28704c0,14, +0x2870540,3, +0x2870600,7, +0x2870620,14, +0x2870680,5, +0x28706a0,7, +0x2870800,13, +0x2870840,2, +0x2870854,4, +0x2870880,27, +0x2870900,12, +0x2870940,14, +0x2870980,28, +0x2870a00,6, +0x2870a40,6, +0x2870a5c,3, +0x2870a80,5, +0x2870aa0,8, +0x2870c00,14, +0x2870c40,14, +0x2870c80,14, +0x2870cc0,14, +0x2870d40,3, +0x2870e00,7, +0x2870e20,14, +0x2870e80,5, +0x2870ea0,7, +0x2871000,13, +0x2871040,2, +0x2871054,4, +0x2871080,27, +0x2871100,12, +0x2871140,14, +0x2871180,28, +0x2871200,6, +0x2871240,6, +0x287125c,3, +0x2871280,5, +0x28712a0,8, +0x2871400,14, +0x2871440,14, +0x2871480,14, +0x28714c0,14, +0x2871540,3, +0x2871600,7, +0x2871620,14, +0x2871680,5, +0x28716a0,7, +0x2871800,13, +0x2871840,2, +0x2871854,4, +0x2871880,27, +0x2871900,12, +0x2871940,14, +0x2871980,28, +0x2871a00,6, +0x2871a40,6, +0x2871a5c,3, +0x2871a80,5, +0x2871aa0,8, +0x2871c00,14, +0x2871c40,14, +0x2871c80,14, +0x2871cc0,14, +0x2871d40,3, +0x2871e00,7, +0x2871e20,14, +0x2871e80,5, +0x2871ea0,7, +0x2872000,8, +0x2872040,8, +0x2872080,1, +0x2872098,6, +0x2872100,10, +0x2872140,3, +0x2872150,2, +0x2872180,2, +0x2872200,6, +0x2872220,18, +0x2872280,4, +0x2872300,8, +0x2872400,2, +0x2872480,2, +0x2872800,28, +0x28729f0,4, +0x2873000,40, +0x2873100,64, +0x2873800,56, +0x2873be0,8, +0x2874000,13, +0x2874040,2, +0x2874054,4, +0x2874080,27, +0x2874100,12, +0x2874140,14, +0x2874180,28, +0x2874200,6, +0x2874240,6, +0x287425c,3, +0x2874280,5, +0x28742a0,8, +0x2874400,14, +0x2874440,14, +0x2874480,14, +0x28744c0,14, +0x2874540,3, +0x2874600,7, +0x2874620,14, +0x2874680,5, +0x28746a0,7, +0x2874800,13, +0x2874840,2, +0x2874854,4, +0x2874880,27, +0x2874900,12, +0x2874940,14, +0x2874980,28, +0x2874a00,6, +0x2874a40,6, +0x2874a5c,3, +0x2874a80,5, +0x2874aa0,8, +0x2874c00,14, +0x2874c40,14, +0x2874c80,14, +0x2874cc0,14, +0x2874d40,3, +0x2874e00,7, +0x2874e20,14, +0x2874e80,5, +0x2874ea0,7, +0x2875000,13, +0x2875040,2, +0x2875054,4, +0x2875080,27, +0x2875100,12, +0x2875140,14, +0x2875180,28, +0x2875200,6, +0x2875240,6, +0x287525c,3, +0x2875280,5, +0x28752a0,8, +0x2875400,14, +0x2875440,14, +0x2875480,14, +0x28754c0,14, +0x2875540,3, +0x2875600,7, +0x2875620,14, +0x2875680,5, +0x28756a0,7, +0x2875800,13, +0x2875840,2, +0x2875854,4, +0x2875880,27, +0x2875900,12, +0x2875940,14, +0x2875980,28, +0x2875a00,6, +0x2875a40,6, +0x2875a5c,3, +0x2875a80,5, +0x2875aa0,8, +0x2875c00,14, +0x2875c40,14, +0x2875c80,14, +0x2875cc0,14, +0x2875d40,3, +0x2875e00,7, +0x2875e20,14, +0x2875e80,5, +0x2875ea0,7, +0x2876000,8, +0x2876040,8, +0x2876080,1, +0x2876098,6, +0x2876100,10, +0x2876140,3, +0x2876150,2, +0x2876180,2, +0x2876200,6, +0x2876220,18, +0x2876280,4, +0x2876300,8, +0x2876400,2, +0x2876480,2, +0x2876800,28, +0x28769f0,4, +0x2877000,40, +0x2877100,64, +0x2877800,56, +0x2877be0,8, +0x2878000,2, +0x287800c,2, +0x2878040,7, +0x2878100,3, +0x2878110,3, +0x2878120,5, +0x2878200,6, +0x2878240,5, +0x2878400,2, +0x287840c,2, +0x2878440,7, +0x2878500,3, +0x2878510,3, +0x2878520,5, +0x2878600,6, +0x2878640,5, +0x2878800,2, +0x287880c,2, +0x2878840,7, +0x2878900,3, +0x2878910,3, +0x2878920,5, +0x2878a00,6, +0x2878a40,5, +0x2878c00,2, +0x2878c0c,2, +0x2878c40,7, +0x2878d00,3, +0x2878d10,3, +0x2878d20,5, +0x2878e00,6, +0x2878e40,5, +0x2879000,2, +0x287900c,2, +0x2879040,7, +0x2879100,3, +0x2879110,3, +0x2879120,5, +0x2879200,6, +0x2879240,5, +0x2879400,2, +0x287940c,2, +0x2879440,7, +0x2879500,3, +0x2879510,3, +0x2879520,5, +0x2879600,6, +0x2879640,5, +0x2879800,2, +0x287980c,2, +0x2879840,7, +0x2879900,3, +0x2879910,3, +0x2879920,5, +0x2879a00,6, +0x2879a40,5, +0x2879c00,2, +0x2879c0c,2, +0x2879c40,7, +0x2879d00,3, +0x2879d10,3, +0x2879d20,5, +0x2879e00,6, +0x2879e40,5, +0x287a000,5, +0x287a040,9, +0x287a100,3, +0x287a200,1, +0x287a210,1, +0x287a220,1, +0x287a230,1, +0x287a240,1, +0x287a300,3, +0x287a314,1, +0x287a320,4, +0x287a400,5, +0x287a440,5, +0x287b000,80, +0x287b200,1, +0x2880000,3, +0x2880010,7, +0x2880030,10, +0x2880080,2, +0x2880100,6, +0x2880140,2, +0x2880180,2, +0x28801a0,1, +0x2880400,2, +0x2880440,4, +0x2880460,5, +0x2880478,1, +0x2880480,6, +0x28804a0,3, +0x28804b0,2, +0x2880500,5, +0x2880600,1, +0x2880800,5, +0x2880900,5, +0x2880a00,5, +0x2880b00,3, +0x2880c00,35, +0x2880d00,25, +0x2880d80,1, +0x2880dc0,3, +0x2880e00,2, +0x2880e20,2, +0x2890000,3, +0x289001c,6, +0x2890080,3, +0x2890090,2, +0x28900d4,4, +0x28900ec,27, +0x289015c,27, +0x28901cc,19, +0x2890224,120, +0x2890408,109, +0x28905f8,4, +0x2890610,27, +0x2890680,27, +0x28906f0,19, +0x2890748,120, +0x289092c,109, +0x2890b1c,4, +0x2890b34,27, +0x2890ba4,27, +0x2890c14,19, +0x2890c6c,120, +0x2890e50,109, +0x2891040,4, +0x2891058,27, +0x28910c8,27, +0x2891138,19, +0x2891190,120, +0x2891374,109, +0x2891564,4, +0x289157c,27, +0x28915ec,27, +0x289165c,19, +0x28916b4,120, +0x2891898,109, +0x2891a88,4, +0x2891aa0,27, +0x2891b10,27, +0x2891b80,19, +0x2891bd8,120, +0x2891dbc,109, +0x2891fac,4, +0x2891fc4,27, +0x2892034,27, +0x28920a4,19, +0x28920fc,120, +0x28922e0,109, +0x28924d0,4, +0x28924e8,27, +0x2892558,27, +0x28925c8,19, +0x2892620,120, +0x2892804,109, +0x28929f4,4, +0x2892a0c,27, +0x2892a7c,27, +0x2892aec,19, +0x2892b44,120, +0x2892d28,109, +0x2892f18,4, +0x2892f30,27, +0x2892fa0,27, +0x2893010,19, +0x2893068,120, +0x289324c,109, +0x289343c,4, +0x2893454,27, +0x28934c4,27, +0x2893534,19, +0x289358c,120, +0x2893770,109, +0x2893960,4, +0x2893978,27, +0x28939e8,27, +0x2893a58,19, +0x2893ab0,120, +0x2893c94,109, +0x2893e84,4, +0x2893e9c,27, +0x2893f0c,27, +0x2893f7c,19, +0x2893fd4,120, +0x28941b8,109, +0x28943a8,4, +0x28943c0,27, +0x2894430,27, +0x28944a0,19, +0x28944f8,120, +0x28946dc,109, +0x28948cc,4, +0x28948e4,27, +0x2894954,27, +0x28949c4,19, +0x2894a1c,120, +0x2894c00,109, +0x2894df0,4, +0x2894e08,27, +0x2894e78,27, +0x2894ee8,19, +0x2894f40,120, +0x2895124,109, +0x2895314,4, +0x289532c,27, +0x289539c,27, +0x289540c,19, +0x2895464,120, +0x2895648,109, +0x2895838,14, +0x2895940,13, +0x2895a44,13, +0x2895b48,16, +0x2895b90,42, +0x2895c40,2, +0x2895c90,54, +0x2895d70,58, +0x2895e60,58, +0x2895f50,58, +0x2896040,58, +0x2896130,58, +0x2896220,58, +0x2896310,58, +0x2896400,58, +0x28964f0,58, +0x28965e0,58, +0x28966d0,58, +0x28967c0,58, +0x28968b0,58, +0x28969a0,58, +0x2896a90,58, +0x2896b80,58, +0x2896c70,58, +0x2896d60,58, +0x2896e50,58, +0x2896f40,58, +0x2897030,58, +0x2897120,58, +0x2897210,58, +0x2897300,58, +0x28973f0,58, +0x28974e0,58, +0x28975d0,58, +0x28976c0,58, +0x28977b0,58, +0x28978a0,58, +0x2897990,58, +0x2897a80,101, +0x2897c90,49, +0x2897db0,18, +0x2897e00,11, +0x2897e30,4, +0x2897e54,45, +0x2897f58,9, +0x2897f88,4, +0x2897fa0,2, +0x2897fd8,14, +0x2898014,12, +0x2898158,3, +0x2898168,2, +0x2898174,68, +0x2898288,2, +0x2898294,68, +0x28983a8,1, +0x28983b0,2, +0x28983bc,68, +0x28984d0,2, +0x28984dc,68, +0x28985f0,1, +0x28985f8,4, +0x2898610,3, +0x2898624,12, +0x2898688,8, +0x28986dc,1, +0x28986e8,4, +0x2898700,3, +0x2898714,12, +0x2898778,8, +0x28987cc,1, +0x28987d8,4, +0x28987f0,3, +0x2898804,12, +0x2898868,8, +0x28988bc,1, +0x28988c8,4, +0x28988e0,3, +0x28988f4,12, +0x2898958,8, +0x28989ac,1, +0x28989b8,4, +0x28989d0,3, +0x28989e4,12, +0x2898a48,8, +0x2898a9c,1, +0x2898aa8,4, +0x2898ac0,3, +0x2898ad4,12, +0x2898b38,8, +0x2898b8c,1, +0x2898b98,4, +0x2898bb0,3, +0x2898bc4,12, +0x2898c28,8, +0x2898c7c,1, +0x2898c88,4, +0x2898ca0,3, +0x2898cb4,12, +0x2898d18,8, +0x2898d6c,1, +0x2898d78,4, +0x2898d90,3, +0x2898da4,12, +0x2898e08,8, +0x2898e5c,1, +0x2898e68,4, +0x2898e80,3, +0x2898e94,12, +0x2898ef8,8, +0x2898f4c,1, +0x2898f58,4, +0x2898f70,3, +0x2898f84,12, +0x2898fe8,8, +0x289903c,1, +0x2899048,4, +0x2899060,3, +0x2899074,12, +0x28990d8,8, +0x289912c,1, +0x2899138,4, +0x2899150,3, +0x2899164,12, +0x28991c8,8, +0x289921c,1, +0x2899228,4, +0x2899240,3, +0x2899254,12, +0x28992b8,8, +0x289930c,1, +0x2899318,4, +0x2899330,3, +0x2899344,12, +0x28993a8,8, +0x28993fc,1, +0x2899408,4, +0x2899420,3, +0x2899434,12, +0x2899498,8, +0x28994ec,1, +0x28994f8,4, +0x2899510,3, +0x2899524,12, +0x2899588,8, +0x28995dc,1, +0x28995e8,64, +0x2899748,5, +0x2899990,28, +0x2899a04,4, +0x2899a98,1, +0x2899be8,11, +0x2899c18,13, +0x2899c50,6, +0x289a000,15, +0x289a044,81, +0x289a18c,84, +0x289a2e0,84, +0x289a434,84, +0x289a588,84, +0x289a6dc,84, +0x289a830,84, +0x289a984,84, +0x289aad8,84, +0x289ac2c,84, +0x289ad80,84, +0x289aed4,84, +0x289b028,84, +0x289b17c,84, +0x289b2d0,84, +0x289b424,84, +0x289b578,84, +0x289b6cc,5, +0x289b760,4, +0x289b8e0,2414, +0x289dea4,88, +0x289e048,4, +0x289ebe0,1, +0x289ebf0,97, +0x289ed94,7, +0x289ee7c,1, +0x289eeac,9, +0x289eed4,5, +0x289eeec,11, +0x289ef2c,17, +0x289ef74,30, +0x289f034,3, +0x289f044,2, +0x289f054,17, +0x289fbe0,3, +0x289fbf0,1, +0x28a0000,3, +0x28a0018,2, +0x28a0024,14, +0x28a0060,27, +0x28a00d0,3, +0x28a00e0,3, +0x28a00f0,3, +0x28a0100,4, +0x28a0120,6, +0x28a0140,3, +0x28a0150,1, +0x28a015c,4, +0x28a0170,1, +0x28a0180,15, +0x28a01c0,1, +0x28a01c8,5, +0x28a01e0,1, +0x28a01f0,3, +0x28a0200,3, +0x28a0218,2, +0x28a0224,14, +0x28a0260,27, +0x28a02d0,3, +0x28a02e0,3, +0x28a02f0,3, +0x28a0300,4, +0x28a0320,6, +0x28a0340,3, +0x28a0350,1, +0x28a035c,4, +0x28a0370,1, +0x28a0380,15, +0x28a03c0,1, +0x28a03c8,5, +0x28a03e0,1, +0x28a03f0,3, +0x28a0400,3, +0x28a0418,2, +0x28a0424,14, +0x28a0460,27, +0x28a04d0,3, +0x28a04e0,3, +0x28a04f0,3, +0x28a0500,4, +0x28a0520,6, +0x28a0540,3, +0x28a0550,1, +0x28a055c,4, +0x28a0570,1, +0x28a0580,15, +0x28a05c0,1, +0x28a05c8,5, +0x28a05e0,1, +0x28a05f0,3, +0x28a0600,3, +0x28a0618,2, +0x28a0624,14, +0x28a0660,27, +0x28a06d0,3, +0x28a06e0,3, +0x28a06f0,3, +0x28a0700,4, +0x28a0720,6, +0x28a0740,3, +0x28a0750,1, +0x28a075c,4, +0x28a0770,1, +0x28a0780,15, +0x28a07c0,1, +0x28a07c8,5, +0x28a07e0,1, +0x28a07f0,3, +0x28a0800,3, +0x28a0818,2, +0x28a0824,14, +0x28a0860,27, +0x28a08d0,3, +0x28a08e0,3, +0x28a08f0,3, +0x28a0900,4, +0x28a0920,6, +0x28a0940,3, +0x28a0950,1, +0x28a095c,4, +0x28a0970,1, +0x28a0980,15, +0x28a09c0,1, +0x28a09c8,5, +0x28a09e0,1, +0x28a09f0,3, +0x28a1844,1, +0x28a1858,5, +0x28a1904,3, +0x28a1950,3, +0x28a1988,2, +0x28a19a0,7, +0x28a19c0,7, +0x28a19e0,4, +0x28a2000,24, +0x28a20f0,3, +0x28a2100,7, +0x28a2120,7, +0x28a2144,7, +0x28a2400,4, +0x28a2420,5, +0x28a25e0,3, +0x28a25f4,1, +0x28a25fc,4, +0x28a2620,3, +0x28a2680,8, +0x28a2700,19, +0x28a2800,99, +0x28a2a00,18, +0x28a2a80,8, +0x28a2b00,1, +0x28a3070,1, +0x28a3080,2, +0x28a308c,1, +0x28a3098,2, +0x28a3404,1, +0x28a3440,20, +0x28a3494,1, +0x28a349c,7, +0x28a34d0,4, +0x28a34e8,2, +0x28a34fc,8, +0x28a3520,7, +0x28a3540,7, +0x28a3560,7, +0x28a3580,7, +0x28a35a0,7, +0x28a35c0,7, +0x28a35e0,7, +0x28a3600,9, +0x28a363c,2, +0x28a3650,6, +0x28a3684,10, +0x28a3a00,10, +0x28a3a30,1, +0x28a3a40,8, +0x28a3a64,5, +0x28a4a04,3, +0x28a4b00,33, +0x28a4b90,3, +0x28a5000,8, +0x28a5040,8, +0x28a5104,1, +0x28a510c,3, +0x28a5124,1, +0x28a512c,3, +0x28a6000,13, +0x28a6200,14, +0x28a6240,1, +0x28a6248,1, +0x28a6258,1, +0x28a6260,8, +0x28a6284,1, +0x28a62a0,8, +0x28a6348,5, +0x28a67f0,1, +0x28a67f8,1, +0x28a6a10,12, +0x28a7000,19, +0x28a7a00,10, +0x28a7a80,3, +0x28a7b00,6, +0x28c0000,1, +0x28c000c,5, +0x28c0044,1, +0x28c0054,5, +0x28c0200,128, +0x28c0404,1, +0x28c0428,54, +0x28c0600,32, +0x28c0704,1, +0x28c0800,1, +0x28c0900,1, +0x28c0910,2, +0x28c0920,3, +0x28c0980,10, +0x28c0a00,19, +0x28c0b00,1, +0x28e0000,2, +0x28e000c,2, +0x28e0018,2, +0x28e0024,2, +0x28e0030,2, +0x28e003c,2, +0x28e0048,2, +0x28e0054,2, +0x28e0060,1, +0x28e0070,2, +0x28e007c,2, +0x28e0088,2, +0x28e0094,2, +0x28e00a0,2, +0x28e00ac,2, +0x28e00b8,2, +0x28e00c4,2, +0x28e00d0,1, +0x28e00e0,2, +0x28e00ec,2, +0x28e00f8,2, +0x28e0104,2, +0x28e0110,2, +0x28e011c,2, +0x28e0128,2, +0x28e0134,2, +0x28e0140,1, +0x28e0150,2, +0x28e015c,2, +0x28e0168,2, +0x28e0174,2, +0x28e0180,2, +0x28e018c,2, +0x28e0198,2, +0x28e01a4,2, +0x28e01b0,1, +0x28e01c0,57, +0x28e02b0,23, +0x28e0310,83, +0x28e0460,83, +0x28e05b0,83, +0x28e0700,83, +0x28e0850,83, +0x28e09a0,83, +0x28e0af0,83, +0x28e0c40,83, +0x28e0d90,83, +0x28e0ee0,83, +0x28e1030,83, +0x28e1180,83, +0x28e12d0,83, +0x28e1420,83, +0x28e1570,83, +0x28e16c0,83, +0x28e1810,83, +0x28e1960,83, +0x28e1ab0,83, +0x28e1c00,83, +0x28e1d50,83, +0x28e1ea0,83, +0x28e1ff0,83, +0x28e2140,83, +0x28e2290,83, +0x28e23e0,83, +0x28e2530,83, +0x28e2680,83, +0x28e27d0,83, +0x28e2920,83, +0x28e2a70,83, +0x28e2bc0,62, +0x28e2db4,3, +0x28e2df4,3, +0x28e2e34,3, +0x28e2e74,3, +0x28e2eb4,3, +0x28e2ef4,3, +0x28e2f34,3, +0x28e2f74,3, +0x28e2fb4,3, +0x28e2ff4,3, +0x28e3034,3, +0x28e3074,3, +0x28e30b4,3, +0x28e30f4,3, +0x28e3134,3, +0x28e3174,3, +0x28e31b4,3, +0x28f0000,4, +0x28f0014,2, +0x28f0020,8, +0x28f0044,2, +0x28f0050,13, +0x28f0088,20, +0x28f00dc,1, +0x28f0180,6, +0x28f0590,3, +0x28f05c0,2, +0x28f0a04,1, +0x28f0a0c,3, +0x28f0a20,1, +0x28f0ba0,4, +0x28f0c00,4, +0x28f0c20,3, +0x28f0c30,5, +0x28f0c50,52, +0x28f0d50,57, +0x28f0ec0,3, +0x28f0ffc,3, +0x28f1020,3, +0x28f1030,3, +0x28f1060,2, +0x28f1100,2, +0x28f1140,18, +0x28f11c0,30, +0x28f1240,14, +0x28f1280,28, +0x28f1300,2, +0x28f13a0,6, +0x28f1400,19, +0x28f1800,19, +0x28f1c00,19, +0x28f1c80,8, +0x28f1d00,3, +0x28f1d50,3, +0x28f1e00,3, +0x28f1e10,2, +0x28f1e20,6, +0x28f1e40,6, +0x28f1e60,6, +0x28f1e80,6, +0x28f1ea0,6, +0x28f1ec0,2, +0x28f1ecc,2, +0x28f1ee0,2, +0x28f1eec,2, +0x28f1f80,3, +0x28f1f90,60, +0x28f2100,32, +0x28f2200,32, +0x28f2300,32, +0x28f2400,32, +0x28f2500,32, +0x28f2600,32, +0x28f2700,32, +0x28f2800,32, +0x28f2900,32, +0x28f2a00,32, +0x28f2b00,32, +0x28f2c00,32, +0x28f2d00,32, +0x28f2e00,32, +0x28f2f00,32, +0x28f3000,32, +0x28f30c0,3, +0x28f4000,2, +0x28f4040,16, +0x28f4100,36, +0x28f4800,5, +0x28f4824,1, +0x28f482c,1, +0x28f4c04,1, +0x28f4cd8,74, +0x28f5000,7, +0x28f5020,4, +0x28f5204,1, +0x28f5280,35, +0x28f5310,4, +0x28f5404,1, +0x28f5480,34, +0x28f5510,10, +0x28f553c,3, +0x28f5800,7, +0x28f5820,4, +0x28f5a04,1, +0x28f5a80,35, +0x28f5b10,4, +0x28f5c04,1, +0x28f5c80,34, +0x28f5d10,10, +0x28f5d3c,3, +0x28fa000,5, +0x28fa01c,13, +0x28fa060,3, +0x28fa080,8, +0x28fa100,5, +0x28fa11c,13, +0x28fa160,3, +0x28fa180,8, +0x2a00004,5, +0x2a00020,3, +0x2a00030,3, +0x2a00040,13, +0x2a00078,4, +0x2a0009c,25, +0x2a00104,5, +0x2a00120,3, +0x2a00130,3, +0x2a00140,13, +0x2a00178,4, +0x2a0019c,25, +0x2a00204,5, +0x2a00220,3, +0x2a00230,3, +0x2a00240,13, +0x2a00278,4, +0x2a0029c,25, +0x2a00304,5, +0x2a00320,3, +0x2a00330,3, +0x2a00340,13, +0x2a00378,4, +0x2a0039c,25, +0x2a00600,4, +0x2a00c00,24, +0x2a00c80,24, +0x2a00d00,24, +0x2a00d80,24, +0x2a00e00,4, +0x2a00e20,4, +0x2a00e40,4, +0x2a00e60,4, +0x2a00e80,39, +0x2a00f20,7, +0x2a00f40,7, +0x2a00f60,7, +0x2a01000,12, +0x2a01200,1, +0x2a01218,2, +0x2a0122c,1, +0x2a01280,1, +0x2a01298,2, +0x2a012ac,1, +0x2a01300,1, +0x2a01318,2, +0x2a0132c,1, +0x2a01380,1, +0x2a01398,2, +0x2a013ac,1, +0x2a01400,4, +0x2a01420,2, +0x2a0142c,1, +0x2a01480,4, +0x2a014a0,2, +0x2a014ac,1, +0x2a01500,4, +0x2a01520,2, +0x2a0152c,1, +0x2a01580,4, +0x2a015a0,2, +0x2a015ac,1, +0x2a01600,4, +0x2a01640,4, +0x2a01680,4, +0x2a016c0,4, +0x2a01700,7, +0x2a01720,7, +0x2a01740,7, +0x2a01760,7, +0x2a01780,4, +0x2a0179c,11, +0x2a017d0,2, +0x2a017e0,2, +0x2a017f0,2, +0x2a01900,44, +0x2a02000,7, +0x2a02020,4, +0x2a02040,4, +0x2a02060,7, +0x2a02080,7, +0x2a020a0,4, +0x2a020c0,4, +0x2a020e0,7, +0x2a02100,7, +0x2a02120,4, +0x2a02140,4, +0x2a02160,7, +0x2a02180,7, +0x2a021a0,4, +0x2a021c0,4, +0x2a021e0,7, +0x2a02200,32, +0x2a02b00,1, +0x2a02b20,1, +0x2a02b28,4, +0x2a02b40,1, +0x2a02b60,1, +0x2a02b68,4, +0x2a02b80,1, +0x2a02ba0,1, +0x2a02ba8,4, +0x2a02bc0,1, +0x2a02be0,1, +0x2a02be8,4, +0x2a02c00,7, +0x2a02c20,1, +0x2a02c54,18, +0x2a02ca0,1, +0x2a02cd4,18, +0x2a02d20,1, +0x2a02d54,18, +0x2a02da0,1, +0x2a02dd4,12, +0x2a02e08,6, +0x2a03100,7, +0x2a03120,7, +0x2a03140,7, +0x2a03160,7, +0x2a03180,3, +0x2a04004,5, +0x2a04020,3, +0x2a04030,3, +0x2a04040,13, +0x2a04078,4, +0x2a0409c,25, +0x2a04104,5, +0x2a04120,3, +0x2a04130,3, +0x2a04140,13, +0x2a04178,4, +0x2a0419c,25, +0x2a04204,5, +0x2a04220,3, +0x2a04230,3, +0x2a04240,13, +0x2a04278,4, +0x2a0429c,25, +0x2a04304,5, +0x2a04320,3, +0x2a04330,3, +0x2a04340,13, +0x2a04378,4, +0x2a0439c,25, +0x2a04600,4, +0x2a04c00,24, +0x2a04c80,24, +0x2a04d00,24, +0x2a04d80,24, +0x2a04e00,4, +0x2a04e20,4, +0x2a04e40,4, +0x2a04e60,4, +0x2a04e80,39, +0x2a04f20,7, +0x2a04f40,7, +0x2a04f60,7, +0x2a05000,12, +0x2a05200,1, +0x2a05218,2, +0x2a0522c,1, +0x2a05280,1, +0x2a05298,2, +0x2a052ac,1, +0x2a05300,1, +0x2a05318,2, +0x2a0532c,1, +0x2a05380,1, +0x2a05398,2, +0x2a053ac,1, +0x2a05400,4, +0x2a05420,2, +0x2a0542c,1, +0x2a05480,4, +0x2a054a0,2, +0x2a054ac,1, +0x2a05500,4, +0x2a05520,2, +0x2a0552c,1, +0x2a05580,4, +0x2a055a0,2, +0x2a055ac,1, +0x2a05600,4, +0x2a05640,4, +0x2a05680,4, +0x2a056c0,4, +0x2a05700,7, +0x2a05720,7, +0x2a05740,7, +0x2a05760,7, +0x2a05780,4, +0x2a0579c,11, +0x2a057d0,2, +0x2a057e0,2, +0x2a057f0,2, +0x2a05900,44, +0x2a06000,7, +0x2a06020,4, +0x2a06040,4, +0x2a06060,7, +0x2a06080,7, +0x2a060a0,4, +0x2a060c0,4, +0x2a060e0,7, +0x2a06100,7, +0x2a06120,4, +0x2a06140,4, +0x2a06160,7, +0x2a06180,7, +0x2a061a0,4, +0x2a061c0,4, +0x2a061e0,7, +0x2a06200,32, +0x2a06b00,1, +0x2a06b20,1, +0x2a06b28,4, +0x2a06b40,1, +0x2a06b60,1, +0x2a06b68,4, +0x2a06b80,1, +0x2a06ba0,1, +0x2a06ba8,4, +0x2a06bc0,1, +0x2a06be0,1, +0x2a06be8,4, +0x2a06c00,7, +0x2a06c20,1, +0x2a06c54,18, +0x2a06ca0,1, +0x2a06cd4,18, +0x2a06d20,1, +0x2a06d54,18, +0x2a06da0,1, +0x2a06dd4,12, +0x2a06e08,6, +0x2a07100,7, +0x2a07120,7, +0x2a07140,7, +0x2a07160,7, +0x2a07180,3, +0x2a08000,10, +0x2a08080,3, +0x2a080c0,1, +0x2a08100,21, +0x2a08180,13, +0x2a081c4,7, +0x2a081e4,7, +0x2a08204,7, +0x2a08224,8, +0x2a09000,7, +0x2a09030,2, +0x2a09040,7, +0x2a09070,2, +0x2a09100,2, +0x2a09120,2, +0x2a09140,2, +0x2a09160,2, +0x2a09180,9, +0x2a09200,7, +0x2a09230,2, +0x2a09240,7, +0x2a09270,2, +0x2a09300,2, +0x2a09320,2, +0x2a09340,2, +0x2a09360,2, +0x2a09380,9, +0x2a09400,11, +0x2a09500,11, +0x2a0a000,3, +0x2a0a010,2, +0x2a0a01c,5, +0x2a0a040,8, +0x2a0a080,3, +0x2a0a090,2, +0x2a0a09c,5, +0x2a0a0c0,8, +0x2a0a100,3, +0x2a0a110,2, +0x2a0a11c,5, +0x2a0a140,8, +0x2a0a180,3, +0x2a0a190,2, +0x2a0a19c,5, +0x2a0a1c0,8, +0x2a0a200,7, +0x2a0a220,12, +0x2a0a280,7, +0x2a0a2a0,12, +0x2a0a300,3, +0x2a0a310,1, +0x2a0a400,3, +0x2a0a410,2, +0x2a0a41c,5, +0x2a0a440,8, +0x2a0a480,3, +0x2a0a490,2, +0x2a0a49c,5, +0x2a0a4c0,8, +0x2a0a500,3, +0x2a0a510,2, +0x2a0a51c,5, +0x2a0a540,8, +0x2a0a580,3, +0x2a0a590,2, +0x2a0a59c,5, +0x2a0a5c0,8, +0x2a0a600,7, +0x2a0a620,12, +0x2a0a680,7, +0x2a0a6a0,12, +0x2a0a700,3, +0x2a0a710,1, +0x2a0a804,1, +0x2a0a824,21, +0x2a0a880,16, +0x2a0a900,5, +0x2a0a920,11, +0x2a0a950,9, +0x2a0a980,22, +0x2a0aa00,22, +0x2a0aa80,22, +0x2a0ab00,22, +0x2a0ab80,22, +0x2a0ac00,22, +0x2a0ac80,22, +0x2a0ad00,22, +0x2a0ad80,3, +0x2a0c000,16, +0x2a0c080,11, +0x2a0c100,11, +0x2a0c204,1, +0x2a0c224,21, +0x2a0c280,16, +0x2a0c300,11, +0x2a0c340,11, +0x2a0c800,21, +0x2a0c860,5, +0x2a0c880,6, +0x2a0c8a0,5, +0x2a0c8c0,6, +0x2a0c900,21, +0x2a0c960,5, +0x2a0c980,6, +0x2a0c9a0,5, +0x2a0c9c0,6, +0x2a0ca00,21, +0x2a0ca60,5, +0x2a0ca80,6, +0x2a0caa0,5, +0x2a0cac0,6, +0x2a0cb00,21, +0x2a0cb60,5, +0x2a0cb80,6, +0x2a0cba0,5, +0x2a0cbc0,6, +0x2a0cc00,9, +0x2a0cc48,7, +0x2a0cc68,2, +0x2a0cc74,9, +0x2a0cc9c,2, +0x2a0cd00,14, +0x2a0cd40,14, +0x2a0cd80,28, +0x2a0ce00,19, +0x2a0ce50,3, +0x2a0ce60,25, +0x2a0cec8,1, +0x2a0ced0,2, +0x2a0cee0,7, +0x2a0cf00,1, +0x2a0cf08,2, +0x2a0cffc,20, +0x2a0d050,25, +0x2a0d100,19, +0x2a0d150,25, +0x2a0d200,19, +0x2a0d250,25, +0x2a0d300,19, +0x2a0d350,25, +0x2a0d400,19, +0x2a0d450,25, +0x2a0d500,19, +0x2a0d550,25, +0x2a0d600,19, +0x2a0d650,25, +0x2a0d700,19, +0x2a0d750,25, +0x2a0d800,19, +0x2a0d850,25, +0x2a0d904,1, +0x2a0d914,10, +0x2a0d948,11, +0x2a0d980,2, +0x2a0d9a0,6, +0x2a0d9c0,2, +0x2a0d9cc,2, +0x2a0e000,35, +0x2a0ea00,10, +0x2a0ea80,3, +0x2a0eb00,6, +0x2a0f000,1, +0x2a0f008,5, +0x2a0f038,1, +0x2a0f044,1, +0x2a0f050,2, +0x2a0f100,13, +0x2a0f140,11, +0x2a0f170,12, +0x2a0f1a4,1, +0x2a0f200,104, +0x2a0f400,104, +0x2a0f600,104, +0x2a0f800,104, +0x2a10000,13, +0x2a10040,2, +0x2a10054,4, +0x2a10080,27, +0x2a10100,12, +0x2a10140,14, +0x2a10180,28, +0x2a10200,6, +0x2a10240,6, +0x2a1025c,3, +0x2a10280,5, +0x2a102a0,8, +0x2a10400,14, +0x2a10440,14, +0x2a10480,14, +0x2a104c0,14, +0x2a10540,3, +0x2a10600,7, +0x2a10620,14, +0x2a10680,5, +0x2a106a0,7, +0x2a10800,13, +0x2a10840,2, +0x2a10854,4, +0x2a10880,27, +0x2a10900,12, +0x2a10940,14, +0x2a10980,28, +0x2a10a00,6, +0x2a10a40,6, +0x2a10a5c,3, +0x2a10a80,5, +0x2a10aa0,8, +0x2a10c00,14, +0x2a10c40,14, +0x2a10c80,14, +0x2a10cc0,14, +0x2a10d40,3, +0x2a10e00,7, +0x2a10e20,14, +0x2a10e80,5, +0x2a10ea0,7, +0x2a11000,13, +0x2a11040,2, +0x2a11054,4, +0x2a11080,27, +0x2a11100,12, +0x2a11140,14, +0x2a11180,28, +0x2a11200,6, +0x2a11240,6, +0x2a1125c,3, +0x2a11280,5, +0x2a112a0,8, +0x2a11400,14, +0x2a11440,14, +0x2a11480,14, +0x2a114c0,14, +0x2a11540,3, +0x2a11600,7, +0x2a11620,14, +0x2a11680,5, +0x2a116a0,7, +0x2a11800,13, +0x2a11840,2, +0x2a11854,4, +0x2a11880,27, +0x2a11900,12, +0x2a11940,14, +0x2a11980,28, +0x2a11a00,6, +0x2a11a40,6, +0x2a11a5c,3, +0x2a11a80,5, +0x2a11aa0,8, +0x2a11c00,14, +0x2a11c40,14, +0x2a11c80,14, +0x2a11cc0,14, +0x2a11d40,3, +0x2a11e00,7, +0x2a11e20,14, +0x2a11e80,5, +0x2a11ea0,7, +0x2a12000,8, +0x2a12040,8, +0x2a12080,1, +0x2a12098,6, +0x2a12100,10, +0x2a12140,3, +0x2a12150,2, +0x2a12180,2, +0x2a12200,6, +0x2a12220,18, +0x2a12280,4, +0x2a12300,8, +0x2a12400,2, +0x2a12480,2, +0x2a12800,28, +0x2a129f0,4, +0x2a13000,40, +0x2a13100,64, +0x2a13800,56, +0x2a13be0,8, +0x2a14000,13, +0x2a14040,2, +0x2a14054,4, +0x2a14080,27, +0x2a14100,12, +0x2a14140,14, +0x2a14180,28, +0x2a14200,6, +0x2a14240,6, +0x2a1425c,3, +0x2a14280,5, +0x2a142a0,8, +0x2a14400,14, +0x2a14440,14, +0x2a14480,14, +0x2a144c0,14, +0x2a14540,3, +0x2a14600,7, +0x2a14620,14, +0x2a14680,5, +0x2a146a0,7, +0x2a14800,13, +0x2a14840,2, +0x2a14854,4, +0x2a14880,27, +0x2a14900,12, +0x2a14940,14, +0x2a14980,28, +0x2a14a00,6, +0x2a14a40,6, +0x2a14a5c,3, +0x2a14a80,5, +0x2a14aa0,8, +0x2a14c00,14, +0x2a14c40,14, +0x2a14c80,14, +0x2a14cc0,14, +0x2a14d40,3, +0x2a14e00,7, +0x2a14e20,14, +0x2a14e80,5, +0x2a14ea0,7, +0x2a15000,13, +0x2a15040,2, +0x2a15054,4, +0x2a15080,27, +0x2a15100,12, +0x2a15140,14, +0x2a15180,28, +0x2a15200,6, +0x2a15240,6, +0x2a1525c,3, +0x2a15280,5, +0x2a152a0,8, +0x2a15400,14, +0x2a15440,14, +0x2a15480,14, +0x2a154c0,14, +0x2a15540,3, +0x2a15600,7, +0x2a15620,14, +0x2a15680,5, +0x2a156a0,7, +0x2a15800,13, +0x2a15840,2, +0x2a15854,4, +0x2a15880,27, +0x2a15900,12, +0x2a15940,14, +0x2a15980,28, +0x2a15a00,6, +0x2a15a40,6, +0x2a15a5c,3, +0x2a15a80,5, +0x2a15aa0,8, +0x2a15c00,14, +0x2a15c40,14, +0x2a15c80,14, +0x2a15cc0,14, +0x2a15d40,3, +0x2a15e00,7, +0x2a15e20,14, +0x2a15e80,5, +0x2a15ea0,7, +0x2a16000,8, +0x2a16040,8, +0x2a16080,1, +0x2a16098,6, +0x2a16100,10, +0x2a16140,3, +0x2a16150,2, +0x2a16180,2, +0x2a16200,6, +0x2a16220,18, +0x2a16280,4, +0x2a16300,8, +0x2a16400,2, +0x2a16480,2, +0x2a16800,28, +0x2a169f0,4, +0x2a17000,40, +0x2a17100,64, +0x2a17800,56, +0x2a17be0,8, +0x2a18000,2, +0x2a1800c,2, +0x2a18040,7, +0x2a18100,3, +0x2a18110,3, +0x2a18120,5, +0x2a18200,6, +0x2a18240,5, +0x2a18400,2, +0x2a1840c,2, +0x2a18440,7, +0x2a18500,3, +0x2a18510,3, +0x2a18520,5, +0x2a18600,6, +0x2a18640,5, +0x2a18800,2, +0x2a1880c,2, +0x2a18840,7, +0x2a18900,3, +0x2a18910,3, +0x2a18920,5, +0x2a18a00,6, +0x2a18a40,5, +0x2a18c00,2, +0x2a18c0c,2, +0x2a18c40,7, +0x2a18d00,3, +0x2a18d10,3, +0x2a18d20,5, +0x2a18e00,6, +0x2a18e40,5, +0x2a19000,2, +0x2a1900c,2, +0x2a19040,7, +0x2a19100,3, +0x2a19110,3, +0x2a19120,5, +0x2a19200,6, +0x2a19240,5, +0x2a19400,2, +0x2a1940c,2, +0x2a19440,7, +0x2a19500,3, +0x2a19510,3, +0x2a19520,5, +0x2a19600,6, +0x2a19640,5, +0x2a19800,2, +0x2a1980c,2, +0x2a19840,7, +0x2a19900,3, +0x2a19910,3, +0x2a19920,5, +0x2a19a00,6, +0x2a19a40,5, +0x2a19c00,2, +0x2a19c0c,2, +0x2a19c40,7, +0x2a19d00,3, +0x2a19d10,3, +0x2a19d20,5, +0x2a19e00,6, +0x2a19e40,5, +0x2a1a000,5, +0x2a1a040,9, +0x2a1a100,3, +0x2a1a200,1, +0x2a1a210,1, +0x2a1a220,1, +0x2a1a230,1, +0x2a1a240,1, +0x2a1a300,3, +0x2a1a314,1, +0x2a1a320,4, +0x2a1a400,5, +0x2a1a440,5, +0x2a1b000,80, +0x2a1b200,1, +0x2a20004,5, +0x2a20020,3, +0x2a20030,3, +0x2a20040,13, +0x2a20078,4, +0x2a2009c,25, +0x2a20104,5, +0x2a20120,3, +0x2a20130,3, +0x2a20140,13, +0x2a20178,4, +0x2a2019c,25, +0x2a20204,5, +0x2a20220,3, +0x2a20230,3, +0x2a20240,13, +0x2a20278,4, +0x2a2029c,25, +0x2a20304,5, +0x2a20320,3, +0x2a20330,3, +0x2a20340,13, +0x2a20378,4, +0x2a2039c,25, +0x2a20600,4, +0x2a20c00,24, +0x2a20c80,24, +0x2a20d00,24, +0x2a20d80,24, +0x2a20e00,4, +0x2a20e20,4, +0x2a20e40,4, +0x2a20e60,4, +0x2a20e80,39, +0x2a20f20,7, +0x2a20f40,7, +0x2a20f60,7, +0x2a21000,12, +0x2a21200,1, +0x2a21218,2, +0x2a2122c,1, +0x2a21280,1, +0x2a21298,2, +0x2a212ac,1, +0x2a21300,1, +0x2a21318,2, +0x2a2132c,1, +0x2a21380,1, +0x2a21398,2, +0x2a213ac,1, +0x2a21400,4, +0x2a21420,2, +0x2a2142c,1, +0x2a21480,4, +0x2a214a0,2, +0x2a214ac,1, +0x2a21500,4, +0x2a21520,2, +0x2a2152c,1, +0x2a21580,4, +0x2a215a0,2, +0x2a215ac,1, +0x2a21600,4, +0x2a21640,4, +0x2a21680,4, +0x2a216c0,4, +0x2a21700,7, +0x2a21720,7, +0x2a21740,7, +0x2a21760,7, +0x2a21780,4, +0x2a2179c,11, +0x2a217d0,2, +0x2a217e0,2, +0x2a217f0,2, +0x2a21900,44, +0x2a22000,7, +0x2a22020,4, +0x2a22040,4, +0x2a22060,7, +0x2a22080,7, +0x2a220a0,4, +0x2a220c0,4, +0x2a220e0,7, +0x2a22100,7, +0x2a22120,4, +0x2a22140,4, +0x2a22160,7, +0x2a22180,7, +0x2a221a0,4, +0x2a221c0,4, +0x2a221e0,7, +0x2a22200,32, +0x2a22b00,1, +0x2a22b20,1, +0x2a22b28,4, +0x2a22b40,1, +0x2a22b60,1, +0x2a22b68,4, +0x2a22b80,1, +0x2a22ba0,1, +0x2a22ba8,4, +0x2a22bc0,1, +0x2a22be0,1, +0x2a22be8,4, +0x2a22c00,7, +0x2a22c20,1, +0x2a22c54,18, +0x2a22ca0,1, +0x2a22cd4,18, +0x2a22d20,1, +0x2a22d54,18, +0x2a22da0,1, +0x2a22dd4,12, +0x2a22e08,6, +0x2a23100,7, +0x2a23120,7, +0x2a23140,7, +0x2a23160,7, +0x2a23180,3, +0x2a24004,5, +0x2a24020,3, +0x2a24030,3, +0x2a24040,13, +0x2a24078,4, +0x2a2409c,25, +0x2a24104,5, +0x2a24120,3, +0x2a24130,3, +0x2a24140,13, +0x2a24178,4, +0x2a2419c,25, +0x2a24204,5, +0x2a24220,3, +0x2a24230,3, +0x2a24240,13, +0x2a24278,4, +0x2a2429c,25, +0x2a24304,5, +0x2a24320,3, +0x2a24330,3, +0x2a24340,13, +0x2a24378,4, +0x2a2439c,25, +0x2a24600,4, +0x2a24c00,24, +0x2a24c80,24, +0x2a24d00,24, +0x2a24d80,24, +0x2a24e00,4, +0x2a24e20,4, +0x2a24e40,4, +0x2a24e60,4, +0x2a24e80,39, +0x2a24f20,7, +0x2a24f40,7, +0x2a24f60,7, +0x2a25000,12, +0x2a25200,1, +0x2a25218,2, +0x2a2522c,1, +0x2a25280,1, +0x2a25298,2, +0x2a252ac,1, +0x2a25300,1, +0x2a25318,2, +0x2a2532c,1, +0x2a25380,1, +0x2a25398,2, +0x2a253ac,1, +0x2a25400,4, +0x2a25420,2, +0x2a2542c,1, +0x2a25480,4, +0x2a254a0,2, +0x2a254ac,1, +0x2a25500,4, +0x2a25520,2, +0x2a2552c,1, +0x2a25580,4, +0x2a255a0,2, +0x2a255ac,1, +0x2a25600,4, +0x2a25640,4, +0x2a25680,4, +0x2a256c0,4, +0x2a25700,7, +0x2a25720,7, +0x2a25740,7, +0x2a25760,7, +0x2a25780,4, +0x2a2579c,11, +0x2a257d0,2, +0x2a257e0,2, +0x2a257f0,2, +0x2a25900,44, +0x2a26000,7, +0x2a26020,4, +0x2a26040,4, +0x2a26060,7, +0x2a26080,7, +0x2a260a0,4, +0x2a260c0,4, +0x2a260e0,7, +0x2a26100,7, +0x2a26120,4, +0x2a26140,4, +0x2a26160,7, +0x2a26180,7, +0x2a261a0,4, +0x2a261c0,4, +0x2a261e0,7, +0x2a26200,32, +0x2a26b00,1, +0x2a26b20,1, +0x2a26b28,4, +0x2a26b40,1, +0x2a26b60,1, +0x2a26b68,4, +0x2a26b80,1, +0x2a26ba0,1, +0x2a26ba8,4, +0x2a26bc0,1, +0x2a26be0,1, +0x2a26be8,4, +0x2a26c00,7, +0x2a26c20,1, +0x2a26c54,18, +0x2a26ca0,1, +0x2a26cd4,18, +0x2a26d20,1, +0x2a26d54,18, +0x2a26da0,1, +0x2a26dd4,12, +0x2a26e08,6, +0x2a27100,7, +0x2a27120,7, +0x2a27140,7, +0x2a27160,7, +0x2a27180,3, +0x2a28000,10, +0x2a28080,3, +0x2a280c0,1, +0x2a28100,21, +0x2a28180,13, +0x2a281c4,7, +0x2a281e4,7, +0x2a28204,7, +0x2a28224,8, +0x2a29000,7, +0x2a29030,2, +0x2a29040,7, +0x2a29070,2, +0x2a29100,2, +0x2a29120,2, +0x2a29140,2, +0x2a29160,2, +0x2a29180,9, +0x2a29200,7, +0x2a29230,2, +0x2a29240,7, +0x2a29270,2, +0x2a29300,2, +0x2a29320,2, +0x2a29340,2, +0x2a29360,2, +0x2a29380,9, +0x2a29400,11, +0x2a29500,11, +0x2a2a000,3, +0x2a2a010,2, +0x2a2a01c,5, +0x2a2a040,8, +0x2a2a080,3, +0x2a2a090,2, +0x2a2a09c,5, +0x2a2a0c0,8, +0x2a2a100,3, +0x2a2a110,2, +0x2a2a11c,5, +0x2a2a140,8, +0x2a2a180,3, +0x2a2a190,2, +0x2a2a19c,5, +0x2a2a1c0,8, +0x2a2a200,7, +0x2a2a220,12, +0x2a2a280,7, +0x2a2a2a0,12, +0x2a2a300,3, +0x2a2a310,1, +0x2a2a400,3, +0x2a2a410,2, +0x2a2a41c,5, +0x2a2a440,8, +0x2a2a480,3, +0x2a2a490,2, +0x2a2a49c,5, +0x2a2a4c0,8, +0x2a2a500,3, +0x2a2a510,2, +0x2a2a51c,5, +0x2a2a540,8, +0x2a2a580,3, +0x2a2a590,2, +0x2a2a59c,5, +0x2a2a5c0,8, +0x2a2a600,7, +0x2a2a620,12, +0x2a2a680,7, +0x2a2a6a0,12, +0x2a2a700,3, +0x2a2a710,1, +0x2a2a804,1, +0x2a2a824,21, +0x2a2a880,16, +0x2a2a900,5, +0x2a2a920,11, +0x2a2a950,9, +0x2a2a980,22, +0x2a2aa00,22, +0x2a2aa80,22, +0x2a2ab00,22, +0x2a2ab80,22, +0x2a2ac00,22, +0x2a2ac80,22, +0x2a2ad00,22, +0x2a2ad80,3, +0x2a2c000,16, +0x2a2c080,11, +0x2a2c100,11, +0x2a2c204,1, +0x2a2c224,21, +0x2a2c280,16, +0x2a2c300,11, +0x2a2c340,11, +0x2a2c800,21, +0x2a2c860,5, +0x2a2c880,6, +0x2a2c8a0,5, +0x2a2c8c0,6, +0x2a2c900,21, +0x2a2c960,5, +0x2a2c980,6, +0x2a2c9a0,5, +0x2a2c9c0,6, +0x2a2ca00,21, +0x2a2ca60,5, +0x2a2ca80,6, +0x2a2caa0,5, +0x2a2cac0,6, +0x2a2cb00,21, +0x2a2cb60,5, +0x2a2cb80,6, +0x2a2cba0,5, +0x2a2cbc0,6, +0x2a2cc00,9, +0x2a2cc48,7, +0x2a2cc68,2, +0x2a2cc74,9, +0x2a2cc9c,2, +0x2a2cd00,14, +0x2a2cd40,14, +0x2a2cd80,28, +0x2a2ce00,19, +0x2a2ce50,3, +0x2a2ce60,25, +0x2a2cec8,1, +0x2a2ced0,2, +0x2a2cee0,7, +0x2a2cf00,1, +0x2a2cf08,2, +0x2a2cffc,20, +0x2a2d050,25, +0x2a2d100,19, +0x2a2d150,25, +0x2a2d200,19, +0x2a2d250,25, +0x2a2d300,19, +0x2a2d350,25, +0x2a2d400,19, +0x2a2d450,25, +0x2a2d500,19, +0x2a2d550,25, +0x2a2d600,19, +0x2a2d650,25, +0x2a2d700,19, +0x2a2d750,25, +0x2a2d800,19, +0x2a2d850,25, +0x2a2d904,1, +0x2a2d914,10, +0x2a2d948,11, +0x2a2d980,2, +0x2a2d9a0,6, +0x2a2d9c0,2, +0x2a2d9cc,2, +0x2a2e000,35, +0x2a2ea00,10, +0x2a2ea80,3, +0x2a2eb00,6, +0x2a2f000,1, +0x2a2f008,5, +0x2a2f038,1, +0x2a2f044,1, +0x2a2f050,2, +0x2a2f100,13, +0x2a2f140,11, +0x2a2f170,12, +0x2a2f1a4,1, +0x2a2f200,104, +0x2a2f400,104, +0x2a2f600,104, +0x2a2f800,104, +0x2a30000,13, +0x2a30040,2, +0x2a30054,4, +0x2a30080,27, +0x2a30100,12, +0x2a30140,14, +0x2a30180,28, +0x2a30200,6, +0x2a30240,6, +0x2a3025c,3, +0x2a30280,5, +0x2a302a0,8, +0x2a30400,14, +0x2a30440,14, +0x2a30480,14, +0x2a304c0,14, +0x2a30540,3, +0x2a30600,7, +0x2a30620,14, +0x2a30680,5, +0x2a306a0,7, +0x2a30800,13, +0x2a30840,2, +0x2a30854,4, +0x2a30880,27, +0x2a30900,12, +0x2a30940,14, +0x2a30980,28, +0x2a30a00,6, +0x2a30a40,6, +0x2a30a5c,3, +0x2a30a80,5, +0x2a30aa0,8, +0x2a30c00,14, +0x2a30c40,14, +0x2a30c80,14, +0x2a30cc0,14, +0x2a30d40,3, +0x2a30e00,7, +0x2a30e20,14, +0x2a30e80,5, +0x2a30ea0,7, +0x2a31000,13, +0x2a31040,2, +0x2a31054,4, +0x2a31080,27, +0x2a31100,12, +0x2a31140,14, +0x2a31180,28, +0x2a31200,6, +0x2a31240,6, +0x2a3125c,3, +0x2a31280,5, +0x2a312a0,8, +0x2a31400,14, +0x2a31440,14, +0x2a31480,14, +0x2a314c0,14, +0x2a31540,3, +0x2a31600,7, +0x2a31620,14, +0x2a31680,5, +0x2a316a0,7, +0x2a31800,13, +0x2a31840,2, +0x2a31854,4, +0x2a31880,27, +0x2a31900,12, +0x2a31940,14, +0x2a31980,28, +0x2a31a00,6, +0x2a31a40,6, +0x2a31a5c,3, +0x2a31a80,5, +0x2a31aa0,8, +0x2a31c00,14, +0x2a31c40,14, +0x2a31c80,14, +0x2a31cc0,14, +0x2a31d40,3, +0x2a31e00,7, +0x2a31e20,14, +0x2a31e80,5, +0x2a31ea0,7, +0x2a32000,8, +0x2a32040,8, +0x2a32080,1, +0x2a32098,6, +0x2a32100,10, +0x2a32140,3, +0x2a32150,2, +0x2a32180,2, +0x2a32200,6, +0x2a32220,18, +0x2a32280,4, +0x2a32300,8, +0x2a32400,2, +0x2a32480,2, +0x2a32800,28, +0x2a329f0,4, +0x2a33000,40, +0x2a33100,64, +0x2a33800,56, +0x2a33be0,8, +0x2a34000,13, +0x2a34040,2, +0x2a34054,4, +0x2a34080,27, +0x2a34100,12, +0x2a34140,14, +0x2a34180,28, +0x2a34200,6, +0x2a34240,6, +0x2a3425c,3, +0x2a34280,5, +0x2a342a0,8, +0x2a34400,14, +0x2a34440,14, +0x2a34480,14, +0x2a344c0,14, +0x2a34540,3, +0x2a34600,7, +0x2a34620,14, +0x2a34680,5, +0x2a346a0,7, +0x2a34800,13, +0x2a34840,2, +0x2a34854,4, +0x2a34880,27, +0x2a34900,12, +0x2a34940,14, +0x2a34980,28, +0x2a34a00,6, +0x2a34a40,6, +0x2a34a5c,3, +0x2a34a80,5, +0x2a34aa0,8, +0x2a34c00,14, +0x2a34c40,14, +0x2a34c80,14, +0x2a34cc0,14, +0x2a34d40,3, +0x2a34e00,7, +0x2a34e20,14, +0x2a34e80,5, +0x2a34ea0,7, +0x2a35000,13, +0x2a35040,2, +0x2a35054,4, +0x2a35080,27, +0x2a35100,12, +0x2a35140,14, +0x2a35180,28, +0x2a35200,6, +0x2a35240,6, +0x2a3525c,3, +0x2a35280,5, +0x2a352a0,8, +0x2a35400,14, +0x2a35440,14, +0x2a35480,14, +0x2a354c0,14, +0x2a35540,3, +0x2a35600,7, +0x2a35620,14, +0x2a35680,5, +0x2a356a0,7, +0x2a35800,13, +0x2a35840,2, +0x2a35854,4, +0x2a35880,27, +0x2a35900,12, +0x2a35940,14, +0x2a35980,28, +0x2a35a00,6, +0x2a35a40,6, +0x2a35a5c,3, +0x2a35a80,5, +0x2a35aa0,8, +0x2a35c00,14, +0x2a35c40,14, +0x2a35c80,14, +0x2a35cc0,14, +0x2a35d40,3, +0x2a35e00,7, +0x2a35e20,14, +0x2a35e80,5, +0x2a35ea0,7, +0x2a36000,8, +0x2a36040,8, +0x2a36080,1, +0x2a36098,6, +0x2a36100,10, +0x2a36140,3, +0x2a36150,2, +0x2a36180,2, +0x2a36200,6, +0x2a36220,18, +0x2a36280,4, +0x2a36300,8, +0x2a36400,2, +0x2a36480,2, +0x2a36800,28, +0x2a369f0,4, +0x2a37000,40, +0x2a37100,64, +0x2a37800,56, +0x2a37be0,8, +0x2a38000,2, +0x2a3800c,2, +0x2a38040,7, +0x2a38100,3, +0x2a38110,3, +0x2a38120,5, +0x2a38200,6, +0x2a38240,5, +0x2a38400,2, +0x2a3840c,2, +0x2a38440,7, +0x2a38500,3, +0x2a38510,3, +0x2a38520,5, +0x2a38600,6, +0x2a38640,5, +0x2a38800,2, +0x2a3880c,2, +0x2a38840,7, +0x2a38900,3, +0x2a38910,3, +0x2a38920,5, +0x2a38a00,6, +0x2a38a40,5, +0x2a38c00,2, +0x2a38c0c,2, +0x2a38c40,7, +0x2a38d00,3, +0x2a38d10,3, +0x2a38d20,5, +0x2a38e00,6, +0x2a38e40,5, +0x2a39000,2, +0x2a3900c,2, +0x2a39040,7, +0x2a39100,3, +0x2a39110,3, +0x2a39120,5, +0x2a39200,6, +0x2a39240,5, +0x2a39400,2, +0x2a3940c,2, +0x2a39440,7, +0x2a39500,3, +0x2a39510,3, +0x2a39520,5, +0x2a39600,6, +0x2a39640,5, +0x2a39800,2, +0x2a3980c,2, +0x2a39840,7, +0x2a39900,3, +0x2a39910,3, +0x2a39920,5, +0x2a39a00,6, +0x2a39a40,5, +0x2a39c00,2, +0x2a39c0c,2, +0x2a39c40,7, +0x2a39d00,3, +0x2a39d10,3, +0x2a39d20,5, +0x2a39e00,6, +0x2a39e40,5, +0x2a3a000,5, +0x2a3a040,9, +0x2a3a100,3, +0x2a3a200,1, +0x2a3a210,1, +0x2a3a220,1, +0x2a3a230,1, +0x2a3a240,1, +0x2a3a300,3, +0x2a3a314,1, +0x2a3a320,4, +0x2a3a400,5, +0x2a3a440,5, +0x2a3b000,80, +0x2a3b200,1, +0x2a40004,5, +0x2a40020,3, +0x2a40030,3, +0x2a40040,13, +0x2a40078,4, +0x2a4009c,25, +0x2a40104,5, +0x2a40120,3, +0x2a40130,3, +0x2a40140,13, +0x2a40178,4, +0x2a4019c,25, +0x2a40204,5, +0x2a40220,3, +0x2a40230,3, +0x2a40240,13, +0x2a40278,4, +0x2a4029c,25, +0x2a40304,5, +0x2a40320,3, +0x2a40330,3, +0x2a40340,13, +0x2a40378,4, +0x2a4039c,25, +0x2a40600,4, +0x2a40c00,24, +0x2a40c80,24, +0x2a40d00,24, +0x2a40d80,24, +0x2a40e00,4, +0x2a40e20,4, +0x2a40e40,4, +0x2a40e60,4, +0x2a40e80,39, +0x2a40f20,7, +0x2a40f40,7, +0x2a40f60,7, +0x2a41000,12, +0x2a41200,1, +0x2a41218,2, +0x2a4122c,1, +0x2a41280,1, +0x2a41298,2, +0x2a412ac,1, +0x2a41300,1, +0x2a41318,2, +0x2a4132c,1, +0x2a41380,1, +0x2a41398,2, +0x2a413ac,1, +0x2a41400,4, +0x2a41420,2, +0x2a4142c,1, +0x2a41480,4, +0x2a414a0,2, +0x2a414ac,1, +0x2a41500,4, +0x2a41520,2, +0x2a4152c,1, +0x2a41580,4, +0x2a415a0,2, +0x2a415ac,1, +0x2a41600,4, +0x2a41640,4, +0x2a41680,4, +0x2a416c0,4, +0x2a41700,7, +0x2a41720,7, +0x2a41740,7, +0x2a41760,7, +0x2a41780,4, +0x2a4179c,11, +0x2a417d0,2, +0x2a417e0,2, +0x2a417f0,2, +0x2a41900,44, +0x2a42000,7, +0x2a42020,4, +0x2a42040,4, +0x2a42060,7, +0x2a42080,7, +0x2a420a0,4, +0x2a420c0,4, +0x2a420e0,7, +0x2a42100,7, +0x2a42120,4, +0x2a42140,4, +0x2a42160,7, +0x2a42180,7, +0x2a421a0,4, +0x2a421c0,4, +0x2a421e0,7, +0x2a42200,32, +0x2a42b00,1, +0x2a42b20,1, +0x2a42b28,4, +0x2a42b40,1, +0x2a42b60,1, +0x2a42b68,4, +0x2a42b80,1, +0x2a42ba0,1, +0x2a42ba8,4, +0x2a42bc0,1, +0x2a42be0,1, +0x2a42be8,4, +0x2a42c00,7, +0x2a42c20,1, +0x2a42c54,18, +0x2a42ca0,1, +0x2a42cd4,18, +0x2a42d20,1, +0x2a42d54,18, +0x2a42da0,1, +0x2a42dd4,12, +0x2a42e08,6, +0x2a43100,7, +0x2a43120,7, +0x2a43140,7, +0x2a43160,7, +0x2a43180,3, +0x2a44004,5, +0x2a44020,3, +0x2a44030,3, +0x2a44040,13, +0x2a44078,4, +0x2a4409c,25, +0x2a44104,5, +0x2a44120,3, +0x2a44130,3, +0x2a44140,13, +0x2a44178,4, +0x2a4419c,25, +0x2a44204,5, +0x2a44220,3, +0x2a44230,3, +0x2a44240,13, +0x2a44278,4, +0x2a4429c,25, +0x2a44304,5, +0x2a44320,3, +0x2a44330,3, +0x2a44340,13, +0x2a44378,4, +0x2a4439c,25, +0x2a44600,4, +0x2a44c00,24, +0x2a44c80,24, +0x2a44d00,24, +0x2a44d80,24, +0x2a44e00,4, +0x2a44e20,4, +0x2a44e40,4, +0x2a44e60,4, +0x2a44e80,39, +0x2a44f20,7, +0x2a44f40,7, +0x2a44f60,7, +0x2a45000,12, +0x2a45200,1, +0x2a45218,2, +0x2a4522c,1, +0x2a45280,1, +0x2a45298,2, +0x2a452ac,1, +0x2a45300,1, +0x2a45318,2, +0x2a4532c,1, +0x2a45380,1, +0x2a45398,2, +0x2a453ac,1, +0x2a45400,4, +0x2a45420,2, +0x2a4542c,1, +0x2a45480,4, +0x2a454a0,2, +0x2a454ac,1, +0x2a45500,4, +0x2a45520,2, +0x2a4552c,1, +0x2a45580,4, +0x2a455a0,2, +0x2a455ac,1, +0x2a45600,4, +0x2a45640,4, +0x2a45680,4, +0x2a456c0,4, +0x2a45700,7, +0x2a45720,7, +0x2a45740,7, +0x2a45760,7, +0x2a45780,4, +0x2a4579c,11, +0x2a457d0,2, +0x2a457e0,2, +0x2a457f0,2, +0x2a45900,44, +0x2a46000,7, +0x2a46020,4, +0x2a46040,4, +0x2a46060,7, +0x2a46080,7, +0x2a460a0,4, +0x2a460c0,4, +0x2a460e0,7, +0x2a46100,7, +0x2a46120,4, +0x2a46140,4, +0x2a46160,7, +0x2a46180,7, +0x2a461a0,4, +0x2a461c0,4, +0x2a461e0,7, +0x2a46200,32, +0x2a46b00,1, +0x2a46b20,1, +0x2a46b28,4, +0x2a46b40,1, +0x2a46b60,1, +0x2a46b68,4, +0x2a46b80,1, +0x2a46ba0,1, +0x2a46ba8,4, +0x2a46bc0,1, +0x2a46be0,1, +0x2a46be8,4, +0x2a46c00,7, +0x2a46c20,1, +0x2a46c54,18, +0x2a46ca0,1, +0x2a46cd4,18, +0x2a46d20,1, +0x2a46d54,18, +0x2a46da0,1, +0x2a46dd4,12, +0x2a46e08,6, +0x2a47100,7, +0x2a47120,7, +0x2a47140,7, +0x2a47160,7, +0x2a47180,3, +0x2a48000,10, +0x2a48080,3, +0x2a480c0,1, +0x2a48100,21, +0x2a48180,13, +0x2a481c4,7, +0x2a481e4,7, +0x2a48204,7, +0x2a48224,8, +0x2a49000,7, +0x2a49030,2, +0x2a49040,7, +0x2a49070,2, +0x2a49100,2, +0x2a49120,2, +0x2a49140,2, +0x2a49160,2, +0x2a49180,9, +0x2a49200,7, +0x2a49230,2, +0x2a49240,7, +0x2a49270,2, +0x2a49300,2, +0x2a49320,2, +0x2a49340,2, +0x2a49360,2, +0x2a49380,9, +0x2a49400,11, +0x2a49500,11, +0x2a4a000,3, +0x2a4a010,2, +0x2a4a01c,5, +0x2a4a040,8, +0x2a4a080,3, +0x2a4a090,2, +0x2a4a09c,5, +0x2a4a0c0,8, +0x2a4a100,3, +0x2a4a110,2, +0x2a4a11c,5, +0x2a4a140,8, +0x2a4a180,3, +0x2a4a190,2, +0x2a4a19c,5, +0x2a4a1c0,8, +0x2a4a200,7, +0x2a4a220,12, +0x2a4a280,7, +0x2a4a2a0,12, +0x2a4a300,3, +0x2a4a310,1, +0x2a4a400,3, +0x2a4a410,2, +0x2a4a41c,5, +0x2a4a440,8, +0x2a4a480,3, +0x2a4a490,2, +0x2a4a49c,5, +0x2a4a4c0,8, +0x2a4a500,3, +0x2a4a510,2, +0x2a4a51c,5, +0x2a4a540,8, +0x2a4a580,3, +0x2a4a590,2, +0x2a4a59c,5, +0x2a4a5c0,8, +0x2a4a600,7, +0x2a4a620,12, +0x2a4a680,7, +0x2a4a6a0,12, +0x2a4a700,3, +0x2a4a710,1, +0x2a4a804,1, +0x2a4a824,21, +0x2a4a880,16, +0x2a4a900,5, +0x2a4a920,11, +0x2a4a950,9, +0x2a4a980,22, +0x2a4aa00,22, +0x2a4aa80,22, +0x2a4ab00,22, +0x2a4ab80,22, +0x2a4ac00,22, +0x2a4ac80,22, +0x2a4ad00,22, +0x2a4ad80,3, +0x2a4c000,16, +0x2a4c080,11, +0x2a4c100,11, +0x2a4c204,1, +0x2a4c224,21, +0x2a4c280,16, +0x2a4c300,11, +0x2a4c340,11, +0x2a4c800,21, +0x2a4c860,5, +0x2a4c880,6, +0x2a4c8a0,5, +0x2a4c8c0,6, +0x2a4c900,21, +0x2a4c960,5, +0x2a4c980,6, +0x2a4c9a0,5, +0x2a4c9c0,6, +0x2a4ca00,21, +0x2a4ca60,5, +0x2a4ca80,6, +0x2a4caa0,5, +0x2a4cac0,6, +0x2a4cb00,21, +0x2a4cb60,5, +0x2a4cb80,6, +0x2a4cba0,5, +0x2a4cbc0,6, +0x2a4cc00,9, +0x2a4cc48,7, +0x2a4cc68,2, +0x2a4cc74,9, +0x2a4cc9c,2, +0x2a4cd00,14, +0x2a4cd40,14, +0x2a4cd80,28, +0x2a4ce00,19, +0x2a4ce50,3, +0x2a4ce60,25, +0x2a4cec8,1, +0x2a4ced0,2, +0x2a4cee0,7, +0x2a4cf00,1, +0x2a4cf08,2, +0x2a4cffc,20, +0x2a4d050,25, +0x2a4d100,19, +0x2a4d150,25, +0x2a4d200,19, +0x2a4d250,25, +0x2a4d300,19, +0x2a4d350,25, +0x2a4d400,19, +0x2a4d450,25, +0x2a4d500,19, +0x2a4d550,25, +0x2a4d600,19, +0x2a4d650,25, +0x2a4d700,19, +0x2a4d750,25, +0x2a4d800,19, +0x2a4d850,25, +0x2a4d904,1, +0x2a4d914,10, +0x2a4d948,11, +0x2a4d980,2, +0x2a4d9a0,6, +0x2a4d9c0,2, +0x2a4d9cc,2, +0x2a4e000,35, +0x2a4ea00,10, +0x2a4ea80,3, +0x2a4eb00,6, +0x2a4f000,1, +0x2a4f008,5, +0x2a4f038,1, +0x2a4f044,1, +0x2a4f050,2, +0x2a4f100,13, +0x2a4f140,11, +0x2a4f170,12, +0x2a4f1a4,1, +0x2a4f200,104, +0x2a4f400,104, +0x2a4f600,104, +0x2a4f800,104, +0x2a50000,13, +0x2a50040,2, +0x2a50054,4, +0x2a50080,27, +0x2a50100,12, +0x2a50140,14, +0x2a50180,28, +0x2a50200,6, +0x2a50240,6, +0x2a5025c,3, +0x2a50280,5, +0x2a502a0,8, +0x2a50400,14, +0x2a50440,14, +0x2a50480,14, +0x2a504c0,14, +0x2a50540,3, +0x2a50600,7, +0x2a50620,14, +0x2a50680,5, +0x2a506a0,7, +0x2a50800,13, +0x2a50840,2, +0x2a50854,4, +0x2a50880,27, +0x2a50900,12, +0x2a50940,14, +0x2a50980,28, +0x2a50a00,6, +0x2a50a40,6, +0x2a50a5c,3, +0x2a50a80,5, +0x2a50aa0,8, +0x2a50c00,14, +0x2a50c40,14, +0x2a50c80,14, +0x2a50cc0,14, +0x2a50d40,3, +0x2a50e00,7, +0x2a50e20,14, +0x2a50e80,5, +0x2a50ea0,7, +0x2a51000,13, +0x2a51040,2, +0x2a51054,4, +0x2a51080,27, +0x2a51100,12, +0x2a51140,14, +0x2a51180,28, +0x2a51200,6, +0x2a51240,6, +0x2a5125c,3, +0x2a51280,5, +0x2a512a0,8, +0x2a51400,14, +0x2a51440,14, +0x2a51480,14, +0x2a514c0,14, +0x2a51540,3, +0x2a51600,7, +0x2a51620,14, +0x2a51680,5, +0x2a516a0,7, +0x2a51800,13, +0x2a51840,2, +0x2a51854,4, +0x2a51880,27, +0x2a51900,12, +0x2a51940,14, +0x2a51980,28, +0x2a51a00,6, +0x2a51a40,6, +0x2a51a5c,3, +0x2a51a80,5, +0x2a51aa0,8, +0x2a51c00,14, +0x2a51c40,14, +0x2a51c80,14, +0x2a51cc0,14, +0x2a51d40,3, +0x2a51e00,7, +0x2a51e20,14, +0x2a51e80,5, +0x2a51ea0,7, +0x2a52000,8, +0x2a52040,8, +0x2a52080,1, +0x2a52098,6, +0x2a52100,10, +0x2a52140,3, +0x2a52150,2, +0x2a52180,2, +0x2a52200,6, +0x2a52220,18, +0x2a52280,4, +0x2a52300,8, +0x2a52400,2, +0x2a52480,2, +0x2a52800,28, +0x2a529f0,4, +0x2a53000,40, +0x2a53100,64, +0x2a53800,56, +0x2a53be0,8, +0x2a54000,13, +0x2a54040,2, +0x2a54054,4, +0x2a54080,27, +0x2a54100,12, +0x2a54140,14, +0x2a54180,28, +0x2a54200,6, +0x2a54240,6, +0x2a5425c,3, +0x2a54280,5, +0x2a542a0,8, +0x2a54400,14, +0x2a54440,14, +0x2a54480,14, +0x2a544c0,14, +0x2a54540,3, +0x2a54600,7, +0x2a54620,14, +0x2a54680,5, +0x2a546a0,7, +0x2a54800,13, +0x2a54840,2, +0x2a54854,4, +0x2a54880,27, +0x2a54900,12, +0x2a54940,14, +0x2a54980,28, +0x2a54a00,6, +0x2a54a40,6, +0x2a54a5c,3, +0x2a54a80,5, +0x2a54aa0,8, +0x2a54c00,14, +0x2a54c40,14, +0x2a54c80,14, +0x2a54cc0,14, +0x2a54d40,3, +0x2a54e00,7, +0x2a54e20,14, +0x2a54e80,5, +0x2a54ea0,7, +0x2a55000,13, +0x2a55040,2, +0x2a55054,4, +0x2a55080,27, +0x2a55100,12, +0x2a55140,14, +0x2a55180,28, +0x2a55200,6, +0x2a55240,6, +0x2a5525c,3, +0x2a55280,5, +0x2a552a0,8, +0x2a55400,14, +0x2a55440,14, +0x2a55480,14, +0x2a554c0,14, +0x2a55540,3, +0x2a55600,7, +0x2a55620,14, +0x2a55680,5, +0x2a556a0,7, +0x2a55800,13, +0x2a55840,2, +0x2a55854,4, +0x2a55880,27, +0x2a55900,12, +0x2a55940,14, +0x2a55980,28, +0x2a55a00,6, +0x2a55a40,6, +0x2a55a5c,3, +0x2a55a80,5, +0x2a55aa0,8, +0x2a55c00,14, +0x2a55c40,14, +0x2a55c80,14, +0x2a55cc0,14, +0x2a55d40,3, +0x2a55e00,7, +0x2a55e20,14, +0x2a55e80,5, +0x2a55ea0,7, +0x2a56000,8, +0x2a56040,8, +0x2a56080,1, +0x2a56098,6, +0x2a56100,10, +0x2a56140,3, +0x2a56150,2, +0x2a56180,2, +0x2a56200,6, +0x2a56220,18, +0x2a56280,4, +0x2a56300,8, +0x2a56400,2, +0x2a56480,2, +0x2a56800,28, +0x2a569f0,4, +0x2a57000,40, +0x2a57100,64, +0x2a57800,56, +0x2a57be0,8, +0x2a58000,2, +0x2a5800c,2, +0x2a58040,7, +0x2a58100,3, +0x2a58110,3, +0x2a58120,5, +0x2a58200,6, +0x2a58240,5, +0x2a58400,2, +0x2a5840c,2, +0x2a58440,7, +0x2a58500,3, +0x2a58510,3, +0x2a58520,5, +0x2a58600,6, +0x2a58640,5, +0x2a58800,2, +0x2a5880c,2, +0x2a58840,7, +0x2a58900,3, +0x2a58910,3, +0x2a58920,5, +0x2a58a00,6, +0x2a58a40,5, +0x2a58c00,2, +0x2a58c0c,2, +0x2a58c40,7, +0x2a58d00,3, +0x2a58d10,3, +0x2a58d20,5, +0x2a58e00,6, +0x2a58e40,5, +0x2a59000,2, +0x2a5900c,2, +0x2a59040,7, +0x2a59100,3, +0x2a59110,3, +0x2a59120,5, +0x2a59200,6, +0x2a59240,5, +0x2a59400,2, +0x2a5940c,2, +0x2a59440,7, +0x2a59500,3, +0x2a59510,3, +0x2a59520,5, +0x2a59600,6, +0x2a59640,5, +0x2a59800,2, +0x2a5980c,2, +0x2a59840,7, +0x2a59900,3, +0x2a59910,3, +0x2a59920,5, +0x2a59a00,6, +0x2a59a40,5, +0x2a59c00,2, +0x2a59c0c,2, +0x2a59c40,7, +0x2a59d00,3, +0x2a59d10,3, +0x2a59d20,5, +0x2a59e00,6, +0x2a59e40,5, +0x2a5a000,5, +0x2a5a040,9, +0x2a5a100,3, +0x2a5a200,1, +0x2a5a210,1, +0x2a5a220,1, +0x2a5a230,1, +0x2a5a240,1, +0x2a5a300,3, +0x2a5a314,1, +0x2a5a320,4, +0x2a5a400,5, +0x2a5a440,5, +0x2a5b000,80, +0x2a5b200,1, +0x2a60004,5, +0x2a60020,3, +0x2a60030,3, +0x2a60040,13, +0x2a60078,4, +0x2a6009c,25, +0x2a60104,5, +0x2a60120,3, +0x2a60130,3, +0x2a60140,13, +0x2a60178,4, +0x2a6019c,25, +0x2a60204,5, +0x2a60220,3, +0x2a60230,3, +0x2a60240,13, +0x2a60278,4, +0x2a6029c,25, +0x2a60304,5, +0x2a60320,3, +0x2a60330,3, +0x2a60340,13, +0x2a60378,4, +0x2a6039c,25, +0x2a60600,4, +0x2a60c00,24, +0x2a60c80,24, +0x2a60d00,24, +0x2a60d80,24, +0x2a60e00,4, +0x2a60e20,4, +0x2a60e40,4, +0x2a60e60,4, +0x2a60e80,39, +0x2a60f20,7, +0x2a60f40,7, +0x2a60f60,7, +0x2a61000,12, +0x2a61200,1, +0x2a61218,2, +0x2a6122c,1, +0x2a61280,1, +0x2a61298,2, +0x2a612ac,1, +0x2a61300,1, +0x2a61318,2, +0x2a6132c,1, +0x2a61380,1, +0x2a61398,2, +0x2a613ac,1, +0x2a61400,4, +0x2a61420,2, +0x2a6142c,1, +0x2a61480,4, +0x2a614a0,2, +0x2a614ac,1, +0x2a61500,4, +0x2a61520,2, +0x2a6152c,1, +0x2a61580,4, +0x2a615a0,2, +0x2a615ac,1, +0x2a61600,4, +0x2a61640,4, +0x2a61680,4, +0x2a616c0,4, +0x2a61700,7, +0x2a61720,7, +0x2a61740,7, +0x2a61760,7, +0x2a61780,4, +0x2a6179c,11, +0x2a617d0,2, +0x2a617e0,2, +0x2a617f0,2, +0x2a61900,44, +0x2a62000,7, +0x2a62020,4, +0x2a62040,4, +0x2a62060,7, +0x2a62080,7, +0x2a620a0,4, +0x2a620c0,4, +0x2a620e0,7, +0x2a62100,7, +0x2a62120,4, +0x2a62140,4, +0x2a62160,7, +0x2a62180,7, +0x2a621a0,4, +0x2a621c0,4, +0x2a621e0,7, +0x2a62200,32, +0x2a62b00,1, +0x2a62b20,1, +0x2a62b28,4, +0x2a62b40,1, +0x2a62b60,1, +0x2a62b68,4, +0x2a62b80,1, +0x2a62ba0,1, +0x2a62ba8,4, +0x2a62bc0,1, +0x2a62be0,1, +0x2a62be8,4, +0x2a62c00,7, +0x2a62c20,1, +0x2a62c54,18, +0x2a62ca0,1, +0x2a62cd4,18, +0x2a62d20,1, +0x2a62d54,18, +0x2a62da0,1, +0x2a62dd4,12, +0x2a62e08,6, +0x2a63100,7, +0x2a63120,7, +0x2a63140,7, +0x2a63160,7, +0x2a63180,3, +0x2a64004,5, +0x2a64020,3, +0x2a64030,3, +0x2a64040,13, +0x2a64078,4, +0x2a6409c,25, +0x2a64104,5, +0x2a64120,3, +0x2a64130,3, +0x2a64140,13, +0x2a64178,4, +0x2a6419c,25, +0x2a64204,5, +0x2a64220,3, +0x2a64230,3, +0x2a64240,13, +0x2a64278,4, +0x2a6429c,25, +0x2a64304,5, +0x2a64320,3, +0x2a64330,3, +0x2a64340,13, +0x2a64378,4, +0x2a6439c,25, +0x2a64600,4, +0x2a64c00,24, +0x2a64c80,24, +0x2a64d00,24, +0x2a64d80,24, +0x2a64e00,4, +0x2a64e20,4, +0x2a64e40,4, +0x2a64e60,4, +0x2a64e80,39, +0x2a64f20,7, +0x2a64f40,7, +0x2a64f60,7, +0x2a65000,12, +0x2a65200,1, +0x2a65218,2, +0x2a6522c,1, +0x2a65280,1, +0x2a65298,2, +0x2a652ac,1, +0x2a65300,1, +0x2a65318,2, +0x2a6532c,1, +0x2a65380,1, +0x2a65398,2, +0x2a653ac,1, +0x2a65400,4, +0x2a65420,2, +0x2a6542c,1, +0x2a65480,4, +0x2a654a0,2, +0x2a654ac,1, +0x2a65500,4, +0x2a65520,2, +0x2a6552c,1, +0x2a65580,4, +0x2a655a0,2, +0x2a655ac,1, +0x2a65600,4, +0x2a65640,4, +0x2a65680,4, +0x2a656c0,4, +0x2a65700,7, +0x2a65720,7, +0x2a65740,7, +0x2a65760,7, +0x2a65780,4, +0x2a6579c,11, +0x2a657d0,2, +0x2a657e0,2, +0x2a657f0,2, +0x2a65900,44, +0x2a66000,7, +0x2a66020,4, +0x2a66040,4, +0x2a66060,7, +0x2a66080,7, +0x2a660a0,4, +0x2a660c0,4, +0x2a660e0,7, +0x2a66100,7, +0x2a66120,4, +0x2a66140,4, +0x2a66160,7, +0x2a66180,7, +0x2a661a0,4, +0x2a661c0,4, +0x2a661e0,7, +0x2a66200,32, +0x2a66b00,1, +0x2a66b20,1, +0x2a66b28,4, +0x2a66b40,1, +0x2a66b60,1, +0x2a66b68,4, +0x2a66b80,1, +0x2a66ba0,1, +0x2a66ba8,4, +0x2a66bc0,1, +0x2a66be0,1, +0x2a66be8,4, +0x2a66c00,7, +0x2a66c20,1, +0x2a66c54,18, +0x2a66ca0,1, +0x2a66cd4,18, +0x2a66d20,1, +0x2a66d54,18, +0x2a66da0,1, +0x2a66dd4,12, +0x2a66e08,6, +0x2a67100,7, +0x2a67120,7, +0x2a67140,7, +0x2a67160,7, +0x2a67180,3, +0x2a68000,10, +0x2a68080,3, +0x2a680c0,1, +0x2a68100,21, +0x2a68180,13, +0x2a681c4,7, +0x2a681e4,7, +0x2a68204,7, +0x2a68224,8, +0x2a69000,7, +0x2a69030,2, +0x2a69040,7, +0x2a69070,2, +0x2a69100,2, +0x2a69120,2, +0x2a69140,2, +0x2a69160,2, +0x2a69180,9, +0x2a69200,7, +0x2a69230,2, +0x2a69240,7, +0x2a69270,2, +0x2a69300,2, +0x2a69320,2, +0x2a69340,2, +0x2a69360,2, +0x2a69380,9, +0x2a69400,11, +0x2a69500,11, +0x2a6a000,3, +0x2a6a010,2, +0x2a6a01c,5, +0x2a6a040,8, +0x2a6a080,3, +0x2a6a090,2, +0x2a6a09c,5, +0x2a6a0c0,8, +0x2a6a100,3, +0x2a6a110,2, +0x2a6a11c,5, +0x2a6a140,8, +0x2a6a180,3, +0x2a6a190,2, +0x2a6a19c,5, +0x2a6a1c0,8, +0x2a6a200,7, +0x2a6a220,12, +0x2a6a280,7, +0x2a6a2a0,12, +0x2a6a300,3, +0x2a6a310,1, +0x2a6a400,3, +0x2a6a410,2, +0x2a6a41c,5, +0x2a6a440,8, +0x2a6a480,3, +0x2a6a490,2, +0x2a6a49c,5, +0x2a6a4c0,8, +0x2a6a500,3, +0x2a6a510,2, +0x2a6a51c,5, +0x2a6a540,8, +0x2a6a580,3, +0x2a6a590,2, +0x2a6a59c,5, +0x2a6a5c0,8, +0x2a6a600,7, +0x2a6a620,12, +0x2a6a680,7, +0x2a6a6a0,12, +0x2a6a700,3, +0x2a6a710,1, +0x2a6a804,1, +0x2a6a824,21, +0x2a6a880,16, +0x2a6a900,5, +0x2a6a920,11, +0x2a6a950,9, +0x2a6a980,22, +0x2a6aa00,22, +0x2a6aa80,22, +0x2a6ab00,22, +0x2a6ab80,22, +0x2a6ac00,22, +0x2a6ac80,22, +0x2a6ad00,22, +0x2a6ad80,3, +0x2a6c000,16, +0x2a6c080,11, +0x2a6c100,11, +0x2a6c204,1, +0x2a6c224,21, +0x2a6c280,16, +0x2a6c300,11, +0x2a6c340,11, +0x2a6c800,21, +0x2a6c860,5, +0x2a6c880,6, +0x2a6c8a0,5, +0x2a6c8c0,6, +0x2a6c900,21, +0x2a6c960,5, +0x2a6c980,6, +0x2a6c9a0,5, +0x2a6c9c0,6, +0x2a6ca00,21, +0x2a6ca60,5, +0x2a6ca80,6, +0x2a6caa0,5, +0x2a6cac0,6, +0x2a6cb00,21, +0x2a6cb60,5, +0x2a6cb80,6, +0x2a6cba0,5, +0x2a6cbc0,6, +0x2a6cc00,9, +0x2a6cc48,7, +0x2a6cc68,2, +0x2a6cc74,9, +0x2a6cc9c,2, +0x2a6cd00,14, +0x2a6cd40,14, +0x2a6cd80,28, +0x2a6ce00,19, +0x2a6ce50,3, +0x2a6ce60,25, +0x2a6cec8,1, +0x2a6ced0,2, +0x2a6cee0,7, +0x2a6cf00,1, +0x2a6cf08,2, +0x2a6cffc,20, +0x2a6d050,25, +0x2a6d100,19, +0x2a6d150,25, +0x2a6d200,19, +0x2a6d250,25, +0x2a6d300,19, +0x2a6d350,25, +0x2a6d400,19, +0x2a6d450,25, +0x2a6d500,19, +0x2a6d550,25, +0x2a6d600,19, +0x2a6d650,25, +0x2a6d700,19, +0x2a6d750,25, +0x2a6d800,19, +0x2a6d850,25, +0x2a6d904,1, +0x2a6d914,10, +0x2a6d948,11, +0x2a6d980,2, +0x2a6d9a0,6, +0x2a6d9c0,2, +0x2a6d9cc,2, +0x2a6e000,35, +0x2a6ea00,10, +0x2a6ea80,3, +0x2a6eb00,6, +0x2a6f000,1, +0x2a6f008,5, +0x2a6f038,1, +0x2a6f044,1, +0x2a6f050,2, +0x2a6f100,13, +0x2a6f140,11, +0x2a6f170,12, +0x2a6f1a4,1, +0x2a6f200,104, +0x2a6f400,104, +0x2a6f600,104, +0x2a6f800,104, +0x2a70000,13, +0x2a70040,2, +0x2a70054,4, +0x2a70080,27, +0x2a70100,12, +0x2a70140,14, +0x2a70180,28, +0x2a70200,6, +0x2a70240,6, +0x2a7025c,3, +0x2a70280,5, +0x2a702a0,8, +0x2a70400,14, +0x2a70440,14, +0x2a70480,14, +0x2a704c0,14, +0x2a70540,3, +0x2a70600,7, +0x2a70620,14, +0x2a70680,5, +0x2a706a0,7, +0x2a70800,13, +0x2a70840,2, +0x2a70854,4, +0x2a70880,27, +0x2a70900,12, +0x2a70940,14, +0x2a70980,28, +0x2a70a00,6, +0x2a70a40,6, +0x2a70a5c,3, +0x2a70a80,5, +0x2a70aa0,8, +0x2a70c00,14, +0x2a70c40,14, +0x2a70c80,14, +0x2a70cc0,14, +0x2a70d40,3, +0x2a70e00,7, +0x2a70e20,14, +0x2a70e80,5, +0x2a70ea0,7, +0x2a71000,13, +0x2a71040,2, +0x2a71054,4, +0x2a71080,27, +0x2a71100,12, +0x2a71140,14, +0x2a71180,28, +0x2a71200,6, +0x2a71240,6, +0x2a7125c,3, +0x2a71280,5, +0x2a712a0,8, +0x2a71400,14, +0x2a71440,14, +0x2a71480,14, +0x2a714c0,14, +0x2a71540,3, +0x2a71600,7, +0x2a71620,14, +0x2a71680,5, +0x2a716a0,7, +0x2a71800,13, +0x2a71840,2, +0x2a71854,4, +0x2a71880,27, +0x2a71900,12, +0x2a71940,14, +0x2a71980,28, +0x2a71a00,6, +0x2a71a40,6, +0x2a71a5c,3, +0x2a71a80,5, +0x2a71aa0,8, +0x2a71c00,14, +0x2a71c40,14, +0x2a71c80,14, +0x2a71cc0,14, +0x2a71d40,3, +0x2a71e00,7, +0x2a71e20,14, +0x2a71e80,5, +0x2a71ea0,7, +0x2a72000,8, +0x2a72040,8, +0x2a72080,1, +0x2a72098,6, +0x2a72100,10, +0x2a72140,3, +0x2a72150,2, +0x2a72180,2, +0x2a72200,6, +0x2a72220,18, +0x2a72280,4, +0x2a72300,8, +0x2a72400,2, +0x2a72480,2, +0x2a72800,28, +0x2a729f0,4, +0x2a73000,40, +0x2a73100,64, +0x2a73800,56, +0x2a73be0,8, +0x2a74000,13, +0x2a74040,2, +0x2a74054,4, +0x2a74080,27, +0x2a74100,12, +0x2a74140,14, +0x2a74180,28, +0x2a74200,6, +0x2a74240,6, +0x2a7425c,3, +0x2a74280,5, +0x2a742a0,8, +0x2a74400,14, +0x2a74440,14, +0x2a74480,14, +0x2a744c0,14, +0x2a74540,3, +0x2a74600,7, +0x2a74620,14, +0x2a74680,5, +0x2a746a0,7, +0x2a74800,13, +0x2a74840,2, +0x2a74854,4, +0x2a74880,27, +0x2a74900,12, +0x2a74940,14, +0x2a74980,28, +0x2a74a00,6, +0x2a74a40,6, +0x2a74a5c,3, +0x2a74a80,5, +0x2a74aa0,8, +0x2a74c00,14, +0x2a74c40,14, +0x2a74c80,14, +0x2a74cc0,14, +0x2a74d40,3, +0x2a74e00,7, +0x2a74e20,14, +0x2a74e80,5, +0x2a74ea0,7, +0x2a75000,13, +0x2a75040,2, +0x2a75054,4, +0x2a75080,27, +0x2a75100,12, +0x2a75140,14, +0x2a75180,28, +0x2a75200,6, +0x2a75240,6, +0x2a7525c,3, +0x2a75280,5, +0x2a752a0,8, +0x2a75400,14, +0x2a75440,14, +0x2a75480,14, +0x2a754c0,14, +0x2a75540,3, +0x2a75600,7, +0x2a75620,14, +0x2a75680,5, +0x2a756a0,7, +0x2a75800,13, +0x2a75840,2, +0x2a75854,4, +0x2a75880,27, +0x2a75900,12, +0x2a75940,14, +0x2a75980,28, +0x2a75a00,6, +0x2a75a40,6, +0x2a75a5c,3, +0x2a75a80,5, +0x2a75aa0,8, +0x2a75c00,14, +0x2a75c40,14, +0x2a75c80,14, +0x2a75cc0,14, +0x2a75d40,3, +0x2a75e00,7, +0x2a75e20,14, +0x2a75e80,5, +0x2a75ea0,7, +0x2a76000,8, +0x2a76040,8, +0x2a76080,1, +0x2a76098,6, +0x2a76100,10, +0x2a76140,3, +0x2a76150,2, +0x2a76180,2, +0x2a76200,6, +0x2a76220,18, +0x2a76280,4, +0x2a76300,8, +0x2a76400,2, +0x2a76480,2, +0x2a76800,28, +0x2a769f0,4, +0x2a77000,40, +0x2a77100,64, +0x2a77800,56, +0x2a77be0,8, +0x2a78000,2, +0x2a7800c,2, +0x2a78040,7, +0x2a78100,3, +0x2a78110,3, +0x2a78120,5, +0x2a78200,6, +0x2a78240,5, +0x2a78400,2, +0x2a7840c,2, +0x2a78440,7, +0x2a78500,3, +0x2a78510,3, +0x2a78520,5, +0x2a78600,6, +0x2a78640,5, +0x2a78800,2, +0x2a7880c,2, +0x2a78840,7, +0x2a78900,3, +0x2a78910,3, +0x2a78920,5, +0x2a78a00,6, +0x2a78a40,5, +0x2a78c00,2, +0x2a78c0c,2, +0x2a78c40,7, +0x2a78d00,3, +0x2a78d10,3, +0x2a78d20,5, +0x2a78e00,6, +0x2a78e40,5, +0x2a79000,2, +0x2a7900c,2, +0x2a79040,7, +0x2a79100,3, +0x2a79110,3, +0x2a79120,5, +0x2a79200,6, +0x2a79240,5, +0x2a79400,2, +0x2a7940c,2, +0x2a79440,7, +0x2a79500,3, +0x2a79510,3, +0x2a79520,5, +0x2a79600,6, +0x2a79640,5, +0x2a79800,2, +0x2a7980c,2, +0x2a79840,7, +0x2a79900,3, +0x2a79910,3, +0x2a79920,5, +0x2a79a00,6, +0x2a79a40,5, +0x2a79c00,2, +0x2a79c0c,2, +0x2a79c40,7, +0x2a79d00,3, +0x2a79d10,3, +0x2a79d20,5, +0x2a79e00,6, +0x2a79e40,5, +0x2a7a000,5, +0x2a7a040,9, +0x2a7a100,3, +0x2a7a200,1, +0x2a7a210,1, +0x2a7a220,1, +0x2a7a230,1, +0x2a7a240,1, +0x2a7a300,3, +0x2a7a314,1, +0x2a7a320,4, +0x2a7a400,5, +0x2a7a440,5, +0x2a7b000,80, +0x2a7b200,1, +0x2a80000,3, +0x2a80010,7, +0x2a80030,10, +0x2a80080,2, +0x2a80100,6, +0x2a80140,2, +0x2a80180,2, +0x2a801a0,1, +0x2a80400,2, +0x2a80440,4, +0x2a80460,5, +0x2a80478,1, +0x2a80480,6, +0x2a804a0,3, +0x2a804b0,2, +0x2a80500,5, +0x2a80600,1, +0x2a80800,5, +0x2a80900,5, +0x2a80a00,5, +0x2a80b00,3, +0x2a80c00,35, +0x2a80d00,25, +0x2a80d80,1, +0x2a80dc0,3, +0x2a80e00,2, +0x2a80e20,2, +0x2a90000,3, +0x2a9001c,6, +0x2a90080,3, +0x2a90090,2, +0x2a900d4,4, +0x2a900ec,27, +0x2a9015c,27, +0x2a901cc,19, +0x2a90224,120, +0x2a90408,109, +0x2a905f8,4, +0x2a90610,27, +0x2a90680,27, +0x2a906f0,19, +0x2a90748,120, +0x2a9092c,109, +0x2a90b1c,4, +0x2a90b34,27, +0x2a90ba4,27, +0x2a90c14,19, +0x2a90c6c,120, +0x2a90e50,109, +0x2a91040,4, +0x2a91058,27, +0x2a910c8,27, +0x2a91138,19, +0x2a91190,120, +0x2a91374,109, +0x2a91564,4, +0x2a9157c,27, +0x2a915ec,27, +0x2a9165c,19, +0x2a916b4,120, +0x2a91898,109, +0x2a91a88,4, +0x2a91aa0,27, +0x2a91b10,27, +0x2a91b80,19, +0x2a91bd8,120, +0x2a91dbc,109, +0x2a91fac,4, +0x2a91fc4,27, +0x2a92034,27, +0x2a920a4,19, +0x2a920fc,120, +0x2a922e0,109, +0x2a924d0,4, +0x2a924e8,27, +0x2a92558,27, +0x2a925c8,19, +0x2a92620,120, +0x2a92804,109, +0x2a929f4,4, +0x2a92a0c,27, +0x2a92a7c,27, +0x2a92aec,19, +0x2a92b44,120, +0x2a92d28,109, +0x2a92f18,4, +0x2a92f30,27, +0x2a92fa0,27, +0x2a93010,19, +0x2a93068,120, +0x2a9324c,109, +0x2a9343c,4, +0x2a93454,27, +0x2a934c4,27, +0x2a93534,19, +0x2a9358c,120, +0x2a93770,109, +0x2a93960,4, +0x2a93978,27, +0x2a939e8,27, +0x2a93a58,19, +0x2a93ab0,120, +0x2a93c94,109, +0x2a93e84,4, +0x2a93e9c,27, +0x2a93f0c,27, +0x2a93f7c,19, +0x2a93fd4,120, +0x2a941b8,109, +0x2a943a8,4, +0x2a943c0,27, +0x2a94430,27, +0x2a944a0,19, +0x2a944f8,120, +0x2a946dc,109, +0x2a948cc,4, +0x2a948e4,27, +0x2a94954,27, +0x2a949c4,19, +0x2a94a1c,120, +0x2a94c00,109, +0x2a94df0,4, +0x2a94e08,27, +0x2a94e78,27, +0x2a94ee8,19, +0x2a94f40,120, +0x2a95124,109, +0x2a95314,4, +0x2a9532c,27, +0x2a9539c,27, +0x2a9540c,19, +0x2a95464,120, +0x2a95648,109, +0x2a95838,14, +0x2a95940,13, +0x2a95a44,13, +0x2a95b48,16, +0x2a95b90,42, +0x2a95c40,2, +0x2a95c90,54, +0x2a95d70,58, +0x2a95e60,58, +0x2a95f50,58, +0x2a96040,58, +0x2a96130,58, +0x2a96220,58, +0x2a96310,58, +0x2a96400,58, +0x2a964f0,58, +0x2a965e0,58, +0x2a966d0,58, +0x2a967c0,58, +0x2a968b0,58, +0x2a969a0,58, +0x2a96a90,58, +0x2a96b80,58, +0x2a96c70,58, +0x2a96d60,58, +0x2a96e50,58, +0x2a96f40,58, +0x2a97030,58, +0x2a97120,58, +0x2a97210,58, +0x2a97300,58, +0x2a973f0,58, +0x2a974e0,58, +0x2a975d0,58, +0x2a976c0,58, +0x2a977b0,58, +0x2a978a0,58, +0x2a97990,58, +0x2a97a80,101, +0x2a97c90,49, +0x2a97db0,18, +0x2a97e00,11, +0x2a97e30,4, +0x2a97e54,45, +0x2a97f58,9, +0x2a97f88,4, +0x2a97fa0,2, +0x2a97fd8,14, +0x2a98014,12, +0x2a98158,3, +0x2a98168,2, +0x2a98174,68, +0x2a98288,2, +0x2a98294,68, +0x2a983a8,1, +0x2a983b0,2, +0x2a983bc,68, +0x2a984d0,2, +0x2a984dc,68, +0x2a985f0,1, +0x2a985f8,4, +0x2a98610,3, +0x2a98624,12, +0x2a98688,8, +0x2a986dc,1, +0x2a986e8,4, +0x2a98700,3, +0x2a98714,12, +0x2a98778,8, +0x2a987cc,1, +0x2a987d8,4, +0x2a987f0,3, +0x2a98804,12, +0x2a98868,8, +0x2a988bc,1, +0x2a988c8,4, +0x2a988e0,3, +0x2a988f4,12, +0x2a98958,8, +0x2a989ac,1, +0x2a989b8,4, +0x2a989d0,3, +0x2a989e4,12, +0x2a98a48,8, +0x2a98a9c,1, +0x2a98aa8,4, +0x2a98ac0,3, +0x2a98ad4,12, +0x2a98b38,8, +0x2a98b8c,1, +0x2a98b98,4, +0x2a98bb0,3, +0x2a98bc4,12, +0x2a98c28,8, +0x2a98c7c,1, +0x2a98c88,4, +0x2a98ca0,3, +0x2a98cb4,12, +0x2a98d18,8, +0x2a98d6c,1, +0x2a98d78,4, +0x2a98d90,3, +0x2a98da4,12, +0x2a98e08,8, +0x2a98e5c,1, +0x2a98e68,4, +0x2a98e80,3, +0x2a98e94,12, +0x2a98ef8,8, +0x2a98f4c,1, +0x2a98f58,4, +0x2a98f70,3, +0x2a98f84,12, +0x2a98fe8,8, +0x2a9903c,1, +0x2a99048,4, +0x2a99060,3, +0x2a99074,12, +0x2a990d8,8, +0x2a9912c,1, +0x2a99138,4, +0x2a99150,3, +0x2a99164,12, +0x2a991c8,8, +0x2a9921c,1, +0x2a99228,4, +0x2a99240,3, +0x2a99254,12, +0x2a992b8,8, +0x2a9930c,1, +0x2a99318,4, +0x2a99330,3, +0x2a99344,12, +0x2a993a8,8, +0x2a993fc,1, +0x2a99408,4, +0x2a99420,3, +0x2a99434,12, +0x2a99498,8, +0x2a994ec,1, +0x2a994f8,4, +0x2a99510,3, +0x2a99524,12, +0x2a99588,8, +0x2a995dc,1, +0x2a995e8,64, +0x2a99748,5, +0x2a99990,28, +0x2a99a04,4, +0x2a99a98,1, +0x2a99be8,11, +0x2a99c18,13, +0x2a99c50,6, +0x2a9a000,15, +0x2a9a044,81, +0x2a9a18c,84, +0x2a9a2e0,84, +0x2a9a434,84, +0x2a9a588,84, +0x2a9a6dc,84, +0x2a9a830,84, +0x2a9a984,84, +0x2a9aad8,84, +0x2a9ac2c,84, +0x2a9ad80,84, +0x2a9aed4,84, +0x2a9b028,84, +0x2a9b17c,84, +0x2a9b2d0,84, +0x2a9b424,84, +0x2a9b578,84, +0x2a9b6cc,5, +0x2a9b760,4, +0x2a9b8e0,2414, +0x2a9dea4,88, +0x2a9e048,4, +0x2a9ebe0,1, +0x2a9ebf0,97, +0x2a9ed94,7, +0x2a9ee7c,1, +0x2a9eeac,9, +0x2a9eed4,5, +0x2a9eeec,11, +0x2a9ef2c,17, +0x2a9ef74,30, +0x2a9f034,3, +0x2a9f044,2, +0x2a9f054,17, +0x2a9fbe0,3, +0x2a9fbf0,1, +0x2aa0000,3, +0x2aa0018,2, +0x2aa0024,14, +0x2aa0060,27, +0x2aa00d0,3, +0x2aa00e0,3, +0x2aa00f0,3, +0x2aa0100,4, +0x2aa0120,6, +0x2aa0140,3, +0x2aa0150,1, +0x2aa015c,4, +0x2aa0170,1, +0x2aa0180,15, +0x2aa01c0,1, +0x2aa01c8,5, +0x2aa01e0,1, +0x2aa01f0,3, +0x2aa0200,3, +0x2aa0218,2, +0x2aa0224,14, +0x2aa0260,27, +0x2aa02d0,3, +0x2aa02e0,3, +0x2aa02f0,3, +0x2aa0300,4, +0x2aa0320,6, +0x2aa0340,3, +0x2aa0350,1, +0x2aa035c,4, +0x2aa0370,1, +0x2aa0380,15, +0x2aa03c0,1, +0x2aa03c8,5, +0x2aa03e0,1, +0x2aa03f0,3, +0x2aa0400,3, +0x2aa0418,2, +0x2aa0424,14, +0x2aa0460,27, +0x2aa04d0,3, +0x2aa04e0,3, +0x2aa04f0,3, +0x2aa0500,4, +0x2aa0520,6, +0x2aa0540,3, +0x2aa0550,1, +0x2aa055c,4, +0x2aa0570,1, +0x2aa0580,15, +0x2aa05c0,1, +0x2aa05c8,5, +0x2aa05e0,1, +0x2aa05f0,3, +0x2aa0600,3, +0x2aa0618,2, +0x2aa0624,14, +0x2aa0660,27, +0x2aa06d0,3, +0x2aa06e0,3, +0x2aa06f0,3, +0x2aa0700,4, +0x2aa0720,6, +0x2aa0740,3, +0x2aa0750,1, +0x2aa075c,4, +0x2aa0770,1, +0x2aa0780,15, +0x2aa07c0,1, +0x2aa07c8,5, +0x2aa07e0,1, +0x2aa07f0,3, +0x2aa0800,3, +0x2aa0818,2, +0x2aa0824,14, +0x2aa0860,27, +0x2aa08d0,3, +0x2aa08e0,3, +0x2aa08f0,3, +0x2aa0900,4, +0x2aa0920,6, +0x2aa0940,3, +0x2aa0950,1, +0x2aa095c,4, +0x2aa0970,1, +0x2aa0980,15, +0x2aa09c0,1, +0x2aa09c8,5, +0x2aa09e0,1, +0x2aa09f0,3, +0x2aa1844,1, +0x2aa1858,5, +0x2aa1904,3, +0x2aa1950,3, +0x2aa1988,2, +0x2aa19a0,7, +0x2aa19c0,7, +0x2aa19e0,4, +0x2aa2000,24, +0x2aa20f0,3, +0x2aa2100,7, +0x2aa2120,7, +0x2aa2144,7, +0x2aa2400,4, +0x2aa2420,5, +0x2aa25e0,3, +0x2aa25f4,1, +0x2aa25fc,4, +0x2aa2620,3, +0x2aa2680,8, +0x2aa2700,19, +0x2aa2800,99, +0x2aa2a00,18, +0x2aa2a80,8, +0x2aa2b00,1, +0x2aa3070,1, +0x2aa3080,2, +0x2aa308c,1, +0x2aa3098,2, +0x2aa3404,1, +0x2aa3440,20, +0x2aa3494,1, +0x2aa349c,7, +0x2aa34d0,4, +0x2aa34e8,2, +0x2aa34fc,8, +0x2aa3520,7, +0x2aa3540,7, +0x2aa3560,7, +0x2aa3580,7, +0x2aa35a0,7, +0x2aa35c0,7, +0x2aa35e0,7, +0x2aa3600,9, +0x2aa363c,2, +0x2aa3650,6, +0x2aa3684,10, +0x2aa3a00,10, +0x2aa3a30,1, +0x2aa3a40,8, +0x2aa3a64,5, +0x2aa4a04,3, +0x2aa4b00,33, +0x2aa4b90,3, +0x2aa5000,8, +0x2aa5040,8, +0x2aa5104,1, +0x2aa510c,3, +0x2aa5124,1, +0x2aa512c,3, +0x2aa6000,13, +0x2aa6200,14, +0x2aa6240,1, +0x2aa6248,1, +0x2aa6258,1, +0x2aa6260,8, +0x2aa6284,1, +0x2aa62a0,8, +0x2aa6348,5, +0x2aa67f0,1, +0x2aa67f8,1, +0x2aa6a10,12, +0x2aa7000,19, +0x2aa7a00,10, +0x2aa7a80,3, +0x2aa7b00,6, +0x2ac0000,1, +0x2ac000c,5, +0x2ac0044,1, +0x2ac0054,5, +0x2ac0200,128, +0x2ac0404,1, +0x2ac0428,54, +0x2ac0600,32, +0x2ac0704,1, +0x2ac0800,1, +0x2ac0900,1, +0x2ac0910,2, +0x2ac0920,3, +0x2ac0980,10, +0x2ac0a00,19, +0x2ac0b00,1, +0x2ae0000,2, +0x2ae000c,2, +0x2ae0018,2, +0x2ae0024,2, +0x2ae0030,2, +0x2ae003c,2, +0x2ae0048,2, +0x2ae0054,2, +0x2ae0060,1, +0x2ae0070,2, +0x2ae007c,2, +0x2ae0088,2, +0x2ae0094,2, +0x2ae00a0,2, +0x2ae00ac,2, +0x2ae00b8,2, +0x2ae00c4,2, +0x2ae00d0,1, +0x2ae00e0,2, +0x2ae00ec,2, +0x2ae00f8,2, +0x2ae0104,2, +0x2ae0110,2, +0x2ae011c,2, +0x2ae0128,2, +0x2ae0134,2, +0x2ae0140,1, +0x2ae0150,2, +0x2ae015c,2, +0x2ae0168,2, +0x2ae0174,2, +0x2ae0180,2, +0x2ae018c,2, +0x2ae0198,2, +0x2ae01a4,2, +0x2ae01b0,1, +0x2ae01c0,57, +0x2ae02b0,23, +0x2ae0310,83, +0x2ae0460,83, +0x2ae05b0,83, +0x2ae0700,83, +0x2ae0850,83, +0x2ae09a0,83, +0x2ae0af0,83, +0x2ae0c40,83, +0x2ae0d90,83, +0x2ae0ee0,83, +0x2ae1030,83, +0x2ae1180,83, +0x2ae12d0,83, +0x2ae1420,83, +0x2ae1570,83, +0x2ae16c0,83, +0x2ae1810,83, +0x2ae1960,83, +0x2ae1ab0,83, +0x2ae1c00,83, +0x2ae1d50,83, +0x2ae1ea0,83, +0x2ae1ff0,83, +0x2ae2140,83, +0x2ae2290,83, +0x2ae23e0,83, +0x2ae2530,83, +0x2ae2680,83, +0x2ae27d0,83, +0x2ae2920,83, +0x2ae2a70,83, +0x2ae2bc0,62, +0x2ae2db4,3, +0x2ae2df4,3, +0x2ae2e34,3, +0x2ae2e74,3, +0x2ae2eb4,3, +0x2ae2ef4,3, +0x2ae2f34,3, +0x2ae2f74,3, +0x2ae2fb4,3, +0x2ae2ff4,3, +0x2ae3034,3, +0x2ae3074,3, +0x2ae30b4,3, +0x2ae30f4,3, +0x2ae3134,3, +0x2ae3174,3, +0x2ae31b4,3, +0x2af0000,4, +0x2af0014,2, +0x2af0020,8, +0x2af0044,2, +0x2af0050,13, +0x2af0088,20, +0x2af00dc,1, +0x2af0180,6, +0x2af0590,3, +0x2af05c0,2, +0x2af0a04,1, +0x2af0a0c,3, +0x2af0a20,1, +0x2af0ba0,4, +0x2af0c00,4, +0x2af0c20,3, +0x2af0c30,5, +0x2af0c50,52, +0x2af0d50,57, +0x2af0ec0,3, +0x2af0ffc,3, +0x2af1020,3, +0x2af1030,3, +0x2af1060,2, +0x2af1100,2, +0x2af1140,18, +0x2af11c0,30, +0x2af1240,14, +0x2af1280,28, +0x2af1300,2, +0x2af13a0,6, +0x2af1400,19, +0x2af1800,19, +0x2af1c00,19, +0x2af1c80,8, +0x2af1d00,3, +0x2af1d50,3, +0x2af1e00,3, +0x2af1e10,2, +0x2af1e20,6, +0x2af1e40,6, +0x2af1e60,6, +0x2af1e80,6, +0x2af1ea0,6, +0x2af1ec0,2, +0x2af1ecc,2, +0x2af1ee0,2, +0x2af1eec,2, +0x2af1f80,3, +0x2af1f90,60, +0x2af2100,32, +0x2af2200,32, +0x2af2300,32, +0x2af2400,32, +0x2af2500,32, +0x2af2600,32, +0x2af2700,32, +0x2af2800,32, +0x2af2900,32, +0x2af2a00,32, +0x2af2b00,32, +0x2af2c00,32, +0x2af2d00,32, +0x2af2e00,32, +0x2af2f00,32, +0x2af3000,32, +0x2af30c0,3, +0x2af4000,2, +0x2af4040,16, +0x2af4100,36, +0x2af4800,5, +0x2af4824,1, +0x2af482c,1, +0x2af4c04,1, +0x2af4cd8,74, +0x2af5000,7, +0x2af5020,4, +0x2af5204,1, +0x2af5280,35, +0x2af5310,4, +0x2af5404,1, +0x2af5480,34, +0x2af5510,10, +0x2af553c,3, +0x2af5800,7, +0x2af5820,4, +0x2af5a04,1, +0x2af5a80,35, +0x2af5b10,4, +0x2af5c04,1, +0x2af5c80,34, +0x2af5d10,10, +0x2af5d3c,3, +0x2afa000,5, +0x2afa01c,13, +0x2afa060,3, +0x2afa080,8, +0x2afa100,5, +0x2afa11c,13, +0x2afa160,3, +0x2afa180,8, +0x2c00004,5, +0x2c00020,3, +0x2c00030,3, +0x2c00040,13, +0x2c00078,4, +0x2c0009c,25, +0x2c00104,5, +0x2c00120,3, +0x2c00130,3, +0x2c00140,13, +0x2c00178,4, +0x2c0019c,25, +0x2c00204,5, +0x2c00220,3, +0x2c00230,3, +0x2c00240,13, +0x2c00278,4, +0x2c0029c,25, +0x2c00304,5, +0x2c00320,3, +0x2c00330,3, +0x2c00340,13, +0x2c00378,4, +0x2c0039c,25, +0x2c00600,4, +0x2c00c00,24, +0x2c00c80,24, +0x2c00d00,24, +0x2c00d80,24, +0x2c00e00,4, +0x2c00e20,4, +0x2c00e40,4, +0x2c00e60,4, +0x2c00e80,39, +0x2c00f20,7, +0x2c00f40,7, +0x2c00f60,7, +0x2c01000,12, +0x2c01200,1, +0x2c01218,2, +0x2c0122c,1, +0x2c01280,1, +0x2c01298,2, +0x2c012ac,1, +0x2c01300,1, +0x2c01318,2, +0x2c0132c,1, +0x2c01380,1, +0x2c01398,2, +0x2c013ac,1, +0x2c01400,4, +0x2c01420,2, +0x2c0142c,1, +0x2c01480,4, +0x2c014a0,2, +0x2c014ac,1, +0x2c01500,4, +0x2c01520,2, +0x2c0152c,1, +0x2c01580,4, +0x2c015a0,2, +0x2c015ac,1, +0x2c01600,4, +0x2c01640,4, +0x2c01680,4, +0x2c016c0,4, +0x2c01700,7, +0x2c01720,7, +0x2c01740,7, +0x2c01760,7, +0x2c01780,4, +0x2c0179c,11, +0x2c017d0,2, +0x2c017e0,2, +0x2c017f0,2, +0x2c01900,44, +0x2c02000,7, +0x2c02020,4, +0x2c02040,4, +0x2c02060,7, +0x2c02080,7, +0x2c020a0,4, +0x2c020c0,4, +0x2c020e0,7, +0x2c02100,7, +0x2c02120,4, +0x2c02140,4, +0x2c02160,7, +0x2c02180,7, +0x2c021a0,4, +0x2c021c0,4, +0x2c021e0,7, +0x2c02200,32, +0x2c02b00,1, +0x2c02b20,1, +0x2c02b28,4, +0x2c02b40,1, +0x2c02b60,1, +0x2c02b68,4, +0x2c02b80,1, +0x2c02ba0,1, +0x2c02ba8,4, +0x2c02bc0,1, +0x2c02be0,1, +0x2c02be8,4, +0x2c02c00,7, +0x2c02c20,1, +0x2c02c54,18, +0x2c02ca0,1, +0x2c02cd4,18, +0x2c02d20,1, +0x2c02d54,18, +0x2c02da0,1, +0x2c02dd4,12, +0x2c02e08,6, +0x2c03100,7, +0x2c03120,7, +0x2c03140,7, +0x2c03160,7, +0x2c03180,3, +0x2c04004,5, +0x2c04020,3, +0x2c04030,3, +0x2c04040,13, +0x2c04078,4, +0x2c0409c,25, +0x2c04104,5, +0x2c04120,3, +0x2c04130,3, +0x2c04140,13, +0x2c04178,4, +0x2c0419c,25, +0x2c04204,5, +0x2c04220,3, +0x2c04230,3, +0x2c04240,13, +0x2c04278,4, +0x2c0429c,25, +0x2c04304,5, +0x2c04320,3, +0x2c04330,3, +0x2c04340,13, +0x2c04378,4, +0x2c0439c,25, +0x2c04600,4, +0x2c04c00,24, +0x2c04c80,24, +0x2c04d00,24, +0x2c04d80,24, +0x2c04e00,4, +0x2c04e20,4, +0x2c04e40,4, +0x2c04e60,4, +0x2c04e80,39, +0x2c04f20,7, +0x2c04f40,7, +0x2c04f60,7, +0x2c05000,12, +0x2c05200,1, +0x2c05218,2, +0x2c0522c,1, +0x2c05280,1, +0x2c05298,2, +0x2c052ac,1, +0x2c05300,1, +0x2c05318,2, +0x2c0532c,1, +0x2c05380,1, +0x2c05398,2, +0x2c053ac,1, +0x2c05400,4, +0x2c05420,2, +0x2c0542c,1, +0x2c05480,4, +0x2c054a0,2, +0x2c054ac,1, +0x2c05500,4, +0x2c05520,2, +0x2c0552c,1, +0x2c05580,4, +0x2c055a0,2, +0x2c055ac,1, +0x2c05600,4, +0x2c05640,4, +0x2c05680,4, +0x2c056c0,4, +0x2c05700,7, +0x2c05720,7, +0x2c05740,7, +0x2c05760,7, +0x2c05780,4, +0x2c0579c,11, +0x2c057d0,2, +0x2c057e0,2, +0x2c057f0,2, +0x2c05900,44, +0x2c06000,7, +0x2c06020,4, +0x2c06040,4, +0x2c06060,7, +0x2c06080,7, +0x2c060a0,4, +0x2c060c0,4, +0x2c060e0,7, +0x2c06100,7, +0x2c06120,4, +0x2c06140,4, +0x2c06160,7, +0x2c06180,7, +0x2c061a0,4, +0x2c061c0,4, +0x2c061e0,7, +0x2c06200,32, +0x2c06b00,1, +0x2c06b20,1, +0x2c06b28,4, +0x2c06b40,1, +0x2c06b60,1, +0x2c06b68,4, +0x2c06b80,1, +0x2c06ba0,1, +0x2c06ba8,4, +0x2c06bc0,1, +0x2c06be0,1, +0x2c06be8,4, +0x2c06c00,7, +0x2c06c20,1, +0x2c06c54,18, +0x2c06ca0,1, +0x2c06cd4,18, +0x2c06d20,1, +0x2c06d54,18, +0x2c06da0,1, +0x2c06dd4,12, +0x2c06e08,6, +0x2c07100,7, +0x2c07120,7, +0x2c07140,7, +0x2c07160,7, +0x2c07180,3, +0x2c08000,10, +0x2c08080,3, +0x2c080c0,1, +0x2c08100,21, +0x2c08180,13, +0x2c081c4,7, +0x2c081e4,7, +0x2c08204,7, +0x2c08224,8, +0x2c09000,7, +0x2c09030,2, +0x2c09040,7, +0x2c09070,2, +0x2c09100,2, +0x2c09120,2, +0x2c09140,2, +0x2c09160,2, +0x2c09180,9, +0x2c09200,7, +0x2c09230,2, +0x2c09240,7, +0x2c09270,2, +0x2c09300,2, +0x2c09320,2, +0x2c09340,2, +0x2c09360,2, +0x2c09380,9, +0x2c09400,11, +0x2c09500,11, +0x2c0a000,3, +0x2c0a010,2, +0x2c0a01c,5, +0x2c0a040,8, +0x2c0a080,3, +0x2c0a090,2, +0x2c0a09c,5, +0x2c0a0c0,8, +0x2c0a100,3, +0x2c0a110,2, +0x2c0a11c,5, +0x2c0a140,8, +0x2c0a180,3, +0x2c0a190,2, +0x2c0a19c,5, +0x2c0a1c0,8, +0x2c0a200,7, +0x2c0a220,12, +0x2c0a280,7, +0x2c0a2a0,12, +0x2c0a300,3, +0x2c0a310,1, +0x2c0a400,3, +0x2c0a410,2, +0x2c0a41c,5, +0x2c0a440,8, +0x2c0a480,3, +0x2c0a490,2, +0x2c0a49c,5, +0x2c0a4c0,8, +0x2c0a500,3, +0x2c0a510,2, +0x2c0a51c,5, +0x2c0a540,8, +0x2c0a580,3, +0x2c0a590,2, +0x2c0a59c,5, +0x2c0a5c0,8, +0x2c0a600,7, +0x2c0a620,12, +0x2c0a680,7, +0x2c0a6a0,12, +0x2c0a700,3, +0x2c0a710,1, +0x2c0a804,1, +0x2c0a824,21, +0x2c0a880,16, +0x2c0a900,5, +0x2c0a920,11, +0x2c0a950,9, +0x2c0a980,22, +0x2c0aa00,22, +0x2c0aa80,22, +0x2c0ab00,22, +0x2c0ab80,22, +0x2c0ac00,22, +0x2c0ac80,22, +0x2c0ad00,22, +0x2c0ad80,3, +0x2c0c000,16, +0x2c0c080,11, +0x2c0c100,11, +0x2c0c204,1, +0x2c0c224,21, +0x2c0c280,16, +0x2c0c300,11, +0x2c0c340,11, +0x2c0c800,21, +0x2c0c860,5, +0x2c0c880,6, +0x2c0c8a0,5, +0x2c0c8c0,6, +0x2c0c900,21, +0x2c0c960,5, +0x2c0c980,6, +0x2c0c9a0,5, +0x2c0c9c0,6, +0x2c0ca00,21, +0x2c0ca60,5, +0x2c0ca80,6, +0x2c0caa0,5, +0x2c0cac0,6, +0x2c0cb00,21, +0x2c0cb60,5, +0x2c0cb80,6, +0x2c0cba0,5, +0x2c0cbc0,6, +0x2c0cc00,9, +0x2c0cc48,7, +0x2c0cc68,2, +0x2c0cc74,9, +0x2c0cc9c,2, +0x2c0cd00,14, +0x2c0cd40,14, +0x2c0cd80,28, +0x2c0ce00,19, +0x2c0ce50,3, +0x2c0ce60,25, +0x2c0cec8,1, +0x2c0ced0,2, +0x2c0cee0,7, +0x2c0cf00,1, +0x2c0cf08,2, +0x2c0cffc,20, +0x2c0d050,25, +0x2c0d100,19, +0x2c0d150,25, +0x2c0d200,19, +0x2c0d250,25, +0x2c0d300,19, +0x2c0d350,25, +0x2c0d400,19, +0x2c0d450,25, +0x2c0d500,19, +0x2c0d550,25, +0x2c0d600,19, +0x2c0d650,25, +0x2c0d700,19, +0x2c0d750,25, +0x2c0d800,19, +0x2c0d850,25, +0x2c0d904,1, +0x2c0d914,10, +0x2c0d948,11, +0x2c0d980,2, +0x2c0d9a0,6, +0x2c0d9c0,2, +0x2c0d9cc,2, +0x2c0e000,35, +0x2c0ea00,10, +0x2c0ea80,3, +0x2c0eb00,6, +0x2c0f000,1, +0x2c0f008,5, +0x2c0f038,1, +0x2c0f044,1, +0x2c0f050,2, +0x2c0f100,13, +0x2c0f140,11, +0x2c0f170,12, +0x2c0f1a4,1, +0x2c0f200,104, +0x2c0f400,104, +0x2c0f600,104, +0x2c0f800,104, +0x2c10000,13, +0x2c10040,2, +0x2c10054,4, +0x2c10080,27, +0x2c10100,12, +0x2c10140,14, +0x2c10180,28, +0x2c10200,6, +0x2c10240,6, +0x2c1025c,3, +0x2c10280,5, +0x2c102a0,8, +0x2c10400,14, +0x2c10440,14, +0x2c10480,14, +0x2c104c0,14, +0x2c10540,3, +0x2c10600,7, +0x2c10620,14, +0x2c10680,5, +0x2c106a0,7, +0x2c10800,13, +0x2c10840,2, +0x2c10854,4, +0x2c10880,27, +0x2c10900,12, +0x2c10940,14, +0x2c10980,28, +0x2c10a00,6, +0x2c10a40,6, +0x2c10a5c,3, +0x2c10a80,5, +0x2c10aa0,8, +0x2c10c00,14, +0x2c10c40,14, +0x2c10c80,14, +0x2c10cc0,14, +0x2c10d40,3, +0x2c10e00,7, +0x2c10e20,14, +0x2c10e80,5, +0x2c10ea0,7, +0x2c11000,13, +0x2c11040,2, +0x2c11054,4, +0x2c11080,27, +0x2c11100,12, +0x2c11140,14, +0x2c11180,28, +0x2c11200,6, +0x2c11240,6, +0x2c1125c,3, +0x2c11280,5, +0x2c112a0,8, +0x2c11400,14, +0x2c11440,14, +0x2c11480,14, +0x2c114c0,14, +0x2c11540,3, +0x2c11600,7, +0x2c11620,14, +0x2c11680,5, +0x2c116a0,7, +0x2c11800,13, +0x2c11840,2, +0x2c11854,4, +0x2c11880,27, +0x2c11900,12, +0x2c11940,14, +0x2c11980,28, +0x2c11a00,6, +0x2c11a40,6, +0x2c11a5c,3, +0x2c11a80,5, +0x2c11aa0,8, +0x2c11c00,14, +0x2c11c40,14, +0x2c11c80,14, +0x2c11cc0,14, +0x2c11d40,3, +0x2c11e00,7, +0x2c11e20,14, +0x2c11e80,5, +0x2c11ea0,7, +0x2c12000,8, +0x2c12040,8, +0x2c12080,1, +0x2c12098,6, +0x2c12100,10, +0x2c12140,3, +0x2c12150,2, +0x2c12180,2, +0x2c12200,6, +0x2c12220,18, +0x2c12280,4, +0x2c12300,8, +0x2c12400,2, +0x2c12480,2, +0x2c12800,28, +0x2c129f0,4, +0x2c13000,40, +0x2c13100,64, +0x2c13800,56, +0x2c13be0,8, +0x2c14000,13, +0x2c14040,2, +0x2c14054,4, +0x2c14080,27, +0x2c14100,12, +0x2c14140,14, +0x2c14180,28, +0x2c14200,6, +0x2c14240,6, +0x2c1425c,3, +0x2c14280,5, +0x2c142a0,8, +0x2c14400,14, +0x2c14440,14, +0x2c14480,14, +0x2c144c0,14, +0x2c14540,3, +0x2c14600,7, +0x2c14620,14, +0x2c14680,5, +0x2c146a0,7, +0x2c14800,13, +0x2c14840,2, +0x2c14854,4, +0x2c14880,27, +0x2c14900,12, +0x2c14940,14, +0x2c14980,28, +0x2c14a00,6, +0x2c14a40,6, +0x2c14a5c,3, +0x2c14a80,5, +0x2c14aa0,8, +0x2c14c00,14, +0x2c14c40,14, +0x2c14c80,14, +0x2c14cc0,14, +0x2c14d40,3, +0x2c14e00,7, +0x2c14e20,14, +0x2c14e80,5, +0x2c14ea0,7, +0x2c15000,13, +0x2c15040,2, +0x2c15054,4, +0x2c15080,27, +0x2c15100,12, +0x2c15140,14, +0x2c15180,28, +0x2c15200,6, +0x2c15240,6, +0x2c1525c,3, +0x2c15280,5, +0x2c152a0,8, +0x2c15400,14, +0x2c15440,14, +0x2c15480,14, +0x2c154c0,14, +0x2c15540,3, +0x2c15600,7, +0x2c15620,14, +0x2c15680,5, +0x2c156a0,7, +0x2c15800,13, +0x2c15840,2, +0x2c15854,4, +0x2c15880,27, +0x2c15900,12, +0x2c15940,14, +0x2c15980,28, +0x2c15a00,6, +0x2c15a40,6, +0x2c15a5c,3, +0x2c15a80,5, +0x2c15aa0,8, +0x2c15c00,14, +0x2c15c40,14, +0x2c15c80,14, +0x2c15cc0,14, +0x2c15d40,3, +0x2c15e00,7, +0x2c15e20,14, +0x2c15e80,5, +0x2c15ea0,7, +0x2c16000,8, +0x2c16040,8, +0x2c16080,1, +0x2c16098,6, +0x2c16100,10, +0x2c16140,3, +0x2c16150,2, +0x2c16180,2, +0x2c16200,6, +0x2c16220,18, +0x2c16280,4, +0x2c16300,8, +0x2c16400,2, +0x2c16480,2, +0x2c16800,28, +0x2c169f0,4, +0x2c17000,40, +0x2c17100,64, +0x2c17800,56, +0x2c17be0,8, +0x2c18000,2, +0x2c1800c,2, +0x2c18040,7, +0x2c18100,3, +0x2c18110,3, +0x2c18120,5, +0x2c18200,6, +0x2c18240,5, +0x2c18400,2, +0x2c1840c,2, +0x2c18440,7, +0x2c18500,3, +0x2c18510,3, +0x2c18520,5, +0x2c18600,6, +0x2c18640,5, +0x2c18800,2, +0x2c1880c,2, +0x2c18840,7, +0x2c18900,3, +0x2c18910,3, +0x2c18920,5, +0x2c18a00,6, +0x2c18a40,5, +0x2c18c00,2, +0x2c18c0c,2, +0x2c18c40,7, +0x2c18d00,3, +0x2c18d10,3, +0x2c18d20,5, +0x2c18e00,6, +0x2c18e40,5, +0x2c19000,2, +0x2c1900c,2, +0x2c19040,7, +0x2c19100,3, +0x2c19110,3, +0x2c19120,5, +0x2c19200,6, +0x2c19240,5, +0x2c19400,2, +0x2c1940c,2, +0x2c19440,7, +0x2c19500,3, +0x2c19510,3, +0x2c19520,5, +0x2c19600,6, +0x2c19640,5, +0x2c19800,2, +0x2c1980c,2, +0x2c19840,7, +0x2c19900,3, +0x2c19910,3, +0x2c19920,5, +0x2c19a00,6, +0x2c19a40,5, +0x2c19c00,2, +0x2c19c0c,2, +0x2c19c40,7, +0x2c19d00,3, +0x2c19d10,3, +0x2c19d20,5, +0x2c19e00,6, +0x2c19e40,5, +0x2c1a000,5, +0x2c1a040,9, +0x2c1a100,3, +0x2c1a200,1, +0x2c1a210,1, +0x2c1a220,1, +0x2c1a230,1, +0x2c1a240,1, +0x2c1a300,3, +0x2c1a314,1, +0x2c1a320,4, +0x2c1a400,5, +0x2c1a440,5, +0x2c1b000,80, +0x2c1b200,1, +0x2c20004,5, +0x2c20020,3, +0x2c20030,3, +0x2c20040,13, +0x2c20078,4, +0x2c2009c,25, +0x2c20104,5, +0x2c20120,3, +0x2c20130,3, +0x2c20140,13, +0x2c20178,4, +0x2c2019c,25, +0x2c20204,5, +0x2c20220,3, +0x2c20230,3, +0x2c20240,13, +0x2c20278,4, +0x2c2029c,25, +0x2c20304,5, +0x2c20320,3, +0x2c20330,3, +0x2c20340,13, +0x2c20378,4, +0x2c2039c,25, +0x2c20600,4, +0x2c20c00,24, +0x2c20c80,24, +0x2c20d00,24, +0x2c20d80,24, +0x2c20e00,4, +0x2c20e20,4, +0x2c20e40,4, +0x2c20e60,4, +0x2c20e80,39, +0x2c20f20,7, +0x2c20f40,7, +0x2c20f60,7, +0x2c21000,12, +0x2c21200,1, +0x2c21218,2, +0x2c2122c,1, +0x2c21280,1, +0x2c21298,2, +0x2c212ac,1, +0x2c21300,1, +0x2c21318,2, +0x2c2132c,1, +0x2c21380,1, +0x2c21398,2, +0x2c213ac,1, +0x2c21400,4, +0x2c21420,2, +0x2c2142c,1, +0x2c21480,4, +0x2c214a0,2, +0x2c214ac,1, +0x2c21500,4, +0x2c21520,2, +0x2c2152c,1, +0x2c21580,4, +0x2c215a0,2, +0x2c215ac,1, +0x2c21600,4, +0x2c21640,4, +0x2c21680,4, +0x2c216c0,4, +0x2c21700,7, +0x2c21720,7, +0x2c21740,7, +0x2c21760,7, +0x2c21780,4, +0x2c2179c,11, +0x2c217d0,2, +0x2c217e0,2, +0x2c217f0,2, +0x2c21900,44, +0x2c22000,7, +0x2c22020,4, +0x2c22040,4, +0x2c22060,7, +0x2c22080,7, +0x2c220a0,4, +0x2c220c0,4, +0x2c220e0,7, +0x2c22100,7, +0x2c22120,4, +0x2c22140,4, +0x2c22160,7, +0x2c22180,7, +0x2c221a0,4, +0x2c221c0,4, +0x2c221e0,7, +0x2c22200,32, +0x2c22b00,1, +0x2c22b20,1, +0x2c22b28,4, +0x2c22b40,1, +0x2c22b60,1, +0x2c22b68,4, +0x2c22b80,1, +0x2c22ba0,1, +0x2c22ba8,4, +0x2c22bc0,1, +0x2c22be0,1, +0x2c22be8,4, +0x2c22c00,7, +0x2c22c20,1, +0x2c22c54,18, +0x2c22ca0,1, +0x2c22cd4,18, +0x2c22d20,1, +0x2c22d54,18, +0x2c22da0,1, +0x2c22dd4,12, +0x2c22e08,6, +0x2c23100,7, +0x2c23120,7, +0x2c23140,7, +0x2c23160,7, +0x2c23180,3, +0x2c24004,5, +0x2c24020,3, +0x2c24030,3, +0x2c24040,13, +0x2c24078,4, +0x2c2409c,25, +0x2c24104,5, +0x2c24120,3, +0x2c24130,3, +0x2c24140,13, +0x2c24178,4, +0x2c2419c,25, +0x2c24204,5, +0x2c24220,3, +0x2c24230,3, +0x2c24240,13, +0x2c24278,4, +0x2c2429c,25, +0x2c24304,5, +0x2c24320,3, +0x2c24330,3, +0x2c24340,13, +0x2c24378,4, +0x2c2439c,25, +0x2c24600,4, +0x2c24c00,24, +0x2c24c80,24, +0x2c24d00,24, +0x2c24d80,24, +0x2c24e00,4, +0x2c24e20,4, +0x2c24e40,4, +0x2c24e60,4, +0x2c24e80,39, +0x2c24f20,7, +0x2c24f40,7, +0x2c24f60,7, +0x2c25000,12, +0x2c25200,1, +0x2c25218,2, +0x2c2522c,1, +0x2c25280,1, +0x2c25298,2, +0x2c252ac,1, +0x2c25300,1, +0x2c25318,2, +0x2c2532c,1, +0x2c25380,1, +0x2c25398,2, +0x2c253ac,1, +0x2c25400,4, +0x2c25420,2, +0x2c2542c,1, +0x2c25480,4, +0x2c254a0,2, +0x2c254ac,1, +0x2c25500,4, +0x2c25520,2, +0x2c2552c,1, +0x2c25580,4, +0x2c255a0,2, +0x2c255ac,1, +0x2c25600,4, +0x2c25640,4, +0x2c25680,4, +0x2c256c0,4, +0x2c25700,7, +0x2c25720,7, +0x2c25740,7, +0x2c25760,7, +0x2c25780,4, +0x2c2579c,11, +0x2c257d0,2, +0x2c257e0,2, +0x2c257f0,2, +0x2c25900,44, +0x2c26000,7, +0x2c26020,4, +0x2c26040,4, +0x2c26060,7, +0x2c26080,7, +0x2c260a0,4, +0x2c260c0,4, +0x2c260e0,7, +0x2c26100,7, +0x2c26120,4, +0x2c26140,4, +0x2c26160,7, +0x2c26180,7, +0x2c261a0,4, +0x2c261c0,4, +0x2c261e0,7, +0x2c26200,32, +0x2c26b00,1, +0x2c26b20,1, +0x2c26b28,4, +0x2c26b40,1, +0x2c26b60,1, +0x2c26b68,4, +0x2c26b80,1, +0x2c26ba0,1, +0x2c26ba8,4, +0x2c26bc0,1, +0x2c26be0,1, +0x2c26be8,4, +0x2c26c00,7, +0x2c26c20,1, +0x2c26c54,18, +0x2c26ca0,1, +0x2c26cd4,18, +0x2c26d20,1, +0x2c26d54,18, +0x2c26da0,1, +0x2c26dd4,12, +0x2c26e08,6, +0x2c27100,7, +0x2c27120,7, +0x2c27140,7, +0x2c27160,7, +0x2c27180,3, +0x2c28000,10, +0x2c28080,3, +0x2c280c0,1, +0x2c28100,21, +0x2c28180,13, +0x2c281c4,7, +0x2c281e4,7, +0x2c28204,7, +0x2c28224,8, +0x2c29000,7, +0x2c29030,2, +0x2c29040,7, +0x2c29070,2, +0x2c29100,2, +0x2c29120,2, +0x2c29140,2, +0x2c29160,2, +0x2c29180,9, +0x2c29200,7, +0x2c29230,2, +0x2c29240,7, +0x2c29270,2, +0x2c29300,2, +0x2c29320,2, +0x2c29340,2, +0x2c29360,2, +0x2c29380,9, +0x2c29400,11, +0x2c29500,11, +0x2c2a000,3, +0x2c2a010,2, +0x2c2a01c,5, +0x2c2a040,8, +0x2c2a080,3, +0x2c2a090,2, +0x2c2a09c,5, +0x2c2a0c0,8, +0x2c2a100,3, +0x2c2a110,2, +0x2c2a11c,5, +0x2c2a140,8, +0x2c2a180,3, +0x2c2a190,2, +0x2c2a19c,5, +0x2c2a1c0,8, +0x2c2a200,7, +0x2c2a220,12, +0x2c2a280,7, +0x2c2a2a0,12, +0x2c2a300,3, +0x2c2a310,1, +0x2c2a400,3, +0x2c2a410,2, +0x2c2a41c,5, +0x2c2a440,8, +0x2c2a480,3, +0x2c2a490,2, +0x2c2a49c,5, +0x2c2a4c0,8, +0x2c2a500,3, +0x2c2a510,2, +0x2c2a51c,5, +0x2c2a540,8, +0x2c2a580,3, +0x2c2a590,2, +0x2c2a59c,5, +0x2c2a5c0,8, +0x2c2a600,7, +0x2c2a620,12, +0x2c2a680,7, +0x2c2a6a0,12, +0x2c2a700,3, +0x2c2a710,1, +0x2c2a804,1, +0x2c2a824,21, +0x2c2a880,16, +0x2c2a900,5, +0x2c2a920,11, +0x2c2a950,9, +0x2c2a980,22, +0x2c2aa00,22, +0x2c2aa80,22, +0x2c2ab00,22, +0x2c2ab80,22, +0x2c2ac00,22, +0x2c2ac80,22, +0x2c2ad00,22, +0x2c2ad80,3, +0x2c2c000,16, +0x2c2c080,11, +0x2c2c100,11, +0x2c2c204,1, +0x2c2c224,21, +0x2c2c280,16, +0x2c2c300,11, +0x2c2c340,11, +0x2c2c800,21, +0x2c2c860,5, +0x2c2c880,6, +0x2c2c8a0,5, +0x2c2c8c0,6, +0x2c2c900,21, +0x2c2c960,5, +0x2c2c980,6, +0x2c2c9a0,5, +0x2c2c9c0,6, +0x2c2ca00,21, +0x2c2ca60,5, +0x2c2ca80,6, +0x2c2caa0,5, +0x2c2cac0,6, +0x2c2cb00,21, +0x2c2cb60,5, +0x2c2cb80,6, +0x2c2cba0,5, +0x2c2cbc0,6, +0x2c2cc00,9, +0x2c2cc48,7, +0x2c2cc68,2, +0x2c2cc74,9, +0x2c2cc9c,2, +0x2c2cd00,14, +0x2c2cd40,14, +0x2c2cd80,28, +0x2c2ce00,19, +0x2c2ce50,3, +0x2c2ce60,25, +0x2c2cec8,1, +0x2c2ced0,2, +0x2c2cee0,7, +0x2c2cf00,1, +0x2c2cf08,2, +0x2c2cffc,20, +0x2c2d050,25, +0x2c2d100,19, +0x2c2d150,25, +0x2c2d200,19, +0x2c2d250,25, +0x2c2d300,19, +0x2c2d350,25, +0x2c2d400,19, +0x2c2d450,25, +0x2c2d500,19, +0x2c2d550,25, +0x2c2d600,19, +0x2c2d650,25, +0x2c2d700,19, +0x2c2d750,25, +0x2c2d800,19, +0x2c2d850,25, +0x2c2d904,1, +0x2c2d914,10, +0x2c2d948,11, +0x2c2d980,2, +0x2c2d9a0,6, +0x2c2d9c0,2, +0x2c2d9cc,2, +0x2c2e000,35, +0x2c2ea00,10, +0x2c2ea80,3, +0x2c2eb00,6, +0x2c2f000,1, +0x2c2f008,5, +0x2c2f038,1, +0x2c2f044,1, +0x2c2f050,2, +0x2c2f100,13, +0x2c2f140,11, +0x2c2f170,12, +0x2c2f1a4,1, +0x2c2f200,104, +0x2c2f400,104, +0x2c2f600,104, +0x2c2f800,104, +0x2c30000,13, +0x2c30040,2, +0x2c30054,4, +0x2c30080,27, +0x2c30100,12, +0x2c30140,14, +0x2c30180,28, +0x2c30200,6, +0x2c30240,6, +0x2c3025c,3, +0x2c30280,5, +0x2c302a0,8, +0x2c30400,14, +0x2c30440,14, +0x2c30480,14, +0x2c304c0,14, +0x2c30540,3, +0x2c30600,7, +0x2c30620,14, +0x2c30680,5, +0x2c306a0,7, +0x2c30800,13, +0x2c30840,2, +0x2c30854,4, +0x2c30880,27, +0x2c30900,12, +0x2c30940,14, +0x2c30980,28, +0x2c30a00,6, +0x2c30a40,6, +0x2c30a5c,3, +0x2c30a80,5, +0x2c30aa0,8, +0x2c30c00,14, +0x2c30c40,14, +0x2c30c80,14, +0x2c30cc0,14, +0x2c30d40,3, +0x2c30e00,7, +0x2c30e20,14, +0x2c30e80,5, +0x2c30ea0,7, +0x2c31000,13, +0x2c31040,2, +0x2c31054,4, +0x2c31080,27, +0x2c31100,12, +0x2c31140,14, +0x2c31180,28, +0x2c31200,6, +0x2c31240,6, +0x2c3125c,3, +0x2c31280,5, +0x2c312a0,8, +0x2c31400,14, +0x2c31440,14, +0x2c31480,14, +0x2c314c0,14, +0x2c31540,3, +0x2c31600,7, +0x2c31620,14, +0x2c31680,5, +0x2c316a0,7, +0x2c31800,13, +0x2c31840,2, +0x2c31854,4, +0x2c31880,27, +0x2c31900,12, +0x2c31940,14, +0x2c31980,28, +0x2c31a00,6, +0x2c31a40,6, +0x2c31a5c,3, +0x2c31a80,5, +0x2c31aa0,8, +0x2c31c00,14, +0x2c31c40,14, +0x2c31c80,14, +0x2c31cc0,14, +0x2c31d40,3, +0x2c31e00,7, +0x2c31e20,14, +0x2c31e80,5, +0x2c31ea0,7, +0x2c32000,8, +0x2c32040,8, +0x2c32080,1, +0x2c32098,6, +0x2c32100,10, +0x2c32140,3, +0x2c32150,2, +0x2c32180,2, +0x2c32200,6, +0x2c32220,18, +0x2c32280,4, +0x2c32300,8, +0x2c32400,2, +0x2c32480,2, +0x2c32800,28, +0x2c329f0,4, +0x2c33000,40, +0x2c33100,64, +0x2c33800,56, +0x2c33be0,8, +0x2c34000,13, +0x2c34040,2, +0x2c34054,4, +0x2c34080,27, +0x2c34100,12, +0x2c34140,14, +0x2c34180,28, +0x2c34200,6, +0x2c34240,6, +0x2c3425c,3, +0x2c34280,5, +0x2c342a0,8, +0x2c34400,14, +0x2c34440,14, +0x2c34480,14, +0x2c344c0,14, +0x2c34540,3, +0x2c34600,7, +0x2c34620,14, +0x2c34680,5, +0x2c346a0,7, +0x2c34800,13, +0x2c34840,2, +0x2c34854,4, +0x2c34880,27, +0x2c34900,12, +0x2c34940,14, +0x2c34980,28, +0x2c34a00,6, +0x2c34a40,6, +0x2c34a5c,3, +0x2c34a80,5, +0x2c34aa0,8, +0x2c34c00,14, +0x2c34c40,14, +0x2c34c80,14, +0x2c34cc0,14, +0x2c34d40,3, +0x2c34e00,7, +0x2c34e20,14, +0x2c34e80,5, +0x2c34ea0,7, +0x2c35000,13, +0x2c35040,2, +0x2c35054,4, +0x2c35080,27, +0x2c35100,12, +0x2c35140,14, +0x2c35180,28, +0x2c35200,6, +0x2c35240,6, +0x2c3525c,3, +0x2c35280,5, +0x2c352a0,8, +0x2c35400,14, +0x2c35440,14, +0x2c35480,14, +0x2c354c0,14, +0x2c35540,3, +0x2c35600,7, +0x2c35620,14, +0x2c35680,5, +0x2c356a0,7, +0x2c35800,13, +0x2c35840,2, +0x2c35854,4, +0x2c35880,27, +0x2c35900,12, +0x2c35940,14, +0x2c35980,28, +0x2c35a00,6, +0x2c35a40,6, +0x2c35a5c,3, +0x2c35a80,5, +0x2c35aa0,8, +0x2c35c00,14, +0x2c35c40,14, +0x2c35c80,14, +0x2c35cc0,14, +0x2c35d40,3, +0x2c35e00,7, +0x2c35e20,14, +0x2c35e80,5, +0x2c35ea0,7, +0x2c36000,8, +0x2c36040,8, +0x2c36080,1, +0x2c36098,6, +0x2c36100,10, +0x2c36140,3, +0x2c36150,2, +0x2c36180,2, +0x2c36200,6, +0x2c36220,18, +0x2c36280,4, +0x2c36300,8, +0x2c36400,2, +0x2c36480,2, +0x2c36800,28, +0x2c369f0,4, +0x2c37000,40, +0x2c37100,64, +0x2c37800,56, +0x2c37be0,8, +0x2c38000,2, +0x2c3800c,2, +0x2c38040,7, +0x2c38100,3, +0x2c38110,3, +0x2c38120,5, +0x2c38200,6, +0x2c38240,5, +0x2c38400,2, +0x2c3840c,2, +0x2c38440,7, +0x2c38500,3, +0x2c38510,3, +0x2c38520,5, +0x2c38600,6, +0x2c38640,5, +0x2c38800,2, +0x2c3880c,2, +0x2c38840,7, +0x2c38900,3, +0x2c38910,3, +0x2c38920,5, +0x2c38a00,6, +0x2c38a40,5, +0x2c38c00,2, +0x2c38c0c,2, +0x2c38c40,7, +0x2c38d00,3, +0x2c38d10,3, +0x2c38d20,5, +0x2c38e00,6, +0x2c38e40,5, +0x2c39000,2, +0x2c3900c,2, +0x2c39040,7, +0x2c39100,3, +0x2c39110,3, +0x2c39120,5, +0x2c39200,6, +0x2c39240,5, +0x2c39400,2, +0x2c3940c,2, +0x2c39440,7, +0x2c39500,3, +0x2c39510,3, +0x2c39520,5, +0x2c39600,6, +0x2c39640,5, +0x2c39800,2, +0x2c3980c,2, +0x2c39840,7, +0x2c39900,3, +0x2c39910,3, +0x2c39920,5, +0x2c39a00,6, +0x2c39a40,5, +0x2c39c00,2, +0x2c39c0c,2, +0x2c39c40,7, +0x2c39d00,3, +0x2c39d10,3, +0x2c39d20,5, +0x2c39e00,6, +0x2c39e40,5, +0x2c3a000,5, +0x2c3a040,9, +0x2c3a100,3, +0x2c3a200,1, +0x2c3a210,1, +0x2c3a220,1, +0x2c3a230,1, +0x2c3a240,1, +0x2c3a300,3, +0x2c3a314,1, +0x2c3a320,4, +0x2c3a400,5, +0x2c3a440,5, +0x2c3b000,80, +0x2c3b200,1, +0x2c40004,5, +0x2c40020,3, +0x2c40030,3, +0x2c40040,13, +0x2c40078,4, +0x2c4009c,25, +0x2c40104,5, +0x2c40120,3, +0x2c40130,3, +0x2c40140,13, +0x2c40178,4, +0x2c4019c,25, +0x2c40204,5, +0x2c40220,3, +0x2c40230,3, +0x2c40240,13, +0x2c40278,4, +0x2c4029c,25, +0x2c40304,5, +0x2c40320,3, +0x2c40330,3, +0x2c40340,13, +0x2c40378,4, +0x2c4039c,25, +0x2c40600,4, +0x2c40c00,24, +0x2c40c80,24, +0x2c40d00,24, +0x2c40d80,24, +0x2c40e00,4, +0x2c40e20,4, +0x2c40e40,4, +0x2c40e60,4, +0x2c40e80,39, +0x2c40f20,7, +0x2c40f40,7, +0x2c40f60,7, +0x2c41000,12, +0x2c41200,1, +0x2c41218,2, +0x2c4122c,1, +0x2c41280,1, +0x2c41298,2, +0x2c412ac,1, +0x2c41300,1, +0x2c41318,2, +0x2c4132c,1, +0x2c41380,1, +0x2c41398,2, +0x2c413ac,1, +0x2c41400,4, +0x2c41420,2, +0x2c4142c,1, +0x2c41480,4, +0x2c414a0,2, +0x2c414ac,1, +0x2c41500,4, +0x2c41520,2, +0x2c4152c,1, +0x2c41580,4, +0x2c415a0,2, +0x2c415ac,1, +0x2c41600,4, +0x2c41640,4, +0x2c41680,4, +0x2c416c0,4, +0x2c41700,7, +0x2c41720,7, +0x2c41740,7, +0x2c41760,7, +0x2c41780,4, +0x2c4179c,11, +0x2c417d0,2, +0x2c417e0,2, +0x2c417f0,2, +0x2c41900,44, +0x2c42000,7, +0x2c42020,4, +0x2c42040,4, +0x2c42060,7, +0x2c42080,7, +0x2c420a0,4, +0x2c420c0,4, +0x2c420e0,7, +0x2c42100,7, +0x2c42120,4, +0x2c42140,4, +0x2c42160,7, +0x2c42180,7, +0x2c421a0,4, +0x2c421c0,4, +0x2c421e0,7, +0x2c42200,32, +0x2c42b00,1, +0x2c42b20,1, +0x2c42b28,4, +0x2c42b40,1, +0x2c42b60,1, +0x2c42b68,4, +0x2c42b80,1, +0x2c42ba0,1, +0x2c42ba8,4, +0x2c42bc0,1, +0x2c42be0,1, +0x2c42be8,4, +0x2c42c00,7, +0x2c42c20,1, +0x2c42c54,18, +0x2c42ca0,1, +0x2c42cd4,18, +0x2c42d20,1, +0x2c42d54,18, +0x2c42da0,1, +0x2c42dd4,12, +0x2c42e08,6, +0x2c43100,7, +0x2c43120,7, +0x2c43140,7, +0x2c43160,7, +0x2c43180,3, +0x2c44004,5, +0x2c44020,3, +0x2c44030,3, +0x2c44040,13, +0x2c44078,4, +0x2c4409c,25, +0x2c44104,5, +0x2c44120,3, +0x2c44130,3, +0x2c44140,13, +0x2c44178,4, +0x2c4419c,25, +0x2c44204,5, +0x2c44220,3, +0x2c44230,3, +0x2c44240,13, +0x2c44278,4, +0x2c4429c,25, +0x2c44304,5, +0x2c44320,3, +0x2c44330,3, +0x2c44340,13, +0x2c44378,4, +0x2c4439c,25, +0x2c44600,4, +0x2c44c00,24, +0x2c44c80,24, +0x2c44d00,24, +0x2c44d80,24, +0x2c44e00,4, +0x2c44e20,4, +0x2c44e40,4, +0x2c44e60,4, +0x2c44e80,39, +0x2c44f20,7, +0x2c44f40,7, +0x2c44f60,7, +0x2c45000,12, +0x2c45200,1, +0x2c45218,2, +0x2c4522c,1, +0x2c45280,1, +0x2c45298,2, +0x2c452ac,1, +0x2c45300,1, +0x2c45318,2, +0x2c4532c,1, +0x2c45380,1, +0x2c45398,2, +0x2c453ac,1, +0x2c45400,4, +0x2c45420,2, +0x2c4542c,1, +0x2c45480,4, +0x2c454a0,2, +0x2c454ac,1, +0x2c45500,4, +0x2c45520,2, +0x2c4552c,1, +0x2c45580,4, +0x2c455a0,2, +0x2c455ac,1, +0x2c45600,4, +0x2c45640,4, +0x2c45680,4, +0x2c456c0,4, +0x2c45700,7, +0x2c45720,7, +0x2c45740,7, +0x2c45760,7, +0x2c45780,4, +0x2c4579c,11, +0x2c457d0,2, +0x2c457e0,2, +0x2c457f0,2, +0x2c45900,44, +0x2c46000,7, +0x2c46020,4, +0x2c46040,4, +0x2c46060,7, +0x2c46080,7, +0x2c460a0,4, +0x2c460c0,4, +0x2c460e0,7, +0x2c46100,7, +0x2c46120,4, +0x2c46140,4, +0x2c46160,7, +0x2c46180,7, +0x2c461a0,4, +0x2c461c0,4, +0x2c461e0,7, +0x2c46200,32, +0x2c46b00,1, +0x2c46b20,1, +0x2c46b28,4, +0x2c46b40,1, +0x2c46b60,1, +0x2c46b68,4, +0x2c46b80,1, +0x2c46ba0,1, +0x2c46ba8,4, +0x2c46bc0,1, +0x2c46be0,1, +0x2c46be8,4, +0x2c46c00,7, +0x2c46c20,1, +0x2c46c54,18, +0x2c46ca0,1, +0x2c46cd4,18, +0x2c46d20,1, +0x2c46d54,18, +0x2c46da0,1, +0x2c46dd4,12, +0x2c46e08,6, +0x2c47100,7, +0x2c47120,7, +0x2c47140,7, +0x2c47160,7, +0x2c47180,3, +0x2c48000,10, +0x2c48080,3, +0x2c480c0,1, +0x2c48100,21, +0x2c48180,13, +0x2c481c4,7, +0x2c481e4,7, +0x2c48204,7, +0x2c48224,8, +0x2c49000,7, +0x2c49030,2, +0x2c49040,7, +0x2c49070,2, +0x2c49100,2, +0x2c49120,2, +0x2c49140,2, +0x2c49160,2, +0x2c49180,9, +0x2c49200,7, +0x2c49230,2, +0x2c49240,7, +0x2c49270,2, +0x2c49300,2, +0x2c49320,2, +0x2c49340,2, +0x2c49360,2, +0x2c49380,9, +0x2c49400,11, +0x2c49500,11, +0x2c4a000,3, +0x2c4a010,2, +0x2c4a01c,5, +0x2c4a040,8, +0x2c4a080,3, +0x2c4a090,2, +0x2c4a09c,5, +0x2c4a0c0,8, +0x2c4a100,3, +0x2c4a110,2, +0x2c4a11c,5, +0x2c4a140,8, +0x2c4a180,3, +0x2c4a190,2, +0x2c4a19c,5, +0x2c4a1c0,8, +0x2c4a200,7, +0x2c4a220,12, +0x2c4a280,7, +0x2c4a2a0,12, +0x2c4a300,3, +0x2c4a310,1, +0x2c4a400,3, +0x2c4a410,2, +0x2c4a41c,5, +0x2c4a440,8, +0x2c4a480,3, +0x2c4a490,2, +0x2c4a49c,5, +0x2c4a4c0,8, +0x2c4a500,3, +0x2c4a510,2, +0x2c4a51c,5, +0x2c4a540,8, +0x2c4a580,3, +0x2c4a590,2, +0x2c4a59c,5, +0x2c4a5c0,8, +0x2c4a600,7, +0x2c4a620,12, +0x2c4a680,7, +0x2c4a6a0,12, +0x2c4a700,3, +0x2c4a710,1, +0x2c4a804,1, +0x2c4a824,21, +0x2c4a880,16, +0x2c4a900,5, +0x2c4a920,11, +0x2c4a950,9, +0x2c4a980,22, +0x2c4aa00,22, +0x2c4aa80,22, +0x2c4ab00,22, +0x2c4ab80,22, +0x2c4ac00,22, +0x2c4ac80,22, +0x2c4ad00,22, +0x2c4ad80,3, +0x2c4c000,16, +0x2c4c080,11, +0x2c4c100,11, +0x2c4c204,1, +0x2c4c224,21, +0x2c4c280,16, +0x2c4c300,11, +0x2c4c340,11, +0x2c4c800,21, +0x2c4c860,5, +0x2c4c880,6, +0x2c4c8a0,5, +0x2c4c8c0,6, +0x2c4c900,21, +0x2c4c960,5, +0x2c4c980,6, +0x2c4c9a0,5, +0x2c4c9c0,6, +0x2c4ca00,21, +0x2c4ca60,5, +0x2c4ca80,6, +0x2c4caa0,5, +0x2c4cac0,6, +0x2c4cb00,21, +0x2c4cb60,5, +0x2c4cb80,6, +0x2c4cba0,5, +0x2c4cbc0,6, +0x2c4cc00,9, +0x2c4cc48,7, +0x2c4cc68,2, +0x2c4cc74,9, +0x2c4cc9c,2, +0x2c4cd00,14, +0x2c4cd40,14, +0x2c4cd80,28, +0x2c4ce00,19, +0x2c4ce50,3, +0x2c4ce60,25, +0x2c4cec8,1, +0x2c4ced0,2, +0x2c4cee0,7, +0x2c4cf00,1, +0x2c4cf08,2, +0x2c4cffc,20, +0x2c4d050,25, +0x2c4d100,19, +0x2c4d150,25, +0x2c4d200,19, +0x2c4d250,25, +0x2c4d300,19, +0x2c4d350,25, +0x2c4d400,19, +0x2c4d450,25, +0x2c4d500,19, +0x2c4d550,25, +0x2c4d600,19, +0x2c4d650,25, +0x2c4d700,19, +0x2c4d750,25, +0x2c4d800,19, +0x2c4d850,25, +0x2c4d904,1, +0x2c4d914,10, +0x2c4d948,11, +0x2c4d980,2, +0x2c4d9a0,6, +0x2c4d9c0,2, +0x2c4d9cc,2, +0x2c4e000,35, +0x2c4ea00,10, +0x2c4ea80,3, +0x2c4eb00,6, +0x2c4f000,1, +0x2c4f008,5, +0x2c4f038,1, +0x2c4f044,1, +0x2c4f050,2, +0x2c4f100,13, +0x2c4f140,11, +0x2c4f170,12, +0x2c4f1a4,1, +0x2c4f200,104, +0x2c4f400,104, +0x2c4f600,104, +0x2c4f800,104, +0x2c50000,13, +0x2c50040,2, +0x2c50054,4, +0x2c50080,27, +0x2c50100,12, +0x2c50140,14, +0x2c50180,28, +0x2c50200,6, +0x2c50240,6, +0x2c5025c,3, +0x2c50280,5, +0x2c502a0,8, +0x2c50400,14, +0x2c50440,14, +0x2c50480,14, +0x2c504c0,14, +0x2c50540,3, +0x2c50600,7, +0x2c50620,14, +0x2c50680,5, +0x2c506a0,7, +0x2c50800,13, +0x2c50840,2, +0x2c50854,4, +0x2c50880,27, +0x2c50900,12, +0x2c50940,14, +0x2c50980,28, +0x2c50a00,6, +0x2c50a40,6, +0x2c50a5c,3, +0x2c50a80,5, +0x2c50aa0,8, +0x2c50c00,14, +0x2c50c40,14, +0x2c50c80,14, +0x2c50cc0,14, +0x2c50d40,3, +0x2c50e00,7, +0x2c50e20,14, +0x2c50e80,5, +0x2c50ea0,7, +0x2c51000,13, +0x2c51040,2, +0x2c51054,4, +0x2c51080,27, +0x2c51100,12, +0x2c51140,14, +0x2c51180,28, +0x2c51200,6, +0x2c51240,6, +0x2c5125c,3, +0x2c51280,5, +0x2c512a0,8, +0x2c51400,14, +0x2c51440,14, +0x2c51480,14, +0x2c514c0,14, +0x2c51540,3, +0x2c51600,7, +0x2c51620,14, +0x2c51680,5, +0x2c516a0,7, +0x2c51800,13, +0x2c51840,2, +0x2c51854,4, +0x2c51880,27, +0x2c51900,12, +0x2c51940,14, +0x2c51980,28, +0x2c51a00,6, +0x2c51a40,6, +0x2c51a5c,3, +0x2c51a80,5, +0x2c51aa0,8, +0x2c51c00,14, +0x2c51c40,14, +0x2c51c80,14, +0x2c51cc0,14, +0x2c51d40,3, +0x2c51e00,7, +0x2c51e20,14, +0x2c51e80,5, +0x2c51ea0,7, +0x2c52000,8, +0x2c52040,8, +0x2c52080,1, +0x2c52098,6, +0x2c52100,10, +0x2c52140,3, +0x2c52150,2, +0x2c52180,2, +0x2c52200,6, +0x2c52220,18, +0x2c52280,4, +0x2c52300,8, +0x2c52400,2, +0x2c52480,2, +0x2c52800,28, +0x2c529f0,4, +0x2c53000,40, +0x2c53100,64, +0x2c53800,56, +0x2c53be0,8, +0x2c54000,13, +0x2c54040,2, +0x2c54054,4, +0x2c54080,27, +0x2c54100,12, +0x2c54140,14, +0x2c54180,28, +0x2c54200,6, +0x2c54240,6, +0x2c5425c,3, +0x2c54280,5, +0x2c542a0,8, +0x2c54400,14, +0x2c54440,14, +0x2c54480,14, +0x2c544c0,14, +0x2c54540,3, +0x2c54600,7, +0x2c54620,14, +0x2c54680,5, +0x2c546a0,7, +0x2c54800,13, +0x2c54840,2, +0x2c54854,4, +0x2c54880,27, +0x2c54900,12, +0x2c54940,14, +0x2c54980,28, +0x2c54a00,6, +0x2c54a40,6, +0x2c54a5c,3, +0x2c54a80,5, +0x2c54aa0,8, +0x2c54c00,14, +0x2c54c40,14, +0x2c54c80,14, +0x2c54cc0,14, +0x2c54d40,3, +0x2c54e00,7, +0x2c54e20,14, +0x2c54e80,5, +0x2c54ea0,7, +0x2c55000,13, +0x2c55040,2, +0x2c55054,4, +0x2c55080,27, +0x2c55100,12, +0x2c55140,14, +0x2c55180,28, +0x2c55200,6, +0x2c55240,6, +0x2c5525c,3, +0x2c55280,5, +0x2c552a0,8, +0x2c55400,14, +0x2c55440,14, +0x2c55480,14, +0x2c554c0,14, +0x2c55540,3, +0x2c55600,7, +0x2c55620,14, +0x2c55680,5, +0x2c556a0,7, +0x2c55800,13, +0x2c55840,2, +0x2c55854,4, +0x2c55880,27, +0x2c55900,12, +0x2c55940,14, +0x2c55980,28, +0x2c55a00,6, +0x2c55a40,6, +0x2c55a5c,3, +0x2c55a80,5, +0x2c55aa0,8, +0x2c55c00,14, +0x2c55c40,14, +0x2c55c80,14, +0x2c55cc0,14, +0x2c55d40,3, +0x2c55e00,7, +0x2c55e20,14, +0x2c55e80,5, +0x2c55ea0,7, +0x2c56000,8, +0x2c56040,8, +0x2c56080,1, +0x2c56098,6, +0x2c56100,10, +0x2c56140,3, +0x2c56150,2, +0x2c56180,2, +0x2c56200,6, +0x2c56220,18, +0x2c56280,4, +0x2c56300,8, +0x2c56400,2, +0x2c56480,2, +0x2c56800,28, +0x2c569f0,4, +0x2c57000,40, +0x2c57100,64, +0x2c57800,56, +0x2c57be0,8, +0x2c58000,2, +0x2c5800c,2, +0x2c58040,7, +0x2c58100,3, +0x2c58110,3, +0x2c58120,5, +0x2c58200,6, +0x2c58240,5, +0x2c58400,2, +0x2c5840c,2, +0x2c58440,7, +0x2c58500,3, +0x2c58510,3, +0x2c58520,5, +0x2c58600,6, +0x2c58640,5, +0x2c58800,2, +0x2c5880c,2, +0x2c58840,7, +0x2c58900,3, +0x2c58910,3, +0x2c58920,5, +0x2c58a00,6, +0x2c58a40,5, +0x2c58c00,2, +0x2c58c0c,2, +0x2c58c40,7, +0x2c58d00,3, +0x2c58d10,3, +0x2c58d20,5, +0x2c58e00,6, +0x2c58e40,5, +0x2c59000,2, +0x2c5900c,2, +0x2c59040,7, +0x2c59100,3, +0x2c59110,3, +0x2c59120,5, +0x2c59200,6, +0x2c59240,5, +0x2c59400,2, +0x2c5940c,2, +0x2c59440,7, +0x2c59500,3, +0x2c59510,3, +0x2c59520,5, +0x2c59600,6, +0x2c59640,5, +0x2c59800,2, +0x2c5980c,2, +0x2c59840,7, +0x2c59900,3, +0x2c59910,3, +0x2c59920,5, +0x2c59a00,6, +0x2c59a40,5, +0x2c59c00,2, +0x2c59c0c,2, +0x2c59c40,7, +0x2c59d00,3, +0x2c59d10,3, +0x2c59d20,5, +0x2c59e00,6, +0x2c59e40,5, +0x2c5a000,5, +0x2c5a040,9, +0x2c5a100,3, +0x2c5a200,1, +0x2c5a210,1, +0x2c5a220,1, +0x2c5a230,1, +0x2c5a240,1, +0x2c5a300,3, +0x2c5a314,1, +0x2c5a320,4, +0x2c5a400,5, +0x2c5a440,5, +0x2c5b000,80, +0x2c5b200,1, +0x2c60004,5, +0x2c60020,3, +0x2c60030,3, +0x2c60040,13, +0x2c60078,4, +0x2c6009c,25, +0x2c60104,5, +0x2c60120,3, +0x2c60130,3, +0x2c60140,13, +0x2c60178,4, +0x2c6019c,25, +0x2c60204,5, +0x2c60220,3, +0x2c60230,3, +0x2c60240,13, +0x2c60278,4, +0x2c6029c,25, +0x2c60304,5, +0x2c60320,3, +0x2c60330,3, +0x2c60340,13, +0x2c60378,4, +0x2c6039c,25, +0x2c60600,4, +0x2c60c00,24, +0x2c60c80,24, +0x2c60d00,24, +0x2c60d80,24, +0x2c60e00,4, +0x2c60e20,4, +0x2c60e40,4, +0x2c60e60,4, +0x2c60e80,39, +0x2c60f20,7, +0x2c60f40,7, +0x2c60f60,7, +0x2c61000,12, +0x2c61200,1, +0x2c61218,2, +0x2c6122c,1, +0x2c61280,1, +0x2c61298,2, +0x2c612ac,1, +0x2c61300,1, +0x2c61318,2, +0x2c6132c,1, +0x2c61380,1, +0x2c61398,2, +0x2c613ac,1, +0x2c61400,4, +0x2c61420,2, +0x2c6142c,1, +0x2c61480,4, +0x2c614a0,2, +0x2c614ac,1, +0x2c61500,4, +0x2c61520,2, +0x2c6152c,1, +0x2c61580,4, +0x2c615a0,2, +0x2c615ac,1, +0x2c61600,4, +0x2c61640,4, +0x2c61680,4, +0x2c616c0,4, +0x2c61700,7, +0x2c61720,7, +0x2c61740,7, +0x2c61760,7, +0x2c61780,4, +0x2c6179c,11, +0x2c617d0,2, +0x2c617e0,2, +0x2c617f0,2, +0x2c61900,44, +0x2c62000,7, +0x2c62020,4, +0x2c62040,4, +0x2c62060,7, +0x2c62080,7, +0x2c620a0,4, +0x2c620c0,4, +0x2c620e0,7, +0x2c62100,7, +0x2c62120,4, +0x2c62140,4, +0x2c62160,7, +0x2c62180,7, +0x2c621a0,4, +0x2c621c0,4, +0x2c621e0,7, +0x2c62200,32, +0x2c62b00,1, +0x2c62b20,1, +0x2c62b28,4, +0x2c62b40,1, +0x2c62b60,1, +0x2c62b68,4, +0x2c62b80,1, +0x2c62ba0,1, +0x2c62ba8,4, +0x2c62bc0,1, +0x2c62be0,1, +0x2c62be8,4, +0x2c62c00,7, +0x2c62c20,1, +0x2c62c54,18, +0x2c62ca0,1, +0x2c62cd4,18, +0x2c62d20,1, +0x2c62d54,18, +0x2c62da0,1, +0x2c62dd4,12, +0x2c62e08,6, +0x2c63100,7, +0x2c63120,7, +0x2c63140,7, +0x2c63160,7, +0x2c63180,3, +0x2c64004,5, +0x2c64020,3, +0x2c64030,3, +0x2c64040,13, +0x2c64078,4, +0x2c6409c,25, +0x2c64104,5, +0x2c64120,3, +0x2c64130,3, +0x2c64140,13, +0x2c64178,4, +0x2c6419c,25, +0x2c64204,5, +0x2c64220,3, +0x2c64230,3, +0x2c64240,13, +0x2c64278,4, +0x2c6429c,25, +0x2c64304,5, +0x2c64320,3, +0x2c64330,3, +0x2c64340,13, +0x2c64378,4, +0x2c6439c,25, +0x2c64600,4, +0x2c64c00,24, +0x2c64c80,24, +0x2c64d00,24, +0x2c64d80,24, +0x2c64e00,4, +0x2c64e20,4, +0x2c64e40,4, +0x2c64e60,4, +0x2c64e80,39, +0x2c64f20,7, +0x2c64f40,7, +0x2c64f60,7, +0x2c65000,12, +0x2c65200,1, +0x2c65218,2, +0x2c6522c,1, +0x2c65280,1, +0x2c65298,2, +0x2c652ac,1, +0x2c65300,1, +0x2c65318,2, +0x2c6532c,1, +0x2c65380,1, +0x2c65398,2, +0x2c653ac,1, +0x2c65400,4, +0x2c65420,2, +0x2c6542c,1, +0x2c65480,4, +0x2c654a0,2, +0x2c654ac,1, +0x2c65500,4, +0x2c65520,2, +0x2c6552c,1, +0x2c65580,4, +0x2c655a0,2, +0x2c655ac,1, +0x2c65600,4, +0x2c65640,4, +0x2c65680,4, +0x2c656c0,4, +0x2c65700,7, +0x2c65720,7, +0x2c65740,7, +0x2c65760,7, +0x2c65780,4, +0x2c6579c,11, +0x2c657d0,2, +0x2c657e0,2, +0x2c657f0,2, +0x2c65900,44, +0x2c66000,7, +0x2c66020,4, +0x2c66040,4, +0x2c66060,7, +0x2c66080,7, +0x2c660a0,4, +0x2c660c0,4, +0x2c660e0,7, +0x2c66100,7, +0x2c66120,4, +0x2c66140,4, +0x2c66160,7, +0x2c66180,7, +0x2c661a0,4, +0x2c661c0,4, +0x2c661e0,7, +0x2c66200,32, +0x2c66b00,1, +0x2c66b20,1, +0x2c66b28,4, +0x2c66b40,1, +0x2c66b60,1, +0x2c66b68,4, +0x2c66b80,1, +0x2c66ba0,1, +0x2c66ba8,4, +0x2c66bc0,1, +0x2c66be0,1, +0x2c66be8,4, +0x2c66c00,7, +0x2c66c20,1, +0x2c66c54,18, +0x2c66ca0,1, +0x2c66cd4,18, +0x2c66d20,1, +0x2c66d54,18, +0x2c66da0,1, +0x2c66dd4,12, +0x2c66e08,6, +0x2c67100,7, +0x2c67120,7, +0x2c67140,7, +0x2c67160,7, +0x2c67180,3, +0x2c68000,10, +0x2c68080,3, +0x2c680c0,1, +0x2c68100,21, +0x2c68180,13, +0x2c681c4,7, +0x2c681e4,7, +0x2c68204,7, +0x2c68224,8, +0x2c69000,7, +0x2c69030,2, +0x2c69040,7, +0x2c69070,2, +0x2c69100,2, +0x2c69120,2, +0x2c69140,2, +0x2c69160,2, +0x2c69180,9, +0x2c69200,7, +0x2c69230,2, +0x2c69240,7, +0x2c69270,2, +0x2c69300,2, +0x2c69320,2, +0x2c69340,2, +0x2c69360,2, +0x2c69380,9, +0x2c69400,11, +0x2c69500,11, +0x2c6a000,3, +0x2c6a010,2, +0x2c6a01c,5, +0x2c6a040,8, +0x2c6a080,3, +0x2c6a090,2, +0x2c6a09c,5, +0x2c6a0c0,8, +0x2c6a100,3, +0x2c6a110,2, +0x2c6a11c,5, +0x2c6a140,8, +0x2c6a180,3, +0x2c6a190,2, +0x2c6a19c,5, +0x2c6a1c0,8, +0x2c6a200,7, +0x2c6a220,12, +0x2c6a280,7, +0x2c6a2a0,12, +0x2c6a300,3, +0x2c6a310,1, +0x2c6a400,3, +0x2c6a410,2, +0x2c6a41c,5, +0x2c6a440,8, +0x2c6a480,3, +0x2c6a490,2, +0x2c6a49c,5, +0x2c6a4c0,8, +0x2c6a500,3, +0x2c6a510,2, +0x2c6a51c,5, +0x2c6a540,8, +0x2c6a580,3, +0x2c6a590,2, +0x2c6a59c,5, +0x2c6a5c0,8, +0x2c6a600,7, +0x2c6a620,12, +0x2c6a680,7, +0x2c6a6a0,12, +0x2c6a700,3, +0x2c6a710,1, +0x2c6a804,1, +0x2c6a824,21, +0x2c6a880,16, +0x2c6a900,5, +0x2c6a920,11, +0x2c6a950,9, +0x2c6a980,22, +0x2c6aa00,22, +0x2c6aa80,22, +0x2c6ab00,22, +0x2c6ab80,22, +0x2c6ac00,22, +0x2c6ac80,22, +0x2c6ad00,22, +0x2c6ad80,3, +0x2c6c000,16, +0x2c6c080,11, +0x2c6c100,11, +0x2c6c204,1, +0x2c6c224,21, +0x2c6c280,16, +0x2c6c300,11, +0x2c6c340,11, +0x2c6c800,21, +0x2c6c860,5, +0x2c6c880,6, +0x2c6c8a0,5, +0x2c6c8c0,6, +0x2c6c900,21, +0x2c6c960,5, +0x2c6c980,6, +0x2c6c9a0,5, +0x2c6c9c0,6, +0x2c6ca00,21, +0x2c6ca60,5, +0x2c6ca80,6, +0x2c6caa0,5, +0x2c6cac0,6, +0x2c6cb00,21, +0x2c6cb60,5, +0x2c6cb80,6, +0x2c6cba0,5, +0x2c6cbc0,6, +0x2c6cc00,9, +0x2c6cc48,7, +0x2c6cc68,2, +0x2c6cc74,9, +0x2c6cc9c,2, +0x2c6cd00,14, +0x2c6cd40,14, +0x2c6cd80,28, +0x2c6ce00,19, +0x2c6ce50,3, +0x2c6ce60,25, +0x2c6cec8,1, +0x2c6ced0,2, +0x2c6cee0,7, +0x2c6cf00,1, +0x2c6cf08,2, +0x2c6cffc,20, +0x2c6d050,25, +0x2c6d100,19, +0x2c6d150,25, +0x2c6d200,19, +0x2c6d250,25, +0x2c6d300,19, +0x2c6d350,25, +0x2c6d400,19, +0x2c6d450,25, +0x2c6d500,19, +0x2c6d550,25, +0x2c6d600,19, +0x2c6d650,25, +0x2c6d700,19, +0x2c6d750,25, +0x2c6d800,19, +0x2c6d850,25, +0x2c6d904,1, +0x2c6d914,10, +0x2c6d948,11, +0x2c6d980,2, +0x2c6d9a0,6, +0x2c6d9c0,2, +0x2c6d9cc,2, +0x2c6e000,35, +0x2c6ea00,10, +0x2c6ea80,3, +0x2c6eb00,6, +0x2c6f000,1, +0x2c6f008,5, +0x2c6f038,1, +0x2c6f044,1, +0x2c6f050,2, +0x2c6f100,13, +0x2c6f140,11, +0x2c6f170,12, +0x2c6f1a4,1, +0x2c6f200,104, +0x2c6f400,104, +0x2c6f600,104, +0x2c6f800,104, +0x2c70000,13, +0x2c70040,2, +0x2c70054,4, +0x2c70080,27, +0x2c70100,12, +0x2c70140,14, +0x2c70180,28, +0x2c70200,6, +0x2c70240,6, +0x2c7025c,3, +0x2c70280,5, +0x2c702a0,8, +0x2c70400,14, +0x2c70440,14, +0x2c70480,14, +0x2c704c0,14, +0x2c70540,3, +0x2c70600,7, +0x2c70620,14, +0x2c70680,5, +0x2c706a0,7, +0x2c70800,13, +0x2c70840,2, +0x2c70854,4, +0x2c70880,27, +0x2c70900,12, +0x2c70940,14, +0x2c70980,28, +0x2c70a00,6, +0x2c70a40,6, +0x2c70a5c,3, +0x2c70a80,5, +0x2c70aa0,8, +0x2c70c00,14, +0x2c70c40,14, +0x2c70c80,14, +0x2c70cc0,14, +0x2c70d40,3, +0x2c70e00,7, +0x2c70e20,14, +0x2c70e80,5, +0x2c70ea0,7, +0x2c71000,13, +0x2c71040,2, +0x2c71054,4, +0x2c71080,27, +0x2c71100,12, +0x2c71140,14, +0x2c71180,28, +0x2c71200,6, +0x2c71240,6, +0x2c7125c,3, +0x2c71280,5, +0x2c712a0,8, +0x2c71400,14, +0x2c71440,14, +0x2c71480,14, +0x2c714c0,14, +0x2c71540,3, +0x2c71600,7, +0x2c71620,14, +0x2c71680,5, +0x2c716a0,7, +0x2c71800,13, +0x2c71840,2, +0x2c71854,4, +0x2c71880,27, +0x2c71900,12, +0x2c71940,14, +0x2c71980,28, +0x2c71a00,6, +0x2c71a40,6, +0x2c71a5c,3, +0x2c71a80,5, +0x2c71aa0,8, +0x2c71c00,14, +0x2c71c40,14, +0x2c71c80,14, +0x2c71cc0,14, +0x2c71d40,3, +0x2c71e00,7, +0x2c71e20,14, +0x2c71e80,5, +0x2c71ea0,7, +0x2c72000,8, +0x2c72040,8, +0x2c72080,1, +0x2c72098,6, +0x2c72100,10, +0x2c72140,3, +0x2c72150,2, +0x2c72180,2, +0x2c72200,6, +0x2c72220,18, +0x2c72280,4, +0x2c72300,8, +0x2c72400,2, +0x2c72480,2, +0x2c72800,28, +0x2c729f0,4, +0x2c73000,40, +0x2c73100,64, +0x2c73800,56, +0x2c73be0,8, +0x2c74000,13, +0x2c74040,2, +0x2c74054,4, +0x2c74080,27, +0x2c74100,12, +0x2c74140,14, +0x2c74180,28, +0x2c74200,6, +0x2c74240,6, +0x2c7425c,3, +0x2c74280,5, +0x2c742a0,8, +0x2c74400,14, +0x2c74440,14, +0x2c74480,14, +0x2c744c0,14, +0x2c74540,3, +0x2c74600,7, +0x2c74620,14, +0x2c74680,5, +0x2c746a0,7, +0x2c74800,13, +0x2c74840,2, +0x2c74854,4, +0x2c74880,27, +0x2c74900,12, +0x2c74940,14, +0x2c74980,28, +0x2c74a00,6, +0x2c74a40,6, +0x2c74a5c,3, +0x2c74a80,5, +0x2c74aa0,8, +0x2c74c00,14, +0x2c74c40,14, +0x2c74c80,14, +0x2c74cc0,14, +0x2c74d40,3, +0x2c74e00,7, +0x2c74e20,14, +0x2c74e80,5, +0x2c74ea0,7, +0x2c75000,13, +0x2c75040,2, +0x2c75054,4, +0x2c75080,27, +0x2c75100,12, +0x2c75140,14, +0x2c75180,28, +0x2c75200,6, +0x2c75240,6, +0x2c7525c,3, +0x2c75280,5, +0x2c752a0,8, +0x2c75400,14, +0x2c75440,14, +0x2c75480,14, +0x2c754c0,14, +0x2c75540,3, +0x2c75600,7, +0x2c75620,14, +0x2c75680,5, +0x2c756a0,7, +0x2c75800,13, +0x2c75840,2, +0x2c75854,4, +0x2c75880,27, +0x2c75900,12, +0x2c75940,14, +0x2c75980,28, +0x2c75a00,6, +0x2c75a40,6, +0x2c75a5c,3, +0x2c75a80,5, +0x2c75aa0,8, +0x2c75c00,14, +0x2c75c40,14, +0x2c75c80,14, +0x2c75cc0,14, +0x2c75d40,3, +0x2c75e00,7, +0x2c75e20,14, +0x2c75e80,5, +0x2c75ea0,7, +0x2c76000,8, +0x2c76040,8, +0x2c76080,1, +0x2c76098,6, +0x2c76100,10, +0x2c76140,3, +0x2c76150,2, +0x2c76180,2, +0x2c76200,6, +0x2c76220,18, +0x2c76280,4, +0x2c76300,8, +0x2c76400,2, +0x2c76480,2, +0x2c76800,28, +0x2c769f0,4, +0x2c77000,40, +0x2c77100,64, +0x2c77800,56, +0x2c77be0,8, +0x2c78000,2, +0x2c7800c,2, +0x2c78040,7, +0x2c78100,3, +0x2c78110,3, +0x2c78120,5, +0x2c78200,6, +0x2c78240,5, +0x2c78400,2, +0x2c7840c,2, +0x2c78440,7, +0x2c78500,3, +0x2c78510,3, +0x2c78520,5, +0x2c78600,6, +0x2c78640,5, +0x2c78800,2, +0x2c7880c,2, +0x2c78840,7, +0x2c78900,3, +0x2c78910,3, +0x2c78920,5, +0x2c78a00,6, +0x2c78a40,5, +0x2c78c00,2, +0x2c78c0c,2, +0x2c78c40,7, +0x2c78d00,3, +0x2c78d10,3, +0x2c78d20,5, +0x2c78e00,6, +0x2c78e40,5, +0x2c79000,2, +0x2c7900c,2, +0x2c79040,7, +0x2c79100,3, +0x2c79110,3, +0x2c79120,5, +0x2c79200,6, +0x2c79240,5, +0x2c79400,2, +0x2c7940c,2, +0x2c79440,7, +0x2c79500,3, +0x2c79510,3, +0x2c79520,5, +0x2c79600,6, +0x2c79640,5, +0x2c79800,2, +0x2c7980c,2, +0x2c79840,7, +0x2c79900,3, +0x2c79910,3, +0x2c79920,5, +0x2c79a00,6, +0x2c79a40,5, +0x2c79c00,2, +0x2c79c0c,2, +0x2c79c40,7, +0x2c79d00,3, +0x2c79d10,3, +0x2c79d20,5, +0x2c79e00,6, +0x2c79e40,5, +0x2c7a000,5, +0x2c7a040,9, +0x2c7a100,3, +0x2c7a200,1, +0x2c7a210,1, +0x2c7a220,1, +0x2c7a230,1, +0x2c7a240,1, +0x2c7a300,3, +0x2c7a314,1, +0x2c7a320,4, +0x2c7a400,5, +0x2c7a440,5, +0x2c7b000,80, +0x2c7b200,1, +0x2c80000,3, +0x2c80010,7, +0x2c80030,10, +0x2c80080,2, +0x2c80100,6, +0x2c80140,2, +0x2c80180,2, +0x2c801a0,1, +0x2c80400,2, +0x2c80440,4, +0x2c80460,5, +0x2c80478,1, +0x2c80480,6, +0x2c804a0,3, +0x2c804b0,2, +0x2c80500,5, +0x2c80600,1, +0x2c80800,5, +0x2c80900,5, +0x2c80a00,5, +0x2c80b00,3, +0x2c80c00,35, +0x2c80d00,25, +0x2c80d80,1, +0x2c80dc0,3, +0x2c80e00,2, +0x2c80e20,2, +0x2c90000,3, +0x2c9001c,6, +0x2c90080,3, +0x2c90090,2, +0x2c900d4,4, +0x2c900ec,27, +0x2c9015c,27, +0x2c901cc,19, +0x2c90224,120, +0x2c90408,109, +0x2c905f8,4, +0x2c90610,27, +0x2c90680,27, +0x2c906f0,19, +0x2c90748,120, +0x2c9092c,109, +0x2c90b1c,4, +0x2c90b34,27, +0x2c90ba4,27, +0x2c90c14,19, +0x2c90c6c,120, +0x2c90e50,109, +0x2c91040,4, +0x2c91058,27, +0x2c910c8,27, +0x2c91138,19, +0x2c91190,120, +0x2c91374,109, +0x2c91564,4, +0x2c9157c,27, +0x2c915ec,27, +0x2c9165c,19, +0x2c916b4,120, +0x2c91898,109, +0x2c91a88,4, +0x2c91aa0,27, +0x2c91b10,27, +0x2c91b80,19, +0x2c91bd8,120, +0x2c91dbc,109, +0x2c91fac,4, +0x2c91fc4,27, +0x2c92034,27, +0x2c920a4,19, +0x2c920fc,120, +0x2c922e0,109, +0x2c924d0,4, +0x2c924e8,27, +0x2c92558,27, +0x2c925c8,19, +0x2c92620,120, +0x2c92804,109, +0x2c929f4,4, +0x2c92a0c,27, +0x2c92a7c,27, +0x2c92aec,19, +0x2c92b44,120, +0x2c92d28,109, +0x2c92f18,4, +0x2c92f30,27, +0x2c92fa0,27, +0x2c93010,19, +0x2c93068,120, +0x2c9324c,109, +0x2c9343c,4, +0x2c93454,27, +0x2c934c4,27, +0x2c93534,19, +0x2c9358c,120, +0x2c93770,109, +0x2c93960,4, +0x2c93978,27, +0x2c939e8,27, +0x2c93a58,19, +0x2c93ab0,120, +0x2c93c94,109, +0x2c93e84,4, +0x2c93e9c,27, +0x2c93f0c,27, +0x2c93f7c,19, +0x2c93fd4,120, +0x2c941b8,109, +0x2c943a8,4, +0x2c943c0,27, +0x2c94430,27, +0x2c944a0,19, +0x2c944f8,120, +0x2c946dc,109, +0x2c948cc,4, +0x2c948e4,27, +0x2c94954,27, +0x2c949c4,19, +0x2c94a1c,120, +0x2c94c00,109, +0x2c94df0,4, +0x2c94e08,27, +0x2c94e78,27, +0x2c94ee8,19, +0x2c94f40,120, +0x2c95124,109, +0x2c95314,4, +0x2c9532c,27, +0x2c9539c,27, +0x2c9540c,19, +0x2c95464,120, +0x2c95648,109, +0x2c95838,14, +0x2c95940,13, +0x2c95a44,13, +0x2c95b48,16, +0x2c95b90,42, +0x2c95c40,2, +0x2c95c90,54, +0x2c95d70,58, +0x2c95e60,58, +0x2c95f50,58, +0x2c96040,58, +0x2c96130,58, +0x2c96220,58, +0x2c96310,58, +0x2c96400,58, +0x2c964f0,58, +0x2c965e0,58, +0x2c966d0,58, +0x2c967c0,58, +0x2c968b0,58, +0x2c969a0,58, +0x2c96a90,58, +0x2c96b80,58, +0x2c96c70,58, +0x2c96d60,58, +0x2c96e50,58, +0x2c96f40,58, +0x2c97030,58, +0x2c97120,58, +0x2c97210,58, +0x2c97300,58, +0x2c973f0,58, +0x2c974e0,58, +0x2c975d0,58, +0x2c976c0,58, +0x2c977b0,58, +0x2c978a0,58, +0x2c97990,58, +0x2c97a80,101, +0x2c97c90,49, +0x2c97db0,18, +0x2c97e00,11, +0x2c97e30,4, +0x2c97e54,45, +0x2c97f58,9, +0x2c97f88,4, +0x2c97fa0,2, +0x2c97fd8,14, +0x2c98014,12, +0x2c98158,3, +0x2c98168,2, +0x2c98174,68, +0x2c98288,2, +0x2c98294,68, +0x2c983a8,1, +0x2c983b0,2, +0x2c983bc,68, +0x2c984d0,2, +0x2c984dc,68, +0x2c985f0,1, +0x2c985f8,4, +0x2c98610,3, +0x2c98624,12, +0x2c98688,8, +0x2c986dc,1, +0x2c986e8,4, +0x2c98700,3, +0x2c98714,12, +0x2c98778,8, +0x2c987cc,1, +0x2c987d8,4, +0x2c987f0,3, +0x2c98804,12, +0x2c98868,8, +0x2c988bc,1, +0x2c988c8,4, +0x2c988e0,3, +0x2c988f4,12, +0x2c98958,8, +0x2c989ac,1, +0x2c989b8,4, +0x2c989d0,3, +0x2c989e4,12, +0x2c98a48,8, +0x2c98a9c,1, +0x2c98aa8,4, +0x2c98ac0,3, +0x2c98ad4,12, +0x2c98b38,8, +0x2c98b8c,1, +0x2c98b98,4, +0x2c98bb0,3, +0x2c98bc4,12, +0x2c98c28,8, +0x2c98c7c,1, +0x2c98c88,4, +0x2c98ca0,3, +0x2c98cb4,12, +0x2c98d18,8, +0x2c98d6c,1, +0x2c98d78,4, +0x2c98d90,3, +0x2c98da4,12, +0x2c98e08,8, +0x2c98e5c,1, +0x2c98e68,4, +0x2c98e80,3, +0x2c98e94,12, +0x2c98ef8,8, +0x2c98f4c,1, +0x2c98f58,4, +0x2c98f70,3, +0x2c98f84,12, +0x2c98fe8,8, +0x2c9903c,1, +0x2c99048,4, +0x2c99060,3, +0x2c99074,12, +0x2c990d8,8, +0x2c9912c,1, +0x2c99138,4, +0x2c99150,3, +0x2c99164,12, +0x2c991c8,8, +0x2c9921c,1, +0x2c99228,4, +0x2c99240,3, +0x2c99254,12, +0x2c992b8,8, +0x2c9930c,1, +0x2c99318,4, +0x2c99330,3, +0x2c99344,12, +0x2c993a8,8, +0x2c993fc,1, +0x2c99408,4, +0x2c99420,3, +0x2c99434,12, +0x2c99498,8, +0x2c994ec,1, +0x2c994f8,4, +0x2c99510,3, +0x2c99524,12, +0x2c99588,8, +0x2c995dc,1, +0x2c995e8,64, +0x2c99748,5, +0x2c99990,28, +0x2c99a04,4, +0x2c99a98,1, +0x2c99be8,11, +0x2c99c18,13, +0x2c99c50,6, +0x2c9a000,15, +0x2c9a044,81, +0x2c9a18c,84, +0x2c9a2e0,84, +0x2c9a434,84, +0x2c9a588,84, +0x2c9a6dc,84, +0x2c9a830,84, +0x2c9a984,84, +0x2c9aad8,84, +0x2c9ac2c,84, +0x2c9ad80,84, +0x2c9aed4,84, +0x2c9b028,84, +0x2c9b17c,84, +0x2c9b2d0,84, +0x2c9b424,84, +0x2c9b578,84, +0x2c9b6cc,5, +0x2c9b760,4, +0x2c9b8e0,2414, +0x2c9dea4,88, +0x2c9e048,4, +0x2c9ebe0,1, +0x2c9ebf0,97, +0x2c9ed94,7, +0x2c9ee7c,1, +0x2c9eeac,9, +0x2c9eed4,5, +0x2c9eeec,11, +0x2c9ef2c,17, +0x2c9ef74,30, +0x2c9f034,3, +0x2c9f044,2, +0x2c9f054,17, +0x2c9fbe0,3, +0x2c9fbf0,1, +0x2ca0000,3, +0x2ca0018,2, +0x2ca0024,14, +0x2ca0060,27, +0x2ca00d0,3, +0x2ca00e0,3, +0x2ca00f0,3, +0x2ca0100,4, +0x2ca0120,6, +0x2ca0140,3, +0x2ca0150,1, +0x2ca015c,4, +0x2ca0170,1, +0x2ca0180,15, +0x2ca01c0,1, +0x2ca01c8,5, +0x2ca01e0,1, +0x2ca01f0,3, +0x2ca0200,3, +0x2ca0218,2, +0x2ca0224,14, +0x2ca0260,27, +0x2ca02d0,3, +0x2ca02e0,3, +0x2ca02f0,3, +0x2ca0300,4, +0x2ca0320,6, +0x2ca0340,3, +0x2ca0350,1, +0x2ca035c,4, +0x2ca0370,1, +0x2ca0380,15, +0x2ca03c0,1, +0x2ca03c8,5, +0x2ca03e0,1, +0x2ca03f0,3, +0x2ca0400,3, +0x2ca0418,2, +0x2ca0424,14, +0x2ca0460,27, +0x2ca04d0,3, +0x2ca04e0,3, +0x2ca04f0,3, +0x2ca0500,4, +0x2ca0520,6, +0x2ca0540,3, +0x2ca0550,1, +0x2ca055c,4, +0x2ca0570,1, +0x2ca0580,15, +0x2ca05c0,1, +0x2ca05c8,5, +0x2ca05e0,1, +0x2ca05f0,3, +0x2ca0600,3, +0x2ca0618,2, +0x2ca0624,14, +0x2ca0660,27, +0x2ca06d0,3, +0x2ca06e0,3, +0x2ca06f0,3, +0x2ca0700,4, +0x2ca0720,6, +0x2ca0740,3, +0x2ca0750,1, +0x2ca075c,4, +0x2ca0770,1, +0x2ca0780,15, +0x2ca07c0,1, +0x2ca07c8,5, +0x2ca07e0,1, +0x2ca07f0,3, +0x2ca0800,3, +0x2ca0818,2, +0x2ca0824,14, +0x2ca0860,27, +0x2ca08d0,3, +0x2ca08e0,3, +0x2ca08f0,3, +0x2ca0900,4, +0x2ca0920,6, +0x2ca0940,3, +0x2ca0950,1, +0x2ca095c,4, +0x2ca0970,1, +0x2ca0980,15, +0x2ca09c0,1, +0x2ca09c8,5, +0x2ca09e0,1, +0x2ca09f0,3, +0x2ca1844,1, +0x2ca1858,5, +0x2ca1904,3, +0x2ca1950,3, +0x2ca1988,2, +0x2ca19a0,7, +0x2ca19c0,7, +0x2ca19e0,4, +0x2ca2000,24, +0x2ca20f0,3, +0x2ca2100,7, +0x2ca2120,7, +0x2ca2144,7, +0x2ca2400,4, +0x2ca2420,5, +0x2ca25e0,3, +0x2ca25f4,1, +0x2ca25fc,4, +0x2ca2620,3, +0x2ca2680,8, +0x2ca2700,19, +0x2ca2800,99, +0x2ca2a00,18, +0x2ca2a80,8, +0x2ca2b00,1, +0x2ca3070,1, +0x2ca3080,2, +0x2ca308c,1, +0x2ca3098,2, +0x2ca3404,1, +0x2ca3440,20, +0x2ca3494,1, +0x2ca349c,7, +0x2ca34d0,4, +0x2ca34e8,2, +0x2ca34fc,8, +0x2ca3520,7, +0x2ca3540,7, +0x2ca3560,7, +0x2ca3580,7, +0x2ca35a0,7, +0x2ca35c0,7, +0x2ca35e0,7, +0x2ca3600,9, +0x2ca363c,2, +0x2ca3650,6, +0x2ca3684,10, +0x2ca3a00,10, +0x2ca3a30,1, +0x2ca3a40,8, +0x2ca3a64,5, +0x2ca4a04,3, +0x2ca4b00,33, +0x2ca4b90,3, +0x2ca5000,8, +0x2ca5040,8, +0x2ca5104,1, +0x2ca510c,3, +0x2ca5124,1, +0x2ca512c,3, +0x2ca6000,13, +0x2ca6200,14, +0x2ca6240,1, +0x2ca6248,1, +0x2ca6258,1, +0x2ca6260,8, +0x2ca6284,1, +0x2ca62a0,8, +0x2ca6348,5, +0x2ca67f0,1, +0x2ca67f8,1, +0x2ca6a10,12, +0x2ca7000,19, +0x2ca7a00,10, +0x2ca7a80,3, +0x2ca7b00,6, +0x2cc0000,1, +0x2cc000c,5, +0x2cc0044,1, +0x2cc0054,5, +0x2cc0200,128, +0x2cc0404,1, +0x2cc0428,54, +0x2cc0600,32, +0x2cc0704,1, +0x2cc0800,1, +0x2cc0900,1, +0x2cc0910,2, +0x2cc0920,3, +0x2cc0980,10, +0x2cc0a00,19, +0x2cc0b00,1, +0x2ce0000,2, +0x2ce000c,2, +0x2ce0018,2, +0x2ce0024,2, +0x2ce0030,2, +0x2ce003c,2, +0x2ce0048,2, +0x2ce0054,2, +0x2ce0060,1, +0x2ce0070,2, +0x2ce007c,2, +0x2ce0088,2, +0x2ce0094,2, +0x2ce00a0,2, +0x2ce00ac,2, +0x2ce00b8,2, +0x2ce00c4,2, +0x2ce00d0,1, +0x2ce00e0,2, +0x2ce00ec,2, +0x2ce00f8,2, +0x2ce0104,2, +0x2ce0110,2, +0x2ce011c,2, +0x2ce0128,2, +0x2ce0134,2, +0x2ce0140,1, +0x2ce0150,2, +0x2ce015c,2, +0x2ce0168,2, +0x2ce0174,2, +0x2ce0180,2, +0x2ce018c,2, +0x2ce0198,2, +0x2ce01a4,2, +0x2ce01b0,1, +0x2ce01c0,57, +0x2ce02b0,23, +0x2ce0310,83, +0x2ce0460,83, +0x2ce05b0,83, +0x2ce0700,83, +0x2ce0850,83, +0x2ce09a0,83, +0x2ce0af0,83, +0x2ce0c40,83, +0x2ce0d90,83, +0x2ce0ee0,83, +0x2ce1030,83, +0x2ce1180,83, +0x2ce12d0,83, +0x2ce1420,83, +0x2ce1570,83, +0x2ce16c0,83, +0x2ce1810,83, +0x2ce1960,83, +0x2ce1ab0,83, +0x2ce1c00,83, +0x2ce1d50,83, +0x2ce1ea0,83, +0x2ce1ff0,83, +0x2ce2140,83, +0x2ce2290,83, +0x2ce23e0,83, +0x2ce2530,83, +0x2ce2680,83, +0x2ce27d0,83, +0x2ce2920,83, +0x2ce2a70,83, +0x2ce2bc0,62, +0x2ce2db4,3, +0x2ce2df4,3, +0x2ce2e34,3, +0x2ce2e74,3, +0x2ce2eb4,3, +0x2ce2ef4,3, +0x2ce2f34,3, +0x2ce2f74,3, +0x2ce2fb4,3, +0x2ce2ff4,3, +0x2ce3034,3, +0x2ce3074,3, +0x2ce30b4,3, +0x2ce30f4,3, +0x2ce3134,3, +0x2ce3174,3, +0x2ce31b4,3, +0x2cf0000,4, +0x2cf0014,2, +0x2cf0020,8, +0x2cf0044,2, +0x2cf0050,13, +0x2cf0088,20, +0x2cf00dc,1, +0x2cf0180,6, +0x2cf0590,3, +0x2cf05c0,2, +0x2cf0a04,1, +0x2cf0a0c,3, +0x2cf0a20,1, +0x2cf0ba0,4, +0x2cf0c00,4, +0x2cf0c20,3, +0x2cf0c30,5, +0x2cf0c50,52, +0x2cf0d50,57, +0x2cf0ec0,3, +0x2cf0ffc,3, +0x2cf1020,3, +0x2cf1030,3, +0x2cf1060,2, +0x2cf1100,2, +0x2cf1140,18, +0x2cf11c0,30, +0x2cf1240,14, +0x2cf1280,28, +0x2cf1300,2, +0x2cf13a0,6, +0x2cf1400,19, +0x2cf1800,19, +0x2cf1c00,19, +0x2cf1c80,8, +0x2cf1d00,3, +0x2cf1d50,3, +0x2cf1e00,3, +0x2cf1e10,2, +0x2cf1e20,6, +0x2cf1e40,6, +0x2cf1e60,6, +0x2cf1e80,6, +0x2cf1ea0,6, +0x2cf1ec0,2, +0x2cf1ecc,2, +0x2cf1ee0,2, +0x2cf1eec,2, +0x2cf1f80,3, +0x2cf1f90,60, +0x2cf2100,32, +0x2cf2200,32, +0x2cf2300,32, +0x2cf2400,32, +0x2cf2500,32, +0x2cf2600,32, +0x2cf2700,32, +0x2cf2800,32, +0x2cf2900,32, +0x2cf2a00,32, +0x2cf2b00,32, +0x2cf2c00,32, +0x2cf2d00,32, +0x2cf2e00,32, +0x2cf2f00,32, +0x2cf3000,32, +0x2cf30c0,3, +0x2cf4000,2, +0x2cf4040,16, +0x2cf4100,36, +0x2cf4800,5, +0x2cf4824,1, +0x2cf482c,1, +0x2cf4c04,1, +0x2cf4cd8,74, +0x2cf5000,7, +0x2cf5020,4, +0x2cf5204,1, +0x2cf5280,35, +0x2cf5310,4, +0x2cf5404,1, +0x2cf5480,34, +0x2cf5510,10, +0x2cf553c,3, +0x2cf5800,7, +0x2cf5820,4, +0x2cf5a04,1, +0x2cf5a80,35, +0x2cf5b10,4, +0x2cf5c04,1, +0x2cf5c80,34, +0x2cf5d10,10, +0x2cf5d3c,3, +0x2cfa000,5, +0x2cfa01c,13, +0x2cfa060,3, +0x2cfa080,8, +0x2cfa100,5, +0x2cfa11c,13, +0x2cfa160,3, +0x2cfa180,8, +0x2e00004,5, +0x2e00020,3, +0x2e00030,3, +0x2e00040,13, +0x2e00078,4, +0x2e0009c,25, +0x2e00104,5, +0x2e00120,3, +0x2e00130,3, +0x2e00140,13, +0x2e00178,4, +0x2e0019c,25, +0x2e00204,5, +0x2e00220,3, +0x2e00230,3, +0x2e00240,13, +0x2e00278,4, +0x2e0029c,25, +0x2e00304,5, +0x2e00320,3, +0x2e00330,3, +0x2e00340,13, +0x2e00378,4, +0x2e0039c,25, +0x2e00600,4, +0x2e00c00,24, +0x2e00c80,24, +0x2e00d00,24, +0x2e00d80,24, +0x2e00e00,4, +0x2e00e20,4, +0x2e00e40,4, +0x2e00e60,4, +0x2e00e80,39, +0x2e00f20,7, +0x2e00f40,7, +0x2e00f60,7, +0x2e01000,12, +0x2e01200,1, +0x2e01218,2, +0x2e0122c,1, +0x2e01280,1, +0x2e01298,2, +0x2e012ac,1, +0x2e01300,1, +0x2e01318,2, +0x2e0132c,1, +0x2e01380,1, +0x2e01398,2, +0x2e013ac,1, +0x2e01400,4, +0x2e01420,2, +0x2e0142c,1, +0x2e01480,4, +0x2e014a0,2, +0x2e014ac,1, +0x2e01500,4, +0x2e01520,2, +0x2e0152c,1, +0x2e01580,4, +0x2e015a0,2, +0x2e015ac,1, +0x2e01600,4, +0x2e01640,4, +0x2e01680,4, +0x2e016c0,4, +0x2e01700,7, +0x2e01720,7, +0x2e01740,7, +0x2e01760,7, +0x2e01780,4, +0x2e0179c,11, +0x2e017d0,2, +0x2e017e0,2, +0x2e017f0,2, +0x2e01900,44, +0x2e02000,7, +0x2e02020,4, +0x2e02040,4, +0x2e02060,7, +0x2e02080,7, +0x2e020a0,4, +0x2e020c0,4, +0x2e020e0,7, +0x2e02100,7, +0x2e02120,4, +0x2e02140,4, +0x2e02160,7, +0x2e02180,7, +0x2e021a0,4, +0x2e021c0,4, +0x2e021e0,7, +0x2e02200,32, +0x2e02b00,1, +0x2e02b20,1, +0x2e02b28,4, +0x2e02b40,1, +0x2e02b60,1, +0x2e02b68,4, +0x2e02b80,1, +0x2e02ba0,1, +0x2e02ba8,4, +0x2e02bc0,1, +0x2e02be0,1, +0x2e02be8,4, +0x2e02c00,7, +0x2e02c20,1, +0x2e02c54,18, +0x2e02ca0,1, +0x2e02cd4,18, +0x2e02d20,1, +0x2e02d54,18, +0x2e02da0,1, +0x2e02dd4,12, +0x2e02e08,6, +0x2e03100,7, +0x2e03120,7, +0x2e03140,7, +0x2e03160,7, +0x2e03180,3, +0x2e04004,5, +0x2e04020,3, +0x2e04030,3, +0x2e04040,13, +0x2e04078,4, +0x2e0409c,25, +0x2e04104,5, +0x2e04120,3, +0x2e04130,3, +0x2e04140,13, +0x2e04178,4, +0x2e0419c,25, +0x2e04204,5, +0x2e04220,3, +0x2e04230,3, +0x2e04240,13, +0x2e04278,4, +0x2e0429c,25, +0x2e04304,5, +0x2e04320,3, +0x2e04330,3, +0x2e04340,13, +0x2e04378,4, +0x2e0439c,25, +0x2e04600,4, +0x2e04c00,24, +0x2e04c80,24, +0x2e04d00,24, +0x2e04d80,24, +0x2e04e00,4, +0x2e04e20,4, +0x2e04e40,4, +0x2e04e60,4, +0x2e04e80,39, +0x2e04f20,7, +0x2e04f40,7, +0x2e04f60,7, +0x2e05000,12, +0x2e05200,1, +0x2e05218,2, +0x2e0522c,1, +0x2e05280,1, +0x2e05298,2, +0x2e052ac,1, +0x2e05300,1, +0x2e05318,2, +0x2e0532c,1, +0x2e05380,1, +0x2e05398,2, +0x2e053ac,1, +0x2e05400,4, +0x2e05420,2, +0x2e0542c,1, +0x2e05480,4, +0x2e054a0,2, +0x2e054ac,1, +0x2e05500,4, +0x2e05520,2, +0x2e0552c,1, +0x2e05580,4, +0x2e055a0,2, +0x2e055ac,1, +0x2e05600,4, +0x2e05640,4, +0x2e05680,4, +0x2e056c0,4, +0x2e05700,7, +0x2e05720,7, +0x2e05740,7, +0x2e05760,7, +0x2e05780,4, +0x2e0579c,11, +0x2e057d0,2, +0x2e057e0,2, +0x2e057f0,2, +0x2e05900,44, +0x2e06000,7, +0x2e06020,4, +0x2e06040,4, +0x2e06060,7, +0x2e06080,7, +0x2e060a0,4, +0x2e060c0,4, +0x2e060e0,7, +0x2e06100,7, +0x2e06120,4, +0x2e06140,4, +0x2e06160,7, +0x2e06180,7, +0x2e061a0,4, +0x2e061c0,4, +0x2e061e0,7, +0x2e06200,32, +0x2e06b00,1, +0x2e06b20,1, +0x2e06b28,4, +0x2e06b40,1, +0x2e06b60,1, +0x2e06b68,4, +0x2e06b80,1, +0x2e06ba0,1, +0x2e06ba8,4, +0x2e06bc0,1, +0x2e06be0,1, +0x2e06be8,4, +0x2e06c00,7, +0x2e06c20,1, +0x2e06c54,18, +0x2e06ca0,1, +0x2e06cd4,18, +0x2e06d20,1, +0x2e06d54,18, +0x2e06da0,1, +0x2e06dd4,12, +0x2e06e08,6, +0x2e07100,7, +0x2e07120,7, +0x2e07140,7, +0x2e07160,7, +0x2e07180,3, +0x2e08000,10, +0x2e08080,3, +0x2e080c0,1, +0x2e08100,21, +0x2e08180,13, +0x2e081c4,7, +0x2e081e4,7, +0x2e08204,7, +0x2e08224,8, +0x2e09000,7, +0x2e09030,2, +0x2e09040,7, +0x2e09070,2, +0x2e09100,2, +0x2e09120,2, +0x2e09140,2, +0x2e09160,2, +0x2e09180,9, +0x2e09200,7, +0x2e09230,2, +0x2e09240,7, +0x2e09270,2, +0x2e09300,2, +0x2e09320,2, +0x2e09340,2, +0x2e09360,2, +0x2e09380,9, +0x2e09400,11, +0x2e09500,11, +0x2e0a000,3, +0x2e0a010,2, +0x2e0a01c,5, +0x2e0a040,8, +0x2e0a080,3, +0x2e0a090,2, +0x2e0a09c,5, +0x2e0a0c0,8, +0x2e0a100,3, +0x2e0a110,2, +0x2e0a11c,5, +0x2e0a140,8, +0x2e0a180,3, +0x2e0a190,2, +0x2e0a19c,5, +0x2e0a1c0,8, +0x2e0a200,7, +0x2e0a220,12, +0x2e0a280,7, +0x2e0a2a0,12, +0x2e0a300,3, +0x2e0a310,1, +0x2e0a400,3, +0x2e0a410,2, +0x2e0a41c,5, +0x2e0a440,8, +0x2e0a480,3, +0x2e0a490,2, +0x2e0a49c,5, +0x2e0a4c0,8, +0x2e0a500,3, +0x2e0a510,2, +0x2e0a51c,5, +0x2e0a540,8, +0x2e0a580,3, +0x2e0a590,2, +0x2e0a59c,5, +0x2e0a5c0,8, +0x2e0a600,7, +0x2e0a620,12, +0x2e0a680,7, +0x2e0a6a0,12, +0x2e0a700,3, +0x2e0a710,1, +0x2e0a804,1, +0x2e0a824,21, +0x2e0a880,16, +0x2e0a900,5, +0x2e0a920,11, +0x2e0a950,9, +0x2e0a980,22, +0x2e0aa00,22, +0x2e0aa80,22, +0x2e0ab00,22, +0x2e0ab80,22, +0x2e0ac00,22, +0x2e0ac80,22, +0x2e0ad00,22, +0x2e0ad80,3, +0x2e0c000,16, +0x2e0c080,11, +0x2e0c100,11, +0x2e0c204,1, +0x2e0c224,21, +0x2e0c280,16, +0x2e0c300,11, +0x2e0c340,11, +0x2e0c800,21, +0x2e0c860,5, +0x2e0c880,6, +0x2e0c8a0,5, +0x2e0c8c0,6, +0x2e0c900,21, +0x2e0c960,5, +0x2e0c980,6, +0x2e0c9a0,5, +0x2e0c9c0,6, +0x2e0ca00,21, +0x2e0ca60,5, +0x2e0ca80,6, +0x2e0caa0,5, +0x2e0cac0,6, +0x2e0cb00,21, +0x2e0cb60,5, +0x2e0cb80,6, +0x2e0cba0,5, +0x2e0cbc0,6, +0x2e0cc00,9, +0x2e0cc48,7, +0x2e0cc68,2, +0x2e0cc74,9, +0x2e0cc9c,2, +0x2e0cd00,14, +0x2e0cd40,14, +0x2e0cd80,28, +0x2e0ce00,19, +0x2e0ce50,3, +0x2e0ce60,25, +0x2e0cec8,1, +0x2e0ced0,2, +0x2e0cee0,7, +0x2e0cf00,1, +0x2e0cf08,2, +0x2e0cffc,20, +0x2e0d050,25, +0x2e0d100,19, +0x2e0d150,25, +0x2e0d200,19, +0x2e0d250,25, +0x2e0d300,19, +0x2e0d350,25, +0x2e0d400,19, +0x2e0d450,25, +0x2e0d500,19, +0x2e0d550,25, +0x2e0d600,19, +0x2e0d650,25, +0x2e0d700,19, +0x2e0d750,25, +0x2e0d800,19, +0x2e0d850,25, +0x2e0d904,1, +0x2e0d914,10, +0x2e0d948,11, +0x2e0d980,2, +0x2e0d9a0,6, +0x2e0d9c0,2, +0x2e0d9cc,2, +0x2e0e000,35, +0x2e0ea00,10, +0x2e0ea80,3, +0x2e0eb00,6, +0x2e0f000,1, +0x2e0f008,5, +0x2e0f038,1, +0x2e0f044,1, +0x2e0f050,2, +0x2e0f100,13, +0x2e0f140,11, +0x2e0f170,12, +0x2e0f1a4,1, +0x2e0f200,104, +0x2e0f400,104, +0x2e0f600,104, +0x2e0f800,104, +0x2e10000,13, +0x2e10040,2, +0x2e10054,4, +0x2e10080,27, +0x2e10100,12, +0x2e10140,14, +0x2e10180,28, +0x2e10200,6, +0x2e10240,6, +0x2e1025c,3, +0x2e10280,5, +0x2e102a0,8, +0x2e10400,14, +0x2e10440,14, +0x2e10480,14, +0x2e104c0,14, +0x2e10540,3, +0x2e10600,7, +0x2e10620,14, +0x2e10680,5, +0x2e106a0,7, +0x2e10800,13, +0x2e10840,2, +0x2e10854,4, +0x2e10880,27, +0x2e10900,12, +0x2e10940,14, +0x2e10980,28, +0x2e10a00,6, +0x2e10a40,6, +0x2e10a5c,3, +0x2e10a80,5, +0x2e10aa0,8, +0x2e10c00,14, +0x2e10c40,14, +0x2e10c80,14, +0x2e10cc0,14, +0x2e10d40,3, +0x2e10e00,7, +0x2e10e20,14, +0x2e10e80,5, +0x2e10ea0,7, +0x2e11000,13, +0x2e11040,2, +0x2e11054,4, +0x2e11080,27, +0x2e11100,12, +0x2e11140,14, +0x2e11180,28, +0x2e11200,6, +0x2e11240,6, +0x2e1125c,3, +0x2e11280,5, +0x2e112a0,8, +0x2e11400,14, +0x2e11440,14, +0x2e11480,14, +0x2e114c0,14, +0x2e11540,3, +0x2e11600,7, +0x2e11620,14, +0x2e11680,5, +0x2e116a0,7, +0x2e11800,13, +0x2e11840,2, +0x2e11854,4, +0x2e11880,27, +0x2e11900,12, +0x2e11940,14, +0x2e11980,28, +0x2e11a00,6, +0x2e11a40,6, +0x2e11a5c,3, +0x2e11a80,5, +0x2e11aa0,8, +0x2e11c00,14, +0x2e11c40,14, +0x2e11c80,14, +0x2e11cc0,14, +0x2e11d40,3, +0x2e11e00,7, +0x2e11e20,14, +0x2e11e80,5, +0x2e11ea0,7, +0x2e12000,8, +0x2e12040,8, +0x2e12080,1, +0x2e12098,6, +0x2e12100,10, +0x2e12140,3, +0x2e12150,2, +0x2e12180,2, +0x2e12200,6, +0x2e12220,18, +0x2e12280,4, +0x2e12300,8, +0x2e12400,2, +0x2e12480,2, +0x2e12800,28, +0x2e129f0,4, +0x2e13000,40, +0x2e13100,64, +0x2e13800,56, +0x2e13be0,8, +0x2e14000,13, +0x2e14040,2, +0x2e14054,4, +0x2e14080,27, +0x2e14100,12, +0x2e14140,14, +0x2e14180,28, +0x2e14200,6, +0x2e14240,6, +0x2e1425c,3, +0x2e14280,5, +0x2e142a0,8, +0x2e14400,14, +0x2e14440,14, +0x2e14480,14, +0x2e144c0,14, +0x2e14540,3, +0x2e14600,7, +0x2e14620,14, +0x2e14680,5, +0x2e146a0,7, +0x2e14800,13, +0x2e14840,2, +0x2e14854,4, +0x2e14880,27, +0x2e14900,12, +0x2e14940,14, +0x2e14980,28, +0x2e14a00,6, +0x2e14a40,6, +0x2e14a5c,3, +0x2e14a80,5, +0x2e14aa0,8, +0x2e14c00,14, +0x2e14c40,14, +0x2e14c80,14, +0x2e14cc0,14, +0x2e14d40,3, +0x2e14e00,7, +0x2e14e20,14, +0x2e14e80,5, +0x2e14ea0,7, +0x2e15000,13, +0x2e15040,2, +0x2e15054,4, +0x2e15080,27, +0x2e15100,12, +0x2e15140,14, +0x2e15180,28, +0x2e15200,6, +0x2e15240,6, +0x2e1525c,3, +0x2e15280,5, +0x2e152a0,8, +0x2e15400,14, +0x2e15440,14, +0x2e15480,14, +0x2e154c0,14, +0x2e15540,3, +0x2e15600,7, +0x2e15620,14, +0x2e15680,5, +0x2e156a0,7, +0x2e15800,13, +0x2e15840,2, +0x2e15854,4, +0x2e15880,27, +0x2e15900,12, +0x2e15940,14, +0x2e15980,28, +0x2e15a00,6, +0x2e15a40,6, +0x2e15a5c,3, +0x2e15a80,5, +0x2e15aa0,8, +0x2e15c00,14, +0x2e15c40,14, +0x2e15c80,14, +0x2e15cc0,14, +0x2e15d40,3, +0x2e15e00,7, +0x2e15e20,14, +0x2e15e80,5, +0x2e15ea0,7, +0x2e16000,8, +0x2e16040,8, +0x2e16080,1, +0x2e16098,6, +0x2e16100,10, +0x2e16140,3, +0x2e16150,2, +0x2e16180,2, +0x2e16200,6, +0x2e16220,18, +0x2e16280,4, +0x2e16300,8, +0x2e16400,2, +0x2e16480,2, +0x2e16800,28, +0x2e169f0,4, +0x2e17000,40, +0x2e17100,64, +0x2e17800,56, +0x2e17be0,8, +0x2e18000,2, +0x2e1800c,2, +0x2e18040,7, +0x2e18100,3, +0x2e18110,3, +0x2e18120,5, +0x2e18200,6, +0x2e18240,5, +0x2e18400,2, +0x2e1840c,2, +0x2e18440,7, +0x2e18500,3, +0x2e18510,3, +0x2e18520,5, +0x2e18600,6, +0x2e18640,5, +0x2e18800,2, +0x2e1880c,2, +0x2e18840,7, +0x2e18900,3, +0x2e18910,3, +0x2e18920,5, +0x2e18a00,6, +0x2e18a40,5, +0x2e18c00,2, +0x2e18c0c,2, +0x2e18c40,7, +0x2e18d00,3, +0x2e18d10,3, +0x2e18d20,5, +0x2e18e00,6, +0x2e18e40,5, +0x2e19000,2, +0x2e1900c,2, +0x2e19040,7, +0x2e19100,3, +0x2e19110,3, +0x2e19120,5, +0x2e19200,6, +0x2e19240,5, +0x2e19400,2, +0x2e1940c,2, +0x2e19440,7, +0x2e19500,3, +0x2e19510,3, +0x2e19520,5, +0x2e19600,6, +0x2e19640,5, +0x2e19800,2, +0x2e1980c,2, +0x2e19840,7, +0x2e19900,3, +0x2e19910,3, +0x2e19920,5, +0x2e19a00,6, +0x2e19a40,5, +0x2e19c00,2, +0x2e19c0c,2, +0x2e19c40,7, +0x2e19d00,3, +0x2e19d10,3, +0x2e19d20,5, +0x2e19e00,6, +0x2e19e40,5, +0x2e1a000,5, +0x2e1a040,9, +0x2e1a100,3, +0x2e1a200,1, +0x2e1a210,1, +0x2e1a220,1, +0x2e1a230,1, +0x2e1a240,1, +0x2e1a300,3, +0x2e1a314,1, +0x2e1a320,4, +0x2e1a400,5, +0x2e1a440,5, +0x2e1b000,80, +0x2e1b200,1, +0x2e20004,5, +0x2e20020,3, +0x2e20030,3, +0x2e20040,13, +0x2e20078,4, +0x2e2009c,25, +0x2e20104,5, +0x2e20120,3, +0x2e20130,3, +0x2e20140,13, +0x2e20178,4, +0x2e2019c,25, +0x2e20204,5, +0x2e20220,3, +0x2e20230,3, +0x2e20240,13, +0x2e20278,4, +0x2e2029c,25, +0x2e20304,5, +0x2e20320,3, +0x2e20330,3, +0x2e20340,13, +0x2e20378,4, +0x2e2039c,25, +0x2e20600,4, +0x2e20c00,24, +0x2e20c80,24, +0x2e20d00,24, +0x2e20d80,24, +0x2e20e00,4, +0x2e20e20,4, +0x2e20e40,4, +0x2e20e60,4, +0x2e20e80,39, +0x2e20f20,7, +0x2e20f40,7, +0x2e20f60,7, +0x2e21000,12, +0x2e21200,1, +0x2e21218,2, +0x2e2122c,1, +0x2e21280,1, +0x2e21298,2, +0x2e212ac,1, +0x2e21300,1, +0x2e21318,2, +0x2e2132c,1, +0x2e21380,1, +0x2e21398,2, +0x2e213ac,1, +0x2e21400,4, +0x2e21420,2, +0x2e2142c,1, +0x2e21480,4, +0x2e214a0,2, +0x2e214ac,1, +0x2e21500,4, +0x2e21520,2, +0x2e2152c,1, +0x2e21580,4, +0x2e215a0,2, +0x2e215ac,1, +0x2e21600,4, +0x2e21640,4, +0x2e21680,4, +0x2e216c0,4, +0x2e21700,7, +0x2e21720,7, +0x2e21740,7, +0x2e21760,7, +0x2e21780,4, +0x2e2179c,11, +0x2e217d0,2, +0x2e217e0,2, +0x2e217f0,2, +0x2e21900,44, +0x2e22000,7, +0x2e22020,4, +0x2e22040,4, +0x2e22060,7, +0x2e22080,7, +0x2e220a0,4, +0x2e220c0,4, +0x2e220e0,7, +0x2e22100,7, +0x2e22120,4, +0x2e22140,4, +0x2e22160,7, +0x2e22180,7, +0x2e221a0,4, +0x2e221c0,4, +0x2e221e0,7, +0x2e22200,32, +0x2e22b00,1, +0x2e22b20,1, +0x2e22b28,4, +0x2e22b40,1, +0x2e22b60,1, +0x2e22b68,4, +0x2e22b80,1, +0x2e22ba0,1, +0x2e22ba8,4, +0x2e22bc0,1, +0x2e22be0,1, +0x2e22be8,4, +0x2e22c00,7, +0x2e22c20,1, +0x2e22c54,18, +0x2e22ca0,1, +0x2e22cd4,18, +0x2e22d20,1, +0x2e22d54,18, +0x2e22da0,1, +0x2e22dd4,12, +0x2e22e08,6, +0x2e23100,7, +0x2e23120,7, +0x2e23140,7, +0x2e23160,7, +0x2e23180,3, +0x2e24004,5, +0x2e24020,3, +0x2e24030,3, +0x2e24040,13, +0x2e24078,4, +0x2e2409c,25, +0x2e24104,5, +0x2e24120,3, +0x2e24130,3, +0x2e24140,13, +0x2e24178,4, +0x2e2419c,25, +0x2e24204,5, +0x2e24220,3, +0x2e24230,3, +0x2e24240,13, +0x2e24278,4, +0x2e2429c,25, +0x2e24304,5, +0x2e24320,3, +0x2e24330,3, +0x2e24340,13, +0x2e24378,4, +0x2e2439c,25, +0x2e24600,4, +0x2e24c00,24, +0x2e24c80,24, +0x2e24d00,24, +0x2e24d80,24, +0x2e24e00,4, +0x2e24e20,4, +0x2e24e40,4, +0x2e24e60,4, +0x2e24e80,39, +0x2e24f20,7, +0x2e24f40,7, +0x2e24f60,7, +0x2e25000,12, +0x2e25200,1, +0x2e25218,2, +0x2e2522c,1, +0x2e25280,1, +0x2e25298,2, +0x2e252ac,1, +0x2e25300,1, +0x2e25318,2, +0x2e2532c,1, +0x2e25380,1, +0x2e25398,2, +0x2e253ac,1, +0x2e25400,4, +0x2e25420,2, +0x2e2542c,1, +0x2e25480,4, +0x2e254a0,2, +0x2e254ac,1, +0x2e25500,4, +0x2e25520,2, +0x2e2552c,1, +0x2e25580,4, +0x2e255a0,2, +0x2e255ac,1, +0x2e25600,4, +0x2e25640,4, +0x2e25680,4, +0x2e256c0,4, +0x2e25700,7, +0x2e25720,7, +0x2e25740,7, +0x2e25760,7, +0x2e25780,4, +0x2e2579c,11, +0x2e257d0,2, +0x2e257e0,2, +0x2e257f0,2, +0x2e25900,44, +0x2e26000,7, +0x2e26020,4, +0x2e26040,4, +0x2e26060,7, +0x2e26080,7, +0x2e260a0,4, +0x2e260c0,4, +0x2e260e0,7, +0x2e26100,7, +0x2e26120,4, +0x2e26140,4, +0x2e26160,7, +0x2e26180,7, +0x2e261a0,4, +0x2e261c0,4, +0x2e261e0,7, +0x2e26200,32, +0x2e26b00,1, +0x2e26b20,1, +0x2e26b28,4, +0x2e26b40,1, +0x2e26b60,1, +0x2e26b68,4, +0x2e26b80,1, +0x2e26ba0,1, +0x2e26ba8,4, +0x2e26bc0,1, +0x2e26be0,1, +0x2e26be8,4, +0x2e26c00,7, +0x2e26c20,1, +0x2e26c54,18, +0x2e26ca0,1, +0x2e26cd4,18, +0x2e26d20,1, +0x2e26d54,18, +0x2e26da0,1, +0x2e26dd4,12, +0x2e26e08,6, +0x2e27100,7, +0x2e27120,7, +0x2e27140,7, +0x2e27160,7, +0x2e27180,3, +0x2e28000,10, +0x2e28080,3, +0x2e280c0,1, +0x2e28100,21, +0x2e28180,13, +0x2e281c4,7, +0x2e281e4,7, +0x2e28204,7, +0x2e28224,8, +0x2e29000,7, +0x2e29030,2, +0x2e29040,7, +0x2e29070,2, +0x2e29100,2, +0x2e29120,2, +0x2e29140,2, +0x2e29160,2, +0x2e29180,9, +0x2e29200,7, +0x2e29230,2, +0x2e29240,7, +0x2e29270,2, +0x2e29300,2, +0x2e29320,2, +0x2e29340,2, +0x2e29360,2, +0x2e29380,9, +0x2e29400,11, +0x2e29500,11, +0x2e2a000,3, +0x2e2a010,2, +0x2e2a01c,5, +0x2e2a040,8, +0x2e2a080,3, +0x2e2a090,2, +0x2e2a09c,5, +0x2e2a0c0,8, +0x2e2a100,3, +0x2e2a110,2, +0x2e2a11c,5, +0x2e2a140,8, +0x2e2a180,3, +0x2e2a190,2, +0x2e2a19c,5, +0x2e2a1c0,8, +0x2e2a200,7, +0x2e2a220,12, +0x2e2a280,7, +0x2e2a2a0,12, +0x2e2a300,3, +0x2e2a310,1, +0x2e2a400,3, +0x2e2a410,2, +0x2e2a41c,5, +0x2e2a440,8, +0x2e2a480,3, +0x2e2a490,2, +0x2e2a49c,5, +0x2e2a4c0,8, +0x2e2a500,3, +0x2e2a510,2, +0x2e2a51c,5, +0x2e2a540,8, +0x2e2a580,3, +0x2e2a590,2, +0x2e2a59c,5, +0x2e2a5c0,8, +0x2e2a600,7, +0x2e2a620,12, +0x2e2a680,7, +0x2e2a6a0,12, +0x2e2a700,3, +0x2e2a710,1, +0x2e2a804,1, +0x2e2a824,21, +0x2e2a880,16, +0x2e2a900,5, +0x2e2a920,11, +0x2e2a950,9, +0x2e2a980,22, +0x2e2aa00,22, +0x2e2aa80,22, +0x2e2ab00,22, +0x2e2ab80,22, +0x2e2ac00,22, +0x2e2ac80,22, +0x2e2ad00,22, +0x2e2ad80,3, +0x2e2c000,16, +0x2e2c080,11, +0x2e2c100,11, +0x2e2c204,1, +0x2e2c224,21, +0x2e2c280,16, +0x2e2c300,11, +0x2e2c340,11, +0x2e2c800,21, +0x2e2c860,5, +0x2e2c880,6, +0x2e2c8a0,5, +0x2e2c8c0,6, +0x2e2c900,21, +0x2e2c960,5, +0x2e2c980,6, +0x2e2c9a0,5, +0x2e2c9c0,6, +0x2e2ca00,21, +0x2e2ca60,5, +0x2e2ca80,6, +0x2e2caa0,5, +0x2e2cac0,6, +0x2e2cb00,21, +0x2e2cb60,5, +0x2e2cb80,6, +0x2e2cba0,5, +0x2e2cbc0,6, +0x2e2cc00,9, +0x2e2cc48,7, +0x2e2cc68,2, +0x2e2cc74,9, +0x2e2cc9c,2, +0x2e2cd00,14, +0x2e2cd40,14, +0x2e2cd80,28, +0x2e2ce00,19, +0x2e2ce50,3, +0x2e2ce60,25, +0x2e2cec8,1, +0x2e2ced0,2, +0x2e2cee0,7, +0x2e2cf00,1, +0x2e2cf08,2, +0x2e2cffc,20, +0x2e2d050,25, +0x2e2d100,19, +0x2e2d150,25, +0x2e2d200,19, +0x2e2d250,25, +0x2e2d300,19, +0x2e2d350,25, +0x2e2d400,19, +0x2e2d450,25, +0x2e2d500,19, +0x2e2d550,25, +0x2e2d600,19, +0x2e2d650,25, +0x2e2d700,19, +0x2e2d750,25, +0x2e2d800,19, +0x2e2d850,25, +0x2e2d904,1, +0x2e2d914,10, +0x2e2d948,11, +0x2e2d980,2, +0x2e2d9a0,6, +0x2e2d9c0,2, +0x2e2d9cc,2, +0x2e2e000,35, +0x2e2ea00,10, +0x2e2ea80,3, +0x2e2eb00,6, +0x2e2f000,1, +0x2e2f008,5, +0x2e2f038,1, +0x2e2f044,1, +0x2e2f050,2, +0x2e2f100,13, +0x2e2f140,11, +0x2e2f170,12, +0x2e2f1a4,1, +0x2e2f200,104, +0x2e2f400,104, +0x2e2f600,104, +0x2e2f800,104, +0x2e30000,13, +0x2e30040,2, +0x2e30054,4, +0x2e30080,27, +0x2e30100,12, +0x2e30140,14, +0x2e30180,28, +0x2e30200,6, +0x2e30240,6, +0x2e3025c,3, +0x2e30280,5, +0x2e302a0,8, +0x2e30400,14, +0x2e30440,14, +0x2e30480,14, +0x2e304c0,14, +0x2e30540,3, +0x2e30600,7, +0x2e30620,14, +0x2e30680,5, +0x2e306a0,7, +0x2e30800,13, +0x2e30840,2, +0x2e30854,4, +0x2e30880,27, +0x2e30900,12, +0x2e30940,14, +0x2e30980,28, +0x2e30a00,6, +0x2e30a40,6, +0x2e30a5c,3, +0x2e30a80,5, +0x2e30aa0,8, +0x2e30c00,14, +0x2e30c40,14, +0x2e30c80,14, +0x2e30cc0,14, +0x2e30d40,3, +0x2e30e00,7, +0x2e30e20,14, +0x2e30e80,5, +0x2e30ea0,7, +0x2e31000,13, +0x2e31040,2, +0x2e31054,4, +0x2e31080,27, +0x2e31100,12, +0x2e31140,14, +0x2e31180,28, +0x2e31200,6, +0x2e31240,6, +0x2e3125c,3, +0x2e31280,5, +0x2e312a0,8, +0x2e31400,14, +0x2e31440,14, +0x2e31480,14, +0x2e314c0,14, +0x2e31540,3, +0x2e31600,7, +0x2e31620,14, +0x2e31680,5, +0x2e316a0,7, +0x2e31800,13, +0x2e31840,2, +0x2e31854,4, +0x2e31880,27, +0x2e31900,12, +0x2e31940,14, +0x2e31980,28, +0x2e31a00,6, +0x2e31a40,6, +0x2e31a5c,3, +0x2e31a80,5, +0x2e31aa0,8, +0x2e31c00,14, +0x2e31c40,14, +0x2e31c80,14, +0x2e31cc0,14, +0x2e31d40,3, +0x2e31e00,7, +0x2e31e20,14, +0x2e31e80,5, +0x2e31ea0,7, +0x2e32000,8, +0x2e32040,8, +0x2e32080,1, +0x2e32098,6, +0x2e32100,10, +0x2e32140,3, +0x2e32150,2, +0x2e32180,2, +0x2e32200,6, +0x2e32220,18, +0x2e32280,4, +0x2e32300,8, +0x2e32400,2, +0x2e32480,2, +0x2e32800,28, +0x2e329f0,4, +0x2e33000,40, +0x2e33100,64, +0x2e33800,56, +0x2e33be0,8, +0x2e34000,13, +0x2e34040,2, +0x2e34054,4, +0x2e34080,27, +0x2e34100,12, +0x2e34140,14, +0x2e34180,28, +0x2e34200,6, +0x2e34240,6, +0x2e3425c,3, +0x2e34280,5, +0x2e342a0,8, +0x2e34400,14, +0x2e34440,14, +0x2e34480,14, +0x2e344c0,14, +0x2e34540,3, +0x2e34600,7, +0x2e34620,14, +0x2e34680,5, +0x2e346a0,7, +0x2e34800,13, +0x2e34840,2, +0x2e34854,4, +0x2e34880,27, +0x2e34900,12, +0x2e34940,14, +0x2e34980,28, +0x2e34a00,6, +0x2e34a40,6, +0x2e34a5c,3, +0x2e34a80,5, +0x2e34aa0,8, +0x2e34c00,14, +0x2e34c40,14, +0x2e34c80,14, +0x2e34cc0,14, +0x2e34d40,3, +0x2e34e00,7, +0x2e34e20,14, +0x2e34e80,5, +0x2e34ea0,7, +0x2e35000,13, +0x2e35040,2, +0x2e35054,4, +0x2e35080,27, +0x2e35100,12, +0x2e35140,14, +0x2e35180,28, +0x2e35200,6, +0x2e35240,6, +0x2e3525c,3, +0x2e35280,5, +0x2e352a0,8, +0x2e35400,14, +0x2e35440,14, +0x2e35480,14, +0x2e354c0,14, +0x2e35540,3, +0x2e35600,7, +0x2e35620,14, +0x2e35680,5, +0x2e356a0,7, +0x2e35800,13, +0x2e35840,2, +0x2e35854,4, +0x2e35880,27, +0x2e35900,12, +0x2e35940,14, +0x2e35980,28, +0x2e35a00,6, +0x2e35a40,6, +0x2e35a5c,3, +0x2e35a80,5, +0x2e35aa0,8, +0x2e35c00,14, +0x2e35c40,14, +0x2e35c80,14, +0x2e35cc0,14, +0x2e35d40,3, +0x2e35e00,7, +0x2e35e20,14, +0x2e35e80,5, +0x2e35ea0,7, +0x2e36000,8, +0x2e36040,8, +0x2e36080,1, +0x2e36098,6, +0x2e36100,10, +0x2e36140,3, +0x2e36150,2, +0x2e36180,2, +0x2e36200,6, +0x2e36220,18, +0x2e36280,4, +0x2e36300,8, +0x2e36400,2, +0x2e36480,2, +0x2e36800,28, +0x2e369f0,4, +0x2e37000,40, +0x2e37100,64, +0x2e37800,56, +0x2e37be0,8, +0x2e38000,2, +0x2e3800c,2, +0x2e38040,7, +0x2e38100,3, +0x2e38110,3, +0x2e38120,5, +0x2e38200,6, +0x2e38240,5, +0x2e38400,2, +0x2e3840c,2, +0x2e38440,7, +0x2e38500,3, +0x2e38510,3, +0x2e38520,5, +0x2e38600,6, +0x2e38640,5, +0x2e38800,2, +0x2e3880c,2, +0x2e38840,7, +0x2e38900,3, +0x2e38910,3, +0x2e38920,5, +0x2e38a00,6, +0x2e38a40,5, +0x2e38c00,2, +0x2e38c0c,2, +0x2e38c40,7, +0x2e38d00,3, +0x2e38d10,3, +0x2e38d20,5, +0x2e38e00,6, +0x2e38e40,5, +0x2e39000,2, +0x2e3900c,2, +0x2e39040,7, +0x2e39100,3, +0x2e39110,3, +0x2e39120,5, +0x2e39200,6, +0x2e39240,5, +0x2e39400,2, +0x2e3940c,2, +0x2e39440,7, +0x2e39500,3, +0x2e39510,3, +0x2e39520,5, +0x2e39600,6, +0x2e39640,5, +0x2e39800,2, +0x2e3980c,2, +0x2e39840,7, +0x2e39900,3, +0x2e39910,3, +0x2e39920,5, +0x2e39a00,6, +0x2e39a40,5, +0x2e39c00,2, +0x2e39c0c,2, +0x2e39c40,7, +0x2e39d00,3, +0x2e39d10,3, +0x2e39d20,5, +0x2e39e00,6, +0x2e39e40,5, +0x2e3a000,5, +0x2e3a040,9, +0x2e3a100,3, +0x2e3a200,1, +0x2e3a210,1, +0x2e3a220,1, +0x2e3a230,1, +0x2e3a240,1, +0x2e3a300,3, +0x2e3a314,1, +0x2e3a320,4, +0x2e3a400,5, +0x2e3a440,5, +0x2e3b000,80, +0x2e3b200,1, +0x2e40004,5, +0x2e40020,3, +0x2e40030,3, +0x2e40040,13, +0x2e40078,4, +0x2e4009c,25, +0x2e40104,5, +0x2e40120,3, +0x2e40130,3, +0x2e40140,13, +0x2e40178,4, +0x2e4019c,25, +0x2e40204,5, +0x2e40220,3, +0x2e40230,3, +0x2e40240,13, +0x2e40278,4, +0x2e4029c,25, +0x2e40304,5, +0x2e40320,3, +0x2e40330,3, +0x2e40340,13, +0x2e40378,4, +0x2e4039c,25, +0x2e40600,4, +0x2e40c00,24, +0x2e40c80,24, +0x2e40d00,24, +0x2e40d80,24, +0x2e40e00,4, +0x2e40e20,4, +0x2e40e40,4, +0x2e40e60,4, +0x2e40e80,39, +0x2e40f20,7, +0x2e40f40,7, +0x2e40f60,7, +0x2e41000,12, +0x2e41200,1, +0x2e41218,2, +0x2e4122c,1, +0x2e41280,1, +0x2e41298,2, +0x2e412ac,1, +0x2e41300,1, +0x2e41318,2, +0x2e4132c,1, +0x2e41380,1, +0x2e41398,2, +0x2e413ac,1, +0x2e41400,4, +0x2e41420,2, +0x2e4142c,1, +0x2e41480,4, +0x2e414a0,2, +0x2e414ac,1, +0x2e41500,4, +0x2e41520,2, +0x2e4152c,1, +0x2e41580,4, +0x2e415a0,2, +0x2e415ac,1, +0x2e41600,4, +0x2e41640,4, +0x2e41680,4, +0x2e416c0,4, +0x2e41700,7, +0x2e41720,7, +0x2e41740,7, +0x2e41760,7, +0x2e41780,4, +0x2e4179c,11, +0x2e417d0,2, +0x2e417e0,2, +0x2e417f0,2, +0x2e41900,44, +0x2e42000,7, +0x2e42020,4, +0x2e42040,4, +0x2e42060,7, +0x2e42080,7, +0x2e420a0,4, +0x2e420c0,4, +0x2e420e0,7, +0x2e42100,7, +0x2e42120,4, +0x2e42140,4, +0x2e42160,7, +0x2e42180,7, +0x2e421a0,4, +0x2e421c0,4, +0x2e421e0,7, +0x2e42200,32, +0x2e42b00,1, +0x2e42b20,1, +0x2e42b28,4, +0x2e42b40,1, +0x2e42b60,1, +0x2e42b68,4, +0x2e42b80,1, +0x2e42ba0,1, +0x2e42ba8,4, +0x2e42bc0,1, +0x2e42be0,1, +0x2e42be8,4, +0x2e42c00,7, +0x2e42c20,1, +0x2e42c54,18, +0x2e42ca0,1, +0x2e42cd4,18, +0x2e42d20,1, +0x2e42d54,18, +0x2e42da0,1, +0x2e42dd4,12, +0x2e42e08,6, +0x2e43100,7, +0x2e43120,7, +0x2e43140,7, +0x2e43160,7, +0x2e43180,3, +0x2e44004,5, +0x2e44020,3, +0x2e44030,3, +0x2e44040,13, +0x2e44078,4, +0x2e4409c,25, +0x2e44104,5, +0x2e44120,3, +0x2e44130,3, +0x2e44140,13, +0x2e44178,4, +0x2e4419c,25, +0x2e44204,5, +0x2e44220,3, +0x2e44230,3, +0x2e44240,13, +0x2e44278,4, +0x2e4429c,25, +0x2e44304,5, +0x2e44320,3, +0x2e44330,3, +0x2e44340,13, +0x2e44378,4, +0x2e4439c,25, +0x2e44600,4, +0x2e44c00,24, +0x2e44c80,24, +0x2e44d00,24, +0x2e44d80,24, +0x2e44e00,4, +0x2e44e20,4, +0x2e44e40,4, +0x2e44e60,4, +0x2e44e80,39, +0x2e44f20,7, +0x2e44f40,7, +0x2e44f60,7, +0x2e45000,12, +0x2e45200,1, +0x2e45218,2, +0x2e4522c,1, +0x2e45280,1, +0x2e45298,2, +0x2e452ac,1, +0x2e45300,1, +0x2e45318,2, +0x2e4532c,1, +0x2e45380,1, +0x2e45398,2, +0x2e453ac,1, +0x2e45400,4, +0x2e45420,2, +0x2e4542c,1, +0x2e45480,4, +0x2e454a0,2, +0x2e454ac,1, +0x2e45500,4, +0x2e45520,2, +0x2e4552c,1, +0x2e45580,4, +0x2e455a0,2, +0x2e455ac,1, +0x2e45600,4, +0x2e45640,4, +0x2e45680,4, +0x2e456c0,4, +0x2e45700,7, +0x2e45720,7, +0x2e45740,7, +0x2e45760,7, +0x2e45780,4, +0x2e4579c,11, +0x2e457d0,2, +0x2e457e0,2, +0x2e457f0,2, +0x2e45900,44, +0x2e46000,7, +0x2e46020,4, +0x2e46040,4, +0x2e46060,7, +0x2e46080,7, +0x2e460a0,4, +0x2e460c0,4, +0x2e460e0,7, +0x2e46100,7, +0x2e46120,4, +0x2e46140,4, +0x2e46160,7, +0x2e46180,7, +0x2e461a0,4, +0x2e461c0,4, +0x2e461e0,7, +0x2e46200,32, +0x2e46b00,1, +0x2e46b20,1, +0x2e46b28,4, +0x2e46b40,1, +0x2e46b60,1, +0x2e46b68,4, +0x2e46b80,1, +0x2e46ba0,1, +0x2e46ba8,4, +0x2e46bc0,1, +0x2e46be0,1, +0x2e46be8,4, +0x2e46c00,7, +0x2e46c20,1, +0x2e46c54,18, +0x2e46ca0,1, +0x2e46cd4,18, +0x2e46d20,1, +0x2e46d54,18, +0x2e46da0,1, +0x2e46dd4,12, +0x2e46e08,6, +0x2e47100,7, +0x2e47120,7, +0x2e47140,7, +0x2e47160,7, +0x2e47180,3, +0x2e48000,10, +0x2e48080,3, +0x2e480c0,1, +0x2e48100,21, +0x2e48180,13, +0x2e481c4,7, +0x2e481e4,7, +0x2e48204,7, +0x2e48224,8, +0x2e49000,7, +0x2e49030,2, +0x2e49040,7, +0x2e49070,2, +0x2e49100,2, +0x2e49120,2, +0x2e49140,2, +0x2e49160,2, +0x2e49180,9, +0x2e49200,7, +0x2e49230,2, +0x2e49240,7, +0x2e49270,2, +0x2e49300,2, +0x2e49320,2, +0x2e49340,2, +0x2e49360,2, +0x2e49380,9, +0x2e49400,11, +0x2e49500,11, +0x2e4a000,3, +0x2e4a010,2, +0x2e4a01c,5, +0x2e4a040,8, +0x2e4a080,3, +0x2e4a090,2, +0x2e4a09c,5, +0x2e4a0c0,8, +0x2e4a100,3, +0x2e4a110,2, +0x2e4a11c,5, +0x2e4a140,8, +0x2e4a180,3, +0x2e4a190,2, +0x2e4a19c,5, +0x2e4a1c0,8, +0x2e4a200,7, +0x2e4a220,12, +0x2e4a280,7, +0x2e4a2a0,12, +0x2e4a300,3, +0x2e4a310,1, +0x2e4a400,3, +0x2e4a410,2, +0x2e4a41c,5, +0x2e4a440,8, +0x2e4a480,3, +0x2e4a490,2, +0x2e4a49c,5, +0x2e4a4c0,8, +0x2e4a500,3, +0x2e4a510,2, +0x2e4a51c,5, +0x2e4a540,8, +0x2e4a580,3, +0x2e4a590,2, +0x2e4a59c,5, +0x2e4a5c0,8, +0x2e4a600,7, +0x2e4a620,12, +0x2e4a680,7, +0x2e4a6a0,12, +0x2e4a700,3, +0x2e4a710,1, +0x2e4a804,1, +0x2e4a824,21, +0x2e4a880,16, +0x2e4a900,5, +0x2e4a920,11, +0x2e4a950,9, +0x2e4a980,22, +0x2e4aa00,22, +0x2e4aa80,22, +0x2e4ab00,22, +0x2e4ab80,22, +0x2e4ac00,22, +0x2e4ac80,22, +0x2e4ad00,22, +0x2e4ad80,3, +0x2e4c000,16, +0x2e4c080,11, +0x2e4c100,11, +0x2e4c204,1, +0x2e4c224,21, +0x2e4c280,16, +0x2e4c300,11, +0x2e4c340,11, +0x2e4c800,21, +0x2e4c860,5, +0x2e4c880,6, +0x2e4c8a0,5, +0x2e4c8c0,6, +0x2e4c900,21, +0x2e4c960,5, +0x2e4c980,6, +0x2e4c9a0,5, +0x2e4c9c0,6, +0x2e4ca00,21, +0x2e4ca60,5, +0x2e4ca80,6, +0x2e4caa0,5, +0x2e4cac0,6, +0x2e4cb00,21, +0x2e4cb60,5, +0x2e4cb80,6, +0x2e4cba0,5, +0x2e4cbc0,6, +0x2e4cc00,9, +0x2e4cc48,7, +0x2e4cc68,2, +0x2e4cc74,9, +0x2e4cc9c,2, +0x2e4cd00,14, +0x2e4cd40,14, +0x2e4cd80,28, +0x2e4ce00,19, +0x2e4ce50,3, +0x2e4ce60,25, +0x2e4cec8,1, +0x2e4ced0,2, +0x2e4cee0,7, +0x2e4cf00,1, +0x2e4cf08,2, +0x2e4cffc,20, +0x2e4d050,25, +0x2e4d100,19, +0x2e4d150,25, +0x2e4d200,19, +0x2e4d250,25, +0x2e4d300,19, +0x2e4d350,25, +0x2e4d400,19, +0x2e4d450,25, +0x2e4d500,19, +0x2e4d550,25, +0x2e4d600,19, +0x2e4d650,25, +0x2e4d700,19, +0x2e4d750,25, +0x2e4d800,19, +0x2e4d850,25, +0x2e4d904,1, +0x2e4d914,10, +0x2e4d948,11, +0x2e4d980,2, +0x2e4d9a0,6, +0x2e4d9c0,2, +0x2e4d9cc,2, +0x2e4e000,35, +0x2e4ea00,10, +0x2e4ea80,3, +0x2e4eb00,6, +0x2e4f000,1, +0x2e4f008,5, +0x2e4f038,1, +0x2e4f044,1, +0x2e4f050,2, +0x2e4f100,13, +0x2e4f140,11, +0x2e4f170,12, +0x2e4f1a4,1, +0x2e4f200,104, +0x2e4f400,104, +0x2e4f600,104, +0x2e4f800,104, +0x2e50000,13, +0x2e50040,2, +0x2e50054,4, +0x2e50080,27, +0x2e50100,12, +0x2e50140,14, +0x2e50180,28, +0x2e50200,6, +0x2e50240,6, +0x2e5025c,3, +0x2e50280,5, +0x2e502a0,8, +0x2e50400,14, +0x2e50440,14, +0x2e50480,14, +0x2e504c0,14, +0x2e50540,3, +0x2e50600,7, +0x2e50620,14, +0x2e50680,5, +0x2e506a0,7, +0x2e50800,13, +0x2e50840,2, +0x2e50854,4, +0x2e50880,27, +0x2e50900,12, +0x2e50940,14, +0x2e50980,28, +0x2e50a00,6, +0x2e50a40,6, +0x2e50a5c,3, +0x2e50a80,5, +0x2e50aa0,8, +0x2e50c00,14, +0x2e50c40,14, +0x2e50c80,14, +0x2e50cc0,14, +0x2e50d40,3, +0x2e50e00,7, +0x2e50e20,14, +0x2e50e80,5, +0x2e50ea0,7, +0x2e51000,13, +0x2e51040,2, +0x2e51054,4, +0x2e51080,27, +0x2e51100,12, +0x2e51140,14, +0x2e51180,28, +0x2e51200,6, +0x2e51240,6, +0x2e5125c,3, +0x2e51280,5, +0x2e512a0,8, +0x2e51400,14, +0x2e51440,14, +0x2e51480,14, +0x2e514c0,14, +0x2e51540,3, +0x2e51600,7, +0x2e51620,14, +0x2e51680,5, +0x2e516a0,7, +0x2e51800,13, +0x2e51840,2, +0x2e51854,4, +0x2e51880,27, +0x2e51900,12, +0x2e51940,14, +0x2e51980,28, +0x2e51a00,6, +0x2e51a40,6, +0x2e51a5c,3, +0x2e51a80,5, +0x2e51aa0,8, +0x2e51c00,14, +0x2e51c40,14, +0x2e51c80,14, +0x2e51cc0,14, +0x2e51d40,3, +0x2e51e00,7, +0x2e51e20,14, +0x2e51e80,5, +0x2e51ea0,7, +0x2e52000,8, +0x2e52040,8, +0x2e52080,1, +0x2e52098,6, +0x2e52100,10, +0x2e52140,3, +0x2e52150,2, +0x2e52180,2, +0x2e52200,6, +0x2e52220,18, +0x2e52280,4, +0x2e52300,8, +0x2e52400,2, +0x2e52480,2, +0x2e52800,28, +0x2e529f0,4, +0x2e53000,40, +0x2e53100,64, +0x2e53800,56, +0x2e53be0,8, +0x2e54000,13, +0x2e54040,2, +0x2e54054,4, +0x2e54080,27, +0x2e54100,12, +0x2e54140,14, +0x2e54180,28, +0x2e54200,6, +0x2e54240,6, +0x2e5425c,3, +0x2e54280,5, +0x2e542a0,8, +0x2e54400,14, +0x2e54440,14, +0x2e54480,14, +0x2e544c0,14, +0x2e54540,3, +0x2e54600,7, +0x2e54620,14, +0x2e54680,5, +0x2e546a0,7, +0x2e54800,13, +0x2e54840,2, +0x2e54854,4, +0x2e54880,27, +0x2e54900,12, +0x2e54940,14, +0x2e54980,28, +0x2e54a00,6, +0x2e54a40,6, +0x2e54a5c,3, +0x2e54a80,5, +0x2e54aa0,8, +0x2e54c00,14, +0x2e54c40,14, +0x2e54c80,14, +0x2e54cc0,14, +0x2e54d40,3, +0x2e54e00,7, +0x2e54e20,14, +0x2e54e80,5, +0x2e54ea0,7, +0x2e55000,13, +0x2e55040,2, +0x2e55054,4, +0x2e55080,27, +0x2e55100,12, +0x2e55140,14, +0x2e55180,28, +0x2e55200,6, +0x2e55240,6, +0x2e5525c,3, +0x2e55280,5, +0x2e552a0,8, +0x2e55400,14, +0x2e55440,14, +0x2e55480,14, +0x2e554c0,14, +0x2e55540,3, +0x2e55600,7, +0x2e55620,14, +0x2e55680,5, +0x2e556a0,7, +0x2e55800,13, +0x2e55840,2, +0x2e55854,4, +0x2e55880,27, +0x2e55900,12, +0x2e55940,14, +0x2e55980,28, +0x2e55a00,6, +0x2e55a40,6, +0x2e55a5c,3, +0x2e55a80,5, +0x2e55aa0,8, +0x2e55c00,14, +0x2e55c40,14, +0x2e55c80,14, +0x2e55cc0,14, +0x2e55d40,3, +0x2e55e00,7, +0x2e55e20,14, +0x2e55e80,5, +0x2e55ea0,7, +0x2e56000,8, +0x2e56040,8, +0x2e56080,1, +0x2e56098,6, +0x2e56100,10, +0x2e56140,3, +0x2e56150,2, +0x2e56180,2, +0x2e56200,6, +0x2e56220,18, +0x2e56280,4, +0x2e56300,8, +0x2e56400,2, +0x2e56480,2, +0x2e56800,28, +0x2e569f0,4, +0x2e57000,40, +0x2e57100,64, +0x2e57800,56, +0x2e57be0,8, +0x2e58000,2, +0x2e5800c,2, +0x2e58040,7, +0x2e58100,3, +0x2e58110,3, +0x2e58120,5, +0x2e58200,6, +0x2e58240,5, +0x2e58400,2, +0x2e5840c,2, +0x2e58440,7, +0x2e58500,3, +0x2e58510,3, +0x2e58520,5, +0x2e58600,6, +0x2e58640,5, +0x2e58800,2, +0x2e5880c,2, +0x2e58840,7, +0x2e58900,3, +0x2e58910,3, +0x2e58920,5, +0x2e58a00,6, +0x2e58a40,5, +0x2e58c00,2, +0x2e58c0c,2, +0x2e58c40,7, +0x2e58d00,3, +0x2e58d10,3, +0x2e58d20,5, +0x2e58e00,6, +0x2e58e40,5, +0x2e59000,2, +0x2e5900c,2, +0x2e59040,7, +0x2e59100,3, +0x2e59110,3, +0x2e59120,5, +0x2e59200,6, +0x2e59240,5, +0x2e59400,2, +0x2e5940c,2, +0x2e59440,7, +0x2e59500,3, +0x2e59510,3, +0x2e59520,5, +0x2e59600,6, +0x2e59640,5, +0x2e59800,2, +0x2e5980c,2, +0x2e59840,7, +0x2e59900,3, +0x2e59910,3, +0x2e59920,5, +0x2e59a00,6, +0x2e59a40,5, +0x2e59c00,2, +0x2e59c0c,2, +0x2e59c40,7, +0x2e59d00,3, +0x2e59d10,3, +0x2e59d20,5, +0x2e59e00,6, +0x2e59e40,5, +0x2e5a000,5, +0x2e5a040,9, +0x2e5a100,3, +0x2e5a200,1, +0x2e5a210,1, +0x2e5a220,1, +0x2e5a230,1, +0x2e5a240,1, +0x2e5a300,3, +0x2e5a314,1, +0x2e5a320,4, +0x2e5a400,5, +0x2e5a440,5, +0x2e5b000,80, +0x2e5b200,1, +0x2e60004,5, +0x2e60020,3, +0x2e60030,3, +0x2e60040,13, +0x2e60078,4, +0x2e6009c,25, +0x2e60104,5, +0x2e60120,3, +0x2e60130,3, +0x2e60140,13, +0x2e60178,4, +0x2e6019c,25, +0x2e60204,5, +0x2e60220,3, +0x2e60230,3, +0x2e60240,13, +0x2e60278,4, +0x2e6029c,25, +0x2e60304,5, +0x2e60320,3, +0x2e60330,3, +0x2e60340,13, +0x2e60378,4, +0x2e6039c,25, +0x2e60600,4, +0x2e60c00,24, +0x2e60c80,24, +0x2e60d00,24, +0x2e60d80,24, +0x2e60e00,4, +0x2e60e20,4, +0x2e60e40,4, +0x2e60e60,4, +0x2e60e80,39, +0x2e60f20,7, +0x2e60f40,7, +0x2e60f60,7, +0x2e61000,12, +0x2e61200,1, +0x2e61218,2, +0x2e6122c,1, +0x2e61280,1, +0x2e61298,2, +0x2e612ac,1, +0x2e61300,1, +0x2e61318,2, +0x2e6132c,1, +0x2e61380,1, +0x2e61398,2, +0x2e613ac,1, +0x2e61400,4, +0x2e61420,2, +0x2e6142c,1, +0x2e61480,4, +0x2e614a0,2, +0x2e614ac,1, +0x2e61500,4, +0x2e61520,2, +0x2e6152c,1, +0x2e61580,4, +0x2e615a0,2, +0x2e615ac,1, +0x2e61600,4, +0x2e61640,4, +0x2e61680,4, +0x2e616c0,4, +0x2e61700,7, +0x2e61720,7, +0x2e61740,7, +0x2e61760,7, +0x2e61780,4, +0x2e6179c,11, +0x2e617d0,2, +0x2e617e0,2, +0x2e617f0,2, +0x2e61900,44, +0x2e62000,7, +0x2e62020,4, +0x2e62040,4, +0x2e62060,7, +0x2e62080,7, +0x2e620a0,4, +0x2e620c0,4, +0x2e620e0,7, +0x2e62100,7, +0x2e62120,4, +0x2e62140,4, +0x2e62160,7, +0x2e62180,7, +0x2e621a0,4, +0x2e621c0,4, +0x2e621e0,7, +0x2e62200,32, +0x2e62b00,1, +0x2e62b20,1, +0x2e62b28,4, +0x2e62b40,1, +0x2e62b60,1, +0x2e62b68,4, +0x2e62b80,1, +0x2e62ba0,1, +0x2e62ba8,4, +0x2e62bc0,1, +0x2e62be0,1, +0x2e62be8,4, +0x2e62c00,7, +0x2e62c20,1, +0x2e62c54,18, +0x2e62ca0,1, +0x2e62cd4,18, +0x2e62d20,1, +0x2e62d54,18, +0x2e62da0,1, +0x2e62dd4,12, +0x2e62e08,6, +0x2e63100,7, +0x2e63120,7, +0x2e63140,7, +0x2e63160,7, +0x2e63180,3, +0x2e64004,5, +0x2e64020,3, +0x2e64030,3, +0x2e64040,13, +0x2e64078,4, +0x2e6409c,25, +0x2e64104,5, +0x2e64120,3, +0x2e64130,3, +0x2e64140,13, +0x2e64178,4, +0x2e6419c,25, +0x2e64204,5, +0x2e64220,3, +0x2e64230,3, +0x2e64240,13, +0x2e64278,4, +0x2e6429c,25, +0x2e64304,5, +0x2e64320,3, +0x2e64330,3, +0x2e64340,13, +0x2e64378,4, +0x2e6439c,25, +0x2e64600,4, +0x2e64c00,24, +0x2e64c80,24, +0x2e64d00,24, +0x2e64d80,24, +0x2e64e00,4, +0x2e64e20,4, +0x2e64e40,4, +0x2e64e60,4, +0x2e64e80,39, +0x2e64f20,7, +0x2e64f40,7, +0x2e64f60,7, +0x2e65000,12, +0x2e65200,1, +0x2e65218,2, +0x2e6522c,1, +0x2e65280,1, +0x2e65298,2, +0x2e652ac,1, +0x2e65300,1, +0x2e65318,2, +0x2e6532c,1, +0x2e65380,1, +0x2e65398,2, +0x2e653ac,1, +0x2e65400,4, +0x2e65420,2, +0x2e6542c,1, +0x2e65480,4, +0x2e654a0,2, +0x2e654ac,1, +0x2e65500,4, +0x2e65520,2, +0x2e6552c,1, +0x2e65580,4, +0x2e655a0,2, +0x2e655ac,1, +0x2e65600,4, +0x2e65640,4, +0x2e65680,4, +0x2e656c0,4, +0x2e65700,7, +0x2e65720,7, +0x2e65740,7, +0x2e65760,7, +0x2e65780,4, +0x2e6579c,11, +0x2e657d0,2, +0x2e657e0,2, +0x2e657f0,2, +0x2e65900,44, +0x2e66000,7, +0x2e66020,4, +0x2e66040,4, +0x2e66060,7, +0x2e66080,7, +0x2e660a0,4, +0x2e660c0,4, +0x2e660e0,7, +0x2e66100,7, +0x2e66120,4, +0x2e66140,4, +0x2e66160,7, +0x2e66180,7, +0x2e661a0,4, +0x2e661c0,4, +0x2e661e0,7, +0x2e66200,32, +0x2e66b00,1, +0x2e66b20,1, +0x2e66b28,4, +0x2e66b40,1, +0x2e66b60,1, +0x2e66b68,4, +0x2e66b80,1, +0x2e66ba0,1, +0x2e66ba8,4, +0x2e66bc0,1, +0x2e66be0,1, +0x2e66be8,4, +0x2e66c00,7, +0x2e66c20,1, +0x2e66c54,18, +0x2e66ca0,1, +0x2e66cd4,18, +0x2e66d20,1, +0x2e66d54,18, +0x2e66da0,1, +0x2e66dd4,12, +0x2e66e08,6, +0x2e67100,7, +0x2e67120,7, +0x2e67140,7, +0x2e67160,7, +0x2e67180,3, +0x2e68000,10, +0x2e68080,3, +0x2e680c0,1, +0x2e68100,21, +0x2e68180,13, +0x2e681c4,7, +0x2e681e4,7, +0x2e68204,7, +0x2e68224,8, +0x2e69000,7, +0x2e69030,2, +0x2e69040,7, +0x2e69070,2, +0x2e69100,2, +0x2e69120,2, +0x2e69140,2, +0x2e69160,2, +0x2e69180,9, +0x2e69200,7, +0x2e69230,2, +0x2e69240,7, +0x2e69270,2, +0x2e69300,2, +0x2e69320,2, +0x2e69340,2, +0x2e69360,2, +0x2e69380,9, +0x2e69400,11, +0x2e69500,11, +0x2e6a000,3, +0x2e6a010,2, +0x2e6a01c,5, +0x2e6a040,8, +0x2e6a080,3, +0x2e6a090,2, +0x2e6a09c,5, +0x2e6a0c0,8, +0x2e6a100,3, +0x2e6a110,2, +0x2e6a11c,5, +0x2e6a140,8, +0x2e6a180,3, +0x2e6a190,2, +0x2e6a19c,5, +0x2e6a1c0,8, +0x2e6a200,7, +0x2e6a220,12, +0x2e6a280,7, +0x2e6a2a0,12, +0x2e6a300,3, +0x2e6a310,1, +0x2e6a400,3, +0x2e6a410,2, +0x2e6a41c,5, +0x2e6a440,8, +0x2e6a480,3, +0x2e6a490,2, +0x2e6a49c,5, +0x2e6a4c0,8, +0x2e6a500,3, +0x2e6a510,2, +0x2e6a51c,5, +0x2e6a540,8, +0x2e6a580,3, +0x2e6a590,2, +0x2e6a59c,5, +0x2e6a5c0,8, +0x2e6a600,7, +0x2e6a620,12, +0x2e6a680,7, +0x2e6a6a0,12, +0x2e6a700,3, +0x2e6a710,1, +0x2e6a804,1, +0x2e6a824,21, +0x2e6a880,16, +0x2e6a900,5, +0x2e6a920,11, +0x2e6a950,9, +0x2e6a980,22, +0x2e6aa00,22, +0x2e6aa80,22, +0x2e6ab00,22, +0x2e6ab80,22, +0x2e6ac00,22, +0x2e6ac80,22, +0x2e6ad00,22, +0x2e6ad80,3, +0x2e6c000,16, +0x2e6c080,11, +0x2e6c100,11, +0x2e6c204,1, +0x2e6c224,21, +0x2e6c280,16, +0x2e6c300,11, +0x2e6c340,11, +0x2e6c800,21, +0x2e6c860,5, +0x2e6c880,6, +0x2e6c8a0,5, +0x2e6c8c0,6, +0x2e6c900,21, +0x2e6c960,5, +0x2e6c980,6, +0x2e6c9a0,5, +0x2e6c9c0,6, +0x2e6ca00,21, +0x2e6ca60,5, +0x2e6ca80,6, +0x2e6caa0,5, +0x2e6cac0,6, +0x2e6cb00,21, +0x2e6cb60,5, +0x2e6cb80,6, +0x2e6cba0,5, +0x2e6cbc0,6, +0x2e6cc00,9, +0x2e6cc48,7, +0x2e6cc68,2, +0x2e6cc74,9, +0x2e6cc9c,2, +0x2e6cd00,14, +0x2e6cd40,14, +0x2e6cd80,28, +0x2e6ce00,19, +0x2e6ce50,3, +0x2e6ce60,25, +0x2e6cec8,1, +0x2e6ced0,2, +0x2e6cee0,7, +0x2e6cf00,1, +0x2e6cf08,2, +0x2e6cffc,20, +0x2e6d050,25, +0x2e6d100,19, +0x2e6d150,25, +0x2e6d200,19, +0x2e6d250,25, +0x2e6d300,19, +0x2e6d350,25, +0x2e6d400,19, +0x2e6d450,25, +0x2e6d500,19, +0x2e6d550,25, +0x2e6d600,19, +0x2e6d650,25, +0x2e6d700,19, +0x2e6d750,25, +0x2e6d800,19, +0x2e6d850,25, +0x2e6d904,1, +0x2e6d914,10, +0x2e6d948,11, +0x2e6d980,2, +0x2e6d9a0,6, +0x2e6d9c0,2, +0x2e6d9cc,2, +0x2e6e000,35, +0x2e6ea00,10, +0x2e6ea80,3, +0x2e6eb00,6, +0x2e6f000,1, +0x2e6f008,5, +0x2e6f038,1, +0x2e6f044,1, +0x2e6f050,2, +0x2e6f100,13, +0x2e6f140,11, +0x2e6f170,12, +0x2e6f1a4,1, +0x2e6f200,104, +0x2e6f400,104, +0x2e6f600,104, +0x2e6f800,104, +0x2e70000,13, +0x2e70040,2, +0x2e70054,4, +0x2e70080,27, +0x2e70100,12, +0x2e70140,14, +0x2e70180,28, +0x2e70200,6, +0x2e70240,6, +0x2e7025c,3, +0x2e70280,5, +0x2e702a0,8, +0x2e70400,14, +0x2e70440,14, +0x2e70480,14, +0x2e704c0,14, +0x2e70540,3, +0x2e70600,7, +0x2e70620,14, +0x2e70680,5, +0x2e706a0,7, +0x2e70800,13, +0x2e70840,2, +0x2e70854,4, +0x2e70880,27, +0x2e70900,12, +0x2e70940,14, +0x2e70980,28, +0x2e70a00,6, +0x2e70a40,6, +0x2e70a5c,3, +0x2e70a80,5, +0x2e70aa0,8, +0x2e70c00,14, +0x2e70c40,14, +0x2e70c80,14, +0x2e70cc0,14, +0x2e70d40,3, +0x2e70e00,7, +0x2e70e20,14, +0x2e70e80,5, +0x2e70ea0,7, +0x2e71000,13, +0x2e71040,2, +0x2e71054,4, +0x2e71080,27, +0x2e71100,12, +0x2e71140,14, +0x2e71180,28, +0x2e71200,6, +0x2e71240,6, +0x2e7125c,3, +0x2e71280,5, +0x2e712a0,8, +0x2e71400,14, +0x2e71440,14, +0x2e71480,14, +0x2e714c0,14, +0x2e71540,3, +0x2e71600,7, +0x2e71620,14, +0x2e71680,5, +0x2e716a0,7, +0x2e71800,13, +0x2e71840,2, +0x2e71854,4, +0x2e71880,27, +0x2e71900,12, +0x2e71940,14, +0x2e71980,28, +0x2e71a00,6, +0x2e71a40,6, +0x2e71a5c,3, +0x2e71a80,5, +0x2e71aa0,8, +0x2e71c00,14, +0x2e71c40,14, +0x2e71c80,14, +0x2e71cc0,14, +0x2e71d40,3, +0x2e71e00,7, +0x2e71e20,14, +0x2e71e80,5, +0x2e71ea0,7, +0x2e72000,8, +0x2e72040,8, +0x2e72080,1, +0x2e72098,6, +0x2e72100,10, +0x2e72140,3, +0x2e72150,2, +0x2e72180,2, +0x2e72200,6, +0x2e72220,18, +0x2e72280,4, +0x2e72300,8, +0x2e72400,2, +0x2e72480,2, +0x2e72800,28, +0x2e729f0,4, +0x2e73000,40, +0x2e73100,64, +0x2e73800,56, +0x2e73be0,8, +0x2e74000,13, +0x2e74040,2, +0x2e74054,4, +0x2e74080,27, +0x2e74100,12, +0x2e74140,14, +0x2e74180,28, +0x2e74200,6, +0x2e74240,6, +0x2e7425c,3, +0x2e74280,5, +0x2e742a0,8, +0x2e74400,14, +0x2e74440,14, +0x2e74480,14, +0x2e744c0,14, +0x2e74540,3, +0x2e74600,7, +0x2e74620,14, +0x2e74680,5, +0x2e746a0,7, +0x2e74800,13, +0x2e74840,2, +0x2e74854,4, +0x2e74880,27, +0x2e74900,12, +0x2e74940,14, +0x2e74980,28, +0x2e74a00,6, +0x2e74a40,6, +0x2e74a5c,3, +0x2e74a80,5, +0x2e74aa0,8, +0x2e74c00,14, +0x2e74c40,14, +0x2e74c80,14, +0x2e74cc0,14, +0x2e74d40,3, +0x2e74e00,7, +0x2e74e20,14, +0x2e74e80,5, +0x2e74ea0,7, +0x2e75000,13, +0x2e75040,2, +0x2e75054,4, +0x2e75080,27, +0x2e75100,12, +0x2e75140,14, +0x2e75180,28, +0x2e75200,6, +0x2e75240,6, +0x2e7525c,3, +0x2e75280,5, +0x2e752a0,8, +0x2e75400,14, +0x2e75440,14, +0x2e75480,14, +0x2e754c0,14, +0x2e75540,3, +0x2e75600,7, +0x2e75620,14, +0x2e75680,5, +0x2e756a0,7, +0x2e75800,13, +0x2e75840,2, +0x2e75854,4, +0x2e75880,27, +0x2e75900,12, +0x2e75940,14, +0x2e75980,28, +0x2e75a00,6, +0x2e75a40,6, +0x2e75a5c,3, +0x2e75a80,5, +0x2e75aa0,8, +0x2e75c00,14, +0x2e75c40,14, +0x2e75c80,14, +0x2e75cc0,14, +0x2e75d40,3, +0x2e75e00,7, +0x2e75e20,14, +0x2e75e80,5, +0x2e75ea0,7, +0x2e76000,8, +0x2e76040,8, +0x2e76080,1, +0x2e76098,6, +0x2e76100,10, +0x2e76140,3, +0x2e76150,2, +0x2e76180,2, +0x2e76200,6, +0x2e76220,18, +0x2e76280,4, +0x2e76300,8, +0x2e76400,2, +0x2e76480,2, +0x2e76800,28, +0x2e769f0,4, +0x2e77000,40, +0x2e77100,64, +0x2e77800,56, +0x2e77be0,8, +0x2e78000,2, +0x2e7800c,2, +0x2e78040,7, +0x2e78100,3, +0x2e78110,3, +0x2e78120,5, +0x2e78200,6, +0x2e78240,5, +0x2e78400,2, +0x2e7840c,2, +0x2e78440,7, +0x2e78500,3, +0x2e78510,3, +0x2e78520,5, +0x2e78600,6, +0x2e78640,5, +0x2e78800,2, +0x2e7880c,2, +0x2e78840,7, +0x2e78900,3, +0x2e78910,3, +0x2e78920,5, +0x2e78a00,6, +0x2e78a40,5, +0x2e78c00,2, +0x2e78c0c,2, +0x2e78c40,7, +0x2e78d00,3, +0x2e78d10,3, +0x2e78d20,5, +0x2e78e00,6, +0x2e78e40,5, +0x2e79000,2, +0x2e7900c,2, +0x2e79040,7, +0x2e79100,3, +0x2e79110,3, +0x2e79120,5, +0x2e79200,6, +0x2e79240,5, +0x2e79400,2, +0x2e7940c,2, +0x2e79440,7, +0x2e79500,3, +0x2e79510,3, +0x2e79520,5, +0x2e79600,6, +0x2e79640,5, +0x2e79800,2, +0x2e7980c,2, +0x2e79840,7, +0x2e79900,3, +0x2e79910,3, +0x2e79920,5, +0x2e79a00,6, +0x2e79a40,5, +0x2e79c00,2, +0x2e79c0c,2, +0x2e79c40,7, +0x2e79d00,3, +0x2e79d10,3, +0x2e79d20,5, +0x2e79e00,6, +0x2e79e40,5, +0x2e7a000,5, +0x2e7a040,9, +0x2e7a100,3, +0x2e7a200,1, +0x2e7a210,1, +0x2e7a220,1, +0x2e7a230,1, +0x2e7a240,1, +0x2e7a300,3, +0x2e7a314,1, +0x2e7a320,4, +0x2e7a400,5, +0x2e7a440,5, +0x2e7b000,80, +0x2e7b200,1, +0x2e80000,3, +0x2e80010,7, +0x2e80030,10, +0x2e80080,2, +0x2e80100,6, +0x2e80140,2, +0x2e80180,2, +0x2e801a0,1, +0x2e80400,2, +0x2e80440,4, +0x2e80460,5, +0x2e80478,1, +0x2e80480,6, +0x2e804a0,3, +0x2e804b0,2, +0x2e80500,5, +0x2e80600,1, +0x2e80800,5, +0x2e80900,5, +0x2e80a00,5, +0x2e80b00,3, +0x2e80c00,35, +0x2e80d00,25, +0x2e80d80,1, +0x2e80dc0,3, +0x2e80e00,2, +0x2e80e20,2, +0x2e90000,3, +0x2e9001c,6, +0x2e90080,3, +0x2e90090,2, +0x2e900d4,4, +0x2e900ec,27, +0x2e9015c,27, +0x2e901cc,19, +0x2e90224,120, +0x2e90408,109, +0x2e905f8,4, +0x2e90610,27, +0x2e90680,27, +0x2e906f0,19, +0x2e90748,120, +0x2e9092c,109, +0x2e90b1c,4, +0x2e90b34,27, +0x2e90ba4,27, +0x2e90c14,19, +0x2e90c6c,120, +0x2e90e50,109, +0x2e91040,4, +0x2e91058,27, +0x2e910c8,27, +0x2e91138,19, +0x2e91190,120, +0x2e91374,109, +0x2e91564,4, +0x2e9157c,27, +0x2e915ec,27, +0x2e9165c,19, +0x2e916b4,120, +0x2e91898,109, +0x2e91a88,4, +0x2e91aa0,27, +0x2e91b10,27, +0x2e91b80,19, +0x2e91bd8,120, +0x2e91dbc,109, +0x2e91fac,4, +0x2e91fc4,27, +0x2e92034,27, +0x2e920a4,19, +0x2e920fc,120, +0x2e922e0,109, +0x2e924d0,4, +0x2e924e8,27, +0x2e92558,27, +0x2e925c8,19, +0x2e92620,120, +0x2e92804,109, +0x2e929f4,4, +0x2e92a0c,27, +0x2e92a7c,27, +0x2e92aec,19, +0x2e92b44,120, +0x2e92d28,109, +0x2e92f18,4, +0x2e92f30,27, +0x2e92fa0,27, +0x2e93010,19, +0x2e93068,120, +0x2e9324c,109, +0x2e9343c,4, +0x2e93454,27, +0x2e934c4,27, +0x2e93534,19, +0x2e9358c,120, +0x2e93770,109, +0x2e93960,4, +0x2e93978,27, +0x2e939e8,27, +0x2e93a58,19, +0x2e93ab0,120, +0x2e93c94,109, +0x2e93e84,4, +0x2e93e9c,27, +0x2e93f0c,27, +0x2e93f7c,19, +0x2e93fd4,120, +0x2e941b8,109, +0x2e943a8,4, +0x2e943c0,27, +0x2e94430,27, +0x2e944a0,19, +0x2e944f8,120, +0x2e946dc,109, +0x2e948cc,4, +0x2e948e4,27, +0x2e94954,27, +0x2e949c4,19, +0x2e94a1c,120, +0x2e94c00,109, +0x2e94df0,4, +0x2e94e08,27, +0x2e94e78,27, +0x2e94ee8,19, +0x2e94f40,120, +0x2e95124,109, +0x2e95314,4, +0x2e9532c,27, +0x2e9539c,27, +0x2e9540c,19, +0x2e95464,120, +0x2e95648,109, +0x2e95838,14, +0x2e95940,13, +0x2e95a44,13, +0x2e95b48,16, +0x2e95b90,42, +0x2e95c40,2, +0x2e95c90,54, +0x2e95d70,58, +0x2e95e60,58, +0x2e95f50,58, +0x2e96040,58, +0x2e96130,58, +0x2e96220,58, +0x2e96310,58, +0x2e96400,58, +0x2e964f0,58, +0x2e965e0,58, +0x2e966d0,58, +0x2e967c0,58, +0x2e968b0,58, +0x2e969a0,58, +0x2e96a90,58, +0x2e96b80,58, +0x2e96c70,58, +0x2e96d60,58, +0x2e96e50,58, +0x2e96f40,58, +0x2e97030,58, +0x2e97120,58, +0x2e97210,58, +0x2e97300,58, +0x2e973f0,58, +0x2e974e0,58, +0x2e975d0,58, +0x2e976c0,58, +0x2e977b0,58, +0x2e978a0,58, +0x2e97990,58, +0x2e97a80,101, +0x2e97c90,49, +0x2e97db0,18, +0x2e97e00,11, +0x2e97e30,4, +0x2e97e54,45, +0x2e97f58,9, +0x2e97f88,4, +0x2e97fa0,2, +0x2e97fd8,14, +0x2e98014,12, +0x2e98158,3, +0x2e98168,2, +0x2e98174,68, +0x2e98288,2, +0x2e98294,68, +0x2e983a8,1, +0x2e983b0,2, +0x2e983bc,68, +0x2e984d0,2, +0x2e984dc,68, +0x2e985f0,1, +0x2e985f8,4, +0x2e98610,3, +0x2e98624,12, +0x2e98688,8, +0x2e986dc,1, +0x2e986e8,4, +0x2e98700,3, +0x2e98714,12, +0x2e98778,8, +0x2e987cc,1, +0x2e987d8,4, +0x2e987f0,3, +0x2e98804,12, +0x2e98868,8, +0x2e988bc,1, +0x2e988c8,4, +0x2e988e0,3, +0x2e988f4,12, +0x2e98958,8, +0x2e989ac,1, +0x2e989b8,4, +0x2e989d0,3, +0x2e989e4,12, +0x2e98a48,8, +0x2e98a9c,1, +0x2e98aa8,4, +0x2e98ac0,3, +0x2e98ad4,12, +0x2e98b38,8, +0x2e98b8c,1, +0x2e98b98,4, +0x2e98bb0,3, +0x2e98bc4,12, +0x2e98c28,8, +0x2e98c7c,1, +0x2e98c88,4, +0x2e98ca0,3, +0x2e98cb4,12, +0x2e98d18,8, +0x2e98d6c,1, +0x2e98d78,4, +0x2e98d90,3, +0x2e98da4,12, +0x2e98e08,8, +0x2e98e5c,1, +0x2e98e68,4, +0x2e98e80,3, +0x2e98e94,12, +0x2e98ef8,8, +0x2e98f4c,1, +0x2e98f58,4, +0x2e98f70,3, +0x2e98f84,12, +0x2e98fe8,8, +0x2e9903c,1, +0x2e99048,4, +0x2e99060,3, +0x2e99074,12, +0x2e990d8,8, +0x2e9912c,1, +0x2e99138,4, +0x2e99150,3, +0x2e99164,12, +0x2e991c8,8, +0x2e9921c,1, +0x2e99228,4, +0x2e99240,3, +0x2e99254,12, +0x2e992b8,8, +0x2e9930c,1, +0x2e99318,4, +0x2e99330,3, +0x2e99344,12, +0x2e993a8,8, +0x2e993fc,1, +0x2e99408,4, +0x2e99420,3, +0x2e99434,12, +0x2e99498,8, +0x2e994ec,1, +0x2e994f8,4, +0x2e99510,3, +0x2e99524,12, +0x2e99588,8, +0x2e995dc,1, +0x2e995e8,64, +0x2e99748,5, +0x2e99990,28, +0x2e99a04,4, +0x2e99a98,1, +0x2e99be8,11, +0x2e99c18,13, +0x2e99c50,6, +0x2e9a000,15, +0x2e9a044,81, +0x2e9a18c,84, +0x2e9a2e0,84, +0x2e9a434,84, +0x2e9a588,84, +0x2e9a6dc,84, +0x2e9a830,84, +0x2e9a984,84, +0x2e9aad8,84, +0x2e9ac2c,84, +0x2e9ad80,84, +0x2e9aed4,84, +0x2e9b028,84, +0x2e9b17c,84, +0x2e9b2d0,84, +0x2e9b424,84, +0x2e9b578,84, +0x2e9b6cc,5, +0x2e9b760,4, +0x2e9b8e0,2414, +0x2e9dea4,88, +0x2e9e048,4, +0x2e9ebe0,1, +0x2e9ebf0,97, +0x2e9ed94,7, +0x2e9ee7c,1, +0x2e9eeac,9, +0x2e9eed4,5, +0x2e9eeec,11, +0x2e9ef2c,17, +0x2e9ef74,30, +0x2e9f034,3, +0x2e9f044,2, +0x2e9f054,17, +0x2e9fbe0,3, +0x2e9fbf0,1, +0x2ea0000,3, +0x2ea0018,2, +0x2ea0024,14, +0x2ea0060,27, +0x2ea00d0,3, +0x2ea00e0,3, +0x2ea00f0,3, +0x2ea0100,4, +0x2ea0120,6, +0x2ea0140,3, +0x2ea0150,1, +0x2ea015c,4, +0x2ea0170,1, +0x2ea0180,15, +0x2ea01c0,1, +0x2ea01c8,5, +0x2ea01e0,1, +0x2ea01f0,3, +0x2ea0200,3, +0x2ea0218,2, +0x2ea0224,14, +0x2ea0260,27, +0x2ea02d0,3, +0x2ea02e0,3, +0x2ea02f0,3, +0x2ea0300,4, +0x2ea0320,6, +0x2ea0340,3, +0x2ea0350,1, +0x2ea035c,4, +0x2ea0370,1, +0x2ea0380,15, +0x2ea03c0,1, +0x2ea03c8,5, +0x2ea03e0,1, +0x2ea03f0,3, +0x2ea0400,3, +0x2ea0418,2, +0x2ea0424,14, +0x2ea0460,27, +0x2ea04d0,3, +0x2ea04e0,3, +0x2ea04f0,3, +0x2ea0500,4, +0x2ea0520,6, +0x2ea0540,3, +0x2ea0550,1, +0x2ea055c,4, +0x2ea0570,1, +0x2ea0580,15, +0x2ea05c0,1, +0x2ea05c8,5, +0x2ea05e0,1, +0x2ea05f0,3, +0x2ea0600,3, +0x2ea0618,2, +0x2ea0624,14, +0x2ea0660,27, +0x2ea06d0,3, +0x2ea06e0,3, +0x2ea06f0,3, +0x2ea0700,4, +0x2ea0720,6, +0x2ea0740,3, +0x2ea0750,1, +0x2ea075c,4, +0x2ea0770,1, +0x2ea0780,15, +0x2ea07c0,1, +0x2ea07c8,5, +0x2ea07e0,1, +0x2ea07f0,3, +0x2ea0800,3, +0x2ea0818,2, +0x2ea0824,14, +0x2ea0860,27, +0x2ea08d0,3, +0x2ea08e0,3, +0x2ea08f0,3, +0x2ea0900,4, +0x2ea0920,6, +0x2ea0940,3, +0x2ea0950,1, +0x2ea095c,4, +0x2ea0970,1, +0x2ea0980,15, +0x2ea09c0,1, +0x2ea09c8,5, +0x2ea09e0,1, +0x2ea09f0,3, +0x2ea1844,1, +0x2ea1858,5, +0x2ea1904,3, +0x2ea1950,3, +0x2ea1988,2, +0x2ea19a0,7, +0x2ea19c0,7, +0x2ea19e0,4, +0x2ea2000,24, +0x2ea20f0,3, +0x2ea2100,7, +0x2ea2120,7, +0x2ea2144,7, +0x2ea2400,4, +0x2ea2420,5, +0x2ea25e0,3, +0x2ea25f4,1, +0x2ea25fc,4, +0x2ea2620,3, +0x2ea2680,8, +0x2ea2700,19, +0x2ea2800,99, +0x2ea2a00,18, +0x2ea2a80,8, +0x2ea2b00,1, +0x2ea3070,1, +0x2ea3080,2, +0x2ea308c,1, +0x2ea3098,2, +0x2ea3404,1, +0x2ea3440,20, +0x2ea3494,1, +0x2ea349c,7, +0x2ea34d0,4, +0x2ea34e8,2, +0x2ea34fc,8, +0x2ea3520,7, +0x2ea3540,7, +0x2ea3560,7, +0x2ea3580,7, +0x2ea35a0,7, +0x2ea35c0,7, +0x2ea35e0,7, +0x2ea3600,9, +0x2ea363c,2, +0x2ea3650,6, +0x2ea3684,10, +0x2ea3a00,10, +0x2ea3a30,1, +0x2ea3a40,8, +0x2ea3a64,5, +0x2ea4a04,3, +0x2ea4b00,33, +0x2ea4b90,3, +0x2ea5000,8, +0x2ea5040,8, +0x2ea5104,1, +0x2ea510c,3, +0x2ea5124,1, +0x2ea512c,3, +0x2ea6000,13, +0x2ea6200,14, +0x2ea6240,1, +0x2ea6248,1, +0x2ea6258,1, +0x2ea6260,8, +0x2ea6284,1, +0x2ea62a0,8, +0x2ea6348,5, +0x2ea67f0,1, +0x2ea67f8,1, +0x2ea6a10,12, +0x2ea7000,19, +0x2ea7a00,10, +0x2ea7a80,3, +0x2ea7b00,6, +0x2ec0000,1, +0x2ec000c,5, +0x2ec0044,1, +0x2ec0054,5, +0x2ec0200,128, +0x2ec0404,1, +0x2ec0428,54, +0x2ec0600,32, +0x2ec0704,1, +0x2ec0800,1, +0x2ec0900,1, +0x2ec0910,2, +0x2ec0920,3, +0x2ec0980,10, +0x2ec0a00,19, +0x2ec0b00,1, +0x2ee0000,2, +0x2ee000c,2, +0x2ee0018,2, +0x2ee0024,2, +0x2ee0030,2, +0x2ee003c,2, +0x2ee0048,2, +0x2ee0054,2, +0x2ee0060,1, +0x2ee0070,2, +0x2ee007c,2, +0x2ee0088,2, +0x2ee0094,2, +0x2ee00a0,2, +0x2ee00ac,2, +0x2ee00b8,2, +0x2ee00c4,2, +0x2ee00d0,1, +0x2ee00e0,2, +0x2ee00ec,2, +0x2ee00f8,2, +0x2ee0104,2, +0x2ee0110,2, +0x2ee011c,2, +0x2ee0128,2, +0x2ee0134,2, +0x2ee0140,1, +0x2ee0150,2, +0x2ee015c,2, +0x2ee0168,2, +0x2ee0174,2, +0x2ee0180,2, +0x2ee018c,2, +0x2ee0198,2, +0x2ee01a4,2, +0x2ee01b0,1, +0x2ee01c0,57, +0x2ee02b0,23, +0x2ee0310,83, +0x2ee0460,83, +0x2ee05b0,83, +0x2ee0700,83, +0x2ee0850,83, +0x2ee09a0,83, +0x2ee0af0,83, +0x2ee0c40,83, +0x2ee0d90,83, +0x2ee0ee0,83, +0x2ee1030,83, +0x2ee1180,83, +0x2ee12d0,83, +0x2ee1420,83, +0x2ee1570,83, +0x2ee16c0,83, +0x2ee1810,83, +0x2ee1960,83, +0x2ee1ab0,83, +0x2ee1c00,83, +0x2ee1d50,83, +0x2ee1ea0,83, +0x2ee1ff0,83, +0x2ee2140,83, +0x2ee2290,83, +0x2ee23e0,83, +0x2ee2530,83, +0x2ee2680,83, +0x2ee27d0,83, +0x2ee2920,83, +0x2ee2a70,83, +0x2ee2bc0,62, +0x2ee2db4,3, +0x2ee2df4,3, +0x2ee2e34,3, +0x2ee2e74,3, +0x2ee2eb4,3, +0x2ee2ef4,3, +0x2ee2f34,3, +0x2ee2f74,3, +0x2ee2fb4,3, +0x2ee2ff4,3, +0x2ee3034,3, +0x2ee3074,3, +0x2ee30b4,3, +0x2ee30f4,3, +0x2ee3134,3, +0x2ee3174,3, +0x2ee31b4,3, +0x2ef0000,4, +0x2ef0014,2, +0x2ef0020,8, +0x2ef0044,2, +0x2ef0050,13, +0x2ef0088,20, +0x2ef00dc,1, +0x2ef0180,6, +0x2ef0590,3, +0x2ef05c0,2, +0x2ef0a04,1, +0x2ef0a0c,3, +0x2ef0a20,1, +0x2ef0ba0,4, +0x2ef0c00,4, +0x2ef0c20,3, +0x2ef0c30,5, +0x2ef0c50,52, +0x2ef0d50,57, +0x2ef0ec0,3, +0x2ef0ffc,3, +0x2ef1020,3, +0x2ef1030,3, +0x2ef1060,2, +0x2ef1100,2, +0x2ef1140,18, +0x2ef11c0,30, +0x2ef1240,14, +0x2ef1280,28, +0x2ef1300,2, +0x2ef13a0,6, +0x2ef1400,19, +0x2ef1800,19, +0x2ef1c00,19, +0x2ef1c80,8, +0x2ef1d00,3, +0x2ef1d50,3, +0x2ef1e00,3, +0x2ef1e10,2, +0x2ef1e20,6, +0x2ef1e40,6, +0x2ef1e60,6, +0x2ef1e80,6, +0x2ef1ea0,6, +0x2ef1ec0,2, +0x2ef1ecc,2, +0x2ef1ee0,2, +0x2ef1eec,2, +0x2ef1f80,3, +0x2ef1f90,60, +0x2ef2100,32, +0x2ef2200,32, +0x2ef2300,32, +0x2ef2400,32, +0x2ef2500,32, +0x2ef2600,32, +0x2ef2700,32, +0x2ef2800,32, +0x2ef2900,32, +0x2ef2a00,32, +0x2ef2b00,32, +0x2ef2c00,32, +0x2ef2d00,32, +0x2ef2e00,32, +0x2ef2f00,32, +0x2ef3000,32, +0x2ef30c0,3, +0x2ef4000,2, +0x2ef4040,16, +0x2ef4100,36, +0x2ef4800,5, +0x2ef4824,1, +0x2ef482c,1, +0x2ef4c04,1, +0x2ef4cd8,74, +0x2ef5000,7, +0x2ef5020,4, +0x2ef5204,1, +0x2ef5280,35, +0x2ef5310,4, +0x2ef5404,1, +0x2ef5480,34, +0x2ef5510,10, +0x2ef553c,3, +0x2ef5800,7, +0x2ef5820,4, +0x2ef5a04,1, +0x2ef5a80,35, +0x2ef5b10,4, +0x2ef5c04,1, +0x2ef5c80,34, +0x2ef5d10,10, +0x2ef5d3c,3, +0x2efa000,5, +0x2efa01c,13, +0x2efa060,3, +0x2efa080,8, +0x2efa100,5, +0x2efa11c,13, +0x2efa160,3, +0x2efa180,8, diff --git a/mtcr_ul/mtcr_icmd_cif.h b/mtcr_ul/mtcr_icmd_cif.h index 1c4d9e4e..362f6b63 100644 --- a/mtcr_ul/mtcr_icmd_cif.h +++ b/mtcr_ul/mtcr_icmd_cif.h @@ -55,7 +55,7 @@ extern "C" { #endif #define FLASH_REG_ACCESS 0x9001 -#define ICMD_MAX_CMD_SIZE 0x300 // max mailbox size +#define ICMD_MAX_CMD_SIZE 0x340 // max mailbox size MTCR_API extern int increase_poll_time; diff --git a/mtcr_ul/mtcr_ul.c b/mtcr_ul/mtcr_ul.c index 66cb2dd8..00fb9558 100644 --- a/mtcr_ul/mtcr_ul.c +++ b/mtcr_ul/mtcr_ul.c @@ -294,3 +294,14 @@ int mvpd_write4(mfile *mf, unsigned int offset, u_int8_t value[4]) return ME_UNSUPPORTED_OPERATION; } +int is_pci_device(mfile* mf) +{ + return (mf->flags & MDEVS_I2CM) + || (mf->flags & (MDEVS_CABLE | MDEVS_LINKX_CHIP)) + || (mf->flags & MDEVS_SOFTWARE); +} + +int is_livefish_device(mfile *mf) +{ + return is_livefish_device_ul(mf); +} diff --git a/mtcr_ul/mtcr_ul_com.h b/mtcr_ul/mtcr_ul_com.h index e63e16af..d41f6a21 100644 --- a/mtcr_ul/mtcr_ul_com.h +++ b/mtcr_ul/mtcr_ul_com.h @@ -148,6 +148,8 @@ int mvpd_read4_ul(mfile *mf, unsigned int offset, u_int8_t value[4]); int space_to_cap_offset(int space); +int is_livefish_device_ul(mfile *mf); + int get_dma_pages(mfile *mf, struct mtcr_page_info* page_info, int page_amount); diff --git a/mtcr_ul/mtcr_ul_icmd_cif.c b/mtcr_ul/mtcr_ul_icmd_cif.c index 3ab3ba36..77a4e5c1 100644 --- a/mtcr_ul/mtcr_ul_icmd_cif.c +++ b/mtcr_ul/mtcr_ul_icmd_cif.c @@ -56,7 +56,7 @@ // _DEBUG_MODE // un-comment this to enable debug prints - +#define ICMD_DEFAULT_TIMEOUT 5120 #define STAT_CFG_NOT_DONE_ADDR_CIB 0xb0004 #define STAT_CFG_NOT_DONE_ADDR_CX4 0xb0004 #define STAT_CFG_NOT_DONE_ADDR_SW_IB 0x80010 @@ -330,6 +330,24 @@ static int set_sleep() return icmd_sleep; } +static int set_icmd_timeout() +{ + char* icmd_timeout_env; + int icmd_timeout = ICMD_DEFAULT_TIMEOUT; + + icmd_timeout_env = getenv("MFT_ICMD_TIMEOUT"); + + if (icmd_timeout_env) { + char* endptr; + icmd_timeout = strtol(icmd_timeout_env, &endptr, 10); + if (endptr != NULL && *endptr != '\0') { + icmd_timeout = ICMD_DEFAULT_TIMEOUT; + } + } + + return icmd_timeout; +} + /* * get_status */ @@ -402,22 +420,27 @@ static int set_and_poll_on_busy_bit(mfile *mf, int enhanced, int busy_bit_offset // set go bit rc = set_busy_bit(mf, reg, busy_bit_offset); - CHECK_RC(rc); + CHECK_RC(rc); DBG_PRINTF("Busy-bit raised. Waiting for command to exec...\n"); // set sleep time if needed int icmd_sleep = set_sleep(); + int icmd_timeout = set_icmd_timeout(); + // wait for command to execute i = 0; wait = 1; do { - if (++i > 5120) { + if (++i > icmd_timeout) { // this number of iterations should take ~~30sec, which is the defined command t/o DBG_PRINTF("Execution timed-out\n"); return ME_ICMD_STATUS_EXECUTE_TO; } - DBG_PRINTF("Waiting for busy-bit to clear (iteration #%d)...\n", i); + if ((i < 100) || (i % 100 == 0)) { + DBG_PRINTF("Waiting for busy-bit to clear (iteration #%d)...\n", i); + } + if (icmd_sleep > 0) { if (i == 3) { msleep(icmd_sleep); @@ -902,7 +925,6 @@ static int icmd_init_cr(mfile *mf) case (QUANTUM_HW_ID): case (SPECTRUM2_HW_ID): case (SPECTRUM3_HW_ID): - case (SPECTRUM4_HW_ID): cmd_ptr_addr = CMD_PTR_ADDR_QUANTUM; hcr_address = HCR_ADDR_QUANTUM; mf->icmd.semaphore_addr = SEMAPHORE_ADDR_QUANTUM; @@ -911,6 +933,7 @@ static int icmd_init_cr(mfile *mf) break; case (QUANTUM2_HW_ID): + case (SPECTRUM4_HW_ID): cmd_ptr_addr = CMD_PTR_ADDR_QUANTUM; hcr_address = HCR_ADDR_QUANTUM; mf->icmd.semaphore_addr = SEMAPHORE_ADDR_QUANTUM2; @@ -922,7 +945,6 @@ static int icmd_init_cr(mfile *mf) case (CX6DX_HW_ID): case (CX6LX_HW_ID): case (BF2_HW_ID): - case (BF3_HW_ID): cmd_ptr_addr = CMD_PTR_ADDR_CX5; hcr_address = HCR_ADDR_CX5; mf->icmd.semaphore_addr = SEMAPHORE_ADDR_CX5; @@ -931,6 +953,7 @@ static int icmd_init_cr(mfile *mf) break; case (CX7_HW_ID): + case (BF3_HW_ID): cmd_ptr_addr = CMD_PTR_ADDR_CX7; hcr_address = HCR_ADDR_CX7; mf->icmd.semaphore_addr = SEMAPHORE_ADDR_CX7; diff --git a/reg_access/regaccess.py b/reg_access/regaccess.py index 737cd34a..8a0b7f86 100644 --- a/reg_access/regaccess.py +++ b/reg_access/regaccess.py @@ -175,7 +175,9 @@ class MGIR_ST(Structure): ("num_ports",c_uint8), ("hw_dev_id", c_uint16), ("manufacturing_base_mac_47_32", c_uint16), + ("module_base",c_uint8), ("manufacturing_base_mac_31_0", c_uint32), + ("associated_module_id_31_0", c_uint32), ("uptime", c_uint32), ("sub_minor", c_uint8), ("minor", c_uint8), @@ -185,6 +187,7 @@ class MGIR_ST(Structure): ("debug_fw", c_uint8), ("dev_fw", c_uint8), ("string_tlv", c_uint8), + ("dev_sc", c_uint8), ("build_id", c_uint32), ("year", c_uint16), diff --git a/small_utils/binary_file.py b/small_utils/binary_file.py index 1261fb43..dfbc4d5a 100755 --- a/small_utils/binary_file.py +++ b/small_utils/binary_file.py @@ -1,160 +1,160 @@ -# Copyright (c) 2004-2010 Mellanox Technologies LTD. All rights reserved. +# Copyright (c) 2004-2010 Mellanox Technologies LTD. All rights reserved. # Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# -# This software is available to you under a choice of one of two -# licenses. You may choose to be licensed under the terms of the GNU -# General Public License (GPL) Version 2, available from the file -# COPYING in the main directory of this source tree, or the -# OpenIB.org BSD license below: -# -# Redistribution and use in source and binary forms, with or -# without modification, are permitted provided that the following -# conditions are met: -# -# - Redistributions of source code must retain the above -# copyright notice, this list of conditions and the following -# disclaimer. -# -# - Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials -# provided with the distribution. -# -# 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 AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# Author: Ahmed Awwad ahmadaw@mellanox.com Created: 2019-Jan - -import binascii - - -class BinaryFile(object): - """ - Binary File class is dealing with r/w of binary files - """ - def __init__(self, file_path): - self._file_path = file_path - - def read_byte(self, offset): - """ - Read 1B from the pci configuration - """ - return self.read(1, offset)[0] - - def read_word(self, offset): - """ - Read 2B for the pci configuration - """ - bytes_list = self.read(2, offset) - if bytes_list != []: - byte0 = "{0:x}".format(bytes_list[0]).zfill(2) - byte1 = "{0:x}".format(bytes_list[1]).zfill(2) - return int("{0}{1}".format(byte1, byte0), 16) - else: - return None - - def read_long(self, offset): - """ - Reads 4B from the pci configuration - """ - bytes_list = self.read(4, offset) - if bytes_list != []: - byte0 = "{0:x}".format(bytes_list[0]).zfill(2) - byte1 = "{0:x}".format(bytes_list[1]).zfill(2) - byte2 = "{0:x}".format(bytes_list[2]).zfill(2) - byte3 = "{0:x}".format(bytes_list[3]).zfill(2) - return int("{0}{1}{2}{3}".format(byte3, byte2, byte1, byte0), 16) - else: - return None - - def read(self, size, offset=0, skip_offset_list=None): - """ - Read a given binary file and return the output as a string in hex representation - Skip-list is a list of addresses the function need to skip. The function will insert '00' on every address that is skipped - Example read(size=10, offset=0, skip_offset_list=[0x5]) will read from address 0x0 to address 0x9 and replace address 0x5 with '00' - """ - try: - with open(self._file_path, "rb") as f: - if skip_offset_list: - data = binascii.unhexlify("") # Initialization - zero_binary = binascii.unhexlify("00") # Initialization - offset_interval = self._get_read_intervals(skip_offset_list, offset, size) - for interval_start, interval_size in offset_interval: - if interval_size: # read interval - f.seek(interval_start) - data += f.read(interval_size) - else: # add '00' to data - data += zero_binary - else: - f.seek(offset) - data = f.read(size) - except Exception as err: - raise RuntimeError("Failed to parse file: {0} for reading. ERROR: {1}".format(self._file_path, err)) - data = binascii.hexlify(data) - bytes_as_string = self.chunkstring(data, 2) - bytes_list = [] - for byte in bytes_as_string: - if byte != "": - bytes_list.append(int(byte, 16)) - else: - bytes_list.append(None) - return bytes_list - - @staticmethod - def _get_read_intervals(skip_offset_list, offset, size): - """ - The method prepare the skip list in order to read a range and skipping on some (dangerous) offsets - The method return list of tuples - Example , offset:0, size:10, skiplist=[4, 5] - The function return [(0, 4),(4, 0), (5, 0) (6, 10)] when each item is (start, size) - when size is 0 it means we need to skip this offset - """ - # remove out of range skip addresses - for skip_offset in skip_offset_list: - if skip_offset not in range(offset, size + 1): - skip_offset_list.remove(skip_offset) - read_interval_set = set(skip_offset_list) - # Add offset, offset+size to skip_list - read_interval_set.add(offset-1) - read_interval_set.add(offset + size) - - read_interval_list = sorted(list(read_interval_set)) - - result = [] - for start, end in zip(read_interval_list[:-1], read_interval_list[1:]): - interval_start = start + 1 - interval_end = end - result.append((interval_start, interval_end - interval_start)) # interval - result.append((interval_end, 0)) # skip interval - - result = result[:-1] # remove the last tuple (offset+size, 0) - return sorted(set(result)) - - def write(self, bytes_list, size, offset=0): - """ - A method to write data to a binary file - data is a list of values - """ - data_to_write = "" - for byte in bytes_list: - data_to_write += "{0:x}".format(byte).zfill(2) - if len(data_to_write) > size * 2: - raise RuntimeError("Failed to write data {0} invalid size".format(data_to_write)) - bin_data = binascii.unhexlify(data_to_write) # Return the binary data represented by the hexadecimal string - try: - with open(self._file_path, "wb") as f: - f.seek(offset) - f.write(bin_data) - except Exception as e: - raise RuntimeError("Failed writing to a file: {0}. ERROR: {1}".format(self._file_path, e)) - - def chunkstring(self, string, length): - """ - Chunks the string to list of strings in the given length - """ +# +# This software is available to you under a choice of one of two +# licenses. You may choose to be licensed under the terms of the GNU +# General Public License (GPL) Version 2, available from the file +# COPYING in the main directory of this source tree, or the +# OpenIB.org BSD license below: +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the following +# conditions are met: +# +# - Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# - Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 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 AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# Author: Ahmed Awwad ahmadaw@mellanox.com Created: 2019-Jan + +import binascii + + +class BinaryFile(object): + """ + Binary File class is dealing with r/w of binary files + """ + def __init__(self, file_path): + self._file_path = file_path + + def read_byte(self, offset): + """ + Read 1B from the pci configuration + """ + return self.read(1, offset)[0] + + def read_word(self, offset): + """ + Read 2B for the pci configuration + """ + bytes_list = self.read(2, offset) + if bytes_list != []: + byte0 = "{0:x}".format(bytes_list[0]).zfill(2) + byte1 = "{0:x}".format(bytes_list[1]).zfill(2) + return int("{0}{1}".format(byte1, byte0), 16) + else: + return None + + def read_long(self, offset): + """ + Reads 4B from the pci configuration + """ + bytes_list = self.read(4, offset) + if bytes_list != []: + byte0 = "{0:x}".format(bytes_list[0]).zfill(2) + byte1 = "{0:x}".format(bytes_list[1]).zfill(2) + byte2 = "{0:x}".format(bytes_list[2]).zfill(2) + byte3 = "{0:x}".format(bytes_list[3]).zfill(2) + return int("{0}{1}{2}{3}".format(byte3, byte2, byte1, byte0), 16) + else: + return None + + def read(self, size, offset=0, skip_offset_list=None): + """ + Read a given binary file and return the output as a string in hex representation + Skip-list is a list of addresses the function need to skip. The function will insert '00' on every address that is skipped + Example read(size=10, offset=0, skip_offset_list=[0x5]) will read from address 0x0 to address 0x9 and replace address 0x5 with '00' + """ + try: + with open(self._file_path, "rb") as f: + if skip_offset_list: + data = binascii.unhexlify("") # Initialization + zero_binary = binascii.unhexlify("00") # Initialization + offset_interval = self._get_read_intervals(skip_offset_list, offset, size) + for interval_start, interval_size in offset_interval: + if interval_size: # read interval + f.seek(interval_start) + data += f.read(interval_size) + else: # add '00' to data + data += zero_binary + else: + f.seek(offset) + data = f.read(size) + except Exception as err: + raise RuntimeError("Failed to parse file: {0} for reading. ERROR: {1}".format(self._file_path, err)) + data = binascii.hexlify(data) + bytes_as_string = self.chunkstring(data, 2) + bytes_list = [] + for byte in bytes_as_string: + if byte != "": + bytes_list.append(int(byte, 16)) + else: + bytes_list.append(None) + return bytes_list + + @staticmethod + def _get_read_intervals(skip_offset_list, offset, size): + """ + The method prepare the skip list in order to read a range and skipping on some (dangerous) offsets + The method return list of tuples + Example , offset:0, size:10, skiplist=[4, 5] + The function return [(0, 4),(4, 0), (5, 0) (6, 10)] when each item is (start, size) + when size is 0 it means we need to skip this offset + """ + # remove out of range skip addresses + for skip_offset in skip_offset_list: + if skip_offset not in range(offset, size + 1): + skip_offset_list.remove(skip_offset) + read_interval_set = set(skip_offset_list) + # Add offset, offset+size to skip_list + read_interval_set.add(offset-1) + read_interval_set.add(offset + size) + + read_interval_list = sorted(list(read_interval_set)) + + result = [] + for start, end in zip(read_interval_list[:-1], read_interval_list[1:]): + interval_start = start + 1 + interval_end = end + result.append((interval_start, interval_end - interval_start)) # interval + result.append((interval_end, 0)) # skip interval + + result = result[:-1] # remove the last tuple (offset+size, 0) + return sorted(set(result)) + + def write(self, bytes_list, size, offset=0): + """ + A method to write data to a binary file + data is a list of values + """ + data_to_write = "" + for byte in bytes_list: + data_to_write += "{0:x}".format(byte).zfill(2) + if len(data_to_write) > size * 2: + raise RuntimeError("Failed to write data {0} invalid size".format(data_to_write)) + bin_data = binascii.unhexlify(data_to_write) # Return the binary data represented by the hexadecimal string + try: + with open(self._file_path, "wb") as f: + f.seek(offset) + f.write(bin_data) + except Exception as e: + raise RuntimeError("Failed writing to a file: {0}. ERROR: {1}".format(self._file_path, e)) + + def chunkstring(self, string, length): + """ + Chunks the string to list of strings in the given length + """ return (string[0+i:length+i] for i in range(0, len(string), length)) \ No newline at end of file diff --git a/small_utils/mcra.c b/small_utils/mcra.c index f1389e37..0e3c481f 100644 --- a/small_utils/mcra.c +++ b/small_utils/mcra.c @@ -131,7 +131,7 @@ int main(int argc, char *argv[]) case 's': i2c_slave = strtoul(optarg, &endp, 0); if (*endp || i2c_slave == 0 || i2c_slave > 0x7f) { - fprintf(stderr, "-E- Bad slave address given (%s). Expecting a number [0x1 .. 0x7f]\n", optarg); + fprintf(stderr, "-E- Bad slave address given (%s).Expecting a non-negative number\n", optarg); exit(1); } break; @@ -278,6 +278,7 @@ int main(int argc, char *argv[]) adb_dump = getenv(ADB_DUMP_VAR); } strncpy(device, dev, MAX_DEV_LEN - 1); + // Do the job mf = mopen_adv((const char*)device, (MType)(MST_DEFAULT | MST_CABLE | MST_LINKX_CHIP)); if (!mf) { @@ -373,7 +374,7 @@ int main(int argc, char *argv[]) addr = (addr >> 2) << 2; rc = (mread4_block(mf, addr, data, dowrd_size * 4) != dowrd_size * 4); - + if (rc) { free(data); goto access_error; @@ -386,7 +387,7 @@ int main(int argc, char *argv[]) free(data); } else { rc = (mread4(mf, addr, &val) != 4); - + if (rc) { goto access_error; } @@ -403,18 +404,18 @@ int main(int argc, char *argv[]) if (bit_offs != 0 || bit_size != 32) { // read-modify-write u_int32_t tmp_val; - + rc = (mread4(mf, addr, &tmp_val) != 4); - + if (rc) { goto access_error; } val = MERGE(tmp_val, val, bit_offs, bit_size); } - + rc = (mwrite4(mf, addr, val) != 4); - + if (rc) { goto access_error; } diff --git a/small_utils/mlxfwresetlib/cmd_reg_mfrl.py b/small_utils/mlxfwresetlib/cmd_reg_mfrl.py index 70927335..a3b1d470 100755 --- a/small_utils/mlxfwresetlib/cmd_reg_mfrl.py +++ b/small_utils/mlxfwresetlib/cmd_reg_mfrl.py @@ -38,7 +38,7 @@ class CmdRegMfrl(): reset_levels_db = [ {'level': LIVE_PATCH, 'description': 'Driver, PCI link, network link will remain up ("live-Patch")', 'mask' : 0x1, 'support_reset_type': False}, {'level': PCI_RESET, 'description': 'Driver restart and PCI reset', 'mask' : 0x8, 'support_reset_type': True}, - {'level': WARM_REBOOT, 'description': 'Warm Reboot', 'mask' : 0x48, 'support_reset_type': True}, + {'level': WARM_REBOOT, 'description': 'Warm Reboot', 'mask' : 0x40, 'support_reset_type': True}, ] FULL_CHIP, PHY_LESS, NIC_ONLY = 0,1,2 diff --git a/small_utils/mlxpci_lib.py b/small_utils/mlxpci_lib.py index 75627bd4..36e1bc37 100644 --- a/small_utils/mlxpci_lib.py +++ b/small_utils/mlxpci_lib.py @@ -124,7 +124,9 @@ def save_configuration_space(self, to_file=False): # read and save PCI header 0x0-0x3f self.logger.debug("Reading and saving pci header [0x0-0x3f] ...") - self._pci_conf_space["pci_header"] = self.read(0x0, 0x40) + self._pci_conf_space["pci_header_start"] = self.read(0x0, 16) + self._pci_conf_space["pci_header_bars"] = self.read(0x10, 24) + self._pci_conf_space["pci_header_end"] = self.read(0x28, 24) self.logger.debug("Reading and saving legacy list ...") pci_legacy_ptr = self.read_byte(CONFIG_SPACE_PTR_OFFSET) @@ -178,7 +180,10 @@ def restore_configuration_space(self): cached_data = self.read(offset=0x0, size=MAX_PCI_OFFSET, skip_offset_list=MELLANOX_PCI_SKIP_LIST) # write pci header 0x0-0x3f self.logger.debug("Writing PCI header [0x0-0x3f] ...") - self.write(0x0, 0x40, self._pci_conf_space["pci_header"]) + self.write(0x10, 24, self._pci_conf_space["pci_header_bars"]) # Restore the BAR + self.write(0x0, 16, self._pci_conf_space["pci_header_start"]) # and then restore bar_enable (part of the "start") + self.write(0x28, 24, self._pci_conf_space["pci_header_end"]) + # Write Legacy list self.logger.debug("Writing back Legacy list ...") diff --git a/small_utils/mstfwreset.py b/small_utils/mstfwreset.py index 2a87c3cc..f061c277 100644 --- a/small_utils/mstfwreset.py +++ b/small_utils/mstfwreset.py @@ -111,7 +111,7 @@ class SyncOwner(): "ConnectX6", "ConnectX6DX", "ConnectX6LX", "BlueField2", "ConnectX7", "BlueField3"] SUPP_OS = ["FreeBSD", "Linux", "Windows"] -IS_MSTFLINT = True +IS_MSTFLINT = os.path.basename(__file__) == "mstfwreset.py" # TODO latter remove mcra to the new class MCRA = 'mcra' if IS_MSTFLINT: diff --git a/tools_crypto/Makefile.am b/tools_crypto/Makefile.am index a60b9dc8..f80f27eb 100644 --- a/tools_crypto/Makefile.am +++ b/tools_crypto/Makefile.am @@ -33,7 +33,7 @@ # Makefile.am -- Process this file with automake to produce Makefile.in USER_DIR = $(top_srcdir) AM_CPPFLAGS = -I$(USER_DIR) -I$(USER_DIR)/common $(COMPILER_FPIC) -AM_CFLAGS = -MD -pipe -Wall -W -DMST_UL -g $(COMPILER_FPIC) +AM_CFLAGS = -MD -pipe -Wall -Werror -W -DMST_UL -g $(COMPILER_FPIC) noinst_LIBRARIES = libtools_crypto.a libtools_crypto_a_SOURCES = tools_md5.c tools_md5.h diff --git a/tools_layouts/adb/prm/hca/ext/register_access_table.adb b/tools_layouts/adb/prm/hca/ext/register_access_table.adb index de5f4683..69d93bc4 100644 --- a/tools_layouts/adb/prm/hca/ext/register_access_table.adb +++ b/tools_layouts/adb/prm/hca/ext/register_access_table.adb @@ -35,7 +35,7 @@ - + @@ -294,7 +294,7 @@ - + @@ -344,8 +344,8 @@ - - + + @@ -369,7 +369,7 @@ - + @@ -416,7 +416,7 @@ - + @@ -441,7 +441,7 @@ - + @@ -466,14 +466,14 @@ - + - + @@ -861,7 +861,7 @@ - + @@ -902,7 +902,7 @@ - + @@ -910,10 +910,10 @@ - + - - + + @@ -926,7 +926,7 @@ - + @@ -991,7 +991,7 @@ - + @@ -1027,7 +1027,7 @@ - + @@ -1035,8 +1035,8 @@ - - + + @@ -1046,7 +1046,7 @@ - + @@ -1058,7 +1058,7 @@ - + @@ -1092,7 +1092,7 @@ - + @@ -1101,7 +1101,7 @@ - + @@ -1230,7 +1230,7 @@ - + @@ -1263,9 +1263,9 @@ - - - + + + @@ -1296,13 +1296,15 @@ - + + + @@ -1335,15 +1337,15 @@ - + - + - + @@ -1357,14 +1359,14 @@ - + - + @@ -1428,11 +1430,11 @@ - + - + @@ -1483,7 +1485,7 @@ - + @@ -1578,7 +1580,7 @@ - + @@ -1622,7 +1624,7 @@ - + @@ -1720,7 +1722,7 @@ - + @@ -1821,8 +1823,8 @@ - - + + @@ -1833,14 +1835,14 @@ - + - + @@ -1911,22 +1913,22 @@ - - - - - - - - + + + + + + + + - - + + - - - + + + @@ -2225,10 +2227,10 @@ - - - - + + + + @@ -2361,7 +2363,7 @@ - + @@ -2382,7 +2384,7 @@ - + @@ -2533,7 +2535,7 @@ - + @@ -2564,17 +2566,27 @@ + + + + + + + + + + @@ -2585,17 +2597,35 @@ - + + + + + + + + + + + + + + + + + + + - + - - + + @@ -2603,6 +2633,11 @@ + + + + + @@ -2630,7 +2665,7 @@ - + @@ -2675,19 +2710,21 @@ - + - - - - - - - - + + + + + + + + + + @@ -2766,12 +2803,12 @@ - + - + @@ -2794,7 +2831,7 @@ - + @@ -2819,11 +2856,11 @@ - + - + @@ -2843,7 +2880,7 @@ - + @@ -2888,7 +2925,7 @@ - + @@ -2922,7 +2959,7 @@ - + @@ -2953,7 +2990,7 @@ - + @@ -3016,8 +3053,8 @@ - - + + @@ -3054,7 +3091,7 @@ - + @@ -3181,7 +3218,7 @@ - + @@ -3203,8 +3240,8 @@ - - + + @@ -3215,7 +3252,7 @@ - + @@ -3230,7 +3267,7 @@ - + @@ -3238,12 +3275,12 @@ - + - + @@ -3329,7 +3366,7 @@ - + @@ -3390,7 +3427,7 @@ - + @@ -3442,7 +3479,7 @@ - + @@ -3472,7 +3509,7 @@ - + @@ -3596,7 +3633,7 @@ - + diff --git a/tools_layouts/adb/prm/switch/ext/register_access_table.adb b/tools_layouts/adb/prm/switch/ext/register_access_table.adb index 861a8ed8..a25b4625 100644 --- a/tools_layouts/adb/prm/switch/ext/register_access_table.adb +++ b/tools_layouts/adb/prm/switch/ext/register_access_table.adb @@ -35,32 +35,26 @@ - + - - - - + + + + - + - + - - - - - - - - - + + + @@ -68,17 +62,16 @@ - + - - + - - + + @@ -125,18 +118,7 @@ - - - - - - - - - - - - + @@ -197,22 +179,21 @@ - - - - - + + + + - - + + - + - - + + @@ -222,7 +203,7 @@ - + @@ -233,7 +214,7 @@ - + @@ -243,14 +224,14 @@ - + - + @@ -591,6 +572,7 @@ + @@ -720,7 +702,7 @@ - + @@ -738,7 +720,7 @@ - + @@ -813,7 +795,7 @@ - + @@ -917,7 +899,7 @@ - + @@ -943,7 +925,7 @@ - + @@ -960,9 +942,9 @@ - + - + @@ -987,7 +969,7 @@ - + @@ -1031,9 +1013,9 @@ - - - + + + @@ -1427,14 +1409,14 @@ - + - + @@ -1454,21 +1436,21 @@ - - - + + + - + - + @@ -1476,11 +1458,11 @@ - - - - - + + + + + @@ -1532,7 +1514,7 @@ - + @@ -1576,8 +1558,8 @@ - - + + @@ -1645,7 +1627,7 @@ - + @@ -1655,7 +1637,7 @@ - + @@ -1675,19 +1657,19 @@ - + - + - + - + @@ -1701,11 +1683,11 @@ - - + + - + @@ -1738,27 +1720,27 @@ - + - + - + - + - + @@ -1783,7 +1765,7 @@ - + @@ -1807,17 +1789,17 @@ - + - + - + @@ -1825,14 +1807,14 @@ - + - + @@ -1844,13 +1826,13 @@ - + - + - + @@ -1869,7 +1851,7 @@ - + @@ -1895,7 +1877,7 @@ - + @@ -1908,11 +1890,11 @@ - + - + @@ -1958,7 +1940,7 @@ - + @@ -1968,7 +1950,7 @@ - + @@ -1986,13 +1968,13 @@ - + - + @@ -2008,7 +1990,7 @@ - + @@ -2018,11 +2000,11 @@ - + - + @@ -2043,7 +2025,7 @@ - + @@ -2067,7 +2049,7 @@ - + @@ -2168,7 +2150,7 @@ - + @@ -2176,8 +2158,8 @@ - - + + @@ -2199,7 +2181,7 @@ - + @@ -2233,7 +2215,7 @@ - + @@ -2242,7 +2224,7 @@ - + @@ -2344,7 +2326,7 @@ - + @@ -2443,9 +2425,9 @@ - - - + + + @@ -2475,14 +2457,16 @@ - - + + + + @@ -2515,8 +2499,8 @@ - - + + @@ -2526,7 +2510,7 @@ - + @@ -2535,13 +2519,13 @@ - + - + @@ -2568,7 +2552,7 @@ - + @@ -2627,11 +2611,11 @@ - + - + @@ -2645,7 +2629,7 @@ - + @@ -2655,19 +2639,27 @@ - + - + - + - + + + + + + + + + @@ -2683,14 +2675,8 @@ - - - - - - - + @@ -2766,8 +2752,8 @@ - - + + @@ -2782,7 +2768,7 @@ - + @@ -2794,7 +2780,7 @@ - + @@ -2803,7 +2789,7 @@ - + @@ -2851,7 +2837,7 @@ - + @@ -2870,7 +2856,7 @@ - + @@ -2883,7 +2869,7 @@ - + @@ -2898,10 +2884,10 @@ - + - + @@ -2909,9 +2895,9 @@ - - - + + + @@ -2952,7 +2938,7 @@ - + @@ -2995,11 +2981,11 @@ - + - + @@ -3008,7 +2994,7 @@ - + @@ -3024,7 +3010,7 @@ - + @@ -3062,8 +3048,8 @@ - - + + @@ -3091,16 +3077,16 @@ - + - + - - - + + + @@ -3115,8 +3101,8 @@ - - + + @@ -3128,8 +3114,8 @@ - - + + @@ -3144,8 +3130,8 @@ - - + + @@ -3159,19 +3145,19 @@ - + - - - + + + - + @@ -3198,7 +3184,7 @@ - + @@ -3278,7 +3264,7 @@ - + @@ -3391,11 +3377,11 @@ - + - + @@ -3413,7 +3399,7 @@ - + @@ -3462,7 +3448,7 @@ - + @@ -3494,18 +3480,18 @@ - + - + - + @@ -3528,8 +3514,8 @@ - - + + @@ -3540,7 +3526,7 @@ - + @@ -3613,7 +3599,7 @@ - + @@ -3918,10 +3904,10 @@ - - - - + + + + @@ -4054,7 +4040,7 @@ - + @@ -4075,7 +4061,7 @@ - + @@ -4086,7 +4072,7 @@ - + @@ -4107,7 +4093,7 @@ - + @@ -4121,7 +4107,7 @@ - + @@ -4129,8 +4115,8 @@ - - + + @@ -4175,14 +4161,14 @@ - + - + @@ -4219,7 +4205,7 @@ - + @@ -4238,7 +4224,7 @@ - + @@ -4363,7 +4349,7 @@ - + @@ -4501,8 +4487,10 @@ - + + + @@ -4511,7 +4499,7 @@ - + @@ -4542,17 +4530,27 @@ + + + + + + + + + + @@ -4572,7 +4570,7 @@ - + @@ -4580,7 +4578,7 @@ - + @@ -4589,8 +4587,8 @@ - - + + @@ -4645,7 +4643,7 @@ - + @@ -4665,17 +4663,25 @@ - + - + + - - - - - - + + + + + + + + + + + + + @@ -4737,8 +4743,8 @@ - - + + @@ -4748,14 +4754,14 @@ - + - - + + @@ -4873,7 +4879,7 @@ - + @@ -4896,7 +4902,7 @@ - + @@ -4921,11 +4927,11 @@ - + - + @@ -4959,11 +4965,11 @@ - + - + @@ -5029,7 +5035,7 @@ - + @@ -5060,9 +5066,9 @@ - + - + @@ -5080,13 +5086,13 @@ - + - - - + + + @@ -5104,8 +5110,8 @@ - - + + @@ -5113,8 +5119,8 @@ - - + + @@ -5122,10 +5128,10 @@ - - + + - + @@ -5139,10 +5145,10 @@ - - + + - + @@ -5150,8 +5156,8 @@ - - + + @@ -5168,7 +5174,7 @@ - + @@ -5193,7 +5199,7 @@ - + @@ -5281,7 +5287,7 @@ - + @@ -5315,13 +5321,13 @@ - + - - + + @@ -5389,25 +5395,25 @@ - + - + - + - + @@ -5437,7 +5443,7 @@ - + @@ -5499,7 +5505,7 @@ - + @@ -5517,7 +5523,7 @@ - + @@ -5566,7 +5572,7 @@ - + @@ -5582,7 +5588,7 @@ - + @@ -5590,11 +5596,11 @@ - + - - - + + + @@ -5620,6 +5626,11 @@ + + + + + @@ -5651,7 +5662,7 @@ - + @@ -5692,35 +5703,35 @@ - + - + - - - + + + - + - + - + @@ -5737,21 +5748,21 @@ - - - + + + - + - - + + @@ -5771,7 +5782,7 @@ - + @@ -5788,12 +5799,12 @@ - + - + @@ -5803,7 +5814,7 @@ - + @@ -5859,15 +5870,15 @@ - + - + - + @@ -5881,8 +5892,8 @@ - - + + @@ -5895,9 +5906,9 @@ - + - + @@ -5905,7 +5916,7 @@ - + @@ -5915,14 +5926,14 @@ - - + + - + - + @@ -5949,13 +5960,13 @@ - + - - - - + + + + @@ -5981,9 +5992,9 @@ - - - + + + @@ -6013,9 +6024,9 @@ - - - + + + @@ -6024,7 +6035,7 @@ - + @@ -6068,7 +6079,7 @@ - + @@ -6080,7 +6091,7 @@ - + @@ -6090,7 +6101,7 @@ - + @@ -6133,7 +6144,7 @@ - + @@ -6160,9 +6171,9 @@ - + - + @@ -6178,7 +6189,7 @@ - + @@ -6186,18 +6197,18 @@ - + - + - + @@ -6226,7 +6237,7 @@ - + @@ -6250,7 +6261,7 @@ - + @@ -6319,7 +6330,7 @@ - + @@ -6365,17 +6376,17 @@ - + - + - - + + @@ -6388,8 +6399,8 @@ - - + + @@ -6398,10 +6409,10 @@ - + - + @@ -6416,21 +6427,21 @@ - + - + - + - + @@ -6490,8 +6501,8 @@ - - + + @@ -6503,7 +6514,7 @@ - + @@ -6518,7 +6529,7 @@ - + @@ -6530,7 +6541,7 @@ - + @@ -6539,7 +6550,7 @@ - + @@ -6548,7 +6559,7 @@ - + @@ -6559,9 +6570,9 @@ - + - + @@ -6572,12 +6583,12 @@ - + - - + + @@ -6586,19 +6597,19 @@ - + - + - + - + - + @@ -6611,9 +6622,9 @@ - - - + + + @@ -6626,14 +6637,14 @@ - + - - + + @@ -6645,7 +6656,7 @@ - + @@ -6654,7 +6665,7 @@ - + @@ -6664,13 +6675,13 @@ - + - + @@ -6751,7 +6762,7 @@ - + @@ -6803,7 +6814,7 @@ - + @@ -6833,7 +6844,7 @@ - + @@ -6957,7 +6968,7 @@ - + @@ -6973,22 +6984,22 @@ - + - + - + - + @@ -7007,7 +7018,7 @@ - + @@ -7016,7 +7027,7 @@ - + @@ -7035,7 +7046,7 @@ - + @@ -7047,7 +7058,7 @@ - + @@ -7068,7 +7079,12 @@ - + + + + + + @@ -7087,7 +7103,7 @@ - + @@ -7104,7 +7120,7 @@ - + @@ -7113,7 +7129,7 @@ - + @@ -7146,7 +7162,7 @@ - + @@ -7174,8 +7190,8 @@ - - + + @@ -7202,13 +7218,13 @@ - + - - - + + + @@ -7247,7 +7263,7 @@ - + @@ -7260,19 +7276,19 @@ - + - + - - + + - + @@ -7310,7 +7326,7 @@ - + @@ -7319,7 +7335,7 @@ - + @@ -7327,16 +7343,16 @@ - + - + - + - - + + @@ -7351,17 +7367,17 @@ - + - - - - + + + + @@ -7377,7 +7393,7 @@ - + @@ -7399,11 +7415,11 @@ - + - + @@ -7421,12 +7437,12 @@ - - + + - + @@ -7439,11 +7455,11 @@ - + - + - + @@ -7458,12 +7474,12 @@ - + - + @@ -7506,11 +7522,11 @@ - + - + @@ -7533,7 +7549,7 @@ - + @@ -7544,12 +7560,45 @@ - - + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -7660,9 +7709,10 @@ - + - + + @@ -7737,9 +7787,9 @@ - + - + @@ -7771,7 +7821,7 @@ - + @@ -7840,13 +7890,13 @@ - + - + diff --git a/tools_layouts/reg_access_hca_layouts.c b/tools_layouts/reg_access_hca_layouts.c index 5e8a5f6e..121ccb64 100644 --- a/tools_layouts/reg_access_hca_layouts.c +++ b/tools_layouts/reg_access_hca_layouts.c @@ -1385,8 +1385,12 @@ void reg_access_hca_mgir_hardware_info_pack(const struct reg_access_hca_mgir_har adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->hw_dev_id); offset = 144; adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->manufacturing_base_mac_47_32); + offset = 128; + adb2c_push_bits_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->module_base); offset = 160; adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->manufacturing_base_mac_31_0); + offset = 192; + adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->associated_module_id_31_0); offset = 224; adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->uptime); } @@ -1409,8 +1413,12 @@ void reg_access_hca_mgir_hardware_info_unpack(struct reg_access_hca_mgir_hardwar ptr_struct->hw_dev_id = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); offset = 144; ptr_struct->manufacturing_base_mac_47_32 = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); + offset = 128; + ptr_struct->module_base = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 4); offset = 160; ptr_struct->manufacturing_base_mac_31_0 = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); + offset = 192; + ptr_struct->associated_module_id_31_0 = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); offset = 224; ptr_struct->uptime = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); } @@ -1435,8 +1443,12 @@ void reg_access_hca_mgir_hardware_info_print(const struct reg_access_hca_mgir_ha adb2c_add_indentation(fd, indent_level); fprintf(fd, "manufacturing_base_mac_47_32 : " UH_FMT "\n", ptr_struct->manufacturing_base_mac_47_32); adb2c_add_indentation(fd, indent_level); + fprintf(fd, "module_base : " UH_FMT "\n", ptr_struct->module_base); + adb2c_add_indentation(fd, indent_level); fprintf(fd, "manufacturing_base_mac_31_0 : " U32H_FMT "\n", ptr_struct->manufacturing_base_mac_31_0); adb2c_add_indentation(fd, indent_level); + fprintf(fd, "associated_module_id_31_0 : " U32H_FMT "\n", ptr_struct->associated_module_id_31_0); + adb2c_add_indentation(fd, indent_level); fprintf(fd, "uptime : " U32H_FMT "\n", ptr_struct->uptime); } diff --git a/tools_layouts/reg_access_hca_layouts.h b/tools_layouts/reg_access_hca_layouts.h index df9a00f4..b4b29bab 100644 --- a/tools_layouts/reg_access_hca_layouts.h +++ b/tools_layouts/reg_access_hca_layouts.h @@ -793,6 +793,7 @@ manufacturing_base_mac of value 0 means field is not supported. */ /* 0x10.0 - 0x10.15 */ u_int16_t manufacturing_base_mac_47_32; + u_int8_t module_base; /*---------------- DWORD[5] (Offset 0x14) ----------------*/ /* Description - LSB of the "base" MAC address of the NIC that was allocate during manufacturing. The NIC derives the @@ -803,6 +804,7 @@ manufacturing_base_mac of value 0 means field is not supported. */ /* 0x14.0 - 0x14.31 */ u_int32_t manufacturing_base_mac_31_0; + u_int32_t associated_module_id_31_0; /*---------------- DWORD[7] (Offset 0x1c) ----------------*/ /* Description - Time (in secs.) since last reset0 */ /* 0x1c.0 - 0x1c.31 */ diff --git a/tools_res_mgmt/Makefile.am b/tools_res_mgmt/Makefile.am index 3eebb7bd..df47da27 100644 --- a/tools_res_mgmt/Makefile.am +++ b/tools_res_mgmt/Makefile.am @@ -36,7 +36,7 @@ USER_DIR = $(top_srcdir) MTCR_DIR = $(USER_DIR)/include/mtcr_ul AM_CPPFLAGS = -I. -I../common -I$(MTCR_DIR) -I.. -I$(USER_DIR)/${MTCR_CONF_DIR} -AM_CFLAGS = -W -Wall -g -MP -MD $(COMPILER_FPIC) +AM_CFLAGS = -W -Wall -Werror -g -MP -MD $(COMPILER_FPIC) noinst_LIBRARIES = libtools_res_mgmt.a libtools_res_mgmt_a_SOURCES = tools_res_mgmt.c tools_res_mgmt.h tools_time.c tools_time.h diff --git a/xz_utils/Makefile.am b/xz_utils/Makefile.am index 08882cc3..3a72b986 100755 --- a/xz_utils/Makefile.am +++ b/xz_utils/Makefile.am @@ -35,7 +35,7 @@ USER_DIR = .. MTCR_DIR = $(USER_DIR)/${MTCR_CONF_DIR} INCLUDES = -I. -I$(USER_DIR) -I$(MTCR_DIR) -I$(USER_DIR)/common -AM_CFLAGS = -W -g -MP -MD ${COMPILER_FPIC} +AM_CFLAGS = -W -g -MP -MD ${COMPILER_FPIC} -Werror noinst_LTLIBRARIES = libxz_utils.a libxz_utils_a_SOURCES = xz_utils.c xz_utils.h From 5c0fe4d5af576a3b73e5ad1cde3cad0e5c9519f7 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Sun, 13 Mar 2022 21:55:02 +0200 Subject: [PATCH 137/184] Add new 'i2c_secondary' flag to support user defined i2c secondary addr Description: N/A Tested OS: N/A Tested devices: N/A Tested flows: N/A Known gaps (with RM ticket): N/A Issue: 3004107 Change-Id: I9e542ef666fbbf1db83e5d7779c5276121ab990a (cherry picked from commit 25825b9ba8e6d156872ff6bc4968e3871f3f5e3e) Signed-off-by: ashargorodsk --- flint/cmd_line_parser.cpp | 20 ++++++++++++++++++++ flint/flint.cpp | 3 +++ flint/flint_params.cpp | 1 + flint/flint_params.h | 1 + 4 files changed, 25 insertions(+) diff --git a/flint/cmd_line_parser.cpp b/flint/cmd_line_parser.cpp index 5f508e8f..ae8cddaa 100644 --- a/flint/cmd_line_parser.cpp +++ b/flint/cmd_line_parser.cpp @@ -223,6 +223,7 @@ FlagMetaData::FlagMetaData() _flags.push_back(new Flag("", "activate_delay_sec", 1)); _flags.push_back(new Flag("", "downstream_device_ids", 1)); _flags.push_back(new Flag("", "download_transfer", 0)); + _flags.push_back(new Flag("", "i2c_secondary", 1)); #ifndef __WIN__ _flags.push_back(new Flag("", "private_key_label", 1)); _flags.push_back(new Flag("", "public_key_label", 1)); @@ -896,6 +897,14 @@ void Flint::initCmdParser() false, 1); + AddOptions("i2c_secondary", + ' ', + "", + "Use this flag to specify I2C secondary address", + false, + false, + 1); + #ifndef __WIN__ AddOptions("public_key_label", ' ', @@ -1252,6 +1261,17 @@ ParseStatus Flint::HandleOption(string name, string value) _flintParams.cableDeviceSize = cableDeviceSize; _flintParams.cable_device_size_specified = true; } + else if (name == "i2c_secondary") { + int i2cSecondaryAddr = 0; + if (!strToInt(value, i2cSecondaryAddr)) { + return PARSE_ERROR; + } + if (i2cSecondaryAddr < 0) { + printf("Invalid I2C secondary address.\n"); + return PARSE_ERROR; + } + _flintParams.i2cSecondaryAddr = i2cSecondaryAddr; + } else { cout << "Unknown Flag: " << name; cout << _cmdParser.GetSynopsis(); diff --git a/flint/flint.cpp b/flint/flint.cpp index a4bffbe5..e2471d66 100644 --- a/flint/flint.cpp +++ b/flint/flint.cpp @@ -259,6 +259,9 @@ FlintStatus Flint::run(int argc, char *argv[]) printf("-E- FATAL: command object not found."); return FLINT_FAILED; } + if (_flintParams.i2cSecondaryAddr != -1) { + set_force_i2c_address(_flintParams.i2cSecondaryAddr); + } _subcommands[_flintParams.cmd]->setParams(_flintParams); return _subcommands[_flintParams.cmd]->executeCommand(); } diff --git a/flint/flint_params.cpp b/flint/flint_params.cpp index 1d769313..6d1178e8 100644 --- a/flint/flint_params.cpp +++ b/flint/flint_params.cpp @@ -120,6 +120,7 @@ FlintParams::FlintParams() // if no delay specified, use minimal delay to avoid disconnection in case of activating the connect port activate_delay_sec = 1; openssl_engine_usage_specified = false; + i2cSecondaryAddr = -1; } FlintParams::~FlintParams() diff --git a/flint/flint_params.h b/flint/flint_params.h index 7717e623..1feb8649 100644 --- a/flint/flint_params.h +++ b/flint/flint_params.h @@ -202,6 +202,7 @@ class FlintParams { string openssl_engine; string openssl_key_id; bool openssl_engine_usage_specified; + int i2cSecondaryAddr; }; #endif From 97e3f2241f43062da122e604b2a035a2c2e1f646 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Mon, 21 Mar 2022 16:11:44 +0200 Subject: [PATCH 138/184] Since CX7 IB has issues with sending MAD for mgir.fw_info using mad_ifc_general_info_fw() we send regular MGIR Description: Getting mgir.fw_info via mad_ifc_general_info_fw() doesn't return correct data, so in case of CX7 we send regular reg-access MGIR Tested OS: Linux Tested devices: CX7 IB Tested flows: flint query full Known gaps (with RM ticket): N/A Issue: 3012475 Change-Id: I1986bf3758455e99d4ec635c84ce261eeb0de301 Signed-off-by: ashargorodsk --- fw_comps_mgr/fw_comps_mgr.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fw_comps_mgr/fw_comps_mgr.cpp b/fw_comps_mgr/fw_comps_mgr.cpp index 905b1cea..be0bb6c6 100644 --- a/fw_comps_mgr/fw_comps_mgr.cpp +++ b/fw_comps_mgr/fw_comps_mgr.cpp @@ -1009,6 +1009,11 @@ reg_access_status_t FwCompsMgr::getGI(mfile *mf, mgirReg *gi) if (rc) { goto cleanup; } + if (gi->hw_info.device_id == 4129) { + DPRINTF(("FwCompsMgr::getGI CX7 IB device found, sending regular MGIR\n")); + rc = reg_access_mgir(mf, REG_ACCESS_METHOD_GET, gi); + goto cleanup; + } rc = (reg_access_status_t)mad_ifc_general_info_fw(mf, &gi->fw_info); if (rc) { goto cleanup; From b5dd9da48a6b6b871b34114f1966a61151973ca1 Mon Sep 17 00:00:00 2001 From: Alon Strutsovsky Date: Thu, 24 Mar 2022 10:06:04 +0200 Subject: [PATCH 139/184] [adb_parser] remove irrelevant include Description: Tested OS: linux Tested devices: N/A Tested flows: compilation Known gaps (with RM ticket): Issue: 3014307 --- adb_parser/adb_parser.h | 1 - 1 file changed, 1 deletion(-) diff --git a/adb_parser/adb_parser.h b/adb_parser/adb_parser.h index c75f5b66..5edc4b99 100644 --- a/adb_parser/adb_parser.h +++ b/adb_parser/adb_parser.h @@ -59,7 +59,6 @@ class LogFile; #include "adb_exceptionHolder.h" #include "adb_logfile.h" #include "adb_config.h" -#include "adb_progress.h" #include "adb_instance.h" #include #include From bc978976dc8915b5bbaf3d9a7f08565d5d890923 Mon Sep 17 00:00:00 2001 From: ashargorodsk Date: Thu, 24 Mar 2022 10:44:58 +0200 Subject: [PATCH 140/184] Revert "Add new 'i2c_secondary' flag to support user defined i2c secondary addr" This reverts commit 5c0fe4d5af576a3b73e5ad1cde3cad0e5c9519f7. --- flint/cmd_line_parser.cpp | 20 -------------------- flint/flint.cpp | 3 --- flint/flint_params.cpp | 1 - flint/flint_params.h | 1 - 4 files changed, 25 deletions(-) diff --git a/flint/cmd_line_parser.cpp b/flint/cmd_line_parser.cpp index ae8cddaa..5f508e8f 100644 --- a/flint/cmd_line_parser.cpp +++ b/flint/cmd_line_parser.cpp @@ -223,7 +223,6 @@ FlagMetaData::FlagMetaData() _flags.push_back(new Flag("", "activate_delay_sec", 1)); _flags.push_back(new Flag("", "downstream_device_ids", 1)); _flags.push_back(new Flag("", "download_transfer", 0)); - _flags.push_back(new Flag("", "i2c_secondary", 1)); #ifndef __WIN__ _flags.push_back(new Flag("", "private_key_label", 1)); _flags.push_back(new Flag("", "public_key_label", 1)); @@ -897,14 +896,6 @@ void Flint::initCmdParser() false, 1); - AddOptions("i2c_secondary", - ' ', - "", - "Use this flag to specify I2C secondary address", - false, - false, - 1); - #ifndef __WIN__ AddOptions("public_key_label", ' ', @@ -1261,17 +1252,6 @@ ParseStatus Flint::HandleOption(string name, string value) _flintParams.cableDeviceSize = cableDeviceSize; _flintParams.cable_device_size_specified = true; } - else if (name == "i2c_secondary") { - int i2cSecondaryAddr = 0; - if (!strToInt(value, i2cSecondaryAddr)) { - return PARSE_ERROR; - } - if (i2cSecondaryAddr < 0) { - printf("Invalid I2C secondary address.\n"); - return PARSE_ERROR; - } - _flintParams.i2cSecondaryAddr = i2cSecondaryAddr; - } else { cout << "Unknown Flag: " << name; cout << _cmdParser.GetSynopsis(); diff --git a/flint/flint.cpp b/flint/flint.cpp index e2471d66..a4bffbe5 100644 --- a/flint/flint.cpp +++ b/flint/flint.cpp @@ -259,9 +259,6 @@ FlintStatus Flint::run(int argc, char *argv[]) printf("-E- FATAL: command object not found."); return FLINT_FAILED; } - if (_flintParams.i2cSecondaryAddr != -1) { - set_force_i2c_address(_flintParams.i2cSecondaryAddr); - } _subcommands[_flintParams.cmd]->setParams(_flintParams); return _subcommands[_flintParams.cmd]->executeCommand(); } diff --git a/flint/flint_params.cpp b/flint/flint_params.cpp index 6d1178e8..1d769313 100644 --- a/flint/flint_params.cpp +++ b/flint/flint_params.cpp @@ -120,7 +120,6 @@ FlintParams::FlintParams() // if no delay specified, use minimal delay to avoid disconnection in case of activating the connect port activate_delay_sec = 1; openssl_engine_usage_specified = false; - i2cSecondaryAddr = -1; } FlintParams::~FlintParams() diff --git a/flint/flint_params.h b/flint/flint_params.h index 1feb8649..7717e623 100644 --- a/flint/flint_params.h +++ b/flint/flint_params.h @@ -202,7 +202,6 @@ class FlintParams { string openssl_engine; string openssl_key_id; bool openssl_engine_usage_specified; - int i2cSecondaryAddr; }; #endif From b78f77d95b8fd9348463b3d09780c9d576838739 Mon Sep 17 00:00:00 2001 From: Alon Strutsovsky Date: Thu, 10 Mar 2022 08:55:36 +0200 Subject: [PATCH 141/184] fix offset/size adb fields parsing Description: Tested OS: linux Tested devices: NA Tested flows: changed offset/size fields in a rp tracked node in .adb file to all valid forms and ran the tool Known gaps (with RM ticket): Issue: 2937456 Change-Id: I4191b5050d10da4614bbe4b38743ab8d24ea57a3 Signed-off-by: Alon Strutsovsky --- resourceparse/parsers/AdbParser.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/resourceparse/parsers/AdbParser.py b/resourceparse/parsers/AdbParser.py index aba9e219..440c63eb 100755 --- a/resourceparse/parsers/AdbParser.py +++ b/resourceparse/parsers/AdbParser.py @@ -288,16 +288,15 @@ def _parse_node_size(self, size_str): """ hex_size = 0 bit_size = 0 + size_parts = size_str.split(".") - if "." in size_str: - # hex size is in bytes, multiply by 8 to convert to bits - hex_size = size_str[:size_str.index(".")] - bit_size = size_str[size_str.index(".")+1:] + if len(size_parts) == 1: + size_parts = size_parts[0], "0" + if size_parts[0] == "": + size_parts[0] = "0" - hex_size = 0 if len(hex_size) == 0 else int(hex_size, 16) * 8 - bit_size = 0 if len(size_str[size_str.index("."):]) == 0 else int(bit_size, 10) - else: - bit_size = int(size_str, 10) + hex_size = int(size_parts[0], 16) * 8 + bit_size = int(size_parts[1], 10) return hex_size+bit_size From 51d01270c73200e92df8e5cc06b422d46ab2a384 Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Thu, 24 Mar 2022 12:36:26 +0200 Subject: [PATCH 142/184] fix compilation issues from aligning with mft 4.19 --- adb_parser/Makefile.am | 2 +- cmdif/Makefile.am | 2 +- cmdparser/Makefile.am | 2 +- dev_mgt/Makefile.am | 2 +- ext_libs/json/Makefile.am | 2 +- include/mtcr_ul/mtcr.h | 4 ---- libmfa/Makefile.am | 2 +- mad_ifc/Makefile.am | 2 +- mflash/Makefile.am | 2 +- mft_utils/Makefile.am | 4 ++-- mft_utils/hsmclient/Makefile.am | 2 +- mlxarchive/Makefile.am | 2 +- mlxconfig/Makefile.am | 2 +- mlxconfig/mlxcfg_expression.cpp | 2 +- mlxconfig/mlxcfg_generic_commander.cpp | 2 +- mlxconfig/mlxcfg_view.h | 3 ++- mlxfwupdate/Makefile.am | 2 +- mlxlink/Makefile.am | 2 +- mlxlink/modules/Makefile.am | 4 ++-- mlxlink/modules/printutil/Makefile.am | 2 +- mlxreg/Makefile.am | 2 +- mlxsign_lib/Makefile.am | 2 +- mstdump/crd_lib/Makefile.am | 2 +- mtcr_ul/mtcr_ul.c | 12 ------------ mtcr_ul/mtcr_ul_com.h | 2 -- pldmlib/Makefile.am | 2 +- tools_crypto/Makefile.am | 2 +- tools_res_mgmt/Makefile.am | 2 +- xz_utils/Makefile.am | 2 +- 29 files changed, 29 insertions(+), 46 deletions(-) diff --git a/adb_parser/Makefile.am b/adb_parser/Makefile.am index 2522d778..dbe653cf 100644 --- a/adb_parser/Makefile.am +++ b/adb_parser/Makefile.am @@ -38,7 +38,7 @@ DIST_SUBDIRS = . USER_DIR = .. INCLUDES = -I$(USER_DIR) -I$(USER_DIR)/common -AM_CXXFLAGS = -Wall -W -g -MP -MD -Werror -pipe $(COMPILER_FPIC) +AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe $(COMPILER_FPIC) lib_LTLIBRARIES = libadb_parser.a diff --git a/cmdif/Makefile.am b/cmdif/Makefile.am index 26627b2d..b6c43d59 100644 --- a/cmdif/Makefile.am +++ b/cmdif/Makefile.am @@ -38,7 +38,7 @@ TOOLS_LAYOUTS_DIR = $(USER_DIR)/tools_layouts AM_CPPFLAGS = -I. -I../common -I../tools_layouts -I${MTCR_DIR} -I.. -I$(USER_DIR)/${MTCR_CONF_DIR} CCMDIF_SO = ccmdif.so -AM_CFLAGS = -W -Wall -Werror -g -MP -MD $(COMPILER_FPIC) -DCMDIF_EXPORTS +AM_CFLAGS = -W -Wall -g -MP -MD $(COMPILER_FPIC) -DCMDIF_EXPORTS CMDIF_VERSION = 1 lib_LTLIBRARIES = libcmdif.a diff --git a/cmdparser/Makefile.am b/cmdparser/Makefile.am index 76b76bab..b5367dca 100644 --- a/cmdparser/Makefile.am +++ b/cmdparser/Makefile.am @@ -34,7 +34,7 @@ INCLUDES = -I. -I../common -AM_CPPFLAGS = -W -g -MP -MD $(COMPILER_FPIC) -Werror $(COMPILER_FPIE) +AM_CPPFLAGS = -W -g -MP -MD $(COMPILER_FPIC) $(COMPILER_FPIE) noinst_LIBRARIES = libcmdparser.a diff --git a/dev_mgt/Makefile.am b/dev_mgt/Makefile.am index 22eae8ed..2283c2d1 100644 --- a/dev_mgt/Makefile.am +++ b/dev_mgt/Makefile.am @@ -34,7 +34,7 @@ USER_DIR = .. AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/common -I$(top_srcdir)/include/mtcr_ul -AM_CFLAGS = -W -Wall -Werror -g -MP -MD -Wswitch-enum $(COMPILER_FPIC) -DMTCR_EXPORT +AM_CFLAGS = -W -Wall -g -MP -MD -Wswitch-enum $(COMPILER_FPIC) -DMTCR_EXPORT lib_LTLIBRARIES = libdev_mgt.a libdev_mgt_a_SOURCES = \ diff --git a/ext_libs/json/Makefile.am b/ext_libs/json/Makefile.am index ba3ece16..05aad0a9 100644 --- a/ext_libs/json/Makefile.am +++ b/ext_libs/json/Makefile.am @@ -35,7 +35,7 @@ USER_DIR = ../ INCLUDES = -AM_CPPFLAGS = -W -Werror -g -MP -MD ${COMPILER_FPIC} +AM_CPPFLAGS = -W -g -MP -MD ${COMPILER_FPIC} noinst_LTLIBRARIES = libjson.a libjson_a_SOURCES = json_reader.cpp json_value.cpp json_batchallocator.h json_writer.cpp json/*.h diff --git a/include/mtcr_ul/mtcr.h b/include/mtcr_ul/mtcr.h index fb960545..a6b47fe5 100644 --- a/include/mtcr_ul/mtcr.h +++ b/include/mtcr_ul/mtcr.h @@ -141,8 +141,6 @@ int maccess_reg(mfile *mf, // if you dont know what you are doing then r_size_reg = w_size_reg = your_register_size int *reg_status); -int is_livefish_device(mfile *mf); - int icmd_send_command(mfile *mf, int opcode, void *data, int data_size, int skip_write); int icmd_clear_semaphore(mfile *mf); @@ -176,8 +174,6 @@ int mvpd_read4(mfile *mf, unsigned int offset, u_int8_t value[4]); int mvpd_write4(mfile *mf, unsigned int offset, u_int8_t value[4]); -int is_pci_device(mfile* mf); - MTCR_API int MWRITE4_SEMAPHORE(mfile* mf, int offset, int value); MTCR_API int MREAD4_SEMAPHORE(mfile* mf, int offset, u_int32_t* ptr); diff --git a/libmfa/Makefile.am b/libmfa/Makefile.am index 13371ba0..abfba681 100644 --- a/libmfa/Makefile.am +++ b/libmfa/Makefile.am @@ -36,7 +36,7 @@ USER_DIR = $(top_srcdir) #INCLUDES = -I. -I$(USER_DIR)/ext_libs/libtar -I$(USER_DIR)/ext_libs/libtar/listhash -I$(USER_DIR)/ext_libs/minixz INCLUDES = -I. -I$(USER_DIR)/ext_libs/minixz -I$(USER_DIR)/common -AM_CFLAGS = -MD -pipe -Wall -W -g -Werror $(COMPILER_FPIC) +AM_CFLAGS = -MD -pipe -Wall -W -g $(COMPILER_FPIC) noinst_LTLIBRARIES = libmfa.a libmfa_a_LIBADD = -L$(USER_DIR)/ext_libs/minixz -lminixz diff --git a/mad_ifc/Makefile.am b/mad_ifc/Makefile.am index 08d10429..40166c52 100644 --- a/mad_ifc/Makefile.am +++ b/mad_ifc/Makefile.am @@ -37,7 +37,7 @@ MTCR_INC_DIR = $(top_srcdir)/include/mtcr_ul INCLUDES = -I. -I.. -I$(MTCR_INC_DIR) -I../${MTCR_CONF_DIR} -I$(USER_DIR)/tools_ayouts/ -AM_CFLAGS = -W -Wall -Werror -g -MP -MD $(COMPILER_FPIC) +AM_CFLAGS = -W -Wall -g -MP -MD $(COMPILER_FPIC) noinst_LIBRARIES = libmad_ifc.a diff --git a/mflash/Makefile.am b/mflash/Makefile.am index 581fc908..d57abaf4 100644 --- a/mflash/Makefile.am +++ b/mflash/Makefile.am @@ -34,7 +34,7 @@ AM_CPPFLAGS = -I. -I$(top_srcdir)/include/mtcr_ul -I$(top_srcdir)/common -I$(top_srcdir)/tools_layouts -I$(top_srcdir)/reg_access \ -I$(top_srcdir)/cmdif -I$(top_srcdir)/tools_res_mgmt $(COMPILER_FPIC) -AM_CFLAGS = -MD -pipe -Wall -W -Werror -DMST_UL -g ${MFLASH_INBAND_FLAG} $(COMPILER_FPIC) +AM_CFLAGS = -MD -pipe -Wall -W -DMST_UL -g ${MFLASH_INBAND_FLAG} $(COMPILER_FPIC) noinst_LTLIBRARIES = libmflash.a diff --git a/mft_utils/Makefile.am b/mft_utils/Makefile.am index da5286f8..59d5b1b3 100644 --- a/mft_utils/Makefile.am +++ b/mft_utils/Makefile.am @@ -34,9 +34,9 @@ USER_DIR = $(top_srcdir) AM_CPPFLAGS = -I. -I$(USER_DIR)/common $(COMPILER_FPIC) -AM_CFLAGS = -MD -pipe -Wall -W -Werror $(COMPILER_FPIC) +AM_CFLAGS = -MD -pipe -Wall -W $(COMPILER_FPIC) -AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe -Werror $(COMPILER_FPIC) +AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe $(COMPILER_FPIC) noinst_HEADERS = mft_sig_handler.h errmsg.h diff --git a/mft_utils/hsmclient/Makefile.am b/mft_utils/hsmclient/Makefile.am index 58f17a2c..911d3564 100644 --- a/mft_utils/hsmclient/Makefile.am +++ b/mft_utils/hsmclient/Makefile.am @@ -34,7 +34,7 @@ USER_DIR = $(top_srcdir) AM_CPPFLAGS = -I$(USER_DIR)/common -Iinc -Iinc/rsa $(COMPILER_FPIC) -DUNIX -DOS_UNIX -DOS_LINUX -AM_CFLAGS = -Wall -W -g -MP -MD -pipe -Werror $(COMPILER_FPIC) +AM_CFLAGS = -Wall -W -g -MP -MD -pipe $(COMPILER_FPIC) noinst_HEADERS = diff --git a/mlxarchive/Makefile.am b/mlxarchive/Makefile.am index 9fac02f7..e5958e94 100755 --- a/mlxarchive/Makefile.am +++ b/mlxarchive/Makefile.am @@ -63,7 +63,7 @@ libmstarchive_a_SOURCES = \ mlxarchive_mfa2_package_gen.h mlxarchive_mfa2_package_gen.cpp\ mfa2_buff.h mfa2_buff.cpp -AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe -Werror $(INCLUDES) -pthread $(COMPILER_FPIE) +AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe $(INCLUDES) -pthread $(COMPILER_FPIE) AM_LDFLAGS = $(COMPILER_PIE_LINK) bin_PROGRAMS = mlxarchive diff --git a/mlxconfig/Makefile.am b/mlxconfig/Makefile.am index 53625fea..499e3bad 100755 --- a/mlxconfig/Makefile.am +++ b/mlxconfig/Makefile.am @@ -53,7 +53,7 @@ AM_CPPFLAGS = -I. -I$(USER_DIR) -I$(top_srcdir)/include/mtcr_ul -I$(MTCR_DIR) -I -I$(LAYOUTS_DIR) -I$(UTILS_DIR) -I$(DEV_MGT_DIR) -I$(CMDIF_DIR) -I$(TOOLS_RES_MGMT_DIR) $(MUPARSER_CFLAGS) $(SQLITE_CFLAGS) $(COMPILER_FPIC) -AM_CXXFLAGS = -pthread -Wall -W -g -MP -MD -pipe -Werror -Wno-deprecated-declarations $(COMPILER_FPIC) -DDATA_PATH=\"$(pkgdatadir)\" +AM_CXXFLAGS = -pthread -Wall -W -g -MP -MD -pipe -Wno-deprecated-declarations $(COMPILER_FPIC) -DDATA_PATH=\"$(pkgdatadir)\" bin_PROGRAMS = mstconfig MLXPRIVHOST_PYTHON_WRAPPER=mstprivhost bin_SCRIPTS = ${MLXPRIVHOST_PYTHON_WRAPPER} diff --git a/mlxconfig/mlxcfg_expression.cpp b/mlxconfig/mlxcfg_expression.cpp index b27245e0..7b779202 100644 --- a/mlxconfig/mlxcfg_expression.cpp +++ b/mlxconfig/mlxcfg_expression.cpp @@ -159,7 +159,7 @@ double Expression::evaluate() p.SetExpr(expression); return p.Eval(); } else { - double x; + double x = 0.0; const string varXTempName = "x"; size_t pos = expression.find(varXName); if (pos == string::npos) { diff --git a/mlxconfig/mlxcfg_generic_commander.cpp b/mlxconfig/mlxcfg_generic_commander.cpp index 98566f77..2771321c 100644 --- a/mlxconfig/mlxcfg_generic_commander.cpp +++ b/mlxconfig/mlxcfg_generic_commander.cpp @@ -1478,7 +1478,7 @@ void GenericCommander::apply(const vector& buff) vector dwBuff; FwCompsMgr fwCompsAccess(_mf); vector compsToBurn; - FwComponent::comps_ids_t compsId; + FwComponent::comps_ids_t compsId = FwComponent::comps_ids_t::COMPID_UNKNOWN;; size_t fingerPrintLength = strlen(BIN_FILE_FINGERPRINT); diff --git a/mlxconfig/mlxcfg_view.h b/mlxconfig/mlxcfg_view.h index 2e14ec20..2b3db845 100644 --- a/mlxconfig/mlxcfg_view.h +++ b/mlxconfig/mlxcfg_view.h @@ -74,7 +74,8 @@ enum TLVClass { typedef struct ParamView { ParamView() : mlxconfigName(""), description(""), type(BOOLEAN_TYPE), val(MLXCFG_UNKNOWN), - port(0), strVal(""), setVal("") {}; + port(0), strVal(""), setVal(""), + rule(""), supportedFromVersion(0) {}; std::string mlxconfigName; std::string description; enum ParamType type; diff --git a/mlxfwupdate/Makefile.am b/mlxfwupdate/Makefile.am index 38162fef..1e02216b 100755 --- a/mlxfwupdate/Makefile.am +++ b/mlxfwupdate/Makefile.am @@ -63,7 +63,7 @@ common_INCLUDES = -I$(USER_DIR)/common\ -I$(USER_DIR)/mft_utils\ -I$(USER_DIR)/dev_mgt -AM_CXXFLAGS = -g -MP -MD -Wall -W -Werror $(BOOST_CXX_IGNORES) +AM_CXXFLAGS = -g -MP -MD -Wall -W $(BOOST_CXX_IGNORES) common_SOURCEES = mlxfwmanager_common.cpp mlxfwmanager_common.h\ diff --git a/mlxlink/Makefile.am b/mlxlink/Makefile.am index 8ed6b309..7d6d9f69 100644 --- a/mlxlink/Makefile.am +++ b/mlxlink/Makefile.am @@ -47,7 +47,7 @@ MLXLINK_MODULES_DIR = $(top_srcdir)/mlxlink INCLUDES = -I. -I$(top_srcdir) -I$(MTCR_DIR) -I$(MFT_EXT_LIBS_INC_DIR) -I$(UTILS_DIR) -I$(MLXREG_DIR) -I$(MLXLINK_MODULES_DIR) -I$(MTCR_INC_DIR) $(JSON_CFLAGS) -AM_CXXFLAGS = -Wall -W -DMST_UL -g -MP -MD -pipe -Werror -std=c++11 +AM_CXXFLAGS = -Wall -W -DMST_UL -g -MP -MD -pipe -std=c++11 AM_CPPFLAGS = $(AM_CXXFLAGS) bin_PROGRAMS = mstlink diff --git a/mlxlink/modules/Makefile.am b/mlxlink/modules/Makefile.am index 0359611f..7d811b21 100644 --- a/mlxlink/modules/Makefile.am +++ b/mlxlink/modules/Makefile.am @@ -44,8 +44,8 @@ MLXLINK_MODULES_DIR = $(top_srcdir)/mlxlink INCLUDES = -I. -I$(USER_DIR) -I$(MTCR_DIR) -I$(MFT_EXT_LIBS_INC_DIR) -I$(UTILS_DIR) -I$(MLXREG_DIR) -I$(MLXLINK_MODULES_DIR) -I$(MTCR_INC_DIR) $(JSON_CFLAGS) -AM_CFLAGS = -Wall -W -g -MP -MD -pipe -Werror $(COMPILER_FPIC) -DDATA_PATH=\"$(pkgdatadir)\" -AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe -Werror -std=c++11 #$(COMPILER_FPIC) +AM_CFLAGS = -Wall -W -g -MP -MD -pipe $(COMPILER_FPIC) -DDATA_PATH=\"$(pkgdatadir)\" +AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe -std=c++11 #$(COMPILER_FPIC) lib_LTLIBRARIES = libmodules_lib.a diff --git a/mlxlink/modules/printutil/Makefile.am b/mlxlink/modules/printutil/Makefile.am index d17e09be..d47b815b 100644 --- a/mlxlink/modules/printutil/Makefile.am +++ b/mlxlink/modules/printutil/Makefile.am @@ -42,7 +42,7 @@ MLXREG_DIR = $(top_srcdir)/mlxreg INCLUDES = -I. -I$(USER_DIR) -I$(MTCR_DIR) -I$(MFT_EXT_LIBS_INC_DIR) -I$(UTILS_DIR) -I$(MLXREG_DIR) -I$(MTCR_INC_DIR) $(JSON_CFLAGS) -AM_CFLAGS = -Wall -W -g -MP -MD -pipe -Werror -std=c++11 $(COMPILER_FPIC) -DDATA_PATH=\"$(pkgdatadir)\" +AM_CFLAGS = -Wall -W -g -MP -MD -pipe -std=c++11 $(COMPILER_FPIC) -DDATA_PATH=\"$(pkgdatadir)\" lib_LTLIBRARIES = libprint_util_lib.a diff --git a/mlxreg/Makefile.am b/mlxreg/Makefile.am index 8c9f3ab2..fe58f9c7 100644 --- a/mlxreg/Makefile.am +++ b/mlxreg/Makefile.am @@ -45,7 +45,7 @@ MFT_UTILS_DIR = $(top_srcdir)/mft_utils INCLUDES = -I. -I$(USER_DIR) -I$(MTCR_DIR) -I$(MFT_EXT_LIBS_INC_DIR) -I$(UTILS_DIR) -I$(MTCR_INC_DIR) -AM_CXXFLAGS = -Wall -W -DMST_UL -g -MP -MD -pipe -Werror +AM_CXXFLAGS = -Wall -W -DMST_UL -g -MP -MD -pipe lib_LTLIBRARIES = libmstreg_lib.a diff --git a/mlxsign_lib/Makefile.am b/mlxsign_lib/Makefile.am index 45d554c6..7397cc6f 100644 --- a/mlxsign_lib/Makefile.am +++ b/mlxsign_lib/Makefile.am @@ -33,7 +33,7 @@ # Makefile.am -- Process this file with automake to produce Makefile.in USER_DIR = .. INCLUDES = -I$(USER_DIR) -I$(USER_DIR)/common -AM_CXXFLAGS = -Wall -W -Werror -g -MP -MD -pipe $(COMPILER_FPIC) +AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe $(COMPILER_FPIC) AM_CXXFLAGS += -DTOOLS_CRYPTO_KEY='$(TOOLS_CRYPTO_KEY)' -DTOOLS_CRYPTO_IV='$(TOOLS_CRYPTO_IV)' noinst_LIBRARIES = libmlxsign.a diff --git a/mstdump/crd_lib/Makefile.am b/mstdump/crd_lib/Makefile.am index be1e3c55..66146aee 100755 --- a/mstdump/crd_lib/Makefile.am +++ b/mstdump/crd_lib/Makefile.am @@ -34,7 +34,7 @@ AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include/mtcr_ul -I$(top_srcdir)/common $(COMPILER_FPIC) -AM_CFLAGS = -Wall -W -g -MP -MD -pipe -Werror -Wno-unused-function $(COMPILER_FPIC) -DMTCR_EXPORT -DMST_UL -DDATA_PATH=\"$(pkgdatadir)\" $(COMPILER_FPIC) +AM_CFLAGS = -Wall -W -g -MP -MD -pipe -Wno-unused-function $(COMPILER_FPIC) -DMTCR_EXPORT -DMST_UL -DDATA_PATH=\"$(pkgdatadir)\" $(COMPILER_FPIC) noinst_LIBRARIES = libcrdump.a diff --git a/mtcr_ul/mtcr_ul.c b/mtcr_ul/mtcr_ul.c index 00fb9558..57fbe07e 100644 --- a/mtcr_ul/mtcr_ul.c +++ b/mtcr_ul/mtcr_ul.c @@ -293,15 +293,3 @@ int mvpd_write4(mfile *mf, unsigned int offset, u_int8_t value[4]) (void)value; return ME_UNSUPPORTED_OPERATION; } - -int is_pci_device(mfile* mf) -{ - return (mf->flags & MDEVS_I2CM) - || (mf->flags & (MDEVS_CABLE | MDEVS_LINKX_CHIP)) - || (mf->flags & MDEVS_SOFTWARE); -} - -int is_livefish_device(mfile *mf) -{ - return is_livefish_device_ul(mf); -} diff --git a/mtcr_ul/mtcr_ul_com.h b/mtcr_ul/mtcr_ul_com.h index d41f6a21..e63e16af 100644 --- a/mtcr_ul/mtcr_ul_com.h +++ b/mtcr_ul/mtcr_ul_com.h @@ -148,8 +148,6 @@ int mvpd_read4_ul(mfile *mf, unsigned int offset, u_int8_t value[4]); int space_to_cap_offset(int space); -int is_livefish_device_ul(mfile *mf); - int get_dma_pages(mfile *mf, struct mtcr_page_info* page_info, int page_amount); diff --git a/pldmlib/Makefile.am b/pldmlib/Makefile.am index 16a4c266..f4a54ee8 100644 --- a/pldmlib/Makefile.am +++ b/pldmlib/Makefile.am @@ -34,7 +34,7 @@ USER_DIR = $(top_srcdir) INCLUDES = -I. -I$(USER_DIR)/common -AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe -Werror $(COMPILER_FPIC) -DPLDMLIB_EXPORT +AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe $(COMPILER_FPIC) -DPLDMLIB_EXPORT noinst_LTLIBRARIES = libpldm.a diff --git a/tools_crypto/Makefile.am b/tools_crypto/Makefile.am index f80f27eb..9c1b53f5 100644 --- a/tools_crypto/Makefile.am +++ b/tools_crypto/Makefile.am @@ -33,7 +33,7 @@ # Makefile.am -- Process this file with automake to produce Makefile.in USER_DIR = $(top_srcdir) AM_CPPFLAGS = -I$(USER_DIR) -I$(USER_DIR)/common $(COMPILER_FPIC) -AM_CFLAGS = -MD -pipe -Wall -Werror -W -DMST_UL -g $(COMPILER_FPIC) +AM_CFLAGS = -MD -pipe -Wall -W -DMST_UL -g $(COMPILER_FPIC) noinst_LIBRARIES = libtools_crypto.a libtools_crypto_a_SOURCES = tools_md5.c tools_md5.h diff --git a/tools_res_mgmt/Makefile.am b/tools_res_mgmt/Makefile.am index df47da27..6d7ba5d2 100644 --- a/tools_res_mgmt/Makefile.am +++ b/tools_res_mgmt/Makefile.am @@ -36,7 +36,7 @@ USER_DIR = $(top_srcdir) MTCR_DIR = $(USER_DIR)/include/mtcr_ul AM_CPPFLAGS = -I. -I../common -I$(MTCR_DIR) -I.. -I$(USER_DIR)/${MTCR_CONF_DIR} -AM_CFLAGS = -W -Wall -Werror -g -MP -MD $(COMPILER_FPIC) +AM_CFLAGS = -W -Wall -g -MP -MD $(COMPILER_FPIC) noinst_LIBRARIES = libtools_res_mgmt.a libtools_res_mgmt_a_SOURCES = tools_res_mgmt.c tools_res_mgmt.h tools_time.c tools_time.h diff --git a/xz_utils/Makefile.am b/xz_utils/Makefile.am index 3a72b986..71ba5047 100755 --- a/xz_utils/Makefile.am +++ b/xz_utils/Makefile.am @@ -35,7 +35,7 @@ USER_DIR = .. MTCR_DIR = $(USER_DIR)/${MTCR_CONF_DIR} INCLUDES = -I. -I$(USER_DIR) -I$(MTCR_DIR) -I$(USER_DIR)/common -AM_CFLAGS = -W -g -MP -MD ${COMPILER_FPIC} -Werror +AM_CFLAGS = -W -g -MP -MD ${COMPILER_FPIC} noinst_LTLIBRARIES = libxz_utils.a libxz_utils_a_SOURCES = xz_utils.c xz_utils.h From 22b591fe8302553d16dec04eb6c944d8e3efe829 Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Thu, 24 Mar 2022 13:42:19 +0200 Subject: [PATCH 143/184] fix compilation issue when running with old compilers --- mlxconfig/mlxcfg_generic_commander.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlxconfig/mlxcfg_generic_commander.cpp b/mlxconfig/mlxcfg_generic_commander.cpp index 2771321c..e02e6720 100644 --- a/mlxconfig/mlxcfg_generic_commander.cpp +++ b/mlxconfig/mlxcfg_generic_commander.cpp @@ -1478,7 +1478,7 @@ void GenericCommander::apply(const vector& buff) vector dwBuff; FwCompsMgr fwCompsAccess(_mf); vector compsToBurn; - FwComponent::comps_ids_t compsId = FwComponent::comps_ids_t::COMPID_UNKNOWN;; + FwComponent::comps_ids_t compsId = FwComponent::COMPID_UNKNOWN;; size_t fingerPrintLength = strlen(BIN_FILE_FINGERPRINT); From 29d6c318a1b3e89fd3f971e7883e6726a2003c8f Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Sun, 27 Mar 2022 10:25:25 +0300 Subject: [PATCH 144/184] revert changes that ware mistaknly ported into mlxarchive makefile --- mlxarchive/Makefile.am | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mlxarchive/Makefile.am b/mlxarchive/Makefile.am index e5958e94..39e02e2e 100755 --- a/mlxarchive/Makefile.am +++ b/mlxarchive/Makefile.am @@ -63,10 +63,8 @@ libmstarchive_a_SOURCES = \ mlxarchive_mfa2_package_gen.h mlxarchive_mfa2_package_gen.cpp\ mfa2_buff.h mfa2_buff.cpp -AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe $(INCLUDES) -pthread $(COMPILER_FPIE) -AM_LDFLAGS = $(COMPILER_PIE_LINK) - -bin_PROGRAMS = mlxarchive +AM_CXXFLAGS = -Wall -W -g -MP -MD -pipe $(INCLUDES) $(COMPILER_FPIC) +bin_PROGRAMS = mstarchive mstarchive_SOURCES = mlxarchive.cpp mlxarchive.h mstarchive_LDADD = libmstarchive.a\ From d1ce1acddc3e6da6bd4c6823228cb25d9be18dfb Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Sun, 27 Mar 2022 14:38:45 +0300 Subject: [PATCH 145/184] update debian/copyright and debian/changelog for 4.19 --- debian/changelog | 6 +++ debian/copyright | 120 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 107 insertions(+), 19 deletions(-) diff --git a/debian/changelog b/debian/changelog index 2e67135a..7171fc1a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +mstflint (4.19.0-1) unstable; urgency=low + + * Updated from MFT-4.19.0 + + -- Tomer Tubi Thu, 24 Mar 2022 00:00:00 +0200 + mstflint (4.18.0-1) unstable; urgency=low * Python 2.x - Python 2.x is now end-of-life and no longer supported by MFT. diff --git a/debian/copyright b/debian/copyright index 0753136a..2f31194e 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,36 +1,118 @@ -Format: http://dep.debian.net/deps/dep5 +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: mstflint -Source: +Source: https://github.com/Mellanox/mstflint Files: * -Copyright: - -License: - - +Copyright: 2002-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +License: BSD-2-clause or GPL-2 + +Files: ext_libs/iniParser/* +Copyright: 2000-2011 Nicolas Devillard. +License: public-domain or MIT + +Files: ext_libs/json/* +Copyright: 2007-2010 Baptiste Lepilleur +License: public-domain or MIT + +Files: ext_libs/muparser/* +Copyright: 2004-2007 Ingo Berg +License: Expat + 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 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. -# If you want to use GPL v2 or later for the /debian/* files use -# the following clauses, or change it to suit. Delete these two lines Files: debian/* -Copyright: 2012 Gal Sivan +Copyright: 2009 Genome Research Ltd + 2016-2019, Benjamin Drung License: GPL-2+ - This package is free software; you can redistribute it and/or modify + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. . - This package is distributed in the hope that it will be useful, + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . - You should have received a copy of the GNU General Public License - along with this program. If not, see + A copy of the full text of the license can be found on Debian systems + at '/usr/share/common-licenses/GPL-2'. + +License: BSD-2-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + . + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + . + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +License: GPL-2 + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, version 2 of the License. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + . + On Debian systems, the complete text of the GNU General Public License + version 2 can be found in the /usr/share/common-licenses/GPL-2 file. + +License: MIT + 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. . - On Debian systems, the complete text of the GNU General - Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". + 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 AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. -# Please also look if there are files or directories which have a -# different copyright/license attached and list them here. +License: public-domain + The author (Baptiste Lepilleur) explicitly disclaims copyright in all + jurisdictions which recognize such a disclaimer. In such jurisdictions, + this software is released into the Public Domain. \ No newline at end of file From e2a51f39543e7c1f386342dc7e1c9a90bd386a90 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Thu, 31 Mar 2022 13:47:12 +0300 Subject: [PATCH 146/184] [mstlink][PMCR][PMPD][PMPT] Supporting Port Control Parameters Description: -> Supporting port control params configuration -> Supporting module PRBS test mode Issue: 2989291 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_cables_commander.cpp | 192 +++++++++++++++++++ mlxlink/modules/mlxlink_cables_commander.h | 12 +- mlxlink/modules/mlxlink_commander.cpp | 51 +++-- mlxlink/modules/mlxlink_commander.h | 13 ++ mlxlink/modules/mlxlink_enums.h | 27 +++ mlxlink/modules/mlxlink_maps.cpp | 34 ++++ mlxlink/modules/mlxlink_maps.h | 2 + mlxlink/modules/mlxlink_ui.cpp | 98 +++++++++- mlxlink/modules/mlxlink_user_input.cpp | 2 + mlxlink/modules/mlxlink_user_input.h | 3 + 10 files changed, 410 insertions(+), 24 deletions(-) diff --git a/mlxlink/modules/mlxlink_cables_commander.cpp b/mlxlink/modules/mlxlink_cables_commander.cpp index 1815ac50..55a14a8b 100644 --- a/mlxlink/modules/mlxlink_cables_commander.cpp +++ b/mlxlink/modules/mlxlink_cables_commander.cpp @@ -40,6 +40,19 @@ MlxlinkCablesCommander::MlxlinkCablesCommander(Json::Value &jsonRoot): _jsonRoot _passiveQsfp = false; _localPort = 0; _numOfLanes = 0; + + _prbsRate = MODULE_PRBS_LANE_RATE_HDR; + _prbsMode = PRBS31; + _prbsInv = false; + _prbsSwap = false; + _prbsLanes = 0; + + // PMCR control fields names + // pair(UI name, PMCR field name) + _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_TX_EQ] = make_pair("TX Equalization", "tx_equ_override"); + _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_RX_EMPH] = make_pair("RX Emphasis", "rx_emp_override"); + _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_RX_POST_EMPH] = make_pair("RX Post Emphasis", "rx_post_emp_override"); + _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_RX_AMP] = make_pair("RX Amplitude", "rx_amp_override"); } MlxlinkCablesCommander::~MlxlinkCablesCommander() @@ -1431,3 +1444,182 @@ void MlxlinkCablesCommander::clearPrbsDiagInfo() updateField("cl", 1); genBuffSendRegister(ACCESS_REG_PMPD, MACCESS_REG_METHOD_GET); } + +void MlxlinkCablesCommander::showControlParams() +{ + MlxlinkCmdPrint controlParamsOutput = MlxlinkCmdPrint(); + setPrintTitle(controlParamsOutput, "Module Control Parameters", CABLE_CONTROL_PARAMETERS_SET_RX_AMP); + + resetParser(ACCESS_REG_PDDR); + updateField("local_port", _localPort); + updateField("page_select", PDDR_MODULE_INFO_PAGE); + genBuffSendRegister(ACCESS_REG_PDDR, MACCESS_REG_METHOD_GET); + + u_int32_t txEq = getFieldValue("cable_tx_equalization"); + float rxEmph = (double)getFieldValue("cable_rx_emphasis"); + u_int32_t rxPostEmph = getFieldValue("cable_rx_post_emphasis"); + u_int32_t rxAmp = getFieldValue("cable_rx_amp"); + bool isCmis = _cableIdentifier >= IDENTIFIER_SFP_DD; + + if (isCmis) { + _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_RX_EMPH].first += " (pre)"; + rxEmph /= 2; + } + char rxEmphStr[64]; + sprintf(rxEmphStr, "%.1f", rxEmph); + + string strFmt = txEq? to_string(txEq) + " dB" : "No Equalization"; + setPrintVal(controlParamsOutput, _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_TX_EQ].first, strFmt); + + strFmt = (isCmis? rxEmphStr : to_string((u_int32_t) rxEmph)) + " dB"; + strFmt = (rxEmph > 0)? strFmt: "No Equalization"; + setPrintVal(controlParamsOutput, _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_RX_EMPH].first, strFmt); + + strFmt = rxPostEmph? to_string(rxPostEmph) + " dB" : "No Equalization"; + setPrintVal(controlParamsOutput, _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_RX_POST_EMPH].first, strFmt); + + strFmt = _mlxlinkMaps->_moduleRxAmp[rxAmp]; + setPrintVal(controlParamsOutput, _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_RX_AMP].first, strFmt); + + controlParamsOutput.toJsonFormat(_jsonRoot); + cout << controlParamsOutput; +} + +u_int32_t MlxlinkCablesCommander::getPMCRValue(ControlParam paramId, const string &value) +{ + double valueToSet = 0; + bool invalidConfiguration = false; + bool isCmis = _cableIdentifier >= IDENTIFIER_SFP_DD; + bool isDecemal = false; + + try { + valueToSet = value == "NE"? 0 : stod(value); + isDecemal = (valueToSet - (int) valueToSet) > 0; + } catch (exception &exc) { + invalidConfiguration = true; + } + + if (isDecemal && !isCmis && paramId == CABLE_CONTROL_PARAMETERS_SET_RX_EMPH) { + throw MlxRegException("The requested RX Emphasis configuration value is valid for "\ + "CMIS modules only (pre-emphasis): %s", value.c_str()); + } + + if (isCmis && paramId == CABLE_CONTROL_PARAMETERS_SET_RX_EMPH) { + _modulePMCRParams[paramId].first += " (Pre)"; + valueToSet *= 2; + if ((valueToSet - (int) valueToSet) > 0) { + invalidConfiguration = true; + } + } + + if (valueToSet > MAX_SFF_CODE_VALUE || (isDecemal && paramId != CABLE_CONTROL_PARAMETERS_SET_RX_EMPH)) { + invalidConfiguration = true; + } + + if (invalidConfiguration) { + throw MlxRegException("Invalid %s configuration: %s", _modulePMCRParams[paramId].first.c_str(), value.c_str()); + } + + return (u_int32_t) valueToSet; +} + +string MlxlinkCablesCommander::getPMCRCapValueStr(u_int32_t valueCap, ControlParam paramId) +{ + string capStr = ""; + + if (paramId == CABLE_CONTROL_PARAMETERS_SET_RX_AMP) { + capStr = getStrByMask(valueCap, _mlxlinkMaps->_moduleRxAmpCap); + } else { + char tmpFmt[64]; + for (u_int32_t val = 0 ; val <= valueCap; val++) { + if (_cableIdentifier >= IDENTIFIER_SFP_DD && paramId == CABLE_CONTROL_PARAMETERS_SET_RX_EMPH) { + sprintf(tmpFmt, "%.1f,", ((float)val/2.0)); + capStr += string(tmpFmt); + } else { + sprintf(tmpFmt, "%d,", val); + capStr += string(tmpFmt); + } + } + capStr = deleteLastChar(capStr); + } + + return capStr; +} + +void MlxlinkCablesCommander::checkPMCRFieldsCap(vector> ¶ms) +{ + resetParser(ACCESS_REG_PMCR); + updateField("local_port", _localPort); + genBuffSendRegister(ACCESS_REG_PMCR, MACCESS_REG_METHOD_GET); + + // Check provided params exestance capability + string fieldName = ""; + for (auto it = params.begin(); it != params.end(); it++) { + fieldName = _modulePMCRParams[it->first].first; + if (it->first == CABLE_CONTROL_PARAMETERS_SET_RX_POST_EMPH && _cableIdentifier < IDENTIFIER_SFP_DD) { + throw MlxRegException("%s configuration is valid for CMIS only", fieldName.c_str()); + } + if (!getFieldValue( _modulePMCRParams[it->first].second + "_cap")) { + throw MlxRegException("%s configuration is not supported for the current module", fieldName.c_str()); + } + } + + // Check provided params value capability + bool invalidVal = false; + u_int32_t valueToSet = 0; + u_int32_t valueCap = 0; + string validCapStr = ""; + for (auto it = params.begin(); it != params.end(); it++) { + fieldName = _modulePMCRParams[it->first].second; + valueToSet = getPMCRValue(it->first, it->second); + valueCap = getFieldValue(fieldName + "_value_cap");;// + if (it->first == CABLE_CONTROL_PARAMETERS_SET_RX_AMP) { + valueToSet = (u_int32_t)pow(2.0, (double)valueToSet); + if (!(valueCap & valueToSet)) { + invalidVal = true; + } + } else if (valueToSet > valueCap) { + invalidVal = true; + } + if (invalidVal) { + if (valueCap ) { + validCapStr = "\nValid configuration values are ["; + validCapStr += getPMCRCapValueStr(valueCap, it->first); + validCapStr += "]"; + } + throw MlxRegException("Invalid %s configuration value: %s %s", + _modulePMCRParams[it->first].first.c_str(), it->second.c_str(), validCapStr.c_str()); + } + } +} + +void MlxlinkCablesCommander::buildPMCRRequest(ControlParam paramId, const string &value) +{ + u_int32_t valueToSet = getPMCRValue(paramId, value); + + updateField(_modulePMCRParams[paramId].second + "_cntl", 2); + updateField(_modulePMCRParams[paramId].second + "_value", (u_int32_t)valueToSet); +} + +void MlxlinkCablesCommander::setControlParams(vector> ¶ms) +{ + MlxlinkRecord::printCmdLine("Overriding Cable Control Parameters", _jsonRoot); + + checkPMCRFieldsCap(params); + + string fieldsStr = ""; + try { + resetParser(ACCESS_REG_PMCR); + updateField("local_port", _localPort); + + for (auto it = params.begin(); it != params.end(); it++) { + fieldsStr += _modulePMCRParams[it->first].first + ", "; + buildPMCRRequest(it->first, it->second); + } + + genBuffSendRegister(ACCESS_REG_PMCR, MACCESS_REG_METHOD_SET); + } catch (MlxRegException &exc) { + fieldsStr = deleteLastChar(fieldsStr, 2); + throw MlxRegException("Failed to set Control Parameters [%s]:\n%s", fieldsStr.c_str(), exc.what()); + } +} diff --git a/mlxlink/modules/mlxlink_cables_commander.h b/mlxlink/modules/mlxlink_cables_commander.h index 47de9795..26a941d9 100644 --- a/mlxlink/modules/mlxlink_cables_commander.h +++ b/mlxlink/modules/mlxlink_cables_commander.h @@ -71,6 +71,7 @@ typedef struct { #define DDM_THRES_B_SZ 2 #define CMIS_CHANNELS 8 #define CMIS_MODULE_CHANNEL 1 +#define MAX_SFF_CODE_VALUE 15 #define EXTENDED_PAGES_1_2_10_11_ADDR 2 #define EXTENDED_PAGES_1_2_10_11_MASK 0x80 @@ -120,6 +121,8 @@ class MlxlinkCablesCommander :public MlxlinkRegParser{ void showPrbsTestMode(); void showPrpsDiagInfo(); void clearPrbsDiagInfo(); + void showControlParams(); + void setControlParams(vector> ¶ms); u_int32_t _moduleNumber; u_int32_t _slotIndex; @@ -169,12 +172,10 @@ class MlxlinkCablesCommander :public MlxlinkRegParser{ bool getInvAdminFromStr(u_int32_t cap, const string &invStr); bool getSwapAdminFromStr(u_int32_t cap, const string &swapStr); u_int32_t getLanesFromStr(u_int32_t cap, const string &lanesStr); - void getPMPTConfiguration(ModuleAccess_t moduleAccess, vector &prbsPattern, vector &prbsRate, vector &prbsInv, vector &prbsSwap); void getPMPDInfo(vector &traffic, vector &errors, vector &ber, vector &snr); string getPMPDLockStatus(); - void checkAndParsePMPTCap(ModuleAccess_t moduleAccess); void preparePrbsParam(ModuleAccess_t moduleAccess); u_int32_t getPMPTStatus(ModuleAccess_t moduleAccess); @@ -182,17 +183,22 @@ class MlxlinkCablesCommander :public MlxlinkRegParser{ void enablePMPT(ModuleAccess_t moduleAccess); void disablePMPT(); + u_int32_t getPMCRValue(ControlParam paramId, const string &value); + string getPMCRCapValueStr(u_int32_t valueCap, ControlParam paramId); + void checkPMCRFieldsCap(vector> ¶ms); + void buildPMCRRequest(ControlParam paramId, const string &value); + Json::Value &_jsonRoot; vector _validPages; vector _pagesToDump; vector _cableDDMOutput; cable_ddm_q_t _cableDdm; - u_int32_t _prbsRate; u_int32_t _prbsMode; bool _prbsInv; bool _prbsSwap; u_int32_t _prbsLanes; + map> _modulePMCRParams; }; #endif /* MLXLINK_CABLES_COMMANDER_H */ diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index 8c7d4257..31a688ca 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -4439,13 +4439,10 @@ void MlxlinkCommander::showCableDump() { try { initCablesCommander(); - if (_plugged && !_mngCableUnplugged) { - vector dumpOutput = _cablesCommander->getPagesToDump(); - printOuptputVector(dumpOutput); - } + vector dumpOutput = _cablesCommander->getPagesToDump(); + printOuptputVector(dumpOutput); } catch(MlxRegException &exc) { - _allUnhandledErrors += string("Dumping EEPROM pages raised the "\ - "following exception: ") + string(exc.what()) + string("\n"); + _allUnhandledErrors += "Dumping EEPROM pages raised the following exception: " + exc.what_s() + "\n"; } } @@ -4453,13 +4450,11 @@ void MlxlinkCommander::showCableDDM() { try { initCablesCommander(); - if (_plugged && !_mngCableUnplugged) { - if (_ddmSupported) { - vector ddmOutput = _cablesCommander->getCableDDM(); - printOuptputVector(ddmOutput); - } else { - throw MlxRegException(string("Cable does not support DDM")); - } + if (_ddmSupported) { + vector ddmOutput = _cablesCommander->getCableDDM(); + printOuptputVector(ddmOutput); + } else { + throw MlxRegException("Cable does not support DDM"); } } catch(MlxRegException &exc) { _allUnhandledErrors += "Showing DDM info raised the following exception: "; @@ -4502,10 +4497,31 @@ void MlxlinkCommander::readCableEEPROM() { try { initCablesCommander(); - if (_plugged && !_mngCableUnplugged) { - MlxlinkCmdPrint bytesOutput = - _cablesCommander->readFromEEPRM(_userInput._page , _userInput._offset, _userInput._len); - cout << bytesOutput; + MlxlinkCmdPrint bytesOutput = _cablesCommander->readFromEEPRM(_userInput._page , _userInput._offset, + _userInput._len); + cout << bytesOutput; + } catch(MlxRegException &exc) { + _allUnhandledErrors += "Reading cable EEPROM raised the following exception: " + exc.what_s() + "\n"; + } +} + +void MlxlinkCommander::performControlParams() +{ + try { + initCablesCommander(); + if (_cableMediaType == ACTIVE || _cableMediaType == OPTICAL_MODULE) { + + if (_userInput.configParamsToSet.empty()) { + _cablesCommander->showControlParams(); + } else { + if (_linkUP) { + throw MlxRegException("Control parameters can be configured when the port is Disabled only\n"); + } else { + _cablesCommander->setControlParams(_userInput.configParamsToSet); + } + } + } else { + throw MlxRegException("Control parameters are valid over Active/Optical modules only"); } } catch(MlxRegException &exc) { _allUnhandledErrors += "Reading cable EEPROM raised the following exception: "; @@ -4562,7 +4578,6 @@ void MlxlinkCommander::performModulePrbsCommands() } catch(MlxRegException &exc) { _allUnhandledErrors += "Module PRBS test mode raised the following exception: "; _allUnhandledErrors += exc.what_s(); - _allUnhandledErrors += "\n"; } } diff --git a/mlxlink/modules/mlxlink_commander.h b/mlxlink/modules/mlxlink_commander.h index 8d4273ce..6b46068c 100644 --- a/mlxlink/modules/mlxlink_commander.h +++ b/mlxlink/modules/mlxlink_commander.h @@ -207,6 +207,17 @@ #define CABLE_PRBS_SHOW_DIAG_SHORT ' ' #define CABLE_PRBS_CLEAR_DIAG "clear_diagnostic_info" #define CABLE_PRBS_CLEAR_DIAG_SHORT ' ' +#define CTRL_PARAM_FLAG "control_parameters" +#define CTRL_PARAM_FLAG_SHORT ' ' +#define CTRL_PARAM_TX_EQ_FLAG "tx_equalization" +#define CTRL_PARAM_TX_EQ_FLAG_SHORT ' ' +#define CTRL_PARAM_RX_EMPH_FLAG "rx_emphasis" +#define CTRL_PARAM_RX_EMPH_FLAG_SHORT ' ' +#define CTRL_PARAM_RX_POST_EMPH_FLAG "rx_post_emphasis" +#define CTRL_PARAM_RX_POST_EMPH_FLAG_SHORT ' ' +#define CTRL_PARAM_RX_AMP_FLAG "rx_amplitude" +#define CTRL_PARAM_RX_AMP_FLAG_SHORT ' ' + #define SHOW_TX_GROUP_MAP_FLAG "show_tx_group_map" #define SHOW_TX_GROUP_MAP_FLAG_SHORT ' ' #define SET_TX_GROUP_MAP_FLAG "tx_group_map" @@ -281,6 +292,7 @@ enum OPTION_TYPE { CABLE_EEPROM_WRITE, CABLE_EEPROM_READ, CABLE_PRBS_CMDS, + CABLE_CTRL_PARM, SEND_BER_COLLECT, SEND_AMBER_COLLECT, SEND_PAOS, @@ -490,6 +502,7 @@ class MlxlinkCommander: public MlxlinkRegParser { void writeCableEEPROM(); void readCableEEPROM(); void performModulePrbsCommands();; + void performControlParams(); MlxlinkCmdPrint _toolInfoCmd; MlxlinkCmdPrint _operatingInfoCmd; diff --git a/mlxlink/modules/mlxlink_enums.h b/mlxlink/modules/mlxlink_enums.h index 183bc125..1c585178 100644 --- a/mlxlink/modules/mlxlink_enums.h +++ b/mlxlink/modules/mlxlink_enums.h @@ -1422,4 +1422,31 @@ enum PMPD_PARAM { PMPD_PARAM_LAST }; +enum PMCR_RX_AMP { + PMCR_RX_AMP_BIT0 = 0x1, + PMCR_RX_AMP_BIT1 = 0x2, + PMCR_RX_AMP_BIT2 = 0x4, + PMCR_RX_AMP_BIT3 = 0x8, + PMCR_RX_AMP_BIT4 = 0x10, + PMCR_RX_AMP_BIT5 = 0x20, + PMCR_RX_AMP_BIT6 = 0x40, + PMCR_RX_AMP_BIT7 = 0x80, + PMCR_RX_AMP_BIT8 = 0x100, + PMCR_RX_AMP_BIT9 = 0x200, + PMCR_RX_AMP_BIT10 = 0x400, + PMCR_RX_AMP_BIT11 = 0x800, + PMCR_RX_AMP_BIT12 = 0x1000, + PMCR_RX_AMP_BIT13 = 0x2000, + PMCR_RX_AMP_BIT14 = 0x4000, + PMCR_RX_AMP_BIT15 = 0x8000 +}; + +typedef enum { + CABLE_CONTROL_PARAMETERS_QUERY, + CABLE_CONTROL_PARAMETERS_SET_TX_EQ, + CABLE_CONTROL_PARAMETERS_SET_RX_EMPH, + CABLE_CONTROL_PARAMETERS_SET_RX_POST_EMPH, + CABLE_CONTROL_PARAMETERS_SET_RX_AMP +} ControlParam; + #endif /* MLXLINK_ENUMS_H */ diff --git a/mlxlink/modules/mlxlink_maps.cpp b/mlxlink/modules/mlxlink_maps.cpp index 9fa963bd..889ad0ce 100644 --- a/mlxlink/modules/mlxlink_maps.cpp +++ b/mlxlink/modules/mlxlink_maps.cpp @@ -691,6 +691,40 @@ void MlxlinkMaps::rxTxCdrCapMapping() _rxTxCdrCap[RX_TX_CDR_CAP_NO_CDR] = "No CDR"; _rxTxCdrCap[RX_TX_CDR_CAP_BUILD_IN_CDR_WITH_ON_OFF_CONTROL] = "Build-in CDR with on/off control"; _rxTxCdrCap[RX_TX_CDR_CAP_BUILD_IN_CDR_WITHOUT_ON_OFF_CONTROL] = "Build-in CDR without on/off control"; + + _moduleRxAmp[0] = "100-400 mV (P-P)"; + _moduleRxAmp[1] = "300-600 mV (P-P)"; + _moduleRxAmp[2] = "400-800 mV (P-P)"; + _moduleRxAmp[3] = "600-1200 mV (P-P)"; + _moduleRxAmp[4] = "Custom"; + _moduleRxAmp[5] = "Custom"; + _moduleRxAmp[6] = "Custom"; + _moduleRxAmp[7] = "Custom"; + _moduleRxAmp[8] = "Custom"; + _moduleRxAmp[9] = "Custom"; + _moduleRxAmp[10] = "Custom"; + _moduleRxAmp[11] = "Custom"; + _moduleRxAmp[12] = "Custom"; + _moduleRxAmp[13] = "Custom"; + _moduleRxAmp[14] = "Custom"; + _moduleRxAmp[15] = "Custom"; + + _moduleRxAmpCap[PMCR_RX_AMP_BIT0] = "0 (" + _moduleRxAmp[0] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT1] = "1 (" + _moduleRxAmp[1] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT2] = "2 (" + _moduleRxAmp[2] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT3] = "3 (" + _moduleRxAmp[3] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT4] = "4 (" + _moduleRxAmp[4] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT5] = "5 (" + _moduleRxAmp[5] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT6] = "6 (" + _moduleRxAmp[6] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT7] = "7 (" + _moduleRxAmp[7] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT8] = "8 (" + _moduleRxAmp[8] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT9] = "9 (" + _moduleRxAmp[9] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT10] = "10 (" + _moduleRxAmp[10] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT11] = "11 (" + _moduleRxAmp[11] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT12] = "12 (" + _moduleRxAmp[12] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT13] = "13 (" + _moduleRxAmp[13] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT14] = "14 (" + _moduleRxAmp[14] + ")"; + _moduleRxAmpCap[PMCR_RX_AMP_BIT15] = "15 (" + _moduleRxAmp[15] + ")"; } void MlxlinkMaps::rxPowerTypeMapping() diff --git a/mlxlink/modules/mlxlink_maps.h b/mlxlink/modules/mlxlink_maps.h index 6e20bb1f..8d83ff98 100644 --- a/mlxlink/modules/mlxlink_maps.h +++ b/mlxlink/modules/mlxlink_maps.h @@ -176,6 +176,8 @@ class MlxlinkMaps{ std::map _modulePMPDStatus; std::map _modulePrbsModeCapToStr; std::map _modulePrbsModeStrToCap; + std::map _moduleRxAmp; + std::map _moduleRxAmpCap; std::map _pepcStatus; std::map _IBSpeed2Str; std::map _EthExtSpeed2Str; diff --git a/mlxlink/modules/mlxlink_ui.cpp b/mlxlink/modules/mlxlink_ui.cpp index 500e8cab..3736e322 100644 --- a/mlxlink/modules/mlxlink_ui.cpp +++ b/mlxlink/modules/mlxlink_ui.cpp @@ -199,6 +199,65 @@ void MlxlinkUi::printSynopsisCommands() MlxlinkRecord::printFlagLine(WRITE_OFFSET_FLAG_SHORT, WRITE_OFFSET_FLAG, "offset", "Specific page offset to read/write"); + printf(IDENT); + MlxlinkRecord::printFlagLine(CABLE_PRBS_SELECT_SHORT, CABLE_PRBS_SELECT, "side", + "Module PRBS test mode side selector [MEDIA, HOST]"); + printf(IDENT2); + MlxlinkRecord::printFlagLine(CABLE_PRBS_MODE_SHORT, CABLE_PRBS_MODE, "cmd", + "Perform PRBS test mode on the Module [EN(Enable),DS(Disable)]"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_RATE_SHORT, CABLE_PRBS_GEN_RATE, "rate", + "Set PRBS generator lane rate [HDR(50G)(default),1.25G,SDR(2.5G),10.3125G,FDR(14G),EDR(25G),NDR(100G)]"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_PAT_SHORT, CABLE_PRBS_GEN_PAT, "pattern", + "Set PRBS generator pattern [PRBS31(default),PRBS23,PRBS7,PRBS11,PRBS9,PRBS13,SSPR,SSPRQ]"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_SWAP_SHORT, CABLE_PRBS_GEN_SWAP, "", + "Enable PAM4 MSB <-> LSB generator swapping (Optional)"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_INV_SHORT, CABLE_PRBS_GEN_INV, "rate", + "Enable PRBS generator inversion (Optional)"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_LANES_SHORT, CABLE_PRBS_GEN_LANES, "lanes", + "PRBS generator lanes to set (one or more lane separated by comma)[0,1,2,3,4,5,6,7] (Optional - Default all lanes)"); + + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_CH_RATE_SHORT, CABLE_PRBS_CH_RATE, "rate", + "Set PRBS checker lane rate [HDR(50G)(default),1.25G,SDR(2.5G),10.3125G,FDR(14G),EDR(25G),NDR(100G)]"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_CH_PAT_SHORT, CABLE_PRBS_CH_PAT, "pattern", + "Set PRBS checker pattern [PRBS31(default),PRBS23,PRBS7,PRBS11,PRBS9,PRBS13,SSPR,SSPRQ]"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_CH_SWAP_SHORT, CABLE_PRBS_CH_SWAP, "", + "Enable PAM4 MSB <-> LSB checker swapping (Optional)"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_CH_INV_SHORT, CABLE_PRBS_CH_INV, "", + "Enable PRBS checker inversion (Optional)"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_CH_LANES_SHORT, CABLE_PRBS_CH_LANES, "lanes", + "PRBS checker lanes to set (one or more lane separated by comma)[0,1,2,3,4,5,6,7] (Optional - Default all lanes)"); + printf(IDENT2); + MlxlinkRecord::printFlagLine(CABLE_PRBS_SHOW_DIAG_SHORT, CABLE_PRBS_SHOW_DIAG, "", + "Show PRBS diagnostic counters information"); + printf(IDENT2); + MlxlinkRecord::printFlagLine(CABLE_PRBS_CLEAR_DIAG_SHORT, CABLE_PRBS_CLEAR_DIAG, "", + "Clear PRBS diagnostic counters"); + + MlxlinkRecord::printFlagLine(CABLE_DDM_FLAG_SHORT, CTRL_PARAM_FLAG, "", "Show Module Control Parameters"); + printf(IDENT2); + MlxlinkRecord::printFlagLine(CTRL_PARAM_TX_EQ_FLAG_SHORT, CTRL_PARAM_TX_EQ_FLAG, "value", + "Set Module Tx Input Equalization in dB [NE(No Equalization),1,2,3,4,5,6,7,9,10,11,12]"); + printf(IDENT2); + MlxlinkRecord::printFlagLine(CTRL_PARAM_RX_EMPH_FLAG_SHORT, CTRL_PARAM_RX_EMPH_FLAG, "value", + "Set Module RX Output Emphasis in dB. for CMIS, pre-emphasis value will be set "\ + "[NE(No Equalization),0.5,1,1.5,2,2.5,3,3.5,4,5,6,7]"); + printf(IDENT2); + MlxlinkRecord::printFlagLine(CTRL_PARAM_RX_POST_EMPH_FLAG_SHORT, CTRL_PARAM_RX_POST_EMPH_FLAG, "value", + "Set Module Rx Post Emphasis in dB [NE(No Equalization),1,2,3,4,5,6,7]"); + printf(IDENT2); + MlxlinkRecord::printFlagLine(CTRL_PARAM_RX_AMP_FLAG_SHORT, CTRL_PARAM_RX_AMP_FLAG, "value", + "Set Module Rx Output Amplitude [0(100-400mV),1(300-600mV),2(400-800mV),3(600-1200mV)]"); + MlxlinkRecord::printFlagLine(MARGIN_SCAN_FLAG_SHORT, MARGIN_SCAN_FLAG, "", "Read the SerDes eye margins per lane"); printf(IDENT); @@ -471,11 +530,13 @@ void MlxlinkUi::validateCableParams() _mlxlinkCommander->_userInput._len >= 0 ; bool prbsParamProvided = _mlxlinkCommander->_userInput.modulePrbsParams.size(); bool cablePrbsParamProvided = _mlxlinkCommander->_userInput.isPrbsSelProvided || prbsParamProvided; + bool cableConfigParamProvided = _mlxlinkCommander->_userInput.isModuleConfigParamsProvided; + bool paramSetProvided = _mlxlinkCommander->_userInput.configParamsToSet.size(); bool cableCommandProvided = _mlxlinkCommander->_userInput._dump || _mlxlinkCommander->_userInput._write || _mlxlinkCommander->_userInput._read || _mlxlinkCommander->_userInput._ddm || - cablePrbsParamProvided; + cablePrbsParamProvided || cableConfigParamProvided; if(!_mlxlinkCommander->_userInput._cable && (cableCommandProvided || readWriteFlags)){ throw MlxRegException("\"--" CABLE_FLAG "\" flag should be specified!"); @@ -489,6 +550,10 @@ void MlxlinkUi::validateCableParams() _mlxlinkCommander->_userInput._offset == -1)) { throw MlxRegException("\"--" WRITE_PAGE_FLAG "\" and \"--" WRITE_OFFSET_FLAG "\" flags should be specified!"); } + if (!cableConfigParamProvided && paramSetProvided) { + throw MlxRegException("--" CTRL_PARAM_FLAG " should be specified!"); + } + if (readWriteFlags) { if (!_mlxlinkCommander->_userInput._write && !_mlxlinkCommander->_userInput._read) { throw MlxRegException("Read or Write flag should be specified!"); @@ -683,6 +748,12 @@ void MlxlinkUi::initCmdParser() AddOptions(CABLE_PRBS_SHOW_DIAG, CABLE_PRBS_SHOW_DIAG_SHORT, "", ""); AddOptions(CABLE_PRBS_CLEAR_DIAG, CABLE_PRBS_CLEAR_DIAG_SHORT, "", ""); + AddOptions(CTRL_PARAM_FLAG, CTRL_PARAM_FLAG_SHORT, "", "Cable Control Params"); + AddOptions(CTRL_PARAM_TX_EQ_FLAG, CTRL_PARAM_TX_EQ_FLAG_SHORT, "value", "TX Eq override"); + AddOptions(CTRL_PARAM_RX_EMPH_FLAG, CTRL_PARAM_RX_EMPH_FLAG_SHORT, "value", "RX Emp override"); + AddOptions(CTRL_PARAM_RX_POST_EMPH_FLAG, CTRL_PARAM_RX_POST_EMPH_FLAG_SHORT, "value", "RX post emp"); + AddOptions(CTRL_PARAM_RX_AMP_FLAG, CTRL_PARAM_RX_AMP_FLAG_SHORT, "value", "RX Amp"); + AddOptions(SHOW_TX_GROUP_MAP_FLAG, SHOW_TX_GROUP_MAP_FLAG_SHORT, "group_num", "Display all label ports mapped to group "); AddOptions(SET_TX_GROUP_MAP_FLAG, SET_TX_GROUP_MAP_FLAG_SHORT, "group_num", "Map ports to group "); AddOptions(TX_GROUP_PORTS_FLAG, TX_GROUP_PORTS_FLAG_SHORT, "ports", "Ports to be mapped [1,2,3,4,..,128]"); @@ -844,6 +915,10 @@ void MlxlinkUi::commandsCaller() PRINT_LOG(_mlxlinkCommander->_mlxlinkLogger,"-> Cable PRBS Commands"); _mlxlinkCommander->performModulePrbsCommands(); break; + case CABLE_CTRL_PARM: + PRINT_LOG(_mlxlinkCommander->_mlxlinkLogger,"-> Cable Control Parameter"); + _mlxlinkCommander-> performControlParams(); + break; default: break; } @@ -1166,7 +1241,6 @@ ParseStatus MlxlinkUi::HandleOption(string name, string value) _mlxlinkCommander->_userInput.isPrbsGenProvided = true; return PARSE_OK; } else if (name == CABLE_PRBS_GEN_LANES) { - _mlxlinkCommander->checkStrLength(value); _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_GEN_LANES] = value; _mlxlinkCommander->_userInput.isPrbsGenProvided = true; return PARSE_OK; @@ -1189,7 +1263,6 @@ ParseStatus MlxlinkUi::HandleOption(string name, string value) _mlxlinkCommander->_userInput.isPrbsChProvided = true; return PARSE_OK; } else if (name == CABLE_PRBS_CH_LANES) { - _mlxlinkCommander->checkStrLength(value); _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_CH_LANES] = value; _mlxlinkCommander->_userInput.isPrbsChProvided = true; return PARSE_OK; @@ -1202,6 +1275,25 @@ ParseStatus MlxlinkUi::HandleOption(string name, string value) _mlxlinkCommander->checkStrLength(value); _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_CLEAR_DIAG] = value; _mlxlinkCommander->_userInput.isPrbsClearDiagProvided = true; + } else if (name == CTRL_PARAM_FLAG) { + addCmd(CABLE_CTRL_PARM); + _mlxlinkCommander->_userInput.isModuleConfigParamsProvided = true; + return PARSE_OK; + } else if (name == CTRL_PARAM_TX_EQ_FLAG) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.configParamsToSet.push_back(make_pair(CABLE_CONTROL_PARAMETERS_SET_TX_EQ, value)); + return PARSE_OK; + } else if (name == CTRL_PARAM_RX_EMPH_FLAG) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.configParamsToSet.push_back(make_pair(CABLE_CONTROL_PARAMETERS_SET_RX_EMPH, value)); + return PARSE_OK; + } else if (name == CTRL_PARAM_RX_POST_EMPH_FLAG) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.configParamsToSet.push_back(make_pair(CABLE_CONTROL_PARAMETERS_SET_RX_POST_EMPH, value)); + return PARSE_OK; + } else if (name == CTRL_PARAM_RX_AMP_FLAG) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.configParamsToSet.push_back(make_pair(CABLE_CONTROL_PARAMETERS_SET_RX_AMP, value)); return PARSE_OK; } return PARSE_ERROR; diff --git a/mlxlink/modules/mlxlink_user_input.cpp b/mlxlink/modules/mlxlink_user_input.cpp index f131376d..1bc2a754 100644 --- a/mlxlink/modules/mlxlink_user_input.cpp +++ b/mlxlink/modules/mlxlink_user_input.cpp @@ -127,4 +127,6 @@ UserInput::UserInput() isPrbsShowDiagProvided = false; isPrbsClearDiagProvided = false; prbsModuleAccess = MODULE_PRBS_ACCESS_BOTH; + + isModuleConfigParamsProvided = false; } diff --git a/mlxlink/modules/mlxlink_user_input.h b/mlxlink/modules/mlxlink_user_input.h index ae17cba4..3282dfd1 100644 --- a/mlxlink/modules/mlxlink_user_input.h +++ b/mlxlink/modules/mlxlink_user_input.h @@ -145,6 +145,9 @@ class UserInput { bool isPrbsShowDiagProvided; bool isPrbsClearDiagProvided; ModuleAccess_t prbsModuleAccess; + + bool isModuleConfigParamsProvided; + vector> configParamsToSet; }; #endif /* MLXLINK_USER_INPUT_H */ From 1f16171e4e97e5815f6e4ec52d77da28facbe131 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Thu, 31 Mar 2022 15:13:51 +0300 Subject: [PATCH 147/184] [mstlink] Fixing invalid fec error message Description: Fixing invalid fec error message Tested OS: Linux64 Tested devices: CX6 Tested flows: mlxlink fec configuration Known gaps (with RM ticket): NA Issue: 2920878 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_commander.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index 8c7d4257..8f0d8759 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -3973,7 +3973,7 @@ void MlxlinkCommander::checkPplmCap() string supportedFec = fecMaskToUserInputStr(fecCap); string validFecs = fecMaskToUserInputStr(BIT_MASK_ALL_DWORD); string errorMsg = _userInput._pplmFec + " FEC is not supported in " + uiSpeed + " speed, "; - if (validFecs.find(_userInput._pplmFec) == string::npos) { + if (validFecs.find(_userInput._pplmFec) == string::npos || _userInput._pplmFec.size() <= 1) { errorMsg = _userInput._pplmFec + " FEC configuration is not valid, "; } if (supportedFec.empty()) { From a6b852433db669f6bf584a07031349bb6669f044 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Thu, 31 Mar 2022 15:29:59 +0300 Subject: [PATCH 148/184] [mstlink] Extending local port range scan for Switches Description: Extending local port range scan for Switches Issue: 2992340 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_commander.cpp | 153 ++++++++----------------- mlxlink/modules/mlxlink_commander.h | 2 +- mlxlink/modules/mlxlink_enums.h | 4 +- mlxlink/modules/mlxlink_reg_parser.cpp | 11 ++ 4 files changed, 61 insertions(+), 109 deletions(-) diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index 8c7d4257..d8763dc9 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -250,27 +250,35 @@ void MlxlinkCommander::checkValidFW() } } -void MlxlinkCommander::getProductTechnology() +u_int32_t MlxlinkCommander::getTechnologyFromMGIR() { + u_int32_t technology = 0; + try { - if (_devID == DeviceConnectX7 || _devID == DeviceQuantum2) { - resetParser(ACCESS_REG_MGIR); + resetParser(ACCESS_REG_MGIR); + genBuffSendRegister(ACCESS_REG_MGIR, MACCESS_REG_METHOD_GET); - genBuffSendRegister(ACCESS_REG_MGIR, MACCESS_REG_METHOD_GET); + technology = getFieldValue("technology"); + } catch (MlxRegException &exc) {} - _productTechnology = getFieldValue("technology"); - } else { - resetParser(ACCESS_REG_SLRG); - updateField("local_port", _localPort); - updateField("pnat", (_userInput._pcie) ? PNAT_PCIE : PNAT_LOCAL); + return technology; +} - genBuffSendRegister(ACCESS_REG_SLRG, MACCESS_REG_METHOD_GET); +void MlxlinkCommander::getProductTechnology() +{ + try { + resetParser(ACCESS_REG_SLRG); + updateField("local_port", _localPort); + updateField("pnat", (_userInput._pcie) ? PNAT_PCIE : PNAT_LOCAL); - _productTechnology = getVersion(getFieldValue("version")); - } + genBuffSendRegister(ACCESS_REG_SLRG, MACCESS_REG_METHOD_GET); + + _productTechnology = getVersion(getFieldValue("version")); } catch (MlxRegException &exc) { - throw MlxRegException( - "Unable to get product technology: %s", exc.what_s().c_str()); + _productTechnology = getTechnologyFromMGIR(); + if (!_productTechnology) { + throw MlxRegException("Unable to get product technology: %s", exc.what_s().c_str()); + } } } @@ -342,8 +350,7 @@ void MlxlinkCommander::checkAllPortsStatus() } if (_devID == DeviceSpectrum) { string regName = "PMLP"; - for (u_int32_t localPort = 1; localPort <= maxLocalPort(); - localPort++) { + for (u_int32_t localPort = 1; localPort <= maxLocalPort(); localPort++) { resetParser(regName); updateField("local_port", localPort); @@ -358,8 +365,7 @@ void MlxlinkCommander::checkAllPortsStatus() throw MlxRegException("FW Version " + _fwVersion + " is not supported. Please update FW."); } else if (dm_dev_is_ib_switch(_devID)) { string regName = "PLIB"; - for (u_int32_t localPort = 1; localPort <= maxLocalPort(); - localPort++) { + for (u_int32_t localPort = 1; localPort <= maxLocalPort(); localPort++) { resetParser(regName); updateField("local_port", localPort); @@ -619,98 +625,33 @@ void MlxlinkCommander::labelToHCALocalPort() void MlxlinkCommander::labelToSpectLocalPort() { - string regName; - u_int32_t spectWithGearBox = 0; - if (_devID >= DeviceSpectrum2) { - regName = "MGPIR"; - resetParser(regName); - genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); - spectWithGearBox = getFieldValue("num_of_devices"); + if (_userInput._secondSplitProvided) { + throw MlxRegException("Invalid port number!"); } - regName = "PMLP"; - string splitStr = to_string( - (_userInput._splitPort > 0) ? - _userInput._splitPort - 1 : _userInput._splitPort); - int splitAdjustment = 0; - for (u_int32_t localPort = 1; localPort <= maxLocalPort(); localPort++) { - resetParser(regName); - updateField("local_port", localPort); - genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); - _numOfLanes = getFieldValue("width"); - if (_numOfLanes == 0) { - continue; + if (_userInput._splitProvided) { + if (_userInput._splitPort == 1) { + throw MlxRegException("Invalid split number!"); } - splitAdjustment = 0; - if ((getFieldValue("module_0") + 1) == _userInput._labelPort) { - checkWidthSplit(); - if (_userInput._splitProvided) { - if (_devID == DeviceSpectrum3 || _devID == DeviceSpectrum4 || - (_devID != DeviceSpectrum && !spectWithGearBox)) { - if (_devID == DeviceSpectrum2 && _numOfLanes == 4) { - splitAdjustment = 2; - } else if (!((_devID == DeviceSpectrum2 && _numOfLanes == 2) || - ((_devID == DeviceSpectrum3 || _devID == DeviceSpectrum4) && _numOfLanes == 4))) { - splitAdjustment = -1; - } - } else if (_devID == DeviceSpectrum2 && spectWithGearBox){ - if (_numOfLanes != 4) { - splitAdjustment = -1; - } - } else { - splitAdjustment = -1; - } - _localPort = localPort + _userInput._splitPort + splitAdjustment; - } else { - _localPort = localPort; - } - updateField("local_port", _localPort); - genBuffSendRegister(regName, MACCESS_REG_METHOD_GET); - if ((getFieldValue("module_0") + 1) == _userInput._labelPort) { - return; - } + if (_userInput._splitPort > MAX_ETH_SW_SPLIT) { + throw MlxRegException("Port %d/%d does not exist!", _userInput._labelPort, _userInput._splitPort); } } - throw MlxRegException( - "Failed to find Local Port, please provide valid Port Number"); -} -void MlxlinkCommander::checkWidthSplit() -{ - if (_userInput._splitProvided) { - if (_userInput._secondSplitProvided) { - throw MlxRegException("Invalid port number!"); - } - switch (_userInput._splitPort) { - case 1: - throw MlxRegException("Invalid split number!"); - case 2: - if (_numOfLanes < 4 || - ((_devID == DeviceSpectrum3 || _devID == DeviceSpectrum4) && _numOfLanes == 4)) { - return; - } - break; - case 3: - case 4: - if (_numOfLanes == 1 || - ((_devID == DeviceSpectrum3 || _devID == DeviceSpectrum4) && _numOfLanes == 2)) { - return; - } - break; - case 5: - case 6: - case 7: - case 8: - if ((_devID == DeviceSpectrum3 || _devID == DeviceSpectrum4) && _numOfLanes == 1) { - return; - } - break; - default: - break; + for (u_int32_t localPort = 1; localPort <= maxLocalPort(); localPort++) { + try { + resetParser(ACCESS_REG_PLLP); + updateField("local_port", localPort); + genBuffSendRegister(ACCESS_REG_PLLP, MACCESS_REG_METHOD_GET); + } catch(...) {} // access register will fail if local port does not exist + if ((getFieldValue("label_port") == _userInput._labelPort) && + (getFieldValue("split_num") == (_userInput._splitPort - 1))) { + _localPort = localPort; + break; } - throw MlxRegException( - "Port " + to_string(_userInput._labelPort) + "/" - + to_string(_userInput._splitPort) - + " does not exist!"); + } + + if (!_localPort) { + throw MlxRegException("Failed to find Local Port, please provide valid Port Number"); } } @@ -1182,7 +1123,7 @@ void MlxlinkCommander::handleLabelPorts(std::vector labelPortsStr, bool bool spect2WithGb = (_devID == DeviceSpectrum2)? isSpect2WithGb() : false; for (vector::iterator it = labelPortsStr.begin(); it != labelPortsStr.end(); ++it) { strToUint32((char *)(*it).c_str(), labelPort); - if (_devID == DeviceSpectrum2 || _devID == DeviceSpectrum3) { + if (_devID == DeviceSpectrum2 || _devID == DeviceSpectrum3 || _devID == DeviceSpectrum4) { localPort = handleEthLocalPort(labelPort, spect2WithGb); } else if (_devID == DeviceQuantum || _devID == DeviceQuantum2) { localPort = handleIBLocalPort(labelPort, ibSplitReady); @@ -2598,8 +2539,6 @@ void MlxlinkCommander::initValidDPNList() } } } - //break should be removed after fixing pcie index validity from the fw (for switches only) - //bug 1775657 if (!_isHCA) { break; } diff --git a/mlxlink/modules/mlxlink_commander.h b/mlxlink/modules/mlxlink_commander.h index 8d4273ce..4d0d6bed 100644 --- a/mlxlink/modules/mlxlink_commander.h +++ b/mlxlink/modules/mlxlink_commander.h @@ -353,6 +353,7 @@ class MlxlinkCommander: public MlxlinkRegParser { void checkLocalPortDPNMapping(u_int32_t localPort); int getLocalPortFromMPIR(DPN& dpn); void checkValidFW(); + u_int32_t getTechnologyFromMGIR(); void getProductTechnology(); bool checkPortStatus(u_int32_t localPort); void checkAllPortsStatus(); @@ -365,7 +366,6 @@ class MlxlinkCommander: public MlxlinkRegParser { void labelToIBLocalPort(); bool isIBSplitReady(); u_int32_t calculatePanelPort(bool ibSplitReady); - void checkWidthSplit(); u_int32_t maxLocalPort(); void checkStrLength(const string &str); void getActualNumOfLanes(u_int32_t linkSpeedActive, bool extended); diff --git a/mlxlink/modules/mlxlink_enums.h b/mlxlink/modules/mlxlink_enums.h index 183bc125..4d876764 100644 --- a/mlxlink/modules/mlxlink_enums.h +++ b/mlxlink/modules/mlxlink_enums.h @@ -377,7 +377,9 @@ #define MAX_LOCAL_PORT_QUANTUM 82 #define MAX_LOCAL_PORT_QUANTUM2 130 #define MAX_LOCAL_PORT_SPECTRUM2 128 -#define MAX_LOCAL_PORT_SPECTRUM4 256 +#define MAX_LOCAL_PORT_SPECTRUM4 258 + +#define MAX_ETH_SW_SPLIT 8 #define DBN_TO_LOCAL_PORT_BASE 60 diff --git a/mlxlink/modules/mlxlink_reg_parser.cpp b/mlxlink/modules/mlxlink_reg_parser.cpp index 937cd65d..7f7bfc1e 100644 --- a/mlxlink/modules/mlxlink_reg_parser.cpp +++ b/mlxlink/modules/mlxlink_reg_parser.cpp @@ -94,7 +94,18 @@ void MlxlinkRegParser::updateField(string field_name, u_int32_t value) { DEBUG_LOG(_mlxlinkLogger, "%-15s: %-30s\tVALUE: 0x%08x (%d)\n", "UPDATE_FIELD", (char*)field_name.c_str(),value,value); + RegAccessParser::updateField(field_name, value); + + if (field_name == "local_port") { + try { + // the full value for local port is 10 bits, [0:7] in local_port, and [8:9] in lp_msb + // this should be provided for all access registers which have local_port field index + updateField("lp_msb", ((value >> 8) & 0x3)); + } catch(...) { + // If the lp_msb does not exists on some access register, no need to fail the command + } + } } string MlxlinkRegParser::getFieldStr(const string &field) From 25dda7de305099ad407a0e661ed049912dd5493d Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Thu, 31 Mar 2022 15:46:32 +0300 Subject: [PATCH 149/184] [mstlink][AMBER] Updating amber collection to 2.00 Description: Updating amber collection to version 2.00 Issue: 2989296 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_amBER_collector.cpp | 26 +++++++++++++++++---- mlxlink/modules/mlxlink_amBER_collector.h | 1 + mlxlink/modules/mlxlink_enums.h | 5 ++-- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/mlxlink/modules/mlxlink_amBER_collector.cpp b/mlxlink/modules/mlxlink_amBER_collector.cpp index 617809dd..88f79f32 100644 --- a/mlxlink/modules/mlxlink_amBER_collector.cpp +++ b/mlxlink/modules/mlxlink_amBER_collector.cpp @@ -251,12 +251,12 @@ void MlxlinkAmBerCollector::init() } _sheetsList[AMBER_SHEET_GENERAL] = FIELDS_COUNT{4, 4, 4}; - _sheetsList[AMBER_SHEET_INDEXES] = FIELDS_COUNT{2, 2, 3}; + _sheetsList[AMBER_SHEET_INDEXES] = FIELDS_COUNT{2, 2, 4}; _sheetsList[AMBER_SHEET_LINK_STATUS] = FIELDS_COUNT{48, 72, 6}; _sheetsList[AMBER_SHEET_MODULE_STATUS] = FIELDS_COUNT{111, 111, 0}; _sheetsList[AMBER_SHEET_SYSTEM] = FIELDS_COUNT{16, 19, 11}; _sheetsList[AMBER_SHEET_SERDES_16NM] = FIELDS_COUNT{736, 736, 0}; - _sheetsList[AMBER_SHEET_SERDES_7NM] = FIELDS_COUNT{283, 283, 57}; + _sheetsList[AMBER_SHEET_SERDES_7NM] = FIELDS_COUNT{323, 323, 65}; _sheetsList[AMBER_SHEET_PORT_COUNTERS] = FIELDS_COUNT{35, 0, 35}; _sheetsList[AMBER_SHEET_TROUBLESHOOTING] = FIELDS_COUNT{2, 2, 0}; _sheetsList[AMBER_SHEET_PHY_OPERATION_INFO] = FIELDS_COUNT{18, 18, 15}; @@ -264,6 +264,7 @@ void MlxlinkAmBerCollector::init() _sheetsList[AMBER_SHEET_LINK_DOWN_INFO] = FIELDS_COUNT{5, 5, 0}; _sheetsList[AMBER_SHEET_TEST_MODE_INFO] = FIELDS_COUNT{144, 144, 0}; _sheetsList[AMBER_SHEET_TEST_MODE_MODULE_INFO] = FIELDS_COUNT{110, 110, 0}; + _sheetsList[AMBER_SHEET_PHY_DEBUG_INFO] = FIELDS_COUNT{4, 4, 0}; } catch (...) { } } @@ -347,7 +348,7 @@ vector MlxlinkAmBerCollector::getIndexesInfo() { vector fields; - if (_isPortIB) { + if (_isPortIB || _isPortPCIE) { fields.push_back(AmberField("Node_GUID", getNodeGUID())); } @@ -545,7 +546,6 @@ vector MlxlinkAmBerCollector::getPhyOperationInfo() fields.push_back(AmberField("pci_power",getFieldStr("pci_power") + 'W')); fields.push_back(AmberField("device_status",pcieDeviceStatusStr(getFieldValue("device_status")))); } - } catch (const std::exception &exc) { throw MlxRegException( "Failed to get Phy Operation status: %s", exc.what()); @@ -1746,6 +1746,19 @@ vector MlxlinkAmBerCollector::getTestModeModuleInfo() return fields; } +vector MlxlinkAmBerCollector::getPhyDebugInfo() +{ + vector fields; + + try { + } catch (const std::exception &exc) { + throw MlxRegException( + "Failed to get Phy Debug information: %s", exc.what()); + } + + return fields; +} + void MlxlinkAmBerCollector::groupValidIf(bool condition) { if (condition) { @@ -1821,6 +1834,11 @@ vector MlxlinkAmBerCollector::collectSheet(AMBER_SHEET sheet) fields = getTestModeModuleInfo(); } break; + case AMBER_SHEET_PHY_DEBUG_INFO: + if (!_inPRBSMode) { + fields = getPhyDebugInfo(); + } + break; } return fields; } diff --git a/mlxlink/modules/mlxlink_amBER_collector.h b/mlxlink/modules/mlxlink_amBER_collector.h index 7583b755..2bba6db7 100644 --- a/mlxlink/modules/mlxlink_amBER_collector.h +++ b/mlxlink/modules/mlxlink_amBER_collector.h @@ -68,6 +68,7 @@ class MlxlinkAmBerCollector :public MlxlinkRegParser { virtual vector getLinkDownInfo(); virtual vector getTestModeInfo(); virtual vector getTestModeModuleInfo(); + virtual vector getPhyDebugInfo(); void getPpcntBer(u_int32_t portType, vector &fields); bool isGBValid(); diff --git a/mlxlink/modules/mlxlink_enums.h b/mlxlink/modules/mlxlink_enums.h index 183bc125..ff0eb4c4 100644 --- a/mlxlink/modules/mlxlink_enums.h +++ b/mlxlink/modules/mlxlink_enums.h @@ -34,7 +34,7 @@ #define MLXLINK_ENUMS_H // Common definitions -#define AMBER_VERSION "1.80" +#define AMBER_VERSION "2.00" #define ACCESS_REG_PGUID "PGUID" #define ACCESS_REG_SPZR "SPZR" @@ -1360,7 +1360,8 @@ enum AMBER_SHEET { AMBER_SHEET_LINK_UP_INFO = 11, AMBER_SHEET_LINK_DOWN_INFO = 12, AMBER_SHEET_TEST_MODE_INFO = 13, - AMBER_SHEET_TEST_MODE_MODULE_INFO = 14 + AMBER_SHEET_TEST_MODE_MODULE_INFO = 14, + AMBER_SHEET_PHY_DEBUG_INFO = 15 }; typedef enum MODULE_PRBS { From 7fd10f99c5af7bccf2e59211c2e2813709111982 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Thu, 31 Mar 2022 16:01:30 +0300 Subject: [PATCH 150/184] [mstlink] Removing the PCIE device status field Description: Removing the PCIE device status field Issue: 3019369 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_amBER_collector.cpp | 2 +- mlxlink/modules/mlxlink_commander.cpp | 2 -- mlxlink/modules/mlxlink_enums.h | 9 ++++++ mlxlink/modules/mlxlink_maps.cpp | 7 +++++ mlxlink/modules/mlxlink_maps.h | 1 + mlxlink/modules/mlxlink_utils.cpp | 35 --------------------- mlxlink/modules/mlxlink_utils.h | 1 - 7 files changed, 18 insertions(+), 39 deletions(-) diff --git a/mlxlink/modules/mlxlink_amBER_collector.cpp b/mlxlink/modules/mlxlink_amBER_collector.cpp index 617809dd..d546e4c6 100644 --- a/mlxlink/modules/mlxlink_amBER_collector.cpp +++ b/mlxlink/modules/mlxlink_amBER_collector.cpp @@ -543,7 +543,7 @@ vector MlxlinkAmBerCollector::getPhyOperationInfo() fields.push_back(AmberField("port_type",_mlxlinkMaps->_portType[getFieldValue("port_type")])); fields.push_back(AmberField("link_peer_max_speed",_mlxlinkMaps->_linkPeerMaxSpeed[getFieldValue("link_peer_max_speed")])); fields.push_back(AmberField("pci_power",getFieldStr("pci_power") + 'W')); - fields.push_back(AmberField("device_status",pcieDeviceStatusStr(getFieldValue("device_status")))); + fields.push_back(AmberField("device_status",getStrByMask(getFieldValue("device_status"), _mlxlinkMaps->_pcieDevStatus))); } } catch (const std::exception &exc) { diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index 8c7d4257..84e09d89 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -2681,8 +2681,6 @@ void MlxlinkCommander::showPcieState(DPN& dpn) pcieSpeedStr(getFieldValue("link_speed_active"))+ linkSpeedEnabled); setPrintVal(_pcieInfoCmd, "Link Width Active (Enabled)", to_string(_numOfLanesPcie) + "X" + linkWidthEnabled); - setPrintVal(_pcieInfoCmd, "Device Status", - getFieldValue("device_status") ? pcieDeviceStatusStr(getFieldValue("device_status")):"N/A"); cout << _pcieInfoCmd; } diff --git a/mlxlink/modules/mlxlink_enums.h b/mlxlink/modules/mlxlink_enums.h index 183bc125..ec7413f8 100644 --- a/mlxlink/modules/mlxlink_enums.h +++ b/mlxlink/modules/mlxlink_enums.h @@ -1363,6 +1363,15 @@ enum AMBER_SHEET { AMBER_SHEET_TEST_MODE_MODULE_INFO = 14 }; +enum PCIE_DEVICE_STATUS { + PCIE_DEVICE_STATUS_CORRECTABLE_ERROR = 0x1, + PCIE_DEVICE_STATUS_NON_FATAL_ERROR = 0x2, + PCIE_DEVICE_STATUS_FATAL_ERROR = 0x4, + PCIE_DEVICE_STATUS_UNSUP_REQ = 0x8, + PCIE_DEVICE_STATUS_AUX = 0x10, + PCIE_DEVICE_STATUS_TRANSACTION_PEN = 0x20 +}; + typedef enum MODULE_PRBS { MODULE_PRBS_SELECT, MODULE_PRBS_MODE, diff --git a/mlxlink/modules/mlxlink_maps.cpp b/mlxlink/modules/mlxlink_maps.cpp index 9fa963bd..5a3d5086 100644 --- a/mlxlink/modules/mlxlink_maps.cpp +++ b/mlxlink/modules/mlxlink_maps.cpp @@ -108,6 +108,13 @@ void MlxlinkMaps::initPortStateMapping() _networkPorts["GEARBOX_HOST"] = NETWORK_PORT_TYPE_NEAR; _networkPorts["INTERNAL_IC_LR"] = NETWORK_PORT_TYPE_IC_LR; _networkPorts["GEARBOX_LINE"] = NETWORK_PORT_TYPE_FAR; + + _pcieDevStatus[PCIE_DEVICE_STATUS_CORRECTABLE_ERROR] = "Correctable Error detected"; + _pcieDevStatus[PCIE_DEVICE_STATUS_NON_FATAL_ERROR] = "Non-Fatal Error detected"; + _pcieDevStatus[PCIE_DEVICE_STATUS_FATAL_ERROR] = "Fatal Error detected"; + _pcieDevStatus[PCIE_DEVICE_STATUS_UNSUP_REQ] = "Unsupported Request detected"; + _pcieDevStatus[PCIE_DEVICE_STATUS_AUX] = "AUX power"; + _pcieDevStatus[PCIE_DEVICE_STATUS_TRANSACTION_PEN] = "Transaction Pending"; } void MlxlinkMaps::phyHstFsmHdrStateMapping() diff --git a/mlxlink/modules/mlxlink_maps.h b/mlxlink/modules/mlxlink_maps.h index 6e20bb1f..5696fb6c 100644 --- a/mlxlink/modules/mlxlink_maps.h +++ b/mlxlink/modules/mlxlink_maps.h @@ -253,6 +253,7 @@ class MlxlinkMaps{ std::map _aeState; std::map _pllUglState; std::map _slrgFomMode; + std::map _pcieDevStatus; string _sltpHeader; string _berCollectTitle; diff --git a/mlxlink/modules/mlxlink_utils.cpp b/mlxlink/modules/mlxlink_utils.cpp index 27906986..eecb26a6 100644 --- a/mlxlink/modules/mlxlink_utils.cpp +++ b/mlxlink/modules/mlxlink_utils.cpp @@ -1142,41 +1142,6 @@ string getRxTxCDRState(u_int32_t state, u_int32_t numOfLanes) return deleteLastChar(stateMask); } -string pcieDeviceStatusStr(u_int32_t deviceStatus) -{ - string deviceStatusStr, comma; - if (!deviceStatus) { - return "N/A"; - } - if ((deviceStatus >> 0) & 0x1) { - deviceStatusStr += "Correctable Error detected"; - comma=", "; - } - if ((deviceStatus >> 1) & 0x1) { - deviceStatusStr += comma + "Non-Fatal Error detected"; - comma=", "; - } - if ((deviceStatus >> 2) & 0x1) { - deviceStatusStr += comma + "Fatal Error detected" + comma; - comma=", "; - } - if ((deviceStatus >> 3) & 0x1) { - deviceStatusStr += comma + "Unsupported Request detected"; - comma=", "; - } - if ((deviceStatus >> 4) & 0x1) { - deviceStatusStr += comma + "AUX power"; - comma=", "; - } - if ((deviceStatus >> 5) & 0x1) { - deviceStatusStr += comma + "Transaction Pending"; - } - if ("" != deviceStatusStr) { - deviceStatusStr += "."; - } - return deviceStatusStr; -} - double mw_to_dbm(double x) { return 10 * log10(x); diff --git a/mlxlink/modules/mlxlink_utils.h b/mlxlink/modules/mlxlink_utils.h index b55040de..47dce86a 100644 --- a/mlxlink/modules/mlxlink_utils.h +++ b/mlxlink/modules/mlxlink_utils.h @@ -126,7 +126,6 @@ string toUpperCase(string &str); string toLowerCase(string &str); string getCableMedia(u_int32_t cableType); string pcieSpeedStr(u_int32_t linkSpeedActive); -string pcieDeviceStatusStr(u_int32_t deviceStatus); double mw_to_dbm(double x); int readSigned(u_int32_t value, u_int32_t fieldSize); int readSignedByte(u_int32_t value); From 89d5be1b8eaadc3b5cf63e98a4a2ae58e0803441 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Thu, 31 Mar 2022 16:15:31 +0300 Subject: [PATCH 151/184] [mstlink] Fixing error message Description: Fixing error message for invalid port Issue: 3019487 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_commander.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index 8c7d4257..14d13e89 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -530,16 +530,16 @@ void MlxlinkCommander::labeltoDSlocalPort() } if (!isLocalPortValid) { - throw MlxRegException("Invalid port number"); - } - - resetParser(ACCESS_REG_MDDQ); - updateField("query_type", 1); - updateField("slot_index", lineCard); - genBuffSendRegister(ACCESS_REG_MDDQ, MACCESS_REG_METHOD_GET); + resetParser(ACCESS_REG_MDDQ); + updateField("query_type", 1); + updateField("slot_index", lineCard); + genBuffSendRegister(ACCESS_REG_MDDQ, MACCESS_REG_METHOD_GET); - if (getFieldValue("lc_ready") != 1) { - throw MlxRegException("Invalid port number, Line card %d is not ready", lineCard); + if (getFieldValue("lc_ready") != 1) { + throw MlxRegException("Invalid port number, Line card %d is not ready", lineCard); + } else { + throw MlxRegException("Invalid port number"); + } } } From f3da113ef0428283e2882177dc654451aab5a979 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Thu, 31 Mar 2022 16:20:11 +0300 Subject: [PATCH 152/184] [mstprivhost] Supporting new flow for the tool Description: Supporting new flow for the tool to provide more isolation between hosts in multi-host environments Issue: 2989293 Signed-off-by: Mustafa Dalloul --- mlxconfig/mstprivhost.py | 595 +++++++++++++++++++++------------------ 1 file changed, 323 insertions(+), 272 deletions(-) diff --git a/mlxconfig/mstprivhost.py b/mlxconfig/mstprivhost.py index f23cd724..011f5abe 100644 --- a/mlxconfig/mstprivhost.py +++ b/mlxconfig/mstprivhost.py @@ -1,34 +1,34 @@ -#copyright (c) 2004-2021 Mellanox Technologies LTD. All rights reserved. +# Copyright (c) 2004-2021 Mellanox Technologies LTD. All rights reserved. # Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# -# This software is available to you under a choice of one of two -# licenses. You may choose to be licensed under the terms of the GNU -# General Public License (GPL) Version 2, available from the file -# COPYING in the main directory of this source tree, or the -# OpenIB.org BSD license below: -# -# Redistribution and use in source and binary forms, with or -# without modification, are permitted provided that the following -# conditions are met: -# -# - Redistributions of source code must retain the above -# copyright notice, this list of conditions and the following -# disclaimer. -# -# - Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials -# provided with the distribution. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -#-- +# +# This software is available to you under a choice of one of two +# licenses. You may choose to be licensed under the terms of the GNU +# General Public License (GPL) Version 2, available from the file +# COPYING in the main directory of this source tree, or the +# OpenIB.org BSD license below: +# +# Redistribution and use in source and binary forms, with or +# without modification, are permitted provided that the following +# conditions are met: +# +# - Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. +# +# - Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 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 AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# -- from __future__ import print_function @@ -38,44 +38,52 @@ import subprocess import sys import tempfile -import math +import re import tools_version PROG = 'mstprivhost' TOOL_VERSION = "1.0.0" +DEV_HELP = """\ +Perform operation for a specified mst device. +""" + CMD_HELP = """\ -restrict: Set all external hosts restricted except the one that called the command. -privilege: Set all external hosts privileged except the one that called the command. -query: From external host: query the status of the host - From Embedded Arm CPU: query if all external hosts are restricted. +restrict: Set external hosts restricted. +privilege: Set external hosts privileged. +query: From external HOST: query the status of the host + From Embedded ARM CPU: query the status of all external hosts. +""" + +QUERY_FULL_HELP = """\ +Run with query command for high verbosity level - valid from embedded ARM CPU only. """ DESCRIPTION = """\ restrict or privilege host Note: New configurations takes effect immediately. Note: privileged host - host has all supported privileges. - restricted host - host is not allowed to modify global - per port/parameters or access other hosts parametersis. - + restricted host - host capabilities are limited. """ DISABLE_RSHIM_HELP = """\ -When TRUE, the host does not have an RSHIM function -to access the embedded CPU registers -Reboot is required to apply changes +When TRUE, the host does not have an RSHIM function to access the embedded CPU +registers (power cycle is required to apply changes) """ DISABLE_TRACER_HELP = """\ When TRUE, the host will not be allowed to own the Tracer +(requires FW reset to be applied) """ DISABLE_COUNTER_RD_HELP = """\ When TRUE, the host will not be allowed to read Physical port counters +(requires FW reset to be applied) """ DISABLE_PORT_OWNER_HELP = """\ When TRUE, the host will not be allowed to be Port Owner +(requires FW reset to be applied) """ @@ -100,22 +108,24 @@ class PrivilegeException(Exception): class PrivilegeMgr(object): - CONFIG_CMD_LINE = "mstconfig -d %s -f %s --yes set_raw" - QUERY_CMD_LINE = "mstconfig -d %s -f %s --yes get_raw" - QUERY_MMHI_CMD_LINE = "mstreg -d %s --reg_name MMHI --get" - QUERY_SECURE_FW_STATUS = "mlxreg -d %s --reg_name MGIR --get" - QUERY_HW_ACCESS_STATUS = "flint -d %s -ocr hw query" - - MMHI_HOST_EN_FIELD = "host_en" - MMHI_HOST_NUMBER_FIELD = "host_number" - MCRA_CMD_LINE = "mstmcra %s 0xf0014.0:16" + CONFIG_CMD_LINE = "mlxconfig -d %s -f %s --yes set_raw" + QUERY_CMD_LINE = "mlxconfig -d %s -f %s --yes get_raw" + QUERY_MMHI_CMD_LINE = "mlxreg -d %s --reg_name MMHI --get" + QUERY_NVGC_CMD_LINE = "mlxreg -d %s --reg_name MNVGC --get" + QUERY_HW_ACCESS_STATUS = "mlxreg -d %s --reg_id 0x402d --reg_len 0x4 --get" + MCRA_CMD_LINE = "mcra %s 0xf0014.0:16" + TLV_DATA_RE = re.compile(r'Data\s*:\s*(.+)\n', flags=re.MULTILINE) + BLUE_FIELD_DEV_ID = 0x211 BLUE_FIELD2_DEV_ID = 0x214 BLUE_FIELD3_DEV_ID = 0x21c - TITLE = "MLNX_RAW_TLV_FILE\n" - TLV_HEADER = "0x03000204" - CRC = "0x00000000" + PRIVILEGE = 0 + RESTRICT = 1 + + TITLE = "MLNX_RAW_TLV_FILE" + TLV_HEADER = 0x03000204 + CRC = 0x0 TLV_TYPE = 0x07000083 LIMITED = 0x10000000 @@ -124,41 +134,22 @@ class PrivilegeMgr(object): DISABLE_TRACER = 0x04 DISABLE_RSHIM = 0x08 - def __init__(self, device, query, privilege, disable_rshim, disable_tracer, - disable_counter_rd, disable_port_owner): - self._privilege = privilege + def __init__(self, device, query, q_full, level, port_functions): + self._requested_level = level self._device = device self._query = query - self._disable_rshim = disable_rshim - self._disable_tracer = disable_tracer - self._disable_counter_rd = disable_counter_rd - self._disable_port_owner = disable_port_owner - self._file_p = tempfile.NamedTemporaryFile( - suffix='.raw', prefix="nvconfig_setting_") + self._q_full = q_full + self._port_function = port_functions + self._file_p = tempfile.NamedTemporaryFile(suffix='.raw', + prefix="nvconfig_setting_") self._file_name = self._file_p.name self._nv_host_priv_conf = 0 self._current_conf = None - self._current_host, self._total_hosts = self.getNumberOfHosts() - self._isMH = self._total_hosts > 1 - self._isARM = self._current_host == self._total_hosts; + self._current_host = 0 + self._total_hosts = 1 + self._isMH = False + self._isARM = False self._disable_out = False - self._oldFw = False # Fw has invalid MMHi register - - def updateTlvFile(self, host_number, print_info_msgs=False): - tlv_type = self.TLV_TYPE - tlv_type |= (host_number << 18) - raw_bytes = "%s 0x%08x %s" % (self.TLV_HEADER, tlv_type, self.CRC) - if print_info_msgs: - info("preparing configuration file...", end='', hide=self._disable_out) - # use encode for compatibility with python 2/3 - self._file_p.seek(0) - self._file_p.write(self.TITLE.encode()) - nv_host_priv_conf_str = '0x%08x' % self._nv_host_priv_conf - conf_bytes = " ".join((raw_bytes, nv_host_priv_conf_str)) - self._file_p.write(conf_bytes.encode()) - self._file_p.flush() - if print_info_msgs: - self.printCmd("Done!") @staticmethod def _exec_cmd(cmd): @@ -170,12 +161,78 @@ def _exec_cmd(cmd): shell=True) stdout, stderr = p.communicate() exit_code = p.wait() - return (exit_code, stdout, stderr) + def run(self): + self.validate() + self.initParams() + if self._query: + return self.getConf() + else: + return self.setConf() + + def initParams(self): + priv_other_host = False + cmd = self.QUERY_NVGC_CMD_LINE % (self._device) + exit_code, stdout, stderr = self._exec_cmd(cmd) + if not exit_code: + priv_other_host = self.getFieldFromReg( + stdout, "priv_nv_other_host") + if priv_other_host == 1: + self._isARM = True + cmd = self.QUERY_MMHI_CMD_LINE % (self._device) + exit_code, stdout, stderr = self._exec_cmd(cmd) + if not exit_code: + self._current_host = self.getFieldFromReg( + stdout, "host_number") + host_en_mask = self.getFieldFromReg(stdout, "host_en") + # don't count the ARM index (last bit) + self._total_hosts = bin(host_en_mask).count("1") - 1 + self._isMH = self._total_hosts > 1 + elif self.isHwAccessDisabled(): + raise PrivilegeException("Secure host enabled on the device") + else: + raise PrivilegeException(stderr.replace("-E- ", "")) + + def isHwAccessDisabled(self): + hw_disable = 0 + cmd = self.QUERY_HW_ACCESS_STATUS % (self._device) + exit_code, stdout, _ = self._exec_cmd(cmd) + if not exit_code: + hw_disable = int(stdout.splitlines()[4].split('|')[1], 16) & 0xff + return hw_disable + + def getFieldFromReg(self, reg_output, field_name): + field_value = None + for line in reg_output.splitlines(): + if line.startswith(field_name): + field_value = int(line.split()[2], 16) + break + return field_value + + def updateTlvFile(self, host_index, disable_info=False): + self.TLV_TYPE |= (host_index << 18) + raw_bytes = "%s\n0x%08x 0x%08x 0x%08x" % (self.TITLE, + self.TLV_HEADER, + self.TLV_TYPE, + self.CRC) + if not disable_info: + info( + "preparing configuration file...", + end='', + hide=self._disable_out) + # use encode for compatibility with python 2/3 + priv_conf_data = '0x%08x' % self._nv_host_priv_conf + conf_bytes = " ".join((raw_bytes, priv_conf_data)) + self._file_p.seek(0) + self._file_p.write(conf_bytes.encode()) + self._file_p.flush() + if not disable_info: + self.printCmd("Done!") + def printTitle(self, title): print(title) - print("-"*len(title)) + print("-" * len(title)) def printCmd(self, msg): if not self._disable_out: @@ -183,184 +240,143 @@ def printCmd(self, msg): def printConfOut(self, priv_conf): self.printTitle("Host configurations") + if self._q_full: + self.printCmd( + "%-30s: %s" % + ("host index", priv_conf["host index"])) self.printCmd("%-30s: %s" % ("level", priv_conf["level"])) self.printTitle("\nPort functions status:") - self.printCmd("%-30s: %s" % ("disable_rshim", priv_conf["disable_rshim"])) - self.printCmd("%-30s: %s" % ("disable_tracer", priv_conf["disable_tracer"])) - self.printCmd("%-30s: %s" % ("disable_port_owner", priv_conf["disable_port_owner"])) - self.printCmd("%-30s: %s\n" % ("disable_counter_rd", priv_conf["disable_counter_rd"])) + self.printCmd( + "%-30s: %s" % + ("disable_rshim", priv_conf["disable_rshim"])) + self.printCmd( + "%-30s: %s" % + ("disable_tracer", priv_conf["disable_tracer"])) + self.printCmd( + "%-30s: %s" % + ("disable_port_owner", + priv_conf["disable_port_owner"])) + self.printCmd( + "%-30s: %s\n" % + ("disable_counter_rd", + priv_conf["disable_counter_rd"])) def getConf(self): - current_conf = self.queryConf(self._current_host) - if current_conf is not None and current_conf["level"] == "PRIVILEGED": + if self._q_full and not self._isARM: + raise PrivilegeException( + "Query command with verbose option is not valid from host") + current_conf = self.queryConf(0) + # Get all host's status if (full) flag provided + if self._q_full: for host in range(self._total_hosts): - current_conf = self.queryConf(host) - if current_conf["level"] == "PRIVILEGED": - break - if current_conf is not None: - self.printConfOut(current_conf) - return current_conf is None - - def isHwAccessDisabled(self): - cmd = self.QUERY_HW_ACCESS_STATUS % (self._device) - exit_code, _, _ = self._exec_cmd(cmd) - return exit_code != 0 - - def isFWSecured(self): - is_secured = False - cmd = self.QUERY_SECURE_FW_STATUS % (self._device) - exit_code, stdout, stderr = self._exec_cmd(cmd) - mgir_out = stdout.split("\n") - if exit_code == 0: - for line in mgir_out: - if line.startswith("secured"): - is_secured = int(line.split()[2], 16) - return is_secured - - def getNumberOfHosts(self): - total_host_num = 1 - host_number = 0 - cmd = self.QUERY_MMHI_CMD_LINE % (self._device) - exit_code, stdout, stderr = self._exec_cmd(cmd) - if exit_code != 0: - self._oldFw = True - return host_number, total_host_num - - # parsing MMHI from mlxreg out - mmhi_out_lines = stdout.split("\n") - for line in mmhi_out_lines: - if line.startswith(self.MMHI_HOST_NUMBER_FIELD): - host_number = int(line.split()[2], 16) - elif line.startswith(self.MMHI_HOST_EN_FIELD): - host_en = int(line.split()[2], 16) - if host_en == 0xff and host_number == 0: - self._oldFw = True - return host_number, total_host_num - total_host_num = bin(host_en).count("1") - if total_host_num > 16: - raise Exception("Failed to parse MMHI register") - return host_number, total_host_num - - def queryConf(self, host_number, hide=False): - current_conf = {"host_number":host_number, "level": "PRIVILEGED", - "disable_rshim": "FALSE", "disable_tracer": "FALSE", - "disable_port_owner": "FALSE", "disable_counter_rd": "FALSE"} + # Skip the first host info, it's already collected above in + # current_conf + if host == 0: + continue + host_conf = self.queryConf(host) + current_conf.update({"host index": "%-13s%-13s" % + (current_conf["host index"], host_conf["host index"])}) + current_conf.update({"level": "%-13s%-13s" % + (current_conf["level"], host_conf["level"])}) + current_conf.update({"disable_rshim": "%-13s%-13s" % + (current_conf["disable_rshim"], host_conf["disable_rshim"])}) + current_conf.update({"disable_tracer": "%-13s%-13s" % + (current_conf["disable_tracer"], host_conf["disable_tracer"])}) + current_conf.update( + { + "disable_port_owner": "%-13s%-13s" % + (current_conf["disable_port_owner"], + host_conf["disable_port_owner"])}) + current_conf.update( + { + "disable_counter_rd": "%-13s%-13s" % + (current_conf["disable_counter_rd"], + host_conf["disable_counter_rd"])}) + self.printConfOut(current_conf) + # If no configuration queried, then return error code 1 + return len(current_conf) == 0 + + def parseRawTlv(self, host_index, data, valid): + tlv = {"host index": host_index, "level": "PRIVILEGED", + "disable_rshim": "FALSE", "disable_tracer": "FALSE", + "disable_port_owner": "FALSE", "disable_counter_rd": "FALSE"} + if valid: + conf_data = int(self.TLV_DATA_RE.search(data).group(1), 16) + level = int((conf_data & self.LIMITED) / self.LIMITED) + disable_rshim = (conf_data & self.DISABLE_RSHIM) / \ + self.DISABLE_RSHIM + disable_tracer = ( + conf_data & self.DISABLE_TRACER) / self.DISABLE_TRACER + disable_port_owner = ( + conf_data & self.DISABLE_PORT_OWNER) / self.DISABLE_PORT_OWNER + disable_counter_rd = ( + conf_data & self.DISABLE_COUNTER_RD) / self.DISABLE_COUNTER_RD + tlv.update({"level": ("PRIVILEGED", "RESTRICTED")[level]}) + tlv.update({"disable_rshim": str(bool(disable_rshim)).upper()}) + tlv.update({"disable_tracer": str(bool(disable_tracer)).upper()}) + tlv.update({"disable_port_owner": str( + bool(disable_port_owner)).upper()}) + tlv.update({"disable_counter_rd": str( + bool(disable_counter_rd)).upper()}) + return tlv + + def queryConf(self, host_index): # UpdateTlvFile file for query - self.updateTlvFile(host_number) + self.updateTlvFile(host_index, True) # Run query operation cmd = self.QUERY_CMD_LINE % (self._device, self._file_name) - exit_code, stdout, stderr = self._exec_cmd(cmd) + exit_code, stdout, _ = self._exec_cmd(cmd) + return self.parseRawTlv(host_index, stdout, not exit_code) - if exit_code != 0: - error("Failed to query device configurations", hide=self._disable_out or hide) - if self.isHwAccessDisabled(): - error("Secure host enabled on the device", hide=self._disable_out or hide) - return current_conf if self._disable_out else None - else: - indexOfData = stdout.index('Data') + 6 - conf_data = int(stdout[indexOfData:indexOfData + 13], 16) - level = (conf_data & self.LIMITED) >> int(math.log(self.LIMITED, 2)) - disable_rshim = (conf_data & self.DISABLE_RSHIM) >> \ - int(math.log(self.DISABLE_RSHIM, 2)) - disable_tracer = (conf_data & self.DISABLE_TRACER) >> \ - int(math.log(self.DISABLE_TRACER, 2)) - disable_port_owner = (conf_data & self.DISABLE_PORT_OWNER) >> \ - int(math.log(self.DISABLE_PORT_OWNER, 2)) - disable_counter_rd = (conf_data & self.DISABLE_COUNTER_RD) >> \ - int(math.log(self.DISABLE_COUNTER_RD, 2)) - current_conf.update({"level": "RESTRICTED" if level else "PRIVILEGED"}) - current_conf.update({"disable_rshim": "TRUE" if disable_rshim else "FALSE"}) - current_conf.update({"disable_tracer": "TRUE" if disable_tracer else "FALSE"}) - current_conf.update({"disable_port_owner": "TRUE" if disable_port_owner else "FALSE"}) - current_conf.update({"disable_counter_rd": "TRUE" if disable_counter_rd else "FALSE"}) - return current_conf - - def setPrivConf(self, re_restrict, host_number): + def setPrivilegeConf(self, host_index, disable_info=False): self._nv_host_priv_conf = 0 - self.updateTlvFile(host_number, not re_restrict) - if not re_restrict: + self.updateTlvFile(host_index, disable_info) + if not disable_info: info("configuring device...", end='', hide=self._disable_out) cmd = self.CONFIG_CMD_LINE % (self._device, self._file_name) exit_code, stdout, stderr = self._exec_cmd(cmd) - if exit_code != 0 and not re_restrict: - current_conf = self.queryConf(host_number, True) - self.printCmd("Failed") - if current_conf is None: - error("Secure host enabled on the device", hide=self._disable_out) + if not disable_info: + if not exit_code: + self.printCmd("Done!") else: - error("Removing the restriction only effective on the ARM side", hide=self._disable_out) - if exit_code == 0 and not re_restrict: - self.printCmd("Done!") + self.printCmd("Failed") return exit_code - def setRestrictConf(self, host_number): + def setRestrictConf(self, host_index): + current_conf = self.queryConf(host_index) + # If host is restricted, remove the restiction to applay the new + # restrict command + if current_conf["level"] == "RESTRICTED": + self.setPrivilegeConf(host_index, disable_info=True) + # Update the TLV with the restriction bytes and port function + # configuration self._nv_host_priv_conf = self.LIMITED - if self._disable_rshim: - self._nv_host_priv_conf |= self.DISABLE_RSHIM - if self._disable_tracer: - self._nv_host_priv_conf |= self.DISABLE_TRACER - if self._disable_counter_rd: - self._nv_host_priv_conf |= self.DISABLE_COUNTER_RD - if self._disable_port_owner: - self._nv_host_priv_conf |= self.DISABLE_PORT_OWNER - self.updateTlvFile(host_number, True) + for pf in self._port_function: + self._nv_host_priv_conf |= self._port_function[pf] + self.updateTlvFile(host_index) + # Send the new configuration by mlxconfig info("configuring device...", end='', hide=self._disable_out) cmd = self.CONFIG_CMD_LINE % (self._device, self._file_name) exit_code, stdout, stderr = self._exec_cmd(cmd) - if exit_code != 0: - current_conf = self.queryConf(host_number, True) - self.printCmd("Failed") - if current_conf is None and self.isHwAccessDisabled(): - error("Secure host enabled on the device", hide=self._disable_out) - else: - error("Host is already restricted", hide=self._disable_out) - exit_code = 0 - else: + if not exit_code: self.printCmd("Done!") + else: + self.printCmd("Failed") return exit_code def setConf(self): exit_code = 0 - for host in range(self._total_hosts): - if host == self._current_host and self._isMH: - continue - current_conf = self.queryConf(host, True) - if current_conf and (not self._privilege) and (current_conf["level"] == "RESTRICTED"): - # If current state is restricted and user tried to do re-restriction - rc = self.setPrivConf(True, host) - if rc == 0: - self.setRestrictConf(host) - else: - # If user tried to do re-restrction from host, it will fail - # it should be done from ARM only - error("Host is already restricted", hide=self._disable_out) - elif not self._privilege: - # Execute restrict command with flag r - if not self._isMH and not self._isARM: - error("There is only a single host, it cannot restrict itself", hide=self._disable_out) - exit_code = 1 - else: + if self._isARM: + for host in range(self._total_hosts): + if self._requested_level == self.RESTRICT: exit_code = self.setRestrictConf(host) - elif self._privilege: - # Excute privlidge command with flag p - exit_code = self.setPrivConf(False, host) - # All other hosts are having the same output - if not self._disable_out: + elif self._requested_level == self.PRIVILEGE: + exit_code = self.setPrivilegeConf(host) self._disable_out = True - if self._oldFw: - info("Notice, you are using old FW version. In order of Multi-Host system FW must be updated") - return exit_code - - def configure(self): - if self._query: - return self.getConf() else: - return self.setConf() - - def cleanup(self): - self._file_p.close() - if os.path.isfile(self._file_name): - os.remove(self._file_name) + error("Operation is not permitted (refer to the DPU user manual)") + exit_code = 1 + return exit_code def validate(self): # get device ID @@ -369,15 +385,24 @@ def validate(self): if exit_code != 0: raise PrivilegeException("Unknown device '%s'!" % self._device) dev_id = int(stdout, 16) - if dev_id not in (self.BLUE_FIELD_DEV_ID, self.BLUE_FIELD2_DEV_ID, self.BLUE_FIELD3_DEV_ID): + if dev_id not in (self.BLUE_FIELD_DEV_ID, + self.BLUE_FIELD2_DEV_ID, + self.BLUE_FIELD3_DEV_ID): raise PrivilegeException( "Device '%s' is not supported, " - "only BlueField devices are supported!" % self._device) + "only BlueField devices are supported!" % + self._device) + + def cleanup(self): + self._file_p.close() + if os.path.isfile(self._file_name): + os.remove(self._file_name) def parse_args(): parser = argparse.ArgumentParser( - prog=PROG, description=DESCRIPTION, + prog=PROG, + description=DESCRIPTION, formatter_class=argparse.RawTextHelpFormatter) version = tools_version.GetVersionString(PROG, TOOL_VERSION) parser.add_argument("-v", "--version", action="version", version=version, @@ -385,71 +410,97 @@ def parse_args(): # options arguments options_group = parser.add_argument_group('Options') options_group.add_argument( - '--device', '-d', + '--device', required=True, - help='Device to work with.') - + metavar='', + help=DEV_HELP) + restrict_options_group = parser.add_argument_group('Restrict Options') + restrict_options_group.add_argument('--disable_rshim', action="store_true", + help=DISABLE_RSHIM_HELP) + restrict_options_group.add_argument( + '--disable_tracer', + action="store_true", + help=DISABLE_TRACER_HELP) + restrict_options_group.add_argument( + '--disable_counter_rd', + action="store_true", + help=DISABLE_COUNTER_RD_HELP) + restrict_options_group.add_argument( + '--disable_port_owner', + action="store_true", + help=DISABLE_PORT_OWNER_HELP) + query_options_group = parser.add_argument_group('Query Options') + query_options_group.add_argument('--full', '-f', action="store_true", + help=QUERY_FULL_HELP) # command arguments command_group = parser.add_argument_group('Commands') command_group.add_argument( 'command', - nargs=1, - choices=["r", "restrict", "p", "privilege", "q", "query"], + nargs='?', + choices=[ + "r", + "restrict", + "p", + "privilege", + "q", + "query"], help=CMD_HELP) - options_group.add_argument('--disable_rshim', action="store_true", - help=DISABLE_RSHIM_HELP) - options_group.add_argument('--disable_tracer', action="store_true", - help=DISABLE_TRACER_HELP) - options_group.add_argument('--disable_counter_rd', action="store_true", - help=DISABLE_COUNTER_RD_HELP) - options_group.add_argument('--disable_port_owner', action="store_true", - help=DISABLE_PORT_OWNER_HELP) + args = parser.parse_args() + if args.command is None: + parser.error( + "Please provide a command to execute, check the help menu") + disable_flags = args.disable_rshim or args.disable_tracer or \ - args.disable_counter_rd or args.disable_port_owner - rest_flags = args.command[0] in ("r", "restrict") - priv_flags = args.command[0] in ("p", "privilege") - query_flags = args.command[0] in ("q", "query") + args.disable_counter_rd or args.disable_port_owner + q_full_flag = args.full + rest_flags = args.command in ("r", "restrict") + priv_flags = args.command in ("p", "privilege") + query_flags = args.command in ("q", "query") if priv_flags and disable_flags: parser.error("disable flags are not allowed in privilege mode") if query_flags and (priv_flags or rest_flags or disable_flags): - parser.error("privilege or restrict commands are not allowed with query") + parser.error( + "privilege or restrict commands are not allowed with query") + if q_full_flag and not query_flags: + parser.error("The verbose option is allowed with query only") + return args def main(): args = parse_args() device = args.device - command = args.command[0] + command = args.command query = False - privilege = False - if command in ("p", "privilege"): - privilege = True - elif command in ("r", "restrict"): - privilege = False + level = PrivilegeMgr.PRIVILEGE + rc = 0 + if command in ("r", "restrict"): + level = PrivilegeMgr.RESTRICT elif command in ("q", "query"): query = True - retcode = 0 - mgr = PrivilegeMgr(device, query, privilege, args.disable_rshim, - args.disable_tracer, args.disable_counter_rd, - args.disable_port_owner) + port_functions = { + "disable_rshim": (0, PrivilegeMgr.DISABLE_RSHIM)[args.disable_rshim], + "disable_tracer": (0, PrivilegeMgr.DISABLE_TRACER)[args.disable_tracer], + "disable_counter_rd": (0, PrivilegeMgr.DISABLE_COUNTER_RD)[args.disable_counter_rd], + "disable_port_owner": (0, PrivilegeMgr.DISABLE_PORT_OWNER)[args.disable_port_owner]} + mgr = PrivilegeMgr(device, query, args.full, level, port_functions) try: - mgr.validate() - retcode = mgr.configure() + rc = mgr.run() except PrivilegeException as exc: error(str(exc)) - retcode = 1 + rc = 1 except Exception as exc: - error("got an error: %s", str(exc)) - retcode = 1 + error("-E- %s", str(exc)) + rc = 1 except(KeyboardInterrupt, SystemExit): print("\nInterrupted!\nExiting") - retcode = 1 + rc = 1 finally: mgr.cleanup() - return retcode + return rc if __name__ == "__main__": From 7950741b7ecc619b51c884c8c24eaa46a9001743 Mon Sep 17 00:00:00 2001 From: Harel Karni Date: Sun, 3 Apr 2022 20:05:33 +0300 Subject: [PATCH 153/184] [mstregdump] changing the default value of the full flag to true Description: The 'full' flag default value was changed from false to true, causing the tool to print out the sp2 addresses as well. Tested OS: Linux Tested devices: ConnectX5 Tested flows: Known gaps (with RM ticket): Issue: 2979319 --- mstdump/crd_main/mstdump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mstdump/crd_main/mstdump.c b/mstdump/crd_main/mstdump.c index c5226501..b535b3c0 100644 --- a/mstdump/crd_main/mstdump.c +++ b/mstdump/crd_main/mstdump.c @@ -70,7 +70,7 @@ int main(int argc, char *argv[]) int i; mfile *mf; int rc; - int full = 0; + int full = 1; int cause_addr = -1, cause_off = -1; crd_ctxt_t *context; u_int32_t arr_size = 0; From 83351bd5d91e91f9ca29b5d45a33c4c4cedd3827 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Tue, 5 Apr 2022 11:14:47 +0300 Subject: [PATCH 154/184] [mstlink][Module PRBS] Fixing Module Prbs Issues Description: -> Fixing duplicated flags -> Fixing duplicated error message -> Fixing invert_generator flag -> Fixing unnessessary repeated values in show_diagnostic_info command for not supported counters Issue: 3030245 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_cables_commander.cpp | 53 ++++++++++++-------- mlxlink/modules/mlxlink_commander.cpp | 4 +- mlxlink/modules/mlxlink_commander.h | 6 +-- mlxlink/modules/mlxlink_enums.h | 3 +- mlxlink/modules/mlxlink_ui.cpp | 31 ++++-------- 5 files changed, 47 insertions(+), 50 deletions(-) diff --git a/mlxlink/modules/mlxlink_cables_commander.cpp b/mlxlink/modules/mlxlink_cables_commander.cpp index 55a14a8b..ba45a7f3 100644 --- a/mlxlink/modules/mlxlink_cables_commander.cpp +++ b/mlxlink/modules/mlxlink_cables_commander.cpp @@ -1057,7 +1057,7 @@ u_int32_t MlxlinkCablesCommander::getModeAdminFromStr(u_int32_t cap, const strin } validRates = deleteLastChar(validRates); validRates = "]"; - throw MlxRegException("Invalid PRBS pattern value [%s] \nValid values are: %s\n", + throw MlxRegException("Invalid PRBS pattern value [%s] \nValid values are: %s", rateStr.c_str(), validRates.c_str()); } modeAdmin = (int)log2((float) modeAdmin); @@ -1071,12 +1071,6 @@ u_int32_t MlxlinkCablesCommander::getRateAdminFromStr(u_int32_t cap, const strin if (!rateStr.empty()) { rateAdmin = _mlxlinkMaps->_modulePrbsRateStrToCap[rateStr]; if (!rateAdmin) { - if (!_modulePrbsParams[MODULE_PRBS_CH_RATE].empty() && - !_modulePrbsParams[MODULE_PRBS_GEN_RATE].empty()) { - if (_modulePrbsParams[MODULE_PRBS_CH_RATE] != _modulePrbsParams[MODULE_PRBS_GEN_RATE]) { - throw MlxRegException("Checker and Generator must be running in the same lane rate\n"); - } - } string validRates = "["; for (auto it = _mlxlinkMaps->_modulePrbsRateStrToCap.begin(); it != _mlxlinkMaps->_modulePrbsRateStrToCap.end(); it++) { @@ -1086,7 +1080,7 @@ u_int32_t MlxlinkCablesCommander::getRateAdminFromStr(u_int32_t cap, const strin } validRates = deleteLastChar(validRates); validRates += "]"; - throw MlxRegException("Invalid PRBS lane rate configuration [%s] \nValid configurations are: %s\n", + throw MlxRegException("Invalid PRBS lane rate configuration [%s] \nValid configurations are: %s", rateStr.c_str(), validRates.c_str()); } } @@ -1099,7 +1093,7 @@ bool MlxlinkCablesCommander::getInvAdminFromStr(u_int32_t cap, const string &inv if (!invStr.empty()) { invAdmin = true; if (!cap) { - throw MlxRegException("PRBS inversion is not supported by the module\n"); + throw MlxRegException("PRBS inversion is not supported by the module"); } } return invAdmin; @@ -1178,8 +1172,7 @@ void MlxlinkCablesCommander::checkAndParsePMPTCap(ModuleAccess_t moduleAccess) u_int32_t chAccessShift = moduleAccess == MODULE_PRBS_ACCESS_CH? MODULE_PRBS_GEN_INV : 0; - _prbsRate = getRateAdminFromStr(getFieldValue("lane_rate_cap"), - _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_RATE + chAccessShift)]); + _prbsRate = getRateAdminFromStr(getFieldValue("lane_rate_cap"), _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_RATE)]); _prbsMode = getModeAdminFromStr(getFieldValue("prbs_modes_cap"), _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_PAT + chAccessShift)]); _prbsInv = getInvAdminFromStr(getFieldValue("invt_cap"), @@ -1192,11 +1185,6 @@ void MlxlinkCablesCommander::checkAndParsePMPTCap(ModuleAccess_t moduleAccess) void MlxlinkCablesCommander::preparePrbsParam(ModuleAccess_t moduleAccess) { - if (moduleAccess != MODULE_PRBS_ACCESS_BOTH && - (_modulePrbsParams[MODULE_PRBS_GEN_RATE] != _modulePrbsParams[MODULE_PRBS_CH_RATE])) { - throw MlxRegException("PRBS Checker and Generator lane rate must be provided with the same rate"); - } - switch (moduleAccess) { case MODULE_PRBS_ACCESS_CH: case MODULE_PRBS_ACCESS_GEN: @@ -1337,6 +1325,10 @@ string MlxlinkCablesCommander::getPMPDLockStatus() lockStatusStr += MlxlinkRecord::addSpaceForModulePrbs(_mlxlinkMaps->_modulePMPDStatus[getFieldValue("status")]); lockStatusStr += ","; + // Print only one indecation for each cap if it's not supported + if (getFieldValue("status") == PMPD_STATUS_NOT_SUPPORTED) { + break; + } } if (!lockStatusStr.empty()) { @@ -1391,6 +1383,9 @@ void MlxlinkCablesCommander::getPMPDInfo(vector &traffic, vector vector &snr) { string traficStr, errorsStr, berStr, snrStr; + bool skipErrorCap = false; + bool skipBerCap = false; + bool skipSnrCap = false; for (u_int32_t lane = 0; lane < _numOfLanes; lane++) { resetParser(ACCESS_REG_PMPD); updateField("module", _moduleNumber); @@ -1399,16 +1394,32 @@ void MlxlinkCablesCommander::getPMPDInfo(vector &traffic, vector updateField("lane", lane); genBuffSendRegister(ACCESS_REG_PMPD, MACCESS_REG_METHOD_GET); - traficStr = to_string(add32BitTo64(getFieldValue("prbs_bits_high"), - getFieldValue("prbs_bits_low"))); + traficStr = to_string(add32BitTo64(getFieldValue("prbs_bits_high"), getFieldValue("prbs_bits_low"))); errorsStr = to_string(add32BitTo64(getFieldValue("prbs_errors_high"), getFieldValue("prbs_errors_low"))); berStr = to_string(getFieldValue("ber_coef")) + "E-" + to_string(getFieldValue("ber_magnitude")); snrStr = to_string(getFieldValue("measured_snr")) +" dB"; traffic.push_back(MlxlinkRecord::addSpaceForModulePrbs(traficStr)); - errors.push_back(MlxlinkRecord::addSpaceForModulePrbs(getFieldValue("errors_cap")? errorsStr : "Not Supported")); - ber.push_back(MlxlinkRecord::addSpaceForModulePrbs(getFieldValue("ber_cap")? berStr : "Not Supported")); - snr.push_back(MlxlinkRecord::addSpaceForModulePrbs(getFieldValue("snr_cap")? snrStr : "Not Supported")); + + if (!skipErrorCap) { + errors.push_back(MlxlinkRecord::addSpaceForModulePrbs(getFieldValue("errors_cap")? errorsStr : "Not Supported")); + } + if (!skipBerCap) { + ber.push_back(MlxlinkRecord::addSpaceForModulePrbs(getFieldValue("ber_cap")? berStr : "Not Supported")); + } + if (!skipSnrCap) { + snr.push_back(MlxlinkRecord::addSpaceForModulePrbs(getFieldValue("snr_cap")? snrStr : "Not Supported")); + } + // Print only one indecation for each cap if it's not supported + if (getFieldValue("errors_cap") == 0) { + skipErrorCap = true; + } + if (getFieldValue("ber_cap") == 0) { + skipBerCap = true; + } + if (getFieldValue("snr_cap") == 0) { + skipSnrCap = true; + } } } diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index f8d30dee..98ff3d30 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -4487,8 +4487,7 @@ void MlxlinkCommander::performModulePrbsCommands() } else if (_userInput.isPrbsChProvided && _userInput.isPrbsGenProvided) { prbsModuleAccess = MODULE_PRBS_ACCESS_CH_GEN; } - if (_userInput.modulePrbsParams[MODULE_PRBS_GEN_RATE] == _userInput.modulePrbsParams[MODULE_PRBS_CH_RATE] && - _userInput.modulePrbsParams[MODULE_PRBS_GEN_PAT] == _userInput.modulePrbsParams[MODULE_PRBS_CH_PAT] && + if (_userInput.modulePrbsParams[MODULE_PRBS_GEN_PAT] == _userInput.modulePrbsParams[MODULE_PRBS_CH_PAT] && _userInput.modulePrbsParams[MODULE_PRBS_GEN_SWAP] == _userInput.modulePrbsParams[MODULE_PRBS_CH_SWAP] && _userInput.modulePrbsParams[MODULE_PRBS_GEN_INV] == _userInput.modulePrbsParams[MODULE_PRBS_CH_INV] && _userInput.modulePrbsParams[MODULE_PRBS_GEN_LANES] == _userInput.modulePrbsParams[MODULE_PRBS_GEN_LANES]) { @@ -4515,6 +4514,7 @@ void MlxlinkCommander::performModulePrbsCommands() } catch(MlxRegException &exc) { _allUnhandledErrors += "Module PRBS test mode raised the following exception: "; _allUnhandledErrors += exc.what_s(); + _allUnhandledErrors += "\n"; } } diff --git a/mlxlink/modules/mlxlink_commander.h b/mlxlink/modules/mlxlink_commander.h index 15abb5ba..4393cb80 100644 --- a/mlxlink/modules/mlxlink_commander.h +++ b/mlxlink/modules/mlxlink_commander.h @@ -183,8 +183,6 @@ #define CABLE_PRBS_SELECT_SHORT ' ' #define CABLE_PRBS_MODE "prbs_mode" #define CABLE_PRBS_MODE_SHORT ' ' -#define CABLE_PRBS_GEN_RATE "generator_rate" -#define CABLE_PRBS_GEN_RATE_SHORT ' ' #define CABLE_PRBS_GEN_PAT "generator_pattern" #define CABLE_PRBS_GEN_PAT_SHORT ' ' #define CABLE_PRBS_GEN_SWAP "swap_generator" @@ -193,8 +191,6 @@ #define CABLE_PRBS_GEN_INV_SHORT ' ' #define CABLE_PRBS_GEN_LANES "generator_lanes" #define CABLE_PRBS_GEN_LANES_SHORT ' ' -#define CABLE_PRBS_CH_RATE "checker_rate" -#define CABLE_PRBS_CH_RATE_SHORT ' ' #define CABLE_PRBS_CH_PAT "checker_pattern" #define CABLE_PRBS_CH_PAT_SHORT ' ' #define CABLE_PRBS_CH_SWAP "swap_checker" @@ -203,6 +199,8 @@ #define CABLE_PRBS_CH_INV_SHORT ' ' #define CABLE_PRBS_CH_LANES "checker_lanes" #define CABLE_PRBS_CH_LANES_SHORT ' ' +#define CABLE_PRBS_LANE_RATE "lane_rate" +#define CABLE_PRBS_LANE_RATE_SHORT ' ' #define CABLE_PRBS_SHOW_DIAG "show_diagnostic_info" #define CABLE_PRBS_SHOW_DIAG_SHORT ' ' #define CABLE_PRBS_CLEAR_DIAG "clear_diagnostic_info" diff --git a/mlxlink/modules/mlxlink_enums.h b/mlxlink/modules/mlxlink_enums.h index 0b5e2529..ce31facc 100644 --- a/mlxlink/modules/mlxlink_enums.h +++ b/mlxlink/modules/mlxlink_enums.h @@ -1378,16 +1378,15 @@ enum PCIE_DEVICE_STATUS { typedef enum MODULE_PRBS { MODULE_PRBS_SELECT, MODULE_PRBS_MODE, - MODULE_PRBS_GEN_RATE, MODULE_PRBS_GEN_PAT, MODULE_PRBS_GEN_SWAP, MODULE_PRBS_GEN_INV, MODULE_PRBS_GEN_LANES, - MODULE_PRBS_CH_RATE, MODULE_PRBS_CH_PAT, MODULE_PRBS_CH_SWAP, MODULE_PRBS_CH_INV, MODULE_PRBS_CH_LANES, + MODULE_PRBS_RATE, MODULE_PRBS_SHOW_DIAG, MODULE_PRBS_CLEAR_DIAG } ModulePrbs_t; diff --git a/mlxlink/modules/mlxlink_ui.cpp b/mlxlink/modules/mlxlink_ui.cpp index 3736e322..3696289b 100644 --- a/mlxlink/modules/mlxlink_ui.cpp +++ b/mlxlink/modules/mlxlink_ui.cpp @@ -206,24 +206,17 @@ void MlxlinkUi::printSynopsisCommands() MlxlinkRecord::printFlagLine(CABLE_PRBS_MODE_SHORT, CABLE_PRBS_MODE, "cmd", "Perform PRBS test mode on the Module [EN(Enable),DS(Disable)]"); printf(IDENT3); - MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_RATE_SHORT, CABLE_PRBS_GEN_RATE, "rate", - "Set PRBS generator lane rate [HDR(50G)(default),1.25G,SDR(2.5G),10.3125G,FDR(14G),EDR(25G),NDR(100G)]"); - printf(IDENT3); MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_PAT_SHORT, CABLE_PRBS_GEN_PAT, "pattern", "Set PRBS generator pattern [PRBS31(default),PRBS23,PRBS7,PRBS11,PRBS9,PRBS13,SSPR,SSPRQ]"); printf(IDENT3); MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_SWAP_SHORT, CABLE_PRBS_GEN_SWAP, "", "Enable PAM4 MSB <-> LSB generator swapping (Optional)"); printf(IDENT3); - MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_INV_SHORT, CABLE_PRBS_GEN_INV, "rate", + MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_INV_SHORT, CABLE_PRBS_GEN_INV, "", "Enable PRBS generator inversion (Optional)"); printf(IDENT3); MlxlinkRecord::printFlagLine(CABLE_PRBS_GEN_LANES_SHORT, CABLE_PRBS_GEN_LANES, "lanes", "PRBS generator lanes to set (one or more lane separated by comma)[0,1,2,3,4,5,6,7] (Optional - Default all lanes)"); - - printf(IDENT3); - MlxlinkRecord::printFlagLine(CABLE_PRBS_CH_RATE_SHORT, CABLE_PRBS_CH_RATE, "rate", - "Set PRBS checker lane rate [HDR(50G)(default),1.25G,SDR(2.5G),10.3125G,FDR(14G),EDR(25G),NDR(100G)]"); printf(IDENT3); MlxlinkRecord::printFlagLine(CABLE_PRBS_CH_PAT_SHORT, CABLE_PRBS_CH_PAT, "pattern", "Set PRBS checker pattern [PRBS31(default),PRBS23,PRBS7,PRBS11,PRBS9,PRBS13,SSPR,SSPRQ]"); @@ -236,6 +229,9 @@ void MlxlinkUi::printSynopsisCommands() printf(IDENT3); MlxlinkRecord::printFlagLine(CABLE_PRBS_CH_LANES_SHORT, CABLE_PRBS_CH_LANES, "lanes", "PRBS checker lanes to set (one or more lane separated by comma)[0,1,2,3,4,5,6,7] (Optional - Default all lanes)"); + printf(IDENT3); + MlxlinkRecord::printFlagLine(CABLE_PRBS_LANE_RATE_SHORT, CABLE_PRBS_LANE_RATE, "rate", + "Set PRBS checker and generator lane rate [HDR(50G)(default),1.25G,SDR(2.5G),10.3125G,FDR(14G),EDR(25G),NDR(100G)]"); printf(IDENT2); MlxlinkRecord::printFlagLine(CABLE_PRBS_SHOW_DIAG_SHORT, CABLE_PRBS_SHOW_DIAG, "", "Show PRBS diagnostic counters information"); @@ -735,16 +731,15 @@ void MlxlinkUi::initCmdParser() AddOptions(CABLE_PRBS_SELECT, CABLE_PRBS_SELECT_SHORT, "side", ""); AddOptions(CABLE_PRBS_MODE, CABLE_PRBS_MODE_SHORT, "cmd", ""); - AddOptions(CABLE_PRBS_GEN_RATE, CABLE_PRBS_GEN_RATE_SHORT, "rate", ""); AddOptions(CABLE_PRBS_GEN_PAT, CABLE_PRBS_GEN_PAT_SHORT,"pattern", ""); AddOptions(CABLE_PRBS_GEN_SWAP, CABLE_PRBS_GEN_SWAP_SHORT, "", ""); - AddOptions(CABLE_PRBS_GEN_INV, CABLE_PRBS_GEN_INV_SHORT, "rate", ""); + AddOptions(CABLE_PRBS_GEN_INV, CABLE_PRBS_GEN_INV_SHORT, "", ""); AddOptions(CABLE_PRBS_GEN_LANES, CABLE_PRBS_GEN_LANES_SHORT, "lanes", ""); - AddOptions(CABLE_PRBS_CH_RATE, CABLE_PRBS_CH_RATE_SHORT, "rate", ""); AddOptions(CABLE_PRBS_CH_PAT, CABLE_PRBS_CH_PAT_SHORT, "pattern",""); AddOptions(CABLE_PRBS_CH_SWAP, CABLE_PRBS_CH_SWAP_SHORT, "",""); AddOptions(CABLE_PRBS_CH_INV, CABLE_PRBS_CH_INV_SHORT, "", ""); AddOptions(CABLE_PRBS_CH_LANES, CABLE_PRBS_CH_LANES_SHORT, "lanes", ""); + AddOptions(CABLE_PRBS_LANE_RATE, CABLE_PRBS_LANE_RATE_SHORT, "rate", ""); AddOptions(CABLE_PRBS_SHOW_DIAG, CABLE_PRBS_SHOW_DIAG_SHORT, "", ""); AddOptions(CABLE_PRBS_CLEAR_DIAG, CABLE_PRBS_CLEAR_DIAG_SHORT, "", ""); @@ -1222,11 +1217,6 @@ ParseStatus MlxlinkUi::HandleOption(string name, string value) _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_MODE] = toUpperCase(value); _mlxlinkCommander->_userInput.isPrbsModeProvided = true; return PARSE_OK; - } else if (name == CABLE_PRBS_GEN_RATE) { - _mlxlinkCommander->checkStrLength(value); - _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_GEN_RATE] = toUpperCase(value); - _mlxlinkCommander->_userInput.isPrbsGenProvided = true; - return PARSE_OK; } else if (name == CABLE_PRBS_GEN_PAT) { _mlxlinkCommander->checkStrLength(value); _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_GEN_PAT] = toUpperCase(value); @@ -1244,11 +1234,6 @@ ParseStatus MlxlinkUi::HandleOption(string name, string value) _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_GEN_LANES] = value; _mlxlinkCommander->_userInput.isPrbsGenProvided = true; return PARSE_OK; - } else if (name == CABLE_PRBS_CH_RATE) { - _mlxlinkCommander->checkStrLength(value); - _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_CH_RATE] = toUpperCase(value); - _mlxlinkCommander->_userInput.isPrbsChProvided = true; - return PARSE_OK; } else if (name == CABLE_PRBS_CH_PAT) { _mlxlinkCommander->checkStrLength(value); _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_CH_PAT] = toUpperCase(value); @@ -1266,6 +1251,10 @@ ParseStatus MlxlinkUi::HandleOption(string name, string value) _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_CH_LANES] = value; _mlxlinkCommander->_userInput.isPrbsChProvided = true; return PARSE_OK; + } else if (name == CABLE_PRBS_LANE_RATE) { + _mlxlinkCommander->checkStrLength(value); + _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_RATE] = toUpperCase(value); + return PARSE_OK; } else if (name == CABLE_PRBS_SHOW_DIAG) { _mlxlinkCommander->checkStrLength(value); _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_SHOW_DIAG] = value; From 92f542f05b988715430366a500d2f60c374c33ff Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Wed, 6 Apr 2022 13:57:34 +0300 Subject: [PATCH 155/184] [mstprivhost] Fixing per host configuration Fixing per host configuration Issue: 3032958 Signed-off-by: Mustafa Dalloul --- mlxconfig/mstprivhost.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mlxconfig/mstprivhost.py b/mlxconfig/mstprivhost.py index 011f5abe..6381473c 100644 --- a/mlxconfig/mstprivhost.py +++ b/mlxconfig/mstprivhost.py @@ -211,10 +211,11 @@ def getFieldFromReg(self, reg_output, field_name): return field_value def updateTlvFile(self, host_index, disable_info=False): - self.TLV_TYPE |= (host_index << 18) + tlv_type = self.TLV_TYPE + tlv_type |= (host_index << 18) raw_bytes = "%s\n0x%08x 0x%08x 0x%08x" % (self.TITLE, self.TLV_HEADER, - self.TLV_TYPE, + tlv_type, self.CRC) if not disable_info: info( From a48ba19eeed44777d92468ef896de203b437354f Mon Sep 17 00:00:00 2001 From: Alon Strutsovsky Date: Thu, 7 Apr 2022 11:26:28 +0300 Subject: [PATCH 156/184] bugfix, mstdump_pld doesn't dump sp2, where mlxdump mstdump do Description: sp2 addresses are not marked as enabled Tested OS: linux Tested devices: CX6 Tested flows: dump and check that contains the expected address list Known gaps (with RM ticket): Issue: 2979319 Change-Id: I8dbf4176fc69fa899021f42a62fc846830112d30 --- mstdump/crd_lib/crdump.c | 1 + mstdump/crd_main/mstdump.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mstdump/crd_lib/crdump.c b/mstdump/crd_lib/crdump.c index ac966628..9f85fe4f 100644 --- a/mstdump/crd_lib/crdump.c +++ b/mstdump/crd_lib/crdump.c @@ -480,6 +480,7 @@ static int crd_set_tlv_blocks(IN mfile *mf, OUT crd_parsed_csv_t blocks[], IN u_ { blocks[block_number].addr = current_tlv.address; blocks[block_number].len = current_tlv.size; + strcpy(blocks[block_number].enable_addr, CRD_EMPTY); block_number++; rc = crd_get_tlv_from_address(mf, current_tlv.address, ¤t_tlv); diff --git a/mstdump/crd_main/mstdump.c b/mstdump/crd_main/mstdump.c index b535b3c0..c5226501 100644 --- a/mstdump/crd_main/mstdump.c +++ b/mstdump/crd_main/mstdump.c @@ -70,7 +70,7 @@ int main(int argc, char *argv[]) int i; mfile *mf; int rc; - int full = 1; + int full = 0; int cause_addr = -1, cause_off = -1; crd_ctxt_t *context; u_int32_t arr_size = 0; From a31f79e8b9f93ce95f5e0dab9416992d80857094 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Wed, 6 Apr 2022 14:52:02 +0300 Subject: [PATCH 157/184] [mstlink] Fixing parsing clear_diagnostic_info and lane_rate options Description: Fixing parsing clear_diagnostic_info and lane_rate options Issue: 3033765 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_cables_commander.cpp | 135 +++++++++---------- mlxlink/modules/mlxlink_cables_commander.h | 10 +- mlxlink/modules/mlxlink_commander.cpp | 6 - mlxlink/modules/mlxlink_maps.cpp | 6 + mlxlink/modules/mlxlink_maps.h | 1 + mlxlink/modules/mlxlink_ui.cpp | 4 +- 6 files changed, 78 insertions(+), 84 deletions(-) diff --git a/mlxlink/modules/mlxlink_cables_commander.cpp b/mlxlink/modules/mlxlink_cables_commander.cpp index ba45a7f3..472d1021 100644 --- a/mlxlink/modules/mlxlink_cables_commander.cpp +++ b/mlxlink/modules/mlxlink_cables_commander.cpp @@ -1042,70 +1042,70 @@ MlxlinkCmdPrint MlxlinkCablesCommander::readFromEEPRM(u_int16_t page , u_int16_t return bytesOutput; } -u_int32_t MlxlinkCablesCommander::getModeAdminFromStr(u_int32_t cap, const string &rateStr) +u_int32_t MlxlinkCablesCommander::getModeAdminFromStr(u_int32_t cap, const string &adminStr, ModuleAccess_t moduleAccess) { int modeAdmin = _prbsMode; - if (!rateStr.empty()) { - modeAdmin = _mlxlinkMaps->_modulePrbsModeStrToCap[rateStr]; - if (!modeAdmin) { - string validRates = "["; - for (auto it = _mlxlinkMaps->_modulePrbsModeCapToStr.begin(); - it != _mlxlinkMaps->_modulePrbsModeCapToStr.end(); it++) { - if (it->first & cap) { - validRates += it->second + ","; - } + string confStr = adminStr.empty()? DEFAULT_PRBS_MODE_STR : adminStr; + modeAdmin = _mlxlinkMaps->_modulePrbsModeStrToCap[confStr]; + if (!modeAdmin || !(modeAdmin & cap)) { + string validRates = "["; + for (auto it = _mlxlinkMaps->_modulePrbsModeCapToStr.begin(); + it != _mlxlinkMaps->_modulePrbsModeCapToStr.end(); it++) { + if (it->first & cap) { + validRates += it->second + ","; } - validRates = deleteLastChar(validRates); - validRates = "]"; - throw MlxRegException("Invalid PRBS pattern value [%s] \nValid values are: %s", - rateStr.c_str(), validRates.c_str()); } - modeAdmin = (int)log2((float) modeAdmin); + validRates = deleteLastChar(validRates); + validRates += "]"; + throw MlxRegException("Invalid PRBS pattern for the %s [%s]\nValid values are: %s", + _mlxlinkMaps->_moduleScopeToStr[moduleAccess].c_str(), confStr.c_str(), + validRates.c_str()); } - return modeAdmin; + return (int)log2((float) modeAdmin); } u_int32_t MlxlinkCablesCommander::getRateAdminFromStr(u_int32_t cap, const string &rateStr) { int rateAdmin = _prbsRate; - if (!rateStr.empty()) { - rateAdmin = _mlxlinkMaps->_modulePrbsRateStrToCap[rateStr]; - if (!rateAdmin) { - string validRates = "["; - for (auto it = _mlxlinkMaps->_modulePrbsRateStrToCap.begin(); - it != _mlxlinkMaps->_modulePrbsRateStrToCap.end(); it++) { - if (it->second & cap) { - validRates += it->first + ","; - } + string confStr = rateStr.empty()? DEFAULT_PRBS_RATE_STR : rateStr; + rateAdmin = _mlxlinkMaps->_modulePrbsRateStrToCap[confStr]; + if (!rateAdmin || !(rateAdmin & cap)) { + string validRates = "["; + for (auto it = _mlxlinkMaps->_modulePrbsRateStrToCap.begin(); + it != _mlxlinkMaps->_modulePrbsRateStrToCap.end(); it++) { + if (it->second & cap) { + validRates += it->first + ","; } - validRates = deleteLastChar(validRates); - validRates += "]"; - throw MlxRegException("Invalid PRBS lane rate configuration [%s] \nValid configurations are: %s", - rateStr.c_str(), validRates.c_str()); } + validRates = deleteLastChar(validRates); + validRates += "]"; + throw MlxRegException("Invalid PRBS lane rate configuration [%s]\nValid configurations are: %s", + confStr.c_str(), validRates.c_str()); } return rateAdmin; } -bool MlxlinkCablesCommander::getInvAdminFromStr(u_int32_t cap, const string &invStr) +bool MlxlinkCablesCommander::getInvAdminFromStr(u_int32_t cap, const string &invStr, ModuleAccess_t moduleAccess) { bool invAdmin = false; if (!invStr.empty()) { invAdmin = true; if (!cap) { - throw MlxRegException("PRBS inversion is not supported by the module"); + throw MlxRegException("PRBS inversion is not supported by the %s", + _mlxlinkMaps->_moduleScopeToStr[moduleAccess].c_str()); } } return invAdmin; } -bool MlxlinkCablesCommander::getSwapAdminFromStr(u_int32_t cap, const string &swapStr) +bool MlxlinkCablesCommander::getSwapAdminFromStr(u_int32_t cap, const string &swapStr, ModuleAccess_t moduleAccess) { bool swapAdmin = false; if (!swapStr.empty()) { swapAdmin = true; if (!cap) { - throw MlxRegException("PAM4 MSB <-> LSB swapping is not supported by the module"); + throw MlxRegException("PAM4 MSB <-> LSB swapping is not supported by the %s", + _mlxlinkMaps->_moduleScopeToStr[moduleAccess].c_str()); } } return swapAdmin; @@ -1158,47 +1158,39 @@ void MlxlinkCablesCommander::checkAndParsePMPTCap(ModuleAccess_t moduleAccess) resetParser(ACCESS_REG_PMPT); updateField("module", _moduleNumber); updateField("slot_index", _slotIndex); - updateField("host_media", _modulePrbsParams[MODULE_PRBS_SELECT] == "HOST"); - updateField("ch_ge", (u_int32_t)moduleAccess); updateField("lane_mask", 0x1); genBuffSendRegister(ACCESS_REG_PMPT, MACCESS_REG_METHOD_GET); } catch (MlxRegException &exc) { regFaild = true; } - if (regFaild || getFieldValue("status") == PMPT_STATUS_NOT_SUPPORTED) { throw MlxRegException("Module doesn't support PRBS and diagnostics data"); } + _prbsRate = getRateAdminFromStr(getFieldValue("lane_rate_cap"), + _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_RATE)]); + + // read the other PMPT caps according to the prbsRate + resetParser(ACCESS_REG_PMPT); + updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); + updateField("host_media", _modulePrbsParams[MODULE_PRBS_SELECT] == "HOST"); + updateField("ch_ge", (u_int32_t)moduleAccess); + updateField("modulation", _prbsRate >= MODULE_PRBS_LANE_RATE_HDR); + updateField("lane_mask", 0x1); + genBuffSendRegister(ACCESS_REG_PMPT, MACCESS_REG_METHOD_GET); u_int32_t chAccessShift = moduleAccess == MODULE_PRBS_ACCESS_CH? MODULE_PRBS_GEN_INV : 0; - _prbsRate = getRateAdminFromStr(getFieldValue("lane_rate_cap"), _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_RATE)]); _prbsMode = getModeAdminFromStr(getFieldValue("prbs_modes_cap"), - _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_PAT + chAccessShift)]); + _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_PAT + chAccessShift)], moduleAccess); _prbsInv = getInvAdminFromStr(getFieldValue("invt_cap"), - _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_INV + chAccessShift)]); + _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_INV + chAccessShift)], moduleAccess); _prbsSwap = getSwapAdminFromStr(getFieldValue("swap_cap"), - _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_SWAP + chAccessShift)]); + _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_SWAP + chAccessShift)], moduleAccess); _prbsLanes = getLanesFromStr(getFieldValue("ls"), _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_LANES + chAccessShift)]); } -void MlxlinkCablesCommander::preparePrbsParam(ModuleAccess_t moduleAccess) -{ - switch (moduleAccess) { - case MODULE_PRBS_ACCESS_CH: - case MODULE_PRBS_ACCESS_GEN: - checkAndParsePMPTCap(moduleAccess); - break; - case MODULE_PRBS_ACCESS_CH_GEN: - checkAndParsePMPTCap(MODULE_PRBS_ACCESS_CH); - checkAndParsePMPTCap(MODULE_PRBS_ACCESS_GEN); - break; - default: - checkAndParsePMPTCap(MODULE_PRBS_ACCESS_BOTH); - } -} - u_int32_t MlxlinkCablesCommander::getPMPTStatus(ModuleAccess_t moduleAccess) { resetParser(ACCESS_REG_PMPT); @@ -1214,6 +1206,8 @@ u_int32_t MlxlinkCablesCommander::getPMPTStatus(ModuleAccess_t moduleAccess) void MlxlinkCablesCommander::sendPMPT(ModuleAccess_t moduleAccess) { + checkAndParsePMPTCap(moduleAccess); + resetParser(ACCESS_REG_PMPT); updateField("module", _moduleNumber); updateField("slot_index", _slotIndex); @@ -1236,21 +1230,17 @@ void MlxlinkCablesCommander::sendPMPT(ModuleAccess_t moduleAccess) void MlxlinkCablesCommander::enablePMPT(ModuleAccess_t moduleAccess) { - try { - switch (moduleAccess) { - case MODULE_PRBS_ACCESS_CH: - case MODULE_PRBS_ACCESS_GEN: - sendPMPT(moduleAccess); - break; - case MODULE_PRBS_ACCESS_CH_GEN: - sendPMPT(MODULE_PRBS_ACCESS_CH); - sendPMPT(MODULE_PRBS_ACCESS_GEN); - break; - default: - sendPMPT(MODULE_PRBS_ACCESS_BOTH); - } - } catch (MlxRegException &exc) { - throw MlxRegException("Module doesn't support PRBS and diagnostics data"); + switch (moduleAccess) { + case MODULE_PRBS_ACCESS_CH: + case MODULE_PRBS_ACCESS_GEN: + sendPMPT(moduleAccess); + break; + case MODULE_PRBS_ACCESS_CH_GEN: + sendPMPT(MODULE_PRBS_ACCESS_CH); + sendPMPT(MODULE_PRBS_ACCESS_GEN); + break; + default: + sendPMPT(MODULE_PRBS_ACCESS_BOTH); } } @@ -1274,7 +1264,6 @@ void MlxlinkCablesCommander::handlePrbsTestMode(const string &ctrl, ModuleAccess if (ctrl == "EN") { MlxlinkRecord::printCmdLine("Enabling Module PRBS Test Mode", _jsonRoot); getNumOfModuleLanes(); - preparePrbsParam(moduleAccess); enablePMPT(moduleAccess); } else if (ctrl == "DS") { MlxlinkRecord::printCmdLine("Disabling Module PRBS Test Mode", _jsonRoot); @@ -1364,8 +1353,8 @@ void MlxlinkCablesCommander::showPrbsTestMode() prbsAcces.push_back(MlxlinkRecord::addSpaceForModulePrbs("Checker")); prbsAcces.push_back(MlxlinkRecord::addSpaceForModulePrbs("Generator")); - getPMPTConfiguration(MODULE_PRBS_ACCESS_GEN, prbsPattern, prbsRate, prbsInv, prbsSwap); getPMPTConfiguration(MODULE_PRBS_ACCESS_CH, prbsPattern, prbsRate, prbsInv, prbsSwap); + getPMPTConfiguration(MODULE_PRBS_ACCESS_GEN, prbsPattern, prbsRate, prbsInv, prbsSwap); setPrintVal(prbsOutput, "PRBS Access", getStringFromVector(prbsAcces), ANSI_COLOR_RESET, true, true, true); setPrintVal(prbsOutput, "PRBS Pattern", getStringFromVector(prbsPattern), ANSI_COLOR_RESET, true, true, true); diff --git a/mlxlink/modules/mlxlink_cables_commander.h b/mlxlink/modules/mlxlink_cables_commander.h index 26a941d9..145de4b4 100644 --- a/mlxlink/modules/mlxlink_cables_commander.h +++ b/mlxlink/modules/mlxlink_cables_commander.h @@ -83,6 +83,9 @@ typedef struct { #define VOLT_UNIT 1000 #define MILLIVOLT_UNIT 10 +#define DEFAULT_PRBS_MODE_STR "PRBS31" +#define DEFAULT_PRBS_RATE_STR "HDR" + typedef struct Page{ u_int32_t page; u_int16_t offset; @@ -168,16 +171,15 @@ class MlxlinkCablesCommander :public MlxlinkRegParser{ void getNumOfModuleLanes(); u_int32_t getRateAdminFromStr(u_int32_t cap, const string &rateStr); - u_int32_t getModeAdminFromStr(u_int32_t cap, const string &adminStr); - bool getInvAdminFromStr(u_int32_t cap, const string &invStr); - bool getSwapAdminFromStr(u_int32_t cap, const string &swapStr); + u_int32_t getModeAdminFromStr(u_int32_t cap, const string &adminStr, ModuleAccess_t moduleAccess); + bool getInvAdminFromStr(u_int32_t cap, const string &invStr, ModuleAccess_t moduleAccess); + bool getSwapAdminFromStr(u_int32_t cap, const string &swapStr, ModuleAccess_t moduleAccess); u_int32_t getLanesFromStr(u_int32_t cap, const string &lanesStr); void getPMPTConfiguration(ModuleAccess_t moduleAccess, vector &prbsPattern, vector &prbsRate, vector &prbsInv, vector &prbsSwap); void getPMPDInfo(vector &traffic, vector &errors, vector &ber, vector &snr); string getPMPDLockStatus(); void checkAndParsePMPTCap(ModuleAccess_t moduleAccess); - void preparePrbsParam(ModuleAccess_t moduleAccess); u_int32_t getPMPTStatus(ModuleAccess_t moduleAccess); void sendPMPT(ModuleAccess_t moduleAccess); void enablePMPT(ModuleAccess_t moduleAccess); diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index 98ff3d30..a910c141 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -4487,12 +4487,6 @@ void MlxlinkCommander::performModulePrbsCommands() } else if (_userInput.isPrbsChProvided && _userInput.isPrbsGenProvided) { prbsModuleAccess = MODULE_PRBS_ACCESS_CH_GEN; } - if (_userInput.modulePrbsParams[MODULE_PRBS_GEN_PAT] == _userInput.modulePrbsParams[MODULE_PRBS_CH_PAT] && - _userInput.modulePrbsParams[MODULE_PRBS_GEN_SWAP] == _userInput.modulePrbsParams[MODULE_PRBS_CH_SWAP] && - _userInput.modulePrbsParams[MODULE_PRBS_GEN_INV] == _userInput.modulePrbsParams[MODULE_PRBS_CH_INV] && - _userInput.modulePrbsParams[MODULE_PRBS_GEN_LANES] == _userInput.modulePrbsParams[MODULE_PRBS_GEN_LANES]) { - prbsModuleAccess = MODULE_PRBS_ACCESS_BOTH; - } _cablesCommander->handlePrbsTestMode(_userInput.modulePrbsParams[MODULE_PRBS_MODE], prbsModuleAccess); } else { _cablesCommander->showPrbsTestMode(); diff --git a/mlxlink/modules/mlxlink_maps.cpp b/mlxlink/modules/mlxlink_maps.cpp index 04066ada..854fbefe 100644 --- a/mlxlink/modules/mlxlink_maps.cpp +++ b/mlxlink/modules/mlxlink_maps.cpp @@ -990,6 +990,12 @@ void MlxlinkMaps::modulePrbsMapping() _modulePMPDStatus[PMPD_STATUS_NORMAL_MODE] = "Normal Mode"; _modulePMPDStatus[PMPD_STATUS_NOT_LOCKED] = "Not Locked"; _modulePMPDStatus[PMPD_STATUS_LOCKED] = "Locked"; + + _moduleScopeToStr[MODULE_PRBS_ACCESS_CH] = "Checker"; + _moduleScopeToStr[MODULE_PRBS_ACCESS_GEN] = "Generator"; + _moduleScopeToStr[MODULE_PRBS_ACCESS_BOTH] = "Module"; + _moduleScopeToStr[MODULE_PRBS_ACCESS_CH_GEN] = "Module"; + } void MlxlinkMaps::qsfpComlianceMapping() diff --git a/mlxlink/modules/mlxlink_maps.h b/mlxlink/modules/mlxlink_maps.h index 96673b54..954b4157 100644 --- a/mlxlink/modules/mlxlink_maps.h +++ b/mlxlink/modules/mlxlink_maps.h @@ -176,6 +176,7 @@ class MlxlinkMaps{ std::map _modulePMPDStatus; std::map _modulePrbsModeCapToStr; std::map _modulePrbsModeStrToCap; + std::map _moduleScopeToStr; std::map _moduleRxAmp; std::map _moduleRxAmpCap; std::map _pepcStatus; diff --git a/mlxlink/modules/mlxlink_ui.cpp b/mlxlink/modules/mlxlink_ui.cpp index 3696289b..a90117cb 100644 --- a/mlxlink/modules/mlxlink_ui.cpp +++ b/mlxlink/modules/mlxlink_ui.cpp @@ -463,7 +463,8 @@ void MlxlinkUi::validateModulePRBSParams() } if (!_mlxlinkCommander->_userInput.isPrbsModeProvided && (_mlxlinkCommander->_userInput.isPrbsChProvided || - _mlxlinkCommander->_userInput.isPrbsGenProvided)) { + _mlxlinkCommander->_userInput.isPrbsGenProvided || + !_mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_RATE].empty())) { throw MlxRegException("--" CABLE_PRBS_MODE " flag should be provided!"); } @@ -1264,6 +1265,7 @@ ParseStatus MlxlinkUi::HandleOption(string name, string value) _mlxlinkCommander->checkStrLength(value); _mlxlinkCommander->_userInput.modulePrbsParams[MODULE_PRBS_CLEAR_DIAG] = value; _mlxlinkCommander->_userInput.isPrbsClearDiagProvided = true; + return PARSE_OK; } else if (name == CTRL_PARAM_FLAG) { addCmd(CABLE_CTRL_PARM); _mlxlinkCommander->_userInput.isModuleConfigParamsProvided = true; From f7817808572a352b4f4589100948396f154b071d Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Mon, 11 Apr 2022 10:51:29 +0300 Subject: [PATCH 158/184] update mstflint version to 4.20 --- configure.ac | 4 ++-- debian/changelog | 8 +++++++- kernel/mstflint_kernel.spec | 2 +- mstflint.spec.in | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 849b1873..ca955b0f 100644 --- a/configure.ac +++ b/configure.ac @@ -31,12 +31,12 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(mstflint, 4.19.0, eranj@mellanox.co.il) +AC_INIT(mstflint, 4.20.0, eranj@mellanox.co.il) AC_DEFINE_UNQUOTED([PROJECT], ["mstflint"], [Define the project name.]) AC_SUBST([PROJECT]) -AC_DEFINE_UNQUOTED([VERSION], ["4.19.0"], [Define the project version.]) +AC_DEFINE_UNQUOTED([VERSION], ["4.20.0"], [Define the project version.]) AC_SUBST([VERSION]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/debian/changelog b/debian/changelog index 7171fc1a..8f26a337 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,12 @@ +mstflint (4.20.0-1) unstable; urgency=low + + * Updated from MFT-4.20.0 + + -- Tomer Tubi Thu, 28 Apr 2022 00:00:00 +0200 + mstflint (4.19.0-1) unstable; urgency=low - * Updated from MFT-4.19.0 + * Updated from MFT-4.19.0 (internal version) -- Tomer Tubi Thu, 24 Mar 2022 00:00:00 +0200 diff --git a/kernel/mstflint_kernel.spec b/kernel/mstflint_kernel.spec index 25690edf..cbe03cfe 100644 --- a/kernel/mstflint_kernel.spec +++ b/kernel/mstflint_kernel.spec @@ -22,7 +22,7 @@ %global _name kernel-mstflint %endif -%{!?version: %global version 4.19.0} +%{!?version: %global version 4.20.0} %{!?_release: %global _release 1} %global _kmp_rel %{_release}%{?_kmp_build_num}%{?_dist} diff --git a/mstflint.spec.in b/mstflint.spec.in index 689e6bb9..d50eb5aa 100644 --- a/mstflint.spec.in +++ b/mstflint.spec.in @@ -1,6 +1,6 @@ %{!?ibmadlib: %define ibmadlib libibmad-devel} %{!?name: %define name mstflint} -%{!?version: %define version 4.19.0} +%{!?version: %define version 4.20.0} %{!?release: %define release 1} %{!?buildtype: %define buildtype "native"} %{!?noinband: %define noinband 0} From 7aa677c4f262b2a6f5cd4f1909daa022991e3cd8 Mon Sep 17 00:00:00 2001 From: Mustafa Dalloul Date: Wed, 13 Apr 2022 14:50:55 +0300 Subject: [PATCH 159/184] [mstlink][PMCR] Ignoring cap check and fixing pmcr issues Description: Ignoring cap check and fixing pmcr issues Issue: 3030730 Signed-off-by: Mustafa Dalloul --- mlxlink/modules/mlxlink_cables_commander.cpp | 153 ++++++++++--------- mlxlink/modules/mlxlink_cables_commander.h | 10 +- mlxlink/modules/mlxlink_commander.cpp | 6 - mlxlink/modules/mlxlink_maps.cpp | 6 + mlxlink/modules/mlxlink_maps.h | 1 + 5 files changed, 91 insertions(+), 85 deletions(-) diff --git a/mlxlink/modules/mlxlink_cables_commander.cpp b/mlxlink/modules/mlxlink_cables_commander.cpp index ba45a7f3..cc5fbc68 100644 --- a/mlxlink/modules/mlxlink_cables_commander.cpp +++ b/mlxlink/modules/mlxlink_cables_commander.cpp @@ -1042,70 +1042,70 @@ MlxlinkCmdPrint MlxlinkCablesCommander::readFromEEPRM(u_int16_t page , u_int16_t return bytesOutput; } -u_int32_t MlxlinkCablesCommander::getModeAdminFromStr(u_int32_t cap, const string &rateStr) +u_int32_t MlxlinkCablesCommander::getModeAdminFromStr(u_int32_t cap, const string &adminStr, ModuleAccess_t moduleAccess) { int modeAdmin = _prbsMode; - if (!rateStr.empty()) { - modeAdmin = _mlxlinkMaps->_modulePrbsModeStrToCap[rateStr]; - if (!modeAdmin) { - string validRates = "["; - for (auto it = _mlxlinkMaps->_modulePrbsModeCapToStr.begin(); - it != _mlxlinkMaps->_modulePrbsModeCapToStr.end(); it++) { - if (it->first & cap) { - validRates += it->second + ","; - } + string confStr = adminStr.empty()? DEFAULT_PRBS_MODE_STR : adminStr; + modeAdmin = _mlxlinkMaps->_modulePrbsModeStrToCap[confStr]; + if (!modeAdmin || !(modeAdmin & cap)) { + string validRates = "["; + for (auto it = _mlxlinkMaps->_modulePrbsModeCapToStr.begin(); + it != _mlxlinkMaps->_modulePrbsModeCapToStr.end(); it++) { + if (it->first & cap) { + validRates += it->second + ","; } - validRates = deleteLastChar(validRates); - validRates = "]"; - throw MlxRegException("Invalid PRBS pattern value [%s] \nValid values are: %s", - rateStr.c_str(), validRates.c_str()); } - modeAdmin = (int)log2((float) modeAdmin); + validRates = deleteLastChar(validRates); + validRates += "]"; + throw MlxRegException("Invalid PRBS pattern for the %s [%s]\nValid values are: %s", + _mlxlinkMaps->_moduleScopeToStr[moduleAccess].c_str(), confStr.c_str(), + validRates.c_str()); } - return modeAdmin; + return (int)log2((float) modeAdmin); } u_int32_t MlxlinkCablesCommander::getRateAdminFromStr(u_int32_t cap, const string &rateStr) { int rateAdmin = _prbsRate; - if (!rateStr.empty()) { - rateAdmin = _mlxlinkMaps->_modulePrbsRateStrToCap[rateStr]; - if (!rateAdmin) { - string validRates = "["; - for (auto it = _mlxlinkMaps->_modulePrbsRateStrToCap.begin(); - it != _mlxlinkMaps->_modulePrbsRateStrToCap.end(); it++) { - if (it->second & cap) { - validRates += it->first + ","; - } + string confStr = rateStr.empty()? DEFAULT_PRBS_RATE_STR : rateStr; + rateAdmin = _mlxlinkMaps->_modulePrbsRateStrToCap[confStr]; + if (!rateAdmin || !(rateAdmin & cap)) { + string validRates = "["; + for (auto it = _mlxlinkMaps->_modulePrbsRateStrToCap.begin(); + it != _mlxlinkMaps->_modulePrbsRateStrToCap.end(); it++) { + if (it->second & cap) { + validRates += it->first + ","; } - validRates = deleteLastChar(validRates); - validRates += "]"; - throw MlxRegException("Invalid PRBS lane rate configuration [%s] \nValid configurations are: %s", - rateStr.c_str(), validRates.c_str()); } + validRates = deleteLastChar(validRates); + validRates += "]"; + throw MlxRegException("Invalid PRBS lane rate configuration [%s]\nValid configurations are: %s", + confStr.c_str(), validRates.c_str()); } return rateAdmin; } -bool MlxlinkCablesCommander::getInvAdminFromStr(u_int32_t cap, const string &invStr) +bool MlxlinkCablesCommander::getInvAdminFromStr(u_int32_t cap, const string &invStr, ModuleAccess_t moduleAccess) { bool invAdmin = false; if (!invStr.empty()) { invAdmin = true; if (!cap) { - throw MlxRegException("PRBS inversion is not supported by the module"); + throw MlxRegException("PRBS inversion is not supported by the %s", + _mlxlinkMaps->_moduleScopeToStr[moduleAccess].c_str()); } } return invAdmin; } -bool MlxlinkCablesCommander::getSwapAdminFromStr(u_int32_t cap, const string &swapStr) +bool MlxlinkCablesCommander::getSwapAdminFromStr(u_int32_t cap, const string &swapStr, ModuleAccess_t moduleAccess) { bool swapAdmin = false; if (!swapStr.empty()) { swapAdmin = true; if (!cap) { - throw MlxRegException("PAM4 MSB <-> LSB swapping is not supported by the module"); + throw MlxRegException("PAM4 MSB <-> LSB swapping is not supported by the %s", + _mlxlinkMaps->_moduleScopeToStr[moduleAccess].c_str()); } } return swapAdmin; @@ -1158,47 +1158,39 @@ void MlxlinkCablesCommander::checkAndParsePMPTCap(ModuleAccess_t moduleAccess) resetParser(ACCESS_REG_PMPT); updateField("module", _moduleNumber); updateField("slot_index", _slotIndex); - updateField("host_media", _modulePrbsParams[MODULE_PRBS_SELECT] == "HOST"); - updateField("ch_ge", (u_int32_t)moduleAccess); updateField("lane_mask", 0x1); genBuffSendRegister(ACCESS_REG_PMPT, MACCESS_REG_METHOD_GET); } catch (MlxRegException &exc) { regFaild = true; } - if (regFaild || getFieldValue("status") == PMPT_STATUS_NOT_SUPPORTED) { throw MlxRegException("Module doesn't support PRBS and diagnostics data"); } + _prbsRate = getRateAdminFromStr(getFieldValue("lane_rate_cap"), + _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_RATE)]); + + // read the other PMPT caps according to the prbsRate + resetParser(ACCESS_REG_PMPT); + updateField("module", _moduleNumber); + updateField("slot_index", _slotIndex); + updateField("host_media", _modulePrbsParams[MODULE_PRBS_SELECT] == "HOST"); + updateField("ch_ge", (u_int32_t)moduleAccess); + updateField("modulation", _prbsRate >= MODULE_PRBS_LANE_RATE_HDR); + updateField("lane_mask", 0x1); + genBuffSendRegister(ACCESS_REG_PMPT, MACCESS_REG_METHOD_GET); u_int32_t chAccessShift = moduleAccess == MODULE_PRBS_ACCESS_CH? MODULE_PRBS_GEN_INV : 0; - _prbsRate = getRateAdminFromStr(getFieldValue("lane_rate_cap"), _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_RATE)]); _prbsMode = getModeAdminFromStr(getFieldValue("prbs_modes_cap"), - _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_PAT + chAccessShift)]); + _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_PAT + chAccessShift)], moduleAccess); _prbsInv = getInvAdminFromStr(getFieldValue("invt_cap"), - _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_INV + chAccessShift)]); + _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_INV + chAccessShift)], moduleAccess); _prbsSwap = getSwapAdminFromStr(getFieldValue("swap_cap"), - _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_SWAP + chAccessShift)]); + _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_SWAP + chAccessShift)], moduleAccess); _prbsLanes = getLanesFromStr(getFieldValue("ls"), _modulePrbsParams[ModulePrbs_t(MODULE_PRBS_GEN_LANES + chAccessShift)]); } -void MlxlinkCablesCommander::preparePrbsParam(ModuleAccess_t moduleAccess) -{ - switch (moduleAccess) { - case MODULE_PRBS_ACCESS_CH: - case MODULE_PRBS_ACCESS_GEN: - checkAndParsePMPTCap(moduleAccess); - break; - case MODULE_PRBS_ACCESS_CH_GEN: - checkAndParsePMPTCap(MODULE_PRBS_ACCESS_CH); - checkAndParsePMPTCap(MODULE_PRBS_ACCESS_GEN); - break; - default: - checkAndParsePMPTCap(MODULE_PRBS_ACCESS_BOTH); - } -} - u_int32_t MlxlinkCablesCommander::getPMPTStatus(ModuleAccess_t moduleAccess) { resetParser(ACCESS_REG_PMPT); @@ -1214,6 +1206,8 @@ u_int32_t MlxlinkCablesCommander::getPMPTStatus(ModuleAccess_t moduleAccess) void MlxlinkCablesCommander::sendPMPT(ModuleAccess_t moduleAccess) { + checkAndParsePMPTCap(moduleAccess); + resetParser(ACCESS_REG_PMPT); updateField("module", _moduleNumber); updateField("slot_index", _slotIndex); @@ -1236,21 +1230,17 @@ void MlxlinkCablesCommander::sendPMPT(ModuleAccess_t moduleAccess) void MlxlinkCablesCommander::enablePMPT(ModuleAccess_t moduleAccess) { - try { - switch (moduleAccess) { - case MODULE_PRBS_ACCESS_CH: - case MODULE_PRBS_ACCESS_GEN: - sendPMPT(moduleAccess); - break; - case MODULE_PRBS_ACCESS_CH_GEN: - sendPMPT(MODULE_PRBS_ACCESS_CH); - sendPMPT(MODULE_PRBS_ACCESS_GEN); - break; - default: - sendPMPT(MODULE_PRBS_ACCESS_BOTH); - } - } catch (MlxRegException &exc) { - throw MlxRegException("Module doesn't support PRBS and diagnostics data"); + switch (moduleAccess) { + case MODULE_PRBS_ACCESS_CH: + case MODULE_PRBS_ACCESS_GEN: + sendPMPT(moduleAccess); + break; + case MODULE_PRBS_ACCESS_CH_GEN: + sendPMPT(MODULE_PRBS_ACCESS_CH); + sendPMPT(MODULE_PRBS_ACCESS_GEN); + break; + default: + sendPMPT(MODULE_PRBS_ACCESS_BOTH); } } @@ -1274,7 +1264,6 @@ void MlxlinkCablesCommander::handlePrbsTestMode(const string &ctrl, ModuleAccess if (ctrl == "EN") { MlxlinkRecord::printCmdLine("Enabling Module PRBS Test Mode", _jsonRoot); getNumOfModuleLanes(); - preparePrbsParam(moduleAccess); enablePMPT(moduleAccess); } else if (ctrl == "DS") { MlxlinkRecord::printCmdLine("Disabling Module PRBS Test Mode", _jsonRoot); @@ -1364,8 +1353,8 @@ void MlxlinkCablesCommander::showPrbsTestMode() prbsAcces.push_back(MlxlinkRecord::addSpaceForModulePrbs("Checker")); prbsAcces.push_back(MlxlinkRecord::addSpaceForModulePrbs("Generator")); - getPMPTConfiguration(MODULE_PRBS_ACCESS_GEN, prbsPattern, prbsRate, prbsInv, prbsSwap); getPMPTConfiguration(MODULE_PRBS_ACCESS_CH, prbsPattern, prbsRate, prbsInv, prbsSwap); + getPMPTConfiguration(MODULE_PRBS_ACCESS_GEN, prbsPattern, prbsRate, prbsInv, prbsSwap); setPrintVal(prbsOutput, "PRBS Access", getStringFromVector(prbsAcces), ANSI_COLOR_RESET, true, true, true); setPrintVal(prbsOutput, "PRBS Pattern", getStringFromVector(prbsPattern), ANSI_COLOR_RESET, true, true, true); @@ -1472,6 +1461,10 @@ void MlxlinkCablesCommander::showControlParams() u_int32_t rxAmp = getFieldValue("cable_rx_amp"); bool isCmis = _cableIdentifier >= IDENTIFIER_SFP_DD; + resetParser(ACCESS_REG_PMCR); + updateField("local_port", _localPort); + genBuffSendRegister(ACCESS_REG_PMCR, MACCESS_REG_METHOD_GET); + if (isCmis) { _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_RX_EMPH].first += " (pre)"; rxEmph /= 2; @@ -1480,16 +1473,21 @@ void MlxlinkCablesCommander::showControlParams() sprintf(rxEmphStr, "%.1f", rxEmph); string strFmt = txEq? to_string(txEq) + " dB" : "No Equalization"; + strFmt = getFieldValue("tx_equ_override_cap")? strFmt : "Not Supported"; setPrintVal(controlParamsOutput, _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_TX_EQ].first, strFmt); strFmt = (isCmis? rxEmphStr : to_string((u_int32_t) rxEmph)) + " dB"; strFmt = (rxEmph > 0)? strFmt: "No Equalization"; + strFmt = getFieldValue("rx_emp_override_cap")? strFmt : "Not Supported"; setPrintVal(controlParamsOutput, _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_RX_EMPH].first, strFmt); strFmt = rxPostEmph? to_string(rxPostEmph) + " dB" : "No Equalization"; - setPrintVal(controlParamsOutput, _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_RX_POST_EMPH].first, strFmt); + strFmt = getFieldValue("rx_post_emp_override_cap")? strFmt : "Not Supported"; + setPrintVal(controlParamsOutput, _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_RX_POST_EMPH].first, strFmt, + ANSI_COLOR_RESET, isCmis); strFmt = _mlxlinkMaps->_moduleRxAmp[rxAmp]; + strFmt = getFieldValue("rx_amp_override_cap")? strFmt : "Not Supported"; setPrintVal(controlParamsOutput, _modulePMCRParams[CABLE_CONTROL_PARAMETERS_SET_RX_AMP].first, strFmt); controlParamsOutput.toJsonFormat(_jsonRoot); @@ -1502,9 +1500,11 @@ u_int32_t MlxlinkCablesCommander::getPMCRValue(ControlParam paramId, const strin bool invalidConfiguration = false; bool isCmis = _cableIdentifier >= IDENTIFIER_SFP_DD; bool isDecemal = false; + string valueStr = value; try { - valueToSet = value == "NE"? 0 : stod(value); + toUpperCase(valueStr); + valueToSet = valueStr == "NE"? 0 : stod(value); isDecemal = (valueToSet - (int) valueToSet) > 0; } catch (exception &exc) { invalidConfiguration = true; @@ -1576,6 +1576,8 @@ void MlxlinkCablesCommander::checkPMCRFieldsCap(vectorfirst].first.c_str(), it->second.c_str(), validCapStr.c_str()); } } + */ } void MlxlinkCablesCommander::buildPMCRRequest(ControlParam paramId, const string &value) diff --git a/mlxlink/modules/mlxlink_cables_commander.h b/mlxlink/modules/mlxlink_cables_commander.h index 26a941d9..145de4b4 100644 --- a/mlxlink/modules/mlxlink_cables_commander.h +++ b/mlxlink/modules/mlxlink_cables_commander.h @@ -83,6 +83,9 @@ typedef struct { #define VOLT_UNIT 1000 #define MILLIVOLT_UNIT 10 +#define DEFAULT_PRBS_MODE_STR "PRBS31" +#define DEFAULT_PRBS_RATE_STR "HDR" + typedef struct Page{ u_int32_t page; u_int16_t offset; @@ -168,16 +171,15 @@ class MlxlinkCablesCommander :public MlxlinkRegParser{ void getNumOfModuleLanes(); u_int32_t getRateAdminFromStr(u_int32_t cap, const string &rateStr); - u_int32_t getModeAdminFromStr(u_int32_t cap, const string &adminStr); - bool getInvAdminFromStr(u_int32_t cap, const string &invStr); - bool getSwapAdminFromStr(u_int32_t cap, const string &swapStr); + u_int32_t getModeAdminFromStr(u_int32_t cap, const string &adminStr, ModuleAccess_t moduleAccess); + bool getInvAdminFromStr(u_int32_t cap, const string &invStr, ModuleAccess_t moduleAccess); + bool getSwapAdminFromStr(u_int32_t cap, const string &swapStr, ModuleAccess_t moduleAccess); u_int32_t getLanesFromStr(u_int32_t cap, const string &lanesStr); void getPMPTConfiguration(ModuleAccess_t moduleAccess, vector &prbsPattern, vector &prbsRate, vector &prbsInv, vector &prbsSwap); void getPMPDInfo(vector &traffic, vector &errors, vector &ber, vector &snr); string getPMPDLockStatus(); void checkAndParsePMPTCap(ModuleAccess_t moduleAccess); - void preparePrbsParam(ModuleAccess_t moduleAccess); u_int32_t getPMPTStatus(ModuleAccess_t moduleAccess); void sendPMPT(ModuleAccess_t moduleAccess); void enablePMPT(ModuleAccess_t moduleAccess); diff --git a/mlxlink/modules/mlxlink_commander.cpp b/mlxlink/modules/mlxlink_commander.cpp index 98ff3d30..a910c141 100644 --- a/mlxlink/modules/mlxlink_commander.cpp +++ b/mlxlink/modules/mlxlink_commander.cpp @@ -4487,12 +4487,6 @@ void MlxlinkCommander::performModulePrbsCommands() } else if (_userInput.isPrbsChProvided && _userInput.isPrbsGenProvided) { prbsModuleAccess = MODULE_PRBS_ACCESS_CH_GEN; } - if (_userInput.modulePrbsParams[MODULE_PRBS_GEN_PAT] == _userInput.modulePrbsParams[MODULE_PRBS_CH_PAT] && - _userInput.modulePrbsParams[MODULE_PRBS_GEN_SWAP] == _userInput.modulePrbsParams[MODULE_PRBS_CH_SWAP] && - _userInput.modulePrbsParams[MODULE_PRBS_GEN_INV] == _userInput.modulePrbsParams[MODULE_PRBS_CH_INV] && - _userInput.modulePrbsParams[MODULE_PRBS_GEN_LANES] == _userInput.modulePrbsParams[MODULE_PRBS_GEN_LANES]) { - prbsModuleAccess = MODULE_PRBS_ACCESS_BOTH; - } _cablesCommander->handlePrbsTestMode(_userInput.modulePrbsParams[MODULE_PRBS_MODE], prbsModuleAccess); } else { _cablesCommander->showPrbsTestMode(); diff --git a/mlxlink/modules/mlxlink_maps.cpp b/mlxlink/modules/mlxlink_maps.cpp index 04066ada..854fbefe 100644 --- a/mlxlink/modules/mlxlink_maps.cpp +++ b/mlxlink/modules/mlxlink_maps.cpp @@ -990,6 +990,12 @@ void MlxlinkMaps::modulePrbsMapping() _modulePMPDStatus[PMPD_STATUS_NORMAL_MODE] = "Normal Mode"; _modulePMPDStatus[PMPD_STATUS_NOT_LOCKED] = "Not Locked"; _modulePMPDStatus[PMPD_STATUS_LOCKED] = "Locked"; + + _moduleScopeToStr[MODULE_PRBS_ACCESS_CH] = "Checker"; + _moduleScopeToStr[MODULE_PRBS_ACCESS_GEN] = "Generator"; + _moduleScopeToStr[MODULE_PRBS_ACCESS_BOTH] = "Module"; + _moduleScopeToStr[MODULE_PRBS_ACCESS_CH_GEN] = "Module"; + } void MlxlinkMaps::qsfpComlianceMapping() diff --git a/mlxlink/modules/mlxlink_maps.h b/mlxlink/modules/mlxlink_maps.h index 96673b54..954b4157 100644 --- a/mlxlink/modules/mlxlink_maps.h +++ b/mlxlink/modules/mlxlink_maps.h @@ -176,6 +176,7 @@ class MlxlinkMaps{ std::map _modulePMPDStatus; std::map _modulePrbsModeCapToStr; std::map _modulePrbsModeStrToCap; + std::map _moduleScopeToStr; std::map _moduleRxAmp; std::map _moduleRxAmpCap; std::map _pepcStatus; From 0fadf22a21fae3b1a21b7c78cacc9c5fecf325fd Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Mon, 14 Mar 2022 12:11:11 +0200 Subject: [PATCH 160/184] Mask boot-record CRC in fw update signature instead of skipping it Description: Per FW request we'll mask boot-record last DWORD (CRC/auth-tag) with 0xff instead of skipping it for fw-update signature Tested OS: Linux Tested devices: Albatross Tested flows: flint sign Known gaps (with RM ticket): N/A Issue: 3005220 Change-Id: Ic5aed30e730dff7558a4b81d51dd8a938db73068 Signed-off-by: Matan Eliyahu --- mlxfwops/lib/fs4_ops.cpp | 6 +++--- mlxfwops/lib/fs4_ops.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 37e120a7..fd04f774 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -515,13 +515,13 @@ void Fs4Operations::RemoveCRCsFromMainSection(vector& img) { /* This function responsible on removing boot-record last 4B of CRC */ -bool Fs4Operations::RemoveCRCFromBootRecord(vector& img) { +bool Fs4Operations::MaskBootRecordCRC(vector& img) { u_int32_t boot_record_size_without_crc = 0; if (!getBootRecordSize(boot_record_size_without_crc)) { return errmsg("Failed to get boot_record size\n"); } u_int32_t boot_record_crc_addr = _boot_record_ptr + boot_record_size_without_crc; - img.erase(img.begin() + boot_record_crc_addr, img.begin() + boot_record_crc_addr + 4); // Pop 4B of CRC + fill(img.begin() + boot_record_crc_addr, img.begin() + boot_record_crc_addr + 4, 0xff); // Mask 4B of CRC/auth-tag return true; } @@ -538,7 +538,7 @@ bool Fs4Operations::GetImageDataForSign(MlxSign::SHAType shaType, vector& img); - bool RemoveCRCFromBootRecord(vector& img); + bool MaskBootRecordCRC(vector& img); // Members Fs4ImgInfo _fs4ImgInfo; From 1767146760b680f43f713bd0ef0d52384d3fab6e Mon Sep 17 00:00:00 2001 From: Roei Yitzhak Date: Mon, 21 Mar 2022 14:37:43 +0200 Subject: [PATCH 161/184] derefrence before null check Description: Picture attached in RM ticket Tested OS: Tested devices: Tested flows: Known gaps (with RM ticket): Issue: 3012837 Change-Id: I88a8148d93609e2689d805746a2cb076725d90a2 Signed-off-by: Matan Eliyahu --- fw_comps_mgr/fw_comps_mgr.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fw_comps_mgr/fw_comps_mgr.cpp b/fw_comps_mgr/fw_comps_mgr.cpp index be0bb6c6..ffc65119 100644 --- a/fw_comps_mgr/fw_comps_mgr.cpp +++ b/fw_comps_mgr/fw_comps_mgr.cpp @@ -1157,9 +1157,7 @@ FwCompsMgr::FwCompsMgr(uefi_Dev_t *uefi_dev, uefi_dev_extra_t *uefi_extra) _lastError = FWCOMPS_MEM_ALLOC_FAILED; return; } - if (uefi_extra != NULL) { - _hwDevId = uefi_extra->dev_info.hw_dev_id; - } + _hwDevId = uefi_extra->dev_info.hw_dev_id; _openedMfile = true; _autoUpdate = false; _linkXFlow = false; From cd25f39bac7bf3772d30c813ef8d04f151e59c43 Mon Sep 17 00:00:00 2001 From: Roei Yitzhak Date: Mon, 21 Mar 2022 14:32:29 +0200 Subject: [PATCH 162/184] dereference after null check Description: Picture attached in RM ticket Tested OS: Tested devices: Tested flows: Known gaps (with RM ticket): Issue: 3012827 Change-Id: Ia796b3149f610476d9fbb17e4ac68093fe2491d3 Signed-off-by: Matan Eliyahu --- mlxfwops/lib/fw_ops.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 1ed29468..5c6b003c 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -436,9 +436,9 @@ bool FwOperations::FindAllImageStart(FBase *ioAccess, (*found_images)++; } } + DPRINTF(("FwOperations::FindAllImageStart found %d image(s)\n", *found_images)); } - DPRINTF(("FwOperations::FindAllImageStart found %d image(s)\n", *found_images)); return true; } // CAN BE IN ANOTHER MODULE From 75a9b2e9ff2c068e425beb3bd652ba1dd5a30d14 Mon Sep 17 00:00:00 2001 From: Roei Yitzhak Date: Tue, 22 Mar 2022 10:58:29 +0200 Subject: [PATCH 163/184] uninitialized scalar variable Description: Tested OS: Tested devices: Tested flows: Known gaps (with RM ticket): Issue: 3013732 Change-Id: I0d37ebe6a215493de35242eda5acb5a89ff2cb54 Signed-off-by: Matan Eliyahu --- mlxfwops/lib/fs4_ops.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index fd04f774..377ff5d4 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -3514,7 +3514,7 @@ u_int32_t Fs4Operations::getImageSize() bool Fs4Operations::GetImageSize(u_int32_t* image_size){ - bool is_encrypted; + bool is_encrypted = false; if (!isEncrypted(is_encrypted)){ return false; } From ae83b31c5420e24b9e767a7530e03f4811e76ed1 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Sun, 17 Apr 2022 11:01:09 +0300 Subject: [PATCH 164/184] [coverity issue] dereference null return Description: Picture in RM ticket Tested OS: Tested devices: Tested flows: Known gaps (with RM ticket): Issue: 3012931 Change-Id: Ia9e13eabf0f1befe7526f234bd1d3b7b5783b821 Signed-off-by: Matan Eliyahu --- reg_access/reg_access.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/reg_access/reg_access.c b/reg_access/reg_access.c index 549dbd12..93d494e1 100644 --- a/reg_access/reg_access.c +++ b/reg_access/reg_access.c @@ -539,9 +539,10 @@ reg_access_status_t reg_access_nvda(mfile *mf, reg_access_method_t method, struc /************************************ * Function: reg_access_mgir ************************************/ -reg_access_status_t reg_access_mgir(mfile *mf, reg_access_method_t method, - struct reg_access_hca_mgir *mgir) { - if (mf->tp == MST_MLNXOS) { +reg_access_status_t reg_access_mgir(mfile *mf, reg_access_method_t method, struct reg_access_hca_mgir *mgir) { + if (!mf) { + return ME_UNSUPPORTED_DEVICE; + } else if (mf->tp == MST_MLNXOS) { REG_ACCCESS_VAR(mf, method, REG_ID_MGIR, mgir, mgir, MGIR_REG_SIZE, MGIR_REG_SIZE, MGIR_REG_SIZE, reg_access_hca); } else { From 260b91e615258a51f256cdae433f6912abb89aaf Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Tue, 22 Mar 2022 14:59:48 +0200 Subject: [PATCH 165/184] fix query command when not in MCC flow Description: Few fields (prs, PN, description) were missing from query command since they were not parsed from image_info section since they were parsed only if image_info.minor_version == 2, but in some devices (fs3, fs4) we see the actual image_info.minor_version is 3 so we add this as a condition to parse these fields Tested OS: Linux Tested devices: CX5 Tested flows: flint -ocr query full Known gaps (with RM ticket): N/A Issue: 3014364 Change-Id: I98f81264421a82fa82f0c0783bff0aceec805feb Signed-off-by: Matan Eliyahu --- mlxfwops/lib/fs3_ops.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mlxfwops/lib/fs3_ops.cpp b/mlxfwops/lib/fs3_ops.cpp index f86bbf23..8c94cc03 100644 --- a/mlxfwops/lib/fs3_ops.cpp +++ b/mlxfwops/lib/fs3_ops.cpp @@ -320,8 +320,9 @@ bool Fs3Operations::GetImageInfo(u_int8_t *buff) strcpy(_fs3ImgInfo.ext_info.image_vsd, image_info.vsd); strcpy(_fwImgInfo.ext_info.psid, image_info.psid); strcpy(_fwImgInfo.ext_info.product_ver, image_info.prod_ver); + + // get name, prs name and description if (image_info.minor_version == 2) { - // get name, prs name and description struct tools_open_image_info tools_image_info; memset(&tools_image_info, 0, sizeof(tools_image_info)); tools_open_image_info_unpack(&tools_image_info, buff); @@ -329,6 +330,12 @@ bool Fs3Operations::GetImageInfo(u_int8_t *buff) strncpy(_fs3ImgInfo.ext_info.description, tools_image_info.description, DESCRIPTION_LEN); strncpy(_fs3ImgInfo.ext_info.prs_name, tools_image_info.prs_name, FS3_PRS_NAME_LEN); } + else if (image_info.minor_version == 3) { + strncpy(_fs3ImgInfo.ext_info.name, image_info.name, NAME_LEN); + strncpy(_fs3ImgInfo.ext_info.description, image_info.description, DESCRIPTION_LEN); + strncpy(_fs3ImgInfo.ext_info.prs_name, image_info.prs_name, FS3_PRS_NAME_LEN); + } + _fs3ImgInfo.ext_info.mcc_en = image_info.mcc_en; _fs3ImgInfo.ext_info.security_mode = (_fs3ImgInfo.ext_info.security_mode | ((image_info.mcc_en == 1) ? SMM_MCC_EN : 0) | From 6f51be51809199c9c17b8e6d7ab9075fecce3497 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Sun, 27 Mar 2022 15:07:50 +0300 Subject: [PATCH 166/184] Support CX8 for query and sign commands Description: CX8 dev id added + its boot-record size Tested OS: Linux Tested devices: CX8 Tested flows: flint sign/query Known gaps (with RM ticket): N/A Issue: 3015866 Change-Id: If2e624da4d04d53fb88c004ce39ae481840ce8d4 Signed-off-by: Matan Eliyahu --- mlxfwops/lib/fs4_ops.cpp | 3 +++ mlxfwops/lib/fw_ops.cpp | 8 +++++++- mlxfwops/lib/mlxfwops_com.h | 5 ++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 377ff5d4..564852a1 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -3677,6 +3677,9 @@ bool Fs4Operations::getBootRecordSize(u_int32_t& boot_record_size) { case CT_ABIR_GEARBOX: boot_record_size = 0x260; // Actual size is 0x264 return true; + case CT_CONNECTX8: + boot_record_size = 0x2a0; // Actual size is 0x2a4 + return true; default: return false; diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 5c6b003c..61fac971 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -1178,6 +1178,7 @@ const FwOperations::HwDevData FwOperations::hwDevData[] = { { "ConnectX-6DX", CX6DX_HW_ID, CT_CONNECTX6DX, CFT_HCA, 0, {4125, 0}, {{UNKNOWN_BIN, {0}}}}, { "ConnectX-6LX", CX6LX_HW_ID, CT_CONNECTX6LX, CFT_HCA, 0, {4127, 0}, {{UNKNOWN_BIN, {0}}}}, { "ConnectX-7", CX7_HW_ID, CT_CONNECTX7, CFT_HCA, 0, {4129, 0}, {{UNKNOWN_BIN, {0}}}}, + { "ConnectX-8", CX8_HW_ID, CT_CONNECTX8, CFT_HCA, 0, {4131, 0}, {{UNKNOWN_BIN, {0}}}}, { "BlueField", BF_HW_ID, CT_BLUEFIELD, CFT_HCA, 0, {41680, 41681, 41682, 0}, {{UNKNOWN_BIN, {0}}}}, { "BlueField2", BF2_HW_ID, CT_BLUEFIELD2, CFT_HCA, 0, {41684, 41685, 41686, 0}, {{UNKNOWN_BIN, {0}}}}, { "BlueField3", BF3_HW_ID, CT_BLUEFIELD3, CFT_HCA, 0, {41690, 41691, 41692, 0}, {{UNKNOWN_BIN, {0}}}}, @@ -1207,6 +1208,7 @@ const FwOperations::HwDev2Str FwOperations::hwDev2Str[] = { {"ConnectX-6DX", CX6DX_HW_ID, 0x00}, {"ConnectX-6LX", CX6LX_HW_ID, 0x00}, {"ConnectX-7", CX7_HW_ID, 0x00}, + {"ConnectX-8", CX8_HW_ID, 0x00}, {"BlueField", BF_HW_ID, 0x00}, {"BlueField2", BF2_HW_ID, 0x00}, {"BlueField3", BF3_HW_ID, 0x00}, @@ -1262,6 +1264,8 @@ chip_type FwOperations::GetChipType(string chip) return CT_CONNECTX6LX; else if (chip == "CT_CONNECTX7") return CT_CONNECTX7; + else if (chip == "CT_CONNECTX8") + return CT_CONNECTX8; else if (chip == "CT_SPECTRUM3") return CT_SPECTRUM3; else if (chip == "CT_BLUEFIELD2") @@ -1857,7 +1861,8 @@ void FwOperations::SetDevFlags(chip_type_t chipType, u_int32_t devType, fw_img_t (chipType == CT_CONNECTX6) || (chipType == CT_CONNECTX6DX) || (chipType == CT_CONNECTX6LX) || \ (chipType == CT_SPECTRUM) || (chipType == CT_SPECTRUM2) || (chipType == CT_SPECTRUM3) || \ (chipType == CT_CONNECTX7) || (chipType == CT_QUANTUM2) || (chipType == CT_SPECTRUM4) || \ - (chipType == CT_BLUEFIELD) || (chipType == CT_BLUEFIELD2) || (chipType == CT_BLUEFIELD3); + (chipType == CT_BLUEFIELD) || (chipType == CT_BLUEFIELD2) || (chipType == CT_BLUEFIELD3) || \ + (chipType == CT_CONNECTX8); } if ((!ibDev && !ethDev) || chipType == CT_UNKNOWN) { @@ -2289,6 +2294,7 @@ u_int8_t FwOperations::GetFwFormatFromHwDevID(u_int32_t hwDevId) hwDevId == CX6DX_HW_ID || hwDevId == CX6LX_HW_ID || hwDevId == CX7_HW_ID || + hwDevId == CX8_HW_ID || hwDevId == BF_HW_ID || hwDevId == BF2_HW_ID || hwDevId == BF3_HW_ID || diff --git a/mlxfwops/lib/mlxfwops_com.h b/mlxfwops/lib/mlxfwops_com.h index a039195c..74b4385e 100644 --- a/mlxfwops/lib/mlxfwops_com.h +++ b/mlxfwops/lib/mlxfwops_com.h @@ -79,6 +79,7 @@ #define CX6DX_HW_ID 530 #define CX6LX_HW_ID 534 #define CX7_HW_ID 536 +#define CX8_HW_ID 542 #define BF_HW_ID 529 #define BF2_HW_ID 532 #define BF3_HW_ID 540 @@ -87,6 +88,7 @@ #define CX3_PRO_HW_ID 503 #define IS4_HW_ID 435 #define CONNECT_IB_HW_ID 511 + #define INBAND_MAX_REG_SIZE 44 #define MCDA_REG_HEADER 16 @@ -291,6 +293,7 @@ typedef enum chip_type { CT_CONNECTX6DX, CT_CONNECTX6LX, CT_CONNECTX7, + CT_CONNECTX8, CT_SPECTRUM3, CT_BLUEFIELD2, CT_BLUEFIELD3, @@ -308,7 +311,7 @@ typedef enum chip_type { ((chipType) == CT_CONNECTX4) || ((chipType) == CT_CONNECTX4_LX) || \ ((chipType) == CT_CONNECTX5) || \ ((chipType) == CT_CONNECTX6) || ((chipType) == CT_CONNECTX6DX) || ((chipType) == CT_CONNECTX6LX) || \ - ((chipType) == CT_CONNECTX7) || \ + ((chipType) == CT_CONNECTX7) || ((chipType) == CT_CONNECTX8) || \ ((chipType) == CT_BLUEFIELD) || ((chipType) == CT_BLUEFIELD2) || ((chipType) == CT_BLUEFIELD3)) From 5ff4ce9c4e70c73cdefda736dffe87d9fe5f4da7 Mon Sep 17 00:00:00 2001 From: Roei Yitzhak Date: Mon, 21 Mar 2022 14:20:27 +0200 Subject: [PATCH 167/184] invalid type in argument to printf format specifier Description: Tested OS: Tested devices: Tested flows: Known gaps (with RM ticket): Issue: 3012806 Change-Id: Ic8dfd027dad479b2a9aa4ae279c2d58ee560b08d Signed-off-by: Matan Eliyahu --- flint/subcommands.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index 82b6e242..7c13144e 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -654,7 +654,7 @@ bool SubCommand::basicVerifyParams() } else if (_maxCmdParamNum != -1 && (int)_flintParams.cmd_params.size() > _maxCmdParamNum) { // _maxCmdParamNum == -1 means ignore this check if (_maxCmdParamNum) { - reportErr(true, FLINT_CMD_ARGS_ERROR2, _name.c_str(), _maxCmdParamNum, _flintParams.cmd_params.size()); + reportErr(true, FLINT_CMD_ARGS_ERROR2, _name.c_str(), _maxCmdParamNum, (int)_flintParams.cmd_params.size()); } else { reportErr(true, FLINT_CMD_ARGS_ERROR5, _name.c_str()); } @@ -4531,7 +4531,7 @@ FlintStatus SgSubCommand::sgFs2() //different behaviours for fs2 device with blank guids and fs2 device with guids or image //different behaviour if isfailesafe or not if (_flintParams.cmd_params.size() > 1) { - reportErr(true, FLINT_CMD_ARGS_ERROR2, _name.c_str(), 1, _flintParams.cmd_params.size()); + reportErr(true, FLINT_CMD_ARGS_ERROR2, _name.c_str(), 1, (int)_flintParams.cmd_params.size()); } if (_flintParams.device_specified && !_info.fs2_info.blank_guids) { @@ -4694,7 +4694,7 @@ bool SmgSubCommand::verifyParams() } if (_flintParams.cmd_params.size() != 0 && _flintParams.cmd_params.size() != 2) { - reportErr(true, FLINT_CMD_ARGS_ERROR4, _name.c_str(), 0, 2, _flintParams.cmd_params.size()); + reportErr(true, FLINT_CMD_ARGS_ERROR4, _name.c_str(), 0, 2, (int)_flintParams.cmd_params.size()); return false; } From bb18e0653d304c5f02dc13873c9611409d2373db Mon Sep 17 00:00:00 2001 From: Roei Yitzhak Date: Mon, 21 Mar 2022 14:27:38 +0200 Subject: [PATCH 168/184] dereference before null check Description: Picture attached in RM ticket Tested OS: Tested devices: Tested flows: Known gaps (with RM ticket): Issue: 3012817 Change-Id: I5f24fd799f21b0b72360718c3d62e532491d884e Signed-off-by: Matan Eliyahu --- flint/subcommands.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index 7c13144e..d7a0161c 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -2853,12 +2853,10 @@ FlintStatus BurnSubCommand::executeCommand() // query both image and device (deviceQuery can fail but we save rc) _devQueryRes = _fwOps->FwQuery(&_devInfo, true, false, true, false, (_flintParams.silent == false)); - if (_imgOps) { - if (!_imgOps->FwQuery(&_imgInfo)) { - UnlockDevice(_fwOps); - reportErr(true, FLINT_FAILED_QUERY_ERROR, "image", _flintParams.image.c_str(), _imgOps->err()); - return FLINT_FAILED; - } + if (!_imgOps->FwQuery(&_imgInfo)) { + UnlockDevice(_fwOps); + reportErr(true, FLINT_FAILED_QUERY_ERROR, "image", _flintParams.image.c_str(), _imgOps->err()); + return FLINT_FAILED; } // Abort if the image is restricted according to the Security-Version From 55203ea4e925e17c0d16327a2484cfbf243902cd Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Sun, 17 Apr 2022 11:07:47 +0300 Subject: [PATCH 169/184] [flint] Adding string representation to new ITOC section type 0xb0 Description: N/A Tested OS: Linux Tested devices: N/A Tested flows: flint -i v Known gaps (with RM ticket): N/A Issue: 3019470 Change-Id: I3fd3d8ba5f62ef0542adc53197842897f6d129a0 Signed-off-by: Matan Eliyahu --- mlxfwops/lib/flint_base.h | 1 + mlxfwops/lib/fs3_ops.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/mlxfwops/lib/flint_base.h b/mlxfwops/lib/flint_base.h index 7ed968d8..0f7ab498 100644 --- a/mlxfwops/lib/flint_base.h +++ b/mlxfwops/lib/flint_base.h @@ -296,6 +296,7 @@ typedef enum fs3_section { FS3_HMAC_DIGEST = 0xa5, FS4_RSA_PUBLIC_KEY = 0xa6, FS4_RSA_4096_SIGNATURES = 0xa7, + FS4_EXCLKSYNC_INFO = 0xb0, FS3_MFG_INFO = 0xe0, FS3_DEV_INFO = 0xe1, FS3_NV_DATA1 = 0xe2, diff --git a/mlxfwops/lib/fs3_ops.cpp b/mlxfwops/lib/fs3_ops.cpp index 8c94cc03..d534814e 100644 --- a/mlxfwops/lib/fs3_ops.cpp +++ b/mlxfwops/lib/fs3_ops.cpp @@ -145,6 +145,7 @@ const Fs3Operations::SectionInfo Fs3Operations::_fs3SectionsInfoArr[] = { {FS4_TOOLS_AREA, "TOOLS_AREA"}, {FS4_RSA_PUBLIC_KEY, "RSA_PUBLIC_KEY"}, {FS4_RSA_4096_SIGNATURES, "RSA_4096_SIGNATURES"}, + {FS4_EXCLKSYNC_INFO, "EXCLKSYNC_INFO"}, {FS4_HASHES_TABLE, "HASHES_TABLE"} }; From 953dd55d5b0f3782c54503cd894c89fefadb1dfc Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Mon, 28 Mar 2022 15:02:35 +0300 Subject: [PATCH 170/184] Updating SPEC4 boot-record size aligned to model 4.2 Description: Secure-boot signature failed due to misalignment of boot-record size between flint and HW. boot-record size updated accordingly Tested OS: Linux Tested devices: SPEC4 Tested flows: load signed image on model and pass HW auth Known gaps (with RM ticket): N/A Issue: None Change-Id: I13d8f9f94f01eb6086d1fb2838057adc4c130723 Signed-off-by: Matan Eliyahu --- mlxfwops/lib/fs4_ops.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 564852a1..9e6355dd 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -3672,7 +3672,7 @@ bool Fs4Operations::getBootRecordSize(u_int32_t& boot_record_size) { boot_record_size = 0x4d0; // Actual size is 0x4d4 return true; case CT_SPECTRUM4: - boot_record_size = 0x4f0; // Actual size is 0x4f4 + boot_record_size = 0x660; // Actual size is 0x664 return true; case CT_ABIR_GEARBOX: boot_record_size = 0x260; // Actual size is 0x264 From f94abca13f9d388861619d8cc11e90c279fdbae1 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Tue, 29 Mar 2022 16:43:51 +0300 Subject: [PATCH 171/184] QuerySecurityFeatures() failed on CX6DX with applied token and MFBA&direct-access enabled via cr-space Description: Since CX6DX/CX6LX/BF2 doesn't expose security version via cr-space we need to make sure we don't try to read it in case of these devices. We encounter this flow only in a scenario that CS token is applied and the user enabled MFBA and direct-access via CR-space Tested OS: Linux Tested devices: CX6DX Tested flows: apply token && enable MFBA and direct-access && flint query/burn --no_fw_ctrl/-ocr Known gaps (with RM ticket): N/A Issue: 3020135 Change-Id: I7f47b1193aa8460b6e4e57f44f405c908dc3abaa Signed-off-by: Matan Eliyahu --- flint/subcommands.cpp | 4 ++-- mlxfwops/lib/fs4_ops.cpp | 47 +++++++++++++++++++++++++++---------- mlxfwops/lib/fs4_ops.h | 1 + mlxfwops/lib/fsctrl_ops.cpp | 2 +- mlxfwops/lib/fw_ops.cpp | 6 ++--- mlxfwops/lib/mlxfwops_com.h | 2 +- 6 files changed, 43 insertions(+), 19 deletions(-) diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index d7a0161c..1d995806 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -3708,9 +3708,9 @@ FlintStatus QuerySubCommand::printInfo(const fw_info_t& fwInfo, bool fullQuery) else { printf("Life cycle: %s\n", life_cycle_strings[index]); } - if (fwInfo.fs3_info.life_cycle == GA_SECURED) { + if (fwInfo.fs3_info.life_cycle == GA_SECURED && fwInfo.fs3_info.device_security_version_access_method == DIRECT_ACCESS) { printf("EFUSE Security Ver: %d\n", fwInfo.fs3_info.device_security_version_gw); - } + } } } } diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 9e6355dd..01008eab 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -1088,10 +1088,6 @@ bool Fs4Operations::FwQuery(fw_info_t *fwInfo, bool readRom, bool isStripedImage return false; } - //* Security version - _fs3ImgInfo.ext_info.image_security_version = _security_version; - _fs3ImgInfo.ext_info.device_security_version_access_method = NOT_VALID; - if (!QuerySecurityFeatures()) { return false; } @@ -1129,9 +1125,38 @@ bool Fs4Operations::IsLifeCycleAccessible(chip_type_t chip_type) return res; } +bool Fs4Operations::IsSecurityVersionAccessible(chip_type_t chip_type) +{ + DPRINTF(("Fs4Operations::IsSecurityVersionAccessible\n")); + bool res = true; + // Security version feature depends on life-cycle + if (IsLifeCycleSupported()) + { + switch (chip_type) + { + case CT_BLUEFIELD2: + case CT_CONNECTX6DX: + case CT_CONNECTX6LX: + res = false; + break; + default: + break; + } + } + else + { + res = false; + } + + DPRINTF(("Fs4Operations::IsSecurityVersionAccessible res = %s\n", res ? "TRUE" : "FALSE")); + return res; +} + bool Fs4Operations::QuerySecurityFeatures() { DPRINTF(("Fs4Operations::QuerySecurityFeatures _fwImgInfo.ext_info.chip_type = %d\n", _fwImgInfo.ext_info.chip_type)); + _fs3ImgInfo.ext_info.image_security_version = _security_version; + _fs3ImgInfo.ext_info.device_security_version_access_method = NOT_VALID; try { if (IsLifeCycleAccessible(_fwImgInfo.ext_info.chip_type)) { CRSpaceRegisters crSpaceReg(getMfileObj(), _fwImgInfo.ext_info.chip_type); @@ -1140,16 +1165,14 @@ bool Fs4Operations::QuerySecurityFeatures() if (_fs3ImgInfo.ext_info.life_cycle == GA_SECURED) { _fs3ImgInfo.ext_info.global_image_status = crSpaceReg.getGlobalImageStatus(); - _fs3ImgInfo.ext_info.device_security_version_access_method = GW; - _fs3ImgInfo.ext_info.device_security_version_gw = crSpaceReg.getSecurityVersion(); + if (IsSecurityVersionAccessible(_fwImgInfo.ext_info.chip_type)) { + _fs3ImgInfo.ext_info.device_security_version_gw = crSpaceReg.getSecurityVersion(); + _fs3ImgInfo.ext_info.device_security_version_access_method = DIRECT_ACCESS; + } } } } - catch(logic_error e) { - printf("%s\n", e.what()); - return false; - } - catch(exception e) { + catch(exception& e) { printf("%s\n", e.what()); return false; } @@ -4418,7 +4441,7 @@ bool Fs4Operations::IsSecurityVersionViolated(u_int32_t image_security_version) // Set device security-version (from EFUSEs) if (_fs3ImgInfo.ext_info.device_security_version_access_method == MFSV) { deviceEfuseSecurityVersion = _fs3ImgInfo.ext_info.device_security_version_mfsv.efuses_sec_ver; - } else if (_fs3ImgInfo.ext_info.device_security_version_access_method == GW) { + } else if (_fs3ImgInfo.ext_info.device_security_version_access_method == DIRECT_ACCESS) { deviceEfuseSecurityVersion = _fs3ImgInfo.ext_info.device_security_version_gw; } else { deviceEfuseSecurityVersion = 0; diff --git a/mlxfwops/lib/fs4_ops.h b/mlxfwops/lib/fs4_ops.h index 7a46f660..f8cd61a8 100644 --- a/mlxfwops/lib/fs4_ops.h +++ b/mlxfwops/lib/fs4_ops.h @@ -113,6 +113,7 @@ class Fs4Operations : public Fs3Operations { u_int32_t new_image_start, u_int32_t log2_chunk_size); virtual void FwCleanUp(); bool IsLifeCycleAccessible(chip_type_t chip_type); + bool IsSecurityVersionAccessible(chip_type_t chip_type); bool IsSecurityVersionViolated(u_int32_t image_security_version); bool GetImageInfo(u_int8_t *buff); bool GetImageSize(u_int32_t* image_size); diff --git a/mlxfwops/lib/fsctrl_ops.cpp b/mlxfwops/lib/fsctrl_ops.cpp index 244b42e3..7897aee3 100644 --- a/mlxfwops/lib/fsctrl_ops.cpp +++ b/mlxfwops/lib/fsctrl_ops.cpp @@ -989,7 +989,7 @@ bool FsCtrlOperations::IsSecurityVersionViolated(u_int32_t image_security_versio // Set device security-version (from EFUSEs) if (_fsCtrlImgInfo.device_security_version_access_method == MFSV) { deviceEfuseSecurityVersion = _fsCtrlImgInfo.device_security_version_mfsv.efuses_sec_ver; - } else if (_fsCtrlImgInfo.device_security_version_access_method == GW) { + } else if (_fsCtrlImgInfo.device_security_version_access_method == DIRECT_ACCESS) { // matanel - this case is relevant to fsctrl? deviceEfuseSecurityVersion = _fsCtrlImgInfo.device_security_version_gw; } else { deviceEfuseSecurityVersion = 0; diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index 61fac971..c57ff30f 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -2630,7 +2630,7 @@ u_int32_t CRSpaceRegisters::getSecurityVersion() u_int32_t rollbackMSB = 0, rollbackLSB = 0; u_int32_t minimalSecurityVersion = 0; - switch (_chip_type) { + switch (_chip_type) { case CT_QUANTUM2: rollbackMSB = getRegister(0xf3248); rollbackLSB = getRegister(0xf324c); @@ -2647,7 +2647,7 @@ u_int32_t CRSpaceRegisters::getSecurityVersion() minimalSecurityVersion = getConsecutiveBits(getRegister(0xf4538), 4, 8); break; default: - throw logic_error("-E- security version query is not implemented for the current device."); + throw logic_error("-E- Security version query is not implemented for the current device."); break; } @@ -2682,7 +2682,7 @@ u_int32_t CRSpaceRegisters::getRegister(u_int32_t address) u_int32_t crSpaceReg; int rc = mread4(_mf, address, &crSpaceReg); if (rc != 4){ - throw logic_error("-E- Failed to read from CRSpace."); + throw runtime_error("-E- Failed to read from CRSpace."); } return crSpaceReg; diff --git a/mlxfwops/lib/mlxfwops_com.h b/mlxfwops/lib/mlxfwops_com.h index 74b4385e..8cb3966f 100644 --- a/mlxfwops/lib/mlxfwops_com.h +++ b/mlxfwops/lib/mlxfwops_com.h @@ -389,7 +389,7 @@ typedef struct uids { }; } uids_t; -typedef enum {NOT_VALID, GW, MFSV} device_security_version_access_method_t; +typedef enum {NOT_VALID, DIRECT_ACCESS, MFSV} device_security_version_access_method_t; typedef struct fs3_info_ext { u_int8_t guids_override_en; From 2127a3612605db6b19f8bc1a566802522bc01cd2 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Thu, 24 Mar 2022 20:19:33 +0200 Subject: [PATCH 172/184] CX5 failure during burning on 32MB Flash Description: Since CX5 supports 16MB flashes but we need to support 32MB flash, we need to make sure the effective size of the flash that the tool can reach will be 16MB. Specifically this commit fixes the DTOC burning on CX5 in that case Tested OS: Linux Tested devices: CX5 32MB flash Tested flows: production burn Known gaps (with RM ticket): N/A Issue: 3015865 Change-Id: I1ecb9b50cfcc24783dae287f8126054539f326fe Signed-off-by: Matan Eliyahu --- flint/subcommands.cpp | 9 +++++---- mflash/mflash.c | 27 +++++++++++++++++++++------ mflash/mflash.h | 4 ++++ mlxfwops/lib/flint_io.cpp | 19 +++++++++++++++++-- mlxfwops/lib/flint_io.h | 3 +++ mlxfwops/lib/fs3_ops.cpp | 10 +++++----- mlxfwops/lib/fs4_ops.cpp | 4 ++-- mlxfwops/lib/fw_ops.cpp | 14 +++++++------- 8 files changed, 64 insertions(+), 26 deletions(-) diff --git a/flint/subcommands.cpp b/flint/subcommands.cpp index 1d995806..5f0da479 100644 --- a/flint/subcommands.cpp +++ b/flint/subcommands.cpp @@ -781,12 +781,13 @@ SubCommand::~SubCommand() } +// matanel - TODO: duplicated, use same function from fw_ops.cpp bool SubCommand::getRomsInfo(FBase *io, roms_info_t& romsInfo) { std::vector romSector; romSector.clear(); - romSector.resize(io->get_size()); - if (!io->read(0, &romSector[0], io->get_size())) { + romSector.resize(io->get_effective_size()); + if (!io->read(0, &romSector[0], io->get_effective_size())) { reportErr(true, FLINT_READ_ERROR, _flintParams.image.c_str(), io->err()); return false; } @@ -5927,9 +5928,9 @@ bool WbneSubCommand::writeBlock(u_int32_t addr, std::vector dataVec) { //we should work only on flash. //check if flash is big enough - if (addr + (dataVec.size() * 4) > ((Flash*)_io)->get_size()) { + if (addr + (dataVec.size() * 4) > ((Flash*)_io)->get_effective_size()) { reportErr(true, "Writing %#x bytes from address %#x is out of flash limits (%#x bytes)\n", - (unsigned int)(dataVec.size() * 4), (unsigned int)addr, (unsigned int)_io->get_size()); + (unsigned int)(dataVec.size() * 4), (unsigned int)addr, (unsigned int)_io->get_effective_size()); return false; } if (!((Flash*)_io)->write(addr, &dataVec[0], (dataVec.size() * 4), true)) { diff --git a/mflash/mflash.c b/mflash/mflash.c index 12948c70..9757a2f9 100644 --- a/mflash/mflash.c +++ b/mflash/mflash.c @@ -50,11 +50,10 @@ #ifndef UEFI_BUILD #include #endif - #include "mflash_pack_layer.h" #include "mflash_access_layer.h" #include "mflash.h" -#include "flash_int_defs.h" + #include "mflash_dev_capability.h" #include "mflash_common_structs.h" #include "mflash_gw.h" @@ -2067,16 +2066,27 @@ int cntx_flash_init(mflash *mfl, flash_params_t *flash_params) int mf_read(mflash *mfl, u_int32_t addr, u_int32_t len, u_int8_t *data, bool verbose) { - // printf("mfl->attr.size = %#x, addr = %#x, len = %d\n", mfl->attr.size, addr, len); - - CHECK_OUT_OF_RANGE(addr, len, mfl->attr.size); + u_int32_t size = mfl->attr.size; + if ((mfl->dm_dev_id == DeviceConnectX4LX || mfl->dm_dev_id == DeviceConnectX5) && + mfl->attr.vendor == FV_GD25QXXX) + { + size = 1 << FD_128; // 16MB + } + // printf("size = %#x, addr = %#x, len = %d\n", size, addr, len); + CHECK_OUT_OF_RANGE(addr, len, size); //printf("-D- mf_read: addr: %#x, len: %d\n", addr, len); return mfl->f_read(mfl, addr, len, data, verbose); } int mf_write(mflash *mfl, u_int32_t addr, u_int32_t len, u_int8_t *data) { - CHECK_OUT_OF_RANGE(addr, len, mfl->attr.size); + u_int32_t size = mfl->attr.size; + if ((mfl->dm_dev_id == DeviceConnectX4LX || mfl->dm_dev_id == DeviceConnectX5) && + mfl->attr.vendor == FV_GD25QXXX) + { + size = 1 << FD_128; // 16MB + } + CHECK_OUT_OF_RANGE(addr, len, size); // Locking semaphore for the entire existence of the mflash obj for write and erase only. int rc = mfl_com_lock(mfl); CHECK_RC(rc); @@ -3502,6 +3512,11 @@ mfile* mf_get_mfile(mflash *mfl) return mfl->mf; } +dm_dev_id_t mf_get_dm_dev_id(mflash *mfl) +{ + return mfl->dm_dev_id; +} + int mf_get_jedec_id(mflash *mfl, u_int32_t *jedec_id) { return mfl->f_get_jedec_id(mfl, jedec_id); diff --git a/mflash/mflash.h b/mflash/mflash.h index 387dbd63..cf94dec7 100644 --- a/mflash/mflash.h +++ b/mflash/mflash.h @@ -43,7 +43,9 @@ #include #include +#include "dev_mgt/tools_dev_types.h" #include "mflash_types.h" +#include "flash_int_defs.h" #include "mflash_common_structs.h" #include @@ -237,6 +239,8 @@ int mf_release_semaphore(mflash *mfl); // get mfile object mfile* mf_get_mfile(mflash *mfl); +dm_dev_id_t mf_get_dm_dev_id(mflash *mfl); + // // err code to string translation for printing. // diff --git a/mlxfwops/lib/flint_io.cpp b/mlxfwops/lib/flint_io.cpp index 608e4a3b..b2dc135a 100644 --- a/mlxfwops/lib/flint_io.cpp +++ b/mlxfwops/lib/flint_io.cpp @@ -38,6 +38,7 @@ */ #include +#include #include "flint_io.h" @@ -592,12 +593,12 @@ bool Flash::write(u_int32_t addr, } - if (cont2phys(addr + cnt) > get_size()) { + if (cont2phys(addr + cnt) > get_effective_size()) { return errmsg( "Trying to write %d bytes to address 0x%x, which exceeds max image size (0x%x - half of total flash size).", cnt, addr, - get_size() / 2); + get_effective_size() / 2); } u_int8_t *p = (u_int8_t*)data; @@ -1042,3 +1043,17 @@ bool Flash::set_flash_utilization(bool is_applied, int percent) _cpuPercent = percent; return true; } + +u_int32_t Flash::get_effective_size() +{ + u_int32_t effective_size = get_size(); + + dm_dev_id_t dm_dev_id = mf_get_dm_dev_id(_mfl); + if ((dm_dev_id == DeviceConnectX4LX || dm_dev_id == DeviceConnectX5) && + _attr.vendor == FV_GD25QXXX) + { + effective_size = 1 << FD_128; // 16MB + } + + return effective_size; +} diff --git a/mlxfwops/lib/flint_io.h b/mlxfwops/lib/flint_io.h index 6203ead2..3fb26ae5 100644 --- a/mlxfwops/lib/flint_io.h +++ b/mlxfwops/lib/flint_io.h @@ -147,6 +147,7 @@ class MLXFWOP_API FBase : public FlintErrMsg { virtual u_int32_t get_sector_size() = 0; virtual u_int32_t get_size() = 0; + virtual u_int32_t get_effective_size() = 0; virtual u_int32_t get_dev_id() = 0; virtual u_int32_t get_rev_id() = 0; @@ -337,6 +338,7 @@ class MLXFWOP_API FImage : public FBase { } virtual u_int32_t get_sector_size(); virtual u_int32_t get_size() { return getBufLength(); } + virtual u_int32_t get_effective_size() { return get_size(); } virtual u_int32_t get_dev_id() { return 0; } virtual u_int32_t get_rev_id() { return 0; } virtual mfile* getMfileObj() @@ -439,6 +441,7 @@ class MLXFWOP_API Flash : public FBase { u_int32_t get_current_sector_size() { return _curr_sector_size; } u_int32_t get_sector_size() { return _attr.sector_size; } virtual u_int32_t get_size() { return _attr.size; } + virtual u_int32_t get_effective_size(); virtual u_int32_t get_dev_id() { return _attr.hw_dev_id; } u_int32_t get_rev_id() { return _attr.rev_id; } diff --git a/mlxfwops/lib/fs3_ops.cpp b/mlxfwops/lib/fs3_ops.cpp index d534814e..46365ad9 100644 --- a/mlxfwops/lib/fs3_ops.cpp +++ b/mlxfwops/lib/fs3_ops.cpp @@ -705,7 +705,7 @@ bool Fs3Operations::FsVerifyAux(VerifyCallBack verifyCallBackFunc, bool show_ito // adrianc: need to have the sector size hardcoded in the FW binary (since its determined in the image generation process) u_int32_t sector_size = FS3_DEFAULT_SECTOR_SIZE; offset = (offset % sector_size == 0) ? offset : (offset + sector_size - offset % 0x1000); - while (offset < _ioAccess->get_size()) { + while (offset < _ioAccess->get_effective_size()) { if (VerifyTOC(offset, bad_signature, verifyCallBackFunc, show_itoc, queryOptions, ignoreDToc, verbose)) { return true; @@ -1310,7 +1310,7 @@ bool Fs3Operations::ReBurnCurrentImage(ProgressCallBack progressFunc) return false; } - const unsigned int size = (_ioAccess->get_size()); + const unsigned int size = (_ioAccess->get_effective_size()); vector newImageData(size); _imageCache.get(newImageData, 0x0, size); @@ -2077,9 +2077,9 @@ bool Fs3Operations::Fs3UpdateVpdSection(struct toc_info *curr_toc, char *vpd, return errmsg("Size of VPD file: %d is not 4-byte aligned!", vpd_size); } // assuming VPD section is the last piece of Data on the flash - if ((_ioAccess)->is_flash() && (getAbsAddr(curr_toc) + vpd_size > (_ioAccess)->get_size())) { + if ((_ioAccess)->is_flash() && (getAbsAddr(curr_toc) + vpd_size > (_ioAccess)->get_effective_size())) { delete[] vpd_data; - return errmsg("VPD data exceeds flash size, max VPD size: 0x%x bytes", (_ioAccess)->get_size() - getAbsAddr(curr_toc)); + return errmsg("VPD data exceeds flash size, max VPD size: 0x%x bytes", (_ioAccess)->get_effective_size() - getAbsAddr(curr_toc)); } GetSectData(newSectionData, (u_int32_t *)vpd_data, vpd_size); curr_toc->toc_entry.size = vpd_size / 4; @@ -3194,7 +3194,7 @@ bool Fs3Operations::FwShiftDevData(PrintCallBack progressFunc) return errmsg("Failed to get MFG_INFO ITOC information."); } - if (getAbsAddr(mfgToc) < _ioAccess->get_size() - (((Flash *)(_ioAccess))->get_sector_size())) { + if (getAbsAddr(mfgToc) < _ioAccess->get_effective_size() - (((Flash *)(_ioAccess))->get_sector_size())) { return errmsg("Device data sections already shifted."); } diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 01008eab..18e93051 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -928,7 +928,7 @@ bool Fs4Operations::FsVerifyAux(VerifyCallBack verifyCallBackFunc, bool show_ito is_image_in_odd_chunks = _ioAccess->get_is_image_in_odd_chunks(); _ioAccess->set_address_convertor(0, 0); //-Verify DToC Header: - dtocPtr = _ioAccess->get_size() - FS4_DEFAULT_SECTOR_SIZE; + dtocPtr = _ioAccess->get_effective_size() - FS4_DEFAULT_SECTOR_SIZE; DPRINTF(("Fs4Operations::FsVerifyAux call verifyTocHeader() DTOC\n")); if (!verifyTocHeader(dtocPtr, true, verifyCallBackFunc)) { return errmsg(MLXFW_NO_VALID_ITOC_ERR, "No valid DTOC Header was found."); @@ -1208,7 +1208,7 @@ bool Fs4Operations::CheckFs4ImgSize(Fs4Operations& imageOps, bool useImageDevDat //check if minimal dtoc is not overwriting the preceding chunk if (useImageDevData) { - u_int32_t devAreaStartAddress = _ioAccess->get_size() - (1 << imageOps._maxImgLog2Size); + u_int32_t devAreaStartAddress = _ioAccess->get_effective_size() - (1 << imageOps._maxImgLog2Size); if (imageOps._fs4ImgInfo.smallestDTocAddr < devAreaStartAddress) { return errmsg(MLXFW_DTOC_OVERWRITE_CHUNK, "First DTOC address (0x%x) is less than device area start address (0x%x)", diff --git a/mlxfwops/lib/fw_ops.cpp b/mlxfwops/lib/fw_ops.cpp index c57ff30f..bf71cfa6 100644 --- a/mlxfwops/lib/fw_ops.cpp +++ b/mlxfwops/lib/fw_ops.cpp @@ -381,7 +381,7 @@ const u_int32_t FwOperations::_cntx_image_start_pos[FwOperations::CNTX_START_POS bool FwOperations::FindMagicPattern(FBase *ioAccess, u_int32_t addr, u_int32_t const cntx_magic_pattern[]) { - if (addr + 16 > ioAccess->get_size()) { + if (addr + 16 > ioAccess->get_effective_size()) { return false; } for (int i = 0; i < 4; i++) { @@ -1921,9 +1921,9 @@ bool FwOperations::FwWriteBlock(u_int32_t addr, std::vector dataVec, P } //check if flash is big enough - if ((addr + dataVec.size()) > _ioAccess->get_size()) { + if ((addr + dataVec.size()) > _ioAccess->get_effective_size()) { return errmsg("Writing %#x bytes from address %#x is out of flash limits (%#x bytes)\n", - (unsigned int)(dataVec.size()), (unsigned int)addr, (unsigned int)_ioAccess->get_size()); + (unsigned int)(dataVec.size()), (unsigned int)addr, (unsigned int)_ioAccess->get_effective_size()); } if (!writeImage(progressFunc, addr, &dataVec[0], (int)dataVec.size())) { @@ -2011,8 +2011,8 @@ bool FwOperations::getRomsInfo(FBase *io, roms_info_t& romsInfo) { std::vector romSector; romSector.clear(); - romSector.resize(io->get_size()); - if (!io->read(0, &romSector[0], io->get_size())) { + romSector.resize(io->get_effective_size()); + if (!io->read(0, &romSector[0], io->get_effective_size())) { return false; } RomInfo info(romSector, false); @@ -2263,9 +2263,9 @@ bool FwOperations::FwSetForbiddenVersions(char *fname, PrintCallBack callBackFun bool FwOperations::FwReadBlock(u_int32_t addr, u_int32_t size, std::vector& dataVec) { - if (addr + size > _ioAccess->get_size()) { + if (addr + size > _ioAccess->get_effective_size()) { return errmsg(MLXFW_BAD_PARAM_ERR, "Reading %#x bytes from address %#x is out of flash limits (%#x bytes)\n", - size, (unsigned int)addr, (unsigned int)_ioAccess->get_size()); + size, (unsigned int)addr, (unsigned int)_ioAccess->get_effective_size()); } //read from flash/image if (!_ioAccess->read(addr, &dataVec[0], size)) { From 74caa624fd810dd50d43c39ddd114323f3b48882 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Wed, 6 Apr 2022 16:42:27 +0300 Subject: [PATCH 173/184] Wrong security version when querying an encrypted image Description: Setting image_security_version was part of the condition is_flash() so in case of image we didn't set its value with the value we read from HW pointer Tested OS: Linux Tested devices: CX7 Tested flows: flint -i q full Known gaps (with RM ticket): N/A Issue: 3034082 Change-Id: Icb76d833a9fbd4b6976038d23dc2ad172c8cec2a Signed-off-by: Matan Eliyahu --- mlxfwops/lib/fs4_ops.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/mlxfwops/lib/fs4_ops.cpp b/mlxfwops/lib/fs4_ops.cpp index 18e93051..94400d77 100644 --- a/mlxfwops/lib/fs4_ops.cpp +++ b/mlxfwops/lib/fs4_ops.cpp @@ -1058,10 +1058,8 @@ bool Fs4Operations::encryptedFwQuery(fw_info_t *fwInfo, bool readRom, bool quick memcpy(&(fwInfo->fs3_info), &(_fs3ImgInfo.ext_info), sizeof(fs3_info_t)); fwInfo->fw_type = FwType(); - if (_ioAccess->is_flash()) { - if (!QuerySecurityFeatures()) { - return false; - } + if (!QuerySecurityFeatures()) { + return false; } _fwImgInfo.ext_info.is_failsafe = true; @@ -1157,24 +1155,26 @@ bool Fs4Operations::QuerySecurityFeatures() DPRINTF(("Fs4Operations::QuerySecurityFeatures _fwImgInfo.ext_info.chip_type = %d\n", _fwImgInfo.ext_info.chip_type)); _fs3ImgInfo.ext_info.image_security_version = _security_version; _fs3ImgInfo.ext_info.device_security_version_access_method = NOT_VALID; - try { - if (IsLifeCycleAccessible(_fwImgInfo.ext_info.chip_type)) { - CRSpaceRegisters crSpaceReg(getMfileObj(), _fwImgInfo.ext_info.chip_type); - _fs3ImgInfo.ext_info.life_cycle = crSpaceReg.getLifeCycle(); + if (_ioAccess->is_flash()) { + try { + if (IsLifeCycleAccessible(_fwImgInfo.ext_info.chip_type)) { + CRSpaceRegisters crSpaceReg(getMfileObj(), _fwImgInfo.ext_info.chip_type); + _fs3ImgInfo.ext_info.life_cycle = crSpaceReg.getLifeCycle(); - if (_fs3ImgInfo.ext_info.life_cycle == GA_SECURED) { - _fs3ImgInfo.ext_info.global_image_status = crSpaceReg.getGlobalImageStatus(); + if (_fs3ImgInfo.ext_info.life_cycle == GA_SECURED) { + _fs3ImgInfo.ext_info.global_image_status = crSpaceReg.getGlobalImageStatus(); - if (IsSecurityVersionAccessible(_fwImgInfo.ext_info.chip_type)) { - _fs3ImgInfo.ext_info.device_security_version_gw = crSpaceReg.getSecurityVersion(); - _fs3ImgInfo.ext_info.device_security_version_access_method = DIRECT_ACCESS; + if (IsSecurityVersionAccessible(_fwImgInfo.ext_info.chip_type)) { + _fs3ImgInfo.ext_info.device_security_version_gw = crSpaceReg.getSecurityVersion(); + _fs3ImgInfo.ext_info.device_security_version_access_method = DIRECT_ACCESS; + } } } } - } - catch(exception& e) { - printf("%s\n", e.what()); - return false; + catch(exception& e) { + printf("%s\n", e.what()); + return false; + } } return true; From 88d9d23430d0e1a385fa6f6614c2a00dc48cc799 Mon Sep 17 00:00:00 2001 From: Tzafrir Cohen Date: Sun, 17 Apr 2022 15:38:38 +0300 Subject: [PATCH 174/184] Symlink libmtcr_ul.a into the libdir Signed-off-by: Tzafrir Cohen --- debian/mstflint.links | 1 + 1 file changed, 1 insertion(+) create mode 100644 debian/mstflint.links diff --git a/debian/mstflint.links b/debian/mstflint.links new file mode 100644 index 00000000..c78833cb --- /dev/null +++ b/debian/mstflint.links @@ -0,0 +1 @@ +usr/lib/mstflint/mstflint/libmtcr_ul.a usr/lib/mstflint/libmtcr_ul.a From d0d10f7943c5c34ac2be76643ee34da31c3ac3c9 Mon Sep 17 00:00:00 2001 From: Matan Eliyahu Date: Sun, 17 Apr 2022 16:21:33 +0300 Subject: [PATCH 175/184] Revert "Since CX7 IB has issues with sending MAD for mgir.fw_info using mad_ifc_general_info_fw() we send regular MGIR" This reverts commit 97e3f2241f43062da122e604b2a035a2c2e1f646. --- fw_comps_mgr/fw_comps_mgr.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fw_comps_mgr/fw_comps_mgr.cpp b/fw_comps_mgr/fw_comps_mgr.cpp index ffc65119..e77af115 100644 --- a/fw_comps_mgr/fw_comps_mgr.cpp +++ b/fw_comps_mgr/fw_comps_mgr.cpp @@ -1009,11 +1009,6 @@ reg_access_status_t FwCompsMgr::getGI(mfile *mf, mgirReg *gi) if (rc) { goto cleanup; } - if (gi->hw_info.device_id == 4129) { - DPRINTF(("FwCompsMgr::getGI CX7 IB device found, sending regular MGIR\n")); - rc = reg_access_mgir(mf, REG_ACCESS_METHOD_GET, gi); - goto cleanup; - } rc = (reg_access_status_t)mad_ifc_general_info_fw(mf, &gi->fw_info); if (rc) { goto cleanup; From e1de759e4c533c4ea33cfd6855dfeb8963d77a9d Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Mon, 18 Apr 2022 14:07:33 +0300 Subject: [PATCH 176/184] update version changelog for 4.20 --- debian/changelog | 4 ++-- mstflint.spec.in | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index 8f26a337..67db8136 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,13 +2,13 @@ mstflint (4.20.0-1) unstable; urgency=low * Updated from MFT-4.20.0 - -- Tomer Tubi Thu, 28 Apr 2022 00:00:00 +0200 + -- Tomer Tubi Thu, 28 Apr 2022 00:00:00 +0000 mstflint (4.19.0-1) unstable; urgency=low * Updated from MFT-4.19.0 (internal version) - -- Tomer Tubi Thu, 24 Mar 2022 00:00:00 +0200 + -- Tomer Tubi Thu, 24 Mar 2022 00:00:00 +0000 mstflint (4.18.0-1) unstable; urgency=low diff --git a/mstflint.spec.in b/mstflint.spec.in index d50eb5aa..a057179d 100644 --- a/mstflint.spec.in +++ b/mstflint.spec.in @@ -215,7 +215,13 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man1/* %changelog -* Sat Oct 9 2021 Konstantin Maksatov +* Thu Apr 28 2022 Tomer Tubi + MFT 4.20.0 Updates + +* Thu Mar 24 2022 Tomer Tubi + MFT 4.19.0 Updates + +* Thu Nov 25 2021 Tomer Tubi MFT 4.18.0 Updates * Thu Jun 10 2021 Konstantin Maksatov From 1a83f0046f6e9a697fe8eef2a707fd08261ec0d9 Mon Sep 17 00:00:00 2001 From: Alon Strutsovsky Date: Sun, 10 Apr 2022 10:23:02 +0300 Subject: [PATCH 177/184] Update CX7 csv Description: Tested OS: N/A Tested devices: N/A Tested flows: N/A Known gaps (with RM ticket): Issue: 3033259 Change-Id: I04dacd1e3ca8496a11833a7b486c2327ca027896 (cherry picked from commit 98f25d2758d6ff3516d4beaf790c6ee654f17bad) Signed-off-by: Alon Strutsovsky --- mstdump/mstdump_dbs/ConnectX7.csv | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mstdump/mstdump_dbs/ConnectX7.csv b/mstdump/mstdump_dbs/ConnectX7.csv index e7ba9c75..b7ae7e29 100644 --- a/mstdump/mstdump_dbs/ConnectX7.csv +++ b/mstdump/mstdump_dbs/ConnectX7.csv @@ -7730,6 +7730,7 @@ 0x298300,8, 0x298324,1, 0x298400,2, +0x2b0000,8448, 0x300000,19, 0x300100,1, 0x300200,57, @@ -8475,7 +8476,8 @@ 0x340ec0,5, 0x340ee0,5, 0x340f00,17, -0x341000,179, +0x341000,112, +0x341200,51, 0x341400,5, 0x341800,3, 0x341810,3, @@ -9996,7 +9998,8 @@ 0x3c0ec0,5, 0x3c0ee0,5, 0x3c0f00,17, -0x3c1000,179, +0x3c1000,112, +0x3c1200,51, 0x3c1400,5, 0x3c1800,3, 0x3c1810,3, From 1054cb4c05abf5a20fe8726c5837d740e436068e Mon Sep 17 00:00:00 2001 From: Alon Strutsovsky Date: Mon, 11 Apr 2022 16:59:38 +0300 Subject: [PATCH 178/184] Update CX7 dbs Description: Tested OS: N/A Tested devices: N/A Tested flows: N/A Known gaps (with RM ticket): Issue: None Change-Id: I5f3db220e7beefe9b4a8f6dfd024591a3fcd93ed Signed-off-by: Alon Strutsovsky --- mstdump/mstdump_dbs/ConnectX7.csv | 1 - 1 file changed, 1 deletion(-) diff --git a/mstdump/mstdump_dbs/ConnectX7.csv b/mstdump/mstdump_dbs/ConnectX7.csv index b7ae7e29..679a628b 100644 --- a/mstdump/mstdump_dbs/ConnectX7.csv +++ b/mstdump/mstdump_dbs/ConnectX7.csv @@ -7730,7 +7730,6 @@ 0x298300,8, 0x298324,1, 0x298400,2, -0x2b0000,8448, 0x300000,19, 0x300100,1, 0x300200,57, From 38ddc71507310ccda33cda890e69aaf2e656da52 Mon Sep 17 00:00:00 2001 From: Oded Burstein Date: Wed, 13 Apr 2022 17:08:44 +0300 Subject: [PATCH 179/184] Viper | updated tools DBs according to new ADB Description: n/a Tested OS: n/a Tested devices: n/a Tested flows: n/a Known gaps (with RM ticket): n/a Issue: None Change-Id: I8aa09949e7c867c7d083d81dc1b21cc628ceb1e6 Signed-off-by: Alon Strutsovsky --- mstdump/mstdump_dbs/BlueField2.csv | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/mstdump/mstdump_dbs/BlueField2.csv b/mstdump/mstdump_dbs/BlueField2.csv index eef96b19..3f111fb8 100644 --- a/mstdump/mstdump_dbs/BlueField2.csv +++ b/mstdump/mstdump_dbs/BlueField2.csv @@ -3608,7 +3608,7 @@ 0x0f1240,14, 0x0f1280,24, 0x0f1300,6, -0x0f1320,1, +0x0f1320,2, 0x0f1400,27, 0x0f1480,8, 0x0f1500,11, @@ -8859,13 +8859,8 @@ 0x295a00,10, 0x295a80,3, 0x296000,227, -0x310408,1, 0x310488,1, 0x310490,1, -0x310498,1, -0x3104a0,1, -0x3104a8,1, -0x3104b0,1, 0x312000,1, 0x312008,1, 0x312100,1, From 1c25294a356f1aceaab2ef1a004da7c8290202a2 Mon Sep 17 00:00:00 2001 From: Roei Yitzhak Date: Thu, 21 Apr 2022 07:50:38 +0300 Subject: [PATCH 180/184] [mlxfwreset] bug fixes 1. In case of socket-direct devices we need to wait for both PCI devices after the PCI link toggle 2. On Windows OS, where there are no network drivers installed the tool should assume that there is no management (Rshim) driver --- .../mlnx_peripheral_components.py | 2 +- .../mlxfwresetlib/mlxfwreset_mlnxdriver.py | 134 ++++++++++++------ small_utils/mstfwreset.py | 83 ++++++----- 3 files changed, 142 insertions(+), 77 deletions(-) diff --git a/small_utils/mlxfwresetlib/mlnx_peripheral_components.py b/small_utils/mlxfwresetlib/mlnx_peripheral_components.py index f807b82d..a0aaa00a 100644 --- a/small_utils/mlxfwresetlib/mlnx_peripheral_components.py +++ b/small_utils/mlxfwresetlib/mlnx_peripheral_components.py @@ -44,7 +44,7 @@ class MlnxPeripheralComponents(object): - SD_SUPPORTED_DID = [0x218,0x216,0x212,0x20f,0x20d,0x209,0x20b] # Connectx7,Connectx6LX,Connectx6DX,Connectx6,Connectx5 (SD device) ,Connectx4/Connectx4Lx (MH device connected as SD) + SD_SUPPORTED_DID = [0x21e,0x218,0x216,0x212,0x20f,0x20d,0x209,0x20b] # Connectx8,Connectx7,Connectx6LX,Connectx6DX,Connectx6,Connectx5 (SD device) ,Connectx4/Connectx4Lx (MH device connected as SD) def __init__(self): self.pci_devices = [] diff --git a/small_utils/mlxfwresetlib/mlxfwreset_mlnxdriver.py b/small_utils/mlxfwresetlib/mlxfwreset_mlnxdriver.py index 4561aeed..04ca7d23 100644 --- a/small_utils/mlxfwresetlib/mlxfwreset_mlnxdriver.py +++ b/small_utils/mlxfwresetlib/mlxfwreset_mlnxdriver.py @@ -114,6 +114,7 @@ def __init__(self, logger, user_pci_device_name): for rshim_misc_file, rshim_pci_device_name, rshim_drop_mode in self._scan_rshim_drivers(): if user_pci_device_name[5:11] in rshim_pci_device_name and rshim_drop_mode == 0: self.rshim_misc_file = rshim_misc_file + self.pci_device_name = rshim_pci_device_name[5:] break else: raise DriverNotExist("There is no running user-space rshim driver") @@ -154,6 +155,16 @@ def __init__(self,devices,logger,skip): # devices : 1 physical function per card if not os.path.exists(MlnxDriverLinux.PCI_DRIVERS_PATH): raise RuntimeError("path {0} doesn't exist!".format(MlnxDriverLinux.PCI_DRIVERS_PATH)) + # Handle rshim user-space driver + ################################# + self.rshim_driver = None + if len(devices) == 1: # BL devices has only one PCI device name (There is no BL socket-direct device) + pci_device_name = mlxfwreset_utils.getDevDBDF(devices[0], logger) # domain:bus:device.fn + try: + self.rshim_driver = LinuxRshimUserSpaceDriver(logger, pci_device_name) + except DriverNotExist: + pass + for device in devices: dbdf = mlxfwreset_utils.getDevDBDF(device,logger) @@ -181,23 +192,15 @@ def __init__(self,devices,logger,skip): # devices : 1 physical function per card for line in out.split('\n')[:-1]: line = line.split('/') driver_name,dbdf = line[-2],line[-1] + if self.rshim_driver is not None and self.rshim_driver.pci_device_name == dbdf and driver_name in ["vfio-pci", "uio_pci_generic"]: + logger.info("skip on vfio/uio driver (rshim user-space driver will stop it)") + continue if driver_name not in MlnxDriverLinux.mlnx_drivers: raise RuntimeError("mlxfwreset doesn't support 3rd party driver ({0})!\nPlease, stop the driver manually and resume operation with --skip_driver".format(driver_name)) self.drivers_dbdf.append((dbdf,driver_name)) self.drivers_dbdf.sort() - # Handle rshim user-space driver - ################################# - self.rshim_driver = None - if len(devices) == 1: # BL devices has only one PCI device name (There is no BL socket-direct device) - pci_device_name = mlxfwreset_utils.getDevDBDF(devices[0], logger) # domain:bus:device.fn - try: - self.rshim_driver = LinuxRshimUserSpaceDriver(logger, pci_device_name) - except DriverNotExist: - pass - - logger.info('{0}'.format(self.drivers_dbdf)) driverStatus = MlnxDriver.DRIVER_IGNORE if skip or not self.drivers_dbdf else MlnxDriver.DRIVER_LOADED @@ -318,8 +321,9 @@ def getDriverStatusAux(self): class WindowsRshimDriver: """ - Rshim-driver is the "SOC managment driver" (the driver that communicates with the ARMs) in a SmartNIC device - This driver is located in the 'System devices' (and not in the 'Network adapters') + Rshim-driver is the "SOC management driver" (the driver that communicates with the ARMs) in a SmartNIC device + This driver is located in the 'System devices' (and not under the 'Network adapters') + We use the pnp-device utility to find/start/stop the management driver """ def _powershell(self, cmd): @@ -329,33 +333,80 @@ def _powershell(self, cmd): self.logger.info("rc={0}\nstdout={1}\nstderr={2}".format(*result)) return result - def __init__(self, logger, pci_device_id): + def _get_pnp_device_name_for_network_adapter(self, network_adapter_name): + """ + The method will convert network_adapter name e.g "Ethernet 8" to pnp_device name (instance-id) + e.g "PCI\VEN_15B3&DEV_A2D6&SUBSYS_004815B3&REV_00\4&2E75E12A&0&0110" + """ + + cmd = "(Get-NetAdapterHardwareInfo -name '{0}').InterfaceDescription".format(network_adapter_name) + rc, output, _ = self._powershell(cmd) + if rc != 0: + raise RuntimeError("Failed to execute {0}".format(cmd)) + + interface_description = output.strip() + + cmd = "(Get-PnpDevice -FriendlyName '{0}').InstanceId".format(interface_description) # We use the InterfaceDescription from the previous command + rc, output, _ = self._powershell(cmd) # as FriendlyName in the current command + if rc != 0: + raise RuntimeError("Failed to execute {0}".format(cmd)) + + pnp_device_name = output.strip() + self.logger.info("network_adapter_name : {} ; pnp_device_name : {}".format(network_adapter_name, pnp_device_name)) + return pnp_device_name - # Network-adapter to SOC-management PCI-device-id mapping table - PCI_DEVICE_ID_MAPPING_TABLE = {0xA2D2: 0xC2D2, 0xA2D6: 0xC2D3, 0xA2D9: 0xC2D4, 0xA2DC: 0xC2D5} + + def __init__(self, logger, network_adapters, network_adapter_pci_device_id): self.logger = logger - # Check if it's a Smart NIC. If yes, extract PCI device-id of the SOC management (PCI device) - network_adapter_pci_device_id = pci_device_id + #* Network-adapter to SOC-management PCI-device-id mapping table + PCI_DEVICE_ID_MAPPING_TABLE = {0xA2D2: 0xC2D2, 0xA2D6: 0xC2D3, 0xA2D9: 0xC2D4, 0xA2DC: 0xC2D5} + + #* Check if it's a Smart NIC. If yes, extract pci-device-id of the management device if network_adapter_pci_device_id in PCI_DEVICE_ID_MAPPING_TABLE: soc_management_pci_device_id = PCI_DEVICE_ID_MAPPING_TABLE[network_adapter_pci_device_id] else: + self.logger.info("Not a SmartNIC device") raise DriverNotExist("Not a SmartNic device") - # Get the name of the driver - cmd = "(Get-PnpDevice -InstanceId '*VEN_15B3&DEV_{0:x}*').InstanceId".format(soc_management_pci_device_id) + #* Assertion + if len(network_adapters) == 0: + raise DriverNotExist("There is no management driver when there are no network adapters") + + #* Check if "Get-PnpDevice" command exists + #! The "Get-PnpDevice" is not supported in "Windows server 2012" + #! and "Windows server 2012 R2" so we can't support Bluefield in + #! these OS versions + powershell_cmd = 'powershell.exe -c "Get-PnpDevice > $null"' + result = cmdExec(powershell_cmd) + if result[0] != 0: + self.logger.debug("Get-PnpDevice is not supported in this OS version") + raise RuntimeError("Get-PnpDevice is not supported in this OS version") + + #* Create a network-adapter as pnp device + network_adapter_as_pnp_device = self._get_pnp_device_name_for_network_adapter(network_adapters[0]) + self.logger.debug("Network adapter as pnp device: {0}".format(network_adapter_as_pnp_device)) + + + #* Extract the "common part" from the pnp-device + # The "common part" is common for both the network-adapter and SOC management + # Example: + # pnp-device : PCI\VEN_15B3&DEV_A2D6&SUBSYS_004815B3&REV_00\4&2E75E12A&0&0110 + # common part : 2E75E12A + pnp_device_common_part = network_adapter_as_pnp_device.split("&")[4] + self.logger.debug("pnp_device_common_part = {0}".format(pnp_device_common_part)) + + #* Set the name of the management driver + cmd = "(Get-PnpDevice -InstanceId '*VEN_15B3*DEV_{0:x}*{1}*').InstanceId".format(soc_management_pci_device_id, pnp_device_common_part) rc, output, _ = self._powershell(cmd) - if rc == 0 and output: - # TODO if there is more than one BL device from the same type, then will get more than one line - # TODO we need to filter the right driver (according to PCI address) - self.driver_name = output.strip() - self.logger.info("rshim-driver name : {0}".format(self.driver_name)) - else: - raise DriverNotExist("rshim-driver doesn't exist") + if rc != 0: + raise RuntimeError("Faild to execute {0}".format(cmd)) + self.driver_name = output.strip() + self.logger.info("rshim-driver name : {0}".format(self.driver_name)) - # Check if the driver is enabled - cmd = "(Get-PnpDevice -InstanceId '*VEN_15B3&DEV_{0:x}*').Status".format(soc_management_pci_device_id) + #* Check if the management driver is enabled + cmd = "(Get-PnpDevice -InstanceId '{0}').Status".format(self.driver_name) rc, output, _ = self._powershell(cmd) if rc == 0 and output.strip() == 'OK': self.logger.debug("rshim-driver name : {0} is enabled".format(self.driver_name)) @@ -363,6 +414,7 @@ def __init__(self, logger, pci_device_id): self.logger.debug("rshim-driver name : {0} is disabled".format(self.driver_name)) raise DriverDisabled("rshim-driver is disabled") + def start(self): cmd = "Enable-PnpDevice -InstanceId '{0}' -confirm:$false".format(self.driver_name) rc, _, _ = self._powershell(cmd) @@ -409,7 +461,7 @@ def read_5_lines(txt): # Filter only relevant drivers # 1. Ignore drivers that are not relevant to required PCI address - # 2. Ignore the managment driver ('rshim bus' in the 'Network Adapters' section) + # 2. Ignore the management driver ('rshim bus' in the 'Network Adapters' section) if seg_bus_device_list_ii in seg_bus_device_list and 'Management' not in description_line: drivers_names.append(name_ii) @@ -430,14 +482,8 @@ def __init__(self, logger, skip, devices, pci_device_id): if self._is_powershell_exists() is False: raise RuntimeError("PowerShell.exe is not installed. Please stop the driver manually and re-run the tool with --skip_driver ") - try: - self.rshim_driver = WindowsRshimDriver(logger, pci_device_id) - except (DriverNotExist, DriverDisabled): - self.rshim_driver = None - - + # Find seg:bus:device of the device(s) seg_bus_device_list = [] - # Extract bus and device from the device_name for device in devices: seg_bus_device = mlxfwreset_utils.getDevDBDF(device,logger).split('.')[0] seg_num = int(seg_bus_device.split(':')[0],16) @@ -445,11 +491,19 @@ def __init__(self, logger, skip, devices, pci_device_id): device_num = int(seg_bus_device.split(':')[2],16) seg_bus_device_list.append((seg_num, bus_num, device_num)) - # Find the network adapters for the dus:device + # Find the relevant network adapters for the seg:bus:device targetedAdaptersTemp = self.get_device_drivers(logger, seg_bus_device_list) logger.debug(targetedAdaptersTemp) - - # Filter the network adapter thar are disabled + + # Create Rshim-driver (for Bluefield devices) + logger.info("Create Rshim driver") + try: + self.rshim_driver = WindowsRshimDriver(logger, targetedAdaptersTemp, pci_device_id) + except (DriverNotExist, DriverDisabled): + self.rshim_driver = None + + + # Filter the network adapters that are disabled self.targetedAdapters = [] for targetedAdapter in targetedAdaptersTemp: cmd = 'powershell.exe -c "Get-NetAdapter \'%s\' | Format-List -Property Status' % targetedAdapter diff --git a/small_utils/mstfwreset.py b/small_utils/mstfwreset.py index 48550083..3849b2fd 100644 --- a/small_utils/mstfwreset.py +++ b/small_utils/mstfwreset.py @@ -97,10 +97,12 @@ class SyncOwner(): dict(name="BlueField", devid=0x211, status_config_not_done=(0xb5e04, 31)), dict(name="BlueField2", devid=0x214, status_config_not_done=(0xb5f04, 31)), dict(name="BlueField3", devid=0x21c, status_config_not_done=(0xb5f04, 31)), + dict(name="BlueField4", devid=0x220, status_config_not_done=(0xb5f04, 31)), dict(name="ConnectX6", devid=0x20f, status_config_not_done=(0xb5f04, 31)), dict(name="ConnectX6DX", devid=0x212, status_config_not_done=(0xb5f04, 31)), dict(name="ConnectX6LX", devid=0x216, status_config_not_done=(0xb5f04, 31)), dict(name="ConnectX7", devid=0x218, status_config_not_done=(0xb5f04, 31)), + dict(name="ConnectX8", devid=0x21e, status_config_not_done=(0xb5f04, 31)), dict(name="ConnectX3", devid=0x1f5), dict(name="SwitchX", devid=0x245), dict(name="IS4", devid=0x1b3), @@ -108,7 +110,7 @@ class SyncOwner(): # Supported devices. SUPP_DEVICES = ["ConnectIB", "ConnectX4", "ConnectX4LX", "ConnectX5", "BlueField", - "ConnectX6", "ConnectX6DX", "ConnectX6LX", "BlueField2", "ConnectX7", "BlueField3"] + "ConnectX6", "ConnectX6DX", "ConnectX6LX", "BlueField2", "ConnectX7", "BlueField3", "ConnectX8", "BlueField4"] SUPP_OS = ["FreeBSD", "Linux", "Windows"] IS_MSTFLINT = os.path.basename(__file__) == "mstfwreset.py" @@ -938,30 +940,38 @@ def resetPciAddr(device,devicesSD,driverObj, cmdLineArgs): # Determine the pci-device to poll (first Mellanox device in the pci tree) if isWindows is False: + pci_devices_to_poll_devid = [] + root_pci_devices = [] + if is_in_internal_host(): # Bluefied (NIC only reset) pci_device_bridge1 = PciOpsObj.getPciBridgeAddr(DevDBDF) pci_device_bridge2 = PciOpsObj.getPciBridgeAddr(pci_device_bridge1) pci_device_bridge3 = PciOpsObj.getPciBridgeAddr(pci_device_bridge2) - pci_device_to_poll_devid = pci_device_bridge3 - root_pci_device = PCIDeviceFactory().get(pci_device_bridge3, "debug") + pci_devices_to_poll_devid.append(pci_device_bridge3) + root_pci_devices.append(PCIDeviceFactory().get(pci_device_bridge3, "debug")) elif is_pci_bridge_is_mellanox_device(DevDBDF): # Innova (FPGA) pci_device_bridge1 = PciOpsObj.getPciBridgeAddr(DevDBDF) pci_device_bridge2 = PciOpsObj.getPciBridgeAddr(pci_device_bridge1) pci_device_bridge3 = PciOpsObj.getPciBridgeAddr(pci_device_bridge2) - pci_device_to_poll_devid = pci_device_bridge2 - root_pci_device = PCIDeviceFactory().get(pci_device_bridge3, "debug") - elif isPPC: # PPC can run on VM (no PCI bridge device) - pci_device_to_poll_devid = DevDBDF + pci_devices_to_poll_devid.append(pci_device_bridge2) + root_pci_devices.append(PCIDeviceFactory().get(pci_device_bridge3, "debug")) else: - pci_device_to_poll_devid = DevDBDF - pci_device_bridge = PciOpsObj.getPciBridgeAddr(DevDBDF) - root_pci_device = PCIDeviceFactory().get(pci_device_bridge, "debug") - logger.debug('pci_device_to_poll_devid={0}'.format(pci_device_to_poll_devid)) + for dev in [device] + devicesSD: + dbdf = mlxfwreset_utils.getDevDBDF(dev, logger) + pci_devices_to_poll_devid.append(dbdf) + + if not isPPC: # PPC can run on VM (no PCI bridge device) + pci_device_bridge = PciOpsObj.getPciBridgeAddr(dbdf) + root_pci_devices.append(PCIDeviceFactory().get(pci_device_bridge, "debug")) + + for pci_device_to_poll_devid in pci_devices_to_poll_devid: + logger.info('pci_device_to_poll_devid={0}'.format(pci_device_to_poll_devid)) if not isPPC: - logger.debug('root_pci_device={0}'.format(root_pci_device)) + for root_pci_device in root_pci_devices: + logger.info('root_pci_device={0}'.format(root_pci_device.dbdf)) if isWindows is False: # relevant for ppc(p7) TODO check power8/9 shouldn't use mst-save/load @@ -1087,29 +1097,31 @@ def resetPciAddr(device,devicesSD,driverObj, cmdLineArgs): PciOpsObj.waitForDevice(pciDev) # Poll DLL Link Active (required to support AMD - RM #1599465) - if not isPPC and not is_in_internal_host() and root_pci_device.dll_link_active_reporting_capable: # in BlueField's internal host (ARM) the root-port will - MAX_WAIT_TIME = 2 # sec # return a valid response (blocking) or 0xffff0001 when - poll_start_time = time.time() # it's not ready (depending on its configuration) - for _ in range(1000*MAX_WAIT_TIME): - if root_pci_device.dll_link_active == 1: - poll_end_time = (time.time() - poll_start_time) * 1000 - logger.debug('DLL link active is ready after {0} msec'.format(poll_end_time)) - break - time.sleep(0.001) - else: - print("\n-W- DLL link is not active (PCI device {0})".format(root_pci_device.dbdf)) + for root_pci_device in root_pci_devices: + if not isPPC and not is_in_internal_host() and root_pci_device.dll_link_active_reporting_capable: # in BlueField's internal host (ARM) the root-port will + MAX_WAIT_TIME = 2 # sec # return a valid response (blocking) or 0xffff0001 when + poll_start_time = time.time() # it's not ready (depending on its configuration) + for _ in range(1000*MAX_WAIT_TIME): + if root_pci_device.dll_link_active == 1: + poll_end_time = (time.time() - poll_start_time) * 1000 + logger.debug('DLL link active is ready after {0} msec'.format(poll_end_time)) + break + time.sleep(0.001) + else: + print("\n-W- DLL link is not active (PCI device {0})".format(root_pci_device.dbdf)) # Wait for FW (Iron) - Read devid MAX_WAIT_TIME = 2 # sec poll_start_time = time.time() - for _ in range(1000*MAX_WAIT_TIME): - if PciOpsObj.read(pci_device_to_poll_devid, 0)>>16 != 0xffff: # device-id (0x2.W) - iron_end_time = (time.time() - poll_start_time) * 1000 - logger.debug('IRON is ready after {0} msec'.format(iron_end_time)) - break - time.sleep(0.001) - else: - print("\n-W- FW is not ready") + for pci_device_to_poll_devid in pci_devices_to_poll_devid: + for _ in range(1000*MAX_WAIT_TIME): + if PciOpsObj.read(pci_device_to_poll_devid, 0)>>16 != 0xffff: # device-id (0x2.W) + iron_end_time = (time.time() - poll_start_time) * 1000 + logger.debug('IRON is ready after {0} msec'.format(iron_end_time)) + break + time.sleep(0.001) + else: + print("\n-W- FW is not ready") # Restore PCI configuration ############################# @@ -1126,9 +1138,9 @@ def resetPciAddr(device,devicesSD,driverObj, cmdLineArgs): PciOpsObj.loadPCIConfigurationSpace(pciDev, pci_device_object, full=False) else: logger.debug('Indication for re-enumeration is by HotPlug on bridge') - to_restore_pci_conf = not (root_pci_device.hotplug_capable and root_pci_device.hotplug_interrupt_enable) - logger.debug('hotplug_capable={0}'.format(root_pci_device.hotplug_capable)) - logger.debug('hotplug_interrupt_enable={0}'.format(root_pci_device.hotplug_interrupt_enable)) + to_restore_pci_conf = not (root_pci_devices[0].hotplug_capable and root_pci_devices[0].hotplug_interrupt_enable) + logger.debug('hotplug_capable={0}'.format(root_pci_devices[0].hotplug_capable)) + logger.debug('hotplug_interrupt_enable={0}'.format(root_pci_devices[0].hotplug_interrupt_enable)) logger.debug('to_restore_pci_conf={0}'.format(to_restore_pci_conf)) for pciDev in devList+devListsSD: pci_device_object = pci_device_dict[pciDev] @@ -1324,7 +1336,6 @@ def resetFlow(device, devicesSD, reset_level, reset_type, cmdLineArgs, mfrl): all_devices = [device] + devicesSD - # A temporary solution to get the pci-device-id (required for SmartNic) # This solution is not good when the user insert device in PCI address format (-d xx:xx.x) pci_device_id = None @@ -1553,7 +1564,7 @@ def main(): action="store_true") options_group.add_argument('--mst_flags', '-m', - help=": Provide mst flags to be used when invoking mst restart step. For example: --mst_flags=\"--with_fpga\"" + help=": Provide mst flags to be used when invoking mst restart step. For example: --mst_flags=\"--with_i2cdev\"" if platform.system() == "Linux" and not IS_MSTFLINT else argparse.SUPPRESS) options_group.add_argument('--version', '-v', From 7a43aa7b7654a96885429315876cb7f8860b50c4 Mon Sep 17 00:00:00 2001 From: Alon Strutsovsky Date: Sun, 10 Apr 2022 13:52:46 +0300 Subject: [PATCH 181/184] depth>0 fails Description: mem arg did not reach inner fetch function in the case of reference seek Tested OS: linux Tested devices: CX6LX Tested flows: run mstdump with segment 1011 and depth==1 Known gaps (with RM ticket): Issue: 3033347 Change-Id: Ib02f3971c55d288e2e7eea89f21c97d43040c765 Signed-off-by: Alon Strutsovsky --- resourcedump/fetchers/ResourceDumpFetcher.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resourcedump/fetchers/ResourceDumpFetcher.py b/resourcedump/fetchers/ResourceDumpFetcher.py index dff7f367..d34a0107 100755 --- a/resourcedump/fetchers/ResourceDumpFetcher.py +++ b/resourcedump/fetchers/ResourceDumpFetcher.py @@ -325,7 +325,7 @@ def fetch_data(self, **kwargs): inner_inline_data.extend( self._retrieve_resource_dump_inline_data(seg.reference_type, index1=seg.index1, index2=seg.index2, numOfObj1=seg.num_of_obj1, - numOfObj2=seg.num_of_obj2, vHCAid=kwargs["vHCAid"])) + numOfObj2=seg.num_of_obj2, vHCAid=kwargs["vHCAid"], mem=kwargs["mem"])) segments_list_last_position = len(segments_list) segments_list.extend(self._create_segments(inner_inline_data)) From cee0c535c0fd8e98520eb669f5e9ff63faafd2c0 Mon Sep 17 00:00:00 2001 From: Tomer Tubi Date: Sun, 24 Apr 2022 12:02:11 +0300 Subject: [PATCH 182/184] Align code with mft 4.20 --- dev_mgt/tools_dev_types.c | 24 +- dev_mgt/tools_dev_types.h | 4 +- mlxconfig/mlxcfg_commander.cpp | 13 +- mlxconfig/mlxcfg_generic_commander.cpp | 13 +- mlxconfig/mlxcfg_parser.cpp | 15 +- mlxlink/modules/mlxlink_cables_commander.cpp | 6 +- mstdump/mstdump_dbs/BlueField2.csv | 7 +- mstdump/mstdump_dbs/ConnectX7.csv | 6 +- reg_access/reg_access.c | 25 +- reg_access/reg_access.h | 3 - small_utils/mstfwreset.py | 3 +- .../prm/switch/ext/register_access_table.adb | 889 +++++++++--------- tools_layouts/reg_access_hca_layouts.c | 334 ------- tools_layouts/reg_access_hca_layouts.h | 417 ++------ 14 files changed, 583 insertions(+), 1176 deletions(-) diff --git a/dev_mgt/tools_dev_types.c b/dev_mgt/tools_dev_types.c index f0732d3c..43074c4d 100644 --- a/dev_mgt/tools_dev_types.c +++ b/dev_mgt/tools_dev_types.c @@ -270,15 +270,6 @@ static struct device_info g_devs_info[] = { 4, //port_num DM_HCA //dev_type }, - { - DeviceFPGANewton, //dm_id - 0xfff, //hw_dev_id - Dummy device ID till we have official one - -1, //hw_rev_id - -1, //sw_dev_id - "FPGA_NEWTON", //name - 2, //port_num - DM_HCA //dev_type - }, { DeviceSwitchIB2, //dm_id 0x24b, //hw_dev_id @@ -521,14 +512,6 @@ static int dm_get_device_id_inner(mfile *mf, int rc; u_int32_t dev_flags; - //Special case: FPGA device: -#ifndef MST_UL - if (mf->tp == MST_FPGA_ICMD || mf->tp == MST_FPGA_DRIVER) { - *ptr_dm_dev_id = DeviceFPGANewton; - *ptr_hw_dev_id = 0xfff; - return GET_DEV_ID_SUCCESS; - } -#endif #ifdef CABLES_SUPP if (mf->tp == MST_LINKX_CHIP){ @@ -788,7 +771,7 @@ int dm_is_fpp_supported(dm_dev_id_t type) { // Function per port is supported only in HCAs that arrived after CX3 const struct device_info *dp = get_entry(type); - return (dm_is_5th_gen_hca(dp->dm_id) || dm_is_newton(dp->dm_id)); + return dm_is_5th_gen_hca(dp->dm_id); } int dm_is_device_supported(dm_dev_id_t type) @@ -835,11 +818,6 @@ int dm_is_5th_gen_hca(dm_dev_id_t type) return (dm_dev_is_hca(type) && !dm_is_4th_gen(type)); } -int dm_is_newton(dm_dev_id_t type) -{ - return (type == DeviceFPGANewton); -} - int dm_is_connectib(dm_dev_id_t type) { return (type == DeviceConnectIB); diff --git a/dev_mgt/tools_dev_types.h b/dev_mgt/tools_dev_types.h index 79ab714c..2ccbab2a 100644 --- a/dev_mgt/tools_dev_types.h +++ b/dev_mgt/tools_dev_types.h @@ -84,7 +84,7 @@ enum dm_dev_id DeviceBlueField3, DeviceFPGA, // UnSupported DeviceSwitchIB2, - DeviceFPGANewton, + DeviceFPGANewton, // Unsupported DeviceCable, DeviceCableQSFP, DeviceCableQSFPaging, @@ -246,8 +246,6 @@ int dm_is_4th_gen(dm_dev_id_t type); int dm_is_5th_gen_hca(dm_dev_id_t type); -int dm_is_newton(dm_dev_id_t type); - int dm_is_connectib(dm_dev_id_t type); int dm_is_switchx(dm_dev_id_t type); diff --git a/mlxconfig/mlxcfg_commander.cpp b/mlxconfig/mlxcfg_commander.cpp index ef786a49..5ff22b56 100644 --- a/mlxconfig/mlxcfg_commander.cpp +++ b/mlxconfig/mlxcfg_commander.cpp @@ -55,7 +55,10 @@ Commander* Commander::create(std::string device, std::string dbName, bool forceC mf = mopen(device.c_str()); if (mf == NULL) { - throw MlxcfgException("Failed to open the device"); + mf = mopen_adv(device.c_str(), MST_CABLE); + if (mf == NULL) { + throw MlxcfgException("Failed to open the device"); + } } rc = mget_mdevs_type(mf, &type); if (rc) { @@ -92,9 +95,13 @@ Commander* Commander::create(mfile *mf, std::string device, std::string dbName) throw MlxcfgException("Device in Livefish mode is not supported"); } - if (dm_is_new_gen_switch(deviceId) || dm_is_5th_gen_hca(deviceId)) { + if (dm_is_new_gen_switch(deviceId) || dm_is_5th_gen_hca(deviceId) || dm_dev_is_cable(deviceId)) { if (dbName.empty()) {//take internal db file - dbName = getDefaultDBName(dm_dev_is_switch(deviceId)); + if (dm_dev_is_cable(deviceId)) { + dbName = getDefaultDBName(true); // linkx cables use the switch PRM + } else { + dbName = getDefaultDBName(dm_dev_is_switch(deviceId)); + } } commander = new GenericCommander(mf, dbName); } else if (dm_is_4th_gen(deviceId)) { diff --git a/mlxconfig/mlxcfg_generic_commander.cpp b/mlxconfig/mlxcfg_generic_commander.cpp index e02e6720..4d48e162 100644 --- a/mlxconfig/mlxcfg_generic_commander.cpp +++ b/mlxconfig/mlxcfg_generic_commander.cpp @@ -339,10 +339,15 @@ void GenericCommander::printParamViews(FILE *f, vector& v) break; } size_t len = (*pIt).mlxconfigName.length(); + //dont print description for parms _P2 - _P8 if ((*pIt).mlxconfigName.rfind("_P1") == std::string::npos) { - if ((*pIt).mlxconfigName.rfind("_P") == len - 3) { - fprintf(f, "%20s%-40s\n", " ", s.c_str()); - continue; + size_t posP = (*pIt).mlxconfigName.rfind("_P"); + if (posP == len - 3) { + char charP = (*pIt).mlxconfigName[posP+2]; + if (charP >= '2' && charP <='8'){ + fprintf(f, "%20s%-40s\n", " ", s.c_str()); + continue; + } } } size_t prevPos = 0; @@ -1598,7 +1603,7 @@ std::vector RawCfgParams5thGen::getRawData() *it = __be32_to_cpu(*it); } // Truncate to the correct data size - tlvBuff.resize(_nvdaTlv.nv_hdr.length); + tlvBuff.resize(this->_tlvBuff.size()); return tlvBuff; } diff --git a/mlxconfig/mlxcfg_parser.cpp b/mlxconfig/mlxcfg_parser.cpp index 4339ba51..5b37f425 100644 --- a/mlxconfig/mlxcfg_parser.cpp +++ b/mlxconfig/mlxcfg_parser.cpp @@ -599,7 +599,14 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) } if (((_mlxParams.cmd == Mc_Set_Raw || _mlxParams.cmd == Mc_Get_Raw) && _mlxParams.rawTlvFile.size() == 0 )) { - return err(true, "set_raw command expects raw TLV file to be specified."); + if (_mlxParams.cmd == Mc_Set_Raw) + { + return err(true, "set_raw command expects raw TLV file to be specified."); + } + else + { + return err(true, "get_raw command expects raw TLV file to be specified."); + } } if ((_mlxParams.cmd == Mc_Backup && _mlxParams.rawTlvFile.size() == 0 )) { return err(true, "backup command expects file to be specified."); @@ -607,7 +614,7 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) if ((((_mlxParams.cmd != Mc_Set_Raw && _mlxParams.cmd != Mc_Get_Raw) && _mlxParams.cmd != Mc_Backup) && _mlxParams.rawTlvFile.size() != 0 )) { - return err(true, "raw TLV file can only be specified with set_raw command."); + return err(true, "raw TLV file can only be specified with set_raw, get_raw and backup commands."); } if ((_mlxParams.cmd == Mc_ChallengeRequest && (_mlxParams.tokenID == Mc_Token_Unknown)) || @@ -627,6 +634,10 @@ mlxCfgStatus MlxCfg::parseArgs(int argc, char *argv[]) return err(true, "session time for keep alive session can only be specified with remote_token_keep_alive command"); } + if (_mlxParams.cmd == Mc_QueryTokenSession && _mlxParams.deviceType == UNSUPPORTED_DEVICE) { + return err(true, "device type must be specified with query_token_session command"); + } + if (_mlxParams.cmd == Mc_GenTLVsFile) { return extractNVOutputFile(argc - i, &(argv[i])); } diff --git a/mlxlink/modules/mlxlink_cables_commander.cpp b/mlxlink/modules/mlxlink_cables_commander.cpp index cc5fbc68..59144d2d 100644 --- a/mlxlink/modules/mlxlink_cables_commander.cpp +++ b/mlxlink/modules/mlxlink_cables_commander.cpp @@ -1500,11 +1500,11 @@ u_int32_t MlxlinkCablesCommander::getPMCRValue(ControlParam paramId, const strin bool invalidConfiguration = false; bool isCmis = _cableIdentifier >= IDENTIFIER_SFP_DD; bool isDecemal = false; - string valueStr = value; try { - toUpperCase(valueStr); - valueToSet = valueStr == "NE"? 0 : stod(value); + string valueSgtr = value; + toUpperCase(valueSgtr); + valueToSet = valueSgtr == "NE"? 0 : stod(value); isDecemal = (valueToSet - (int) valueToSet) > 0; } catch (exception &exc) { invalidConfiguration = true; diff --git a/mstdump/mstdump_dbs/BlueField2.csv b/mstdump/mstdump_dbs/BlueField2.csv index eef96b19..3f111fb8 100644 --- a/mstdump/mstdump_dbs/BlueField2.csv +++ b/mstdump/mstdump_dbs/BlueField2.csv @@ -3608,7 +3608,7 @@ 0x0f1240,14, 0x0f1280,24, 0x0f1300,6, -0x0f1320,1, +0x0f1320,2, 0x0f1400,27, 0x0f1480,8, 0x0f1500,11, @@ -8859,13 +8859,8 @@ 0x295a00,10, 0x295a80,3, 0x296000,227, -0x310408,1, 0x310488,1, 0x310490,1, -0x310498,1, -0x3104a0,1, -0x3104a8,1, -0x3104b0,1, 0x312000,1, 0x312008,1, 0x312100,1, diff --git a/mstdump/mstdump_dbs/ConnectX7.csv b/mstdump/mstdump_dbs/ConnectX7.csv index e7ba9c75..679a628b 100644 --- a/mstdump/mstdump_dbs/ConnectX7.csv +++ b/mstdump/mstdump_dbs/ConnectX7.csv @@ -8475,7 +8475,8 @@ 0x340ec0,5, 0x340ee0,5, 0x340f00,17, -0x341000,179, +0x341000,112, +0x341200,51, 0x341400,5, 0x341800,3, 0x341810,3, @@ -9996,7 +9997,8 @@ 0x3c0ec0,5, 0x3c0ee0,5, 0x3c0f00,17, -0x3c1000,179, +0x3c1000,112, +0x3c1200,51, 0x3c1400,5, 0x3c1800,3, 0x3c1810,3, diff --git a/reg_access/reg_access.c b/reg_access/reg_access.c index 93d494e1..e64f5ebb 100644 --- a/reg_access/reg_access.c +++ b/reg_access/reg_access.c @@ -33,17 +33,8 @@ #include "reg_access.h" #include "common/compatibility.h" -//FPGA -#define REG_ID_FPGA_CAP 0x4022 -#define REG_ID_FPGA_CTRL 0x4023 #define REG_ID_PCNR 0x5050 -#define REG_ID_PPTCS 0x5801 -#define REG_ID_PGMP 0x5802 -#define REG_ID_PPTS 0x5803 -#define REG_ID_PLTS 0x5804 -#define REG_ID_PLSRP 0x5805 -#define REG_ID_PGPS 0x5806 #define REG_ID_PAOS 0x5006 #define REG_ID_PTYS 0x5004 #define REG_ID_PMAOS 0x5012 @@ -83,6 +74,7 @@ #define REG_ID_STRS_RESOURCE 0x402A #define REG_ID_MTRC_CAP 0x9040 +#define REG_ID_MTRC_STDB 0x9042 #define REG_ID_MCDD 0x905C #define REG_ID_MCQS 0x9060 #define REG_ID_MCC 0x9062 @@ -483,14 +475,6 @@ reg_access_status_t reg_access_pmdic(mfile *mf, reg_access_method_t method, stru REG_ACCCESS(mf, method, REG_ID_PMDIC, pmdic, pmdic, tools_open); } -/************************************ -* Function: reg_access_fpga_cap -************************************/ -reg_access_status_t reg_access_fpga_cap(mfile *mf, reg_access_method_t method, struct reg_access_hca_fpga_cap *fpga_cap) -{ - REG_ACCCESS(mf, method, REG_ID_FPGA_CAP, fpga_cap, fpga_cap, reg_access_hca); -} - //================================================================================================================================= /************************************ @@ -509,13 +493,6 @@ reg_access_status_t reg_access_debug_cap(mfile *mf, reg_access_method_t method, //================================================================================================================================= -/************************************ -* Function: reg_access_fpga_ctrl -************************************/ -reg_access_status_t reg_access_fpga_ctrl(mfile *mf, reg_access_method_t method, struct reg_access_hca_fpga_ctrl *fpga_ctrl) -{ - REG_ACCCESS(mf, method, REG_ID_FPGA_CTRL, fpga_ctrl, fpga_ctrl, reg_access_hca); -} #endif //#ifndef UEFI_BUILD diff --git a/reg_access/reg_access.h b/reg_access/reg_access.h index 05d47f18..2d6ca570 100644 --- a/reg_access/reg_access.h +++ b/reg_access/reg_access.h @@ -82,9 +82,6 @@ reg_access_status_t reg_access_debug_cap(mfile *mf, reg_access_method_t method, reg_access_status_t reg_access_pcnr(mfile *mf, reg_access_method_t method, struct reg_access_hca_pcnr_reg *pcnr); -reg_access_status_t reg_access_fpga_cap(mfile *mf, reg_access_method_t method, struct reg_access_hca_fpga_cap *fpga_cap); -reg_access_status_t reg_access_fpga_ctrl(mfile *mf, reg_access_method_t method, struct reg_access_hca_fpga_ctrl *fpga_ctrl); - reg_access_status_t reg_access_strs_stop_toggle_reg(mfile *mf, reg_access_method_t method, struct reg_access_hca_strs_stop_toggle_reg *streg); reg_access_status_t reg_access_strs_fault_injector_reg(mfile *mf, reg_access_method_t method, struct reg_access_hca_strs_fault_inject_reg *strs_fault_inject_reg); reg_access_status_t reg_access_strs_mini_flow_reg(mfile *mf, reg_access_method_t method, struct reg_access_hca_strs_mini_flow_reg *strs_mini_flow_reg); diff --git a/small_utils/mstfwreset.py b/small_utils/mstfwreset.py index 48550083..888cb859 100644 --- a/small_utils/mstfwreset.py +++ b/small_utils/mstfwreset.py @@ -1324,7 +1324,6 @@ def resetFlow(device, devicesSD, reset_level, reset_type, cmdLineArgs, mfrl): all_devices = [device] + devicesSD - # A temporary solution to get the pci-device-id (required for SmartNic) # This solution is not good when the user insert device in PCI address format (-d xx:xx.x) pci_device_id = None @@ -1553,7 +1552,7 @@ def main(): action="store_true") options_group.add_argument('--mst_flags', '-m', - help=": Provide mst flags to be used when invoking mst restart step. For example: --mst_flags=\"--with_fpga\"" + help=": Provide mst flags to be used when invoking mst restart step. For example: --mst_flags=\"--with_i2cdev\"" if platform.system() == "Linux" and not IS_MSTFLINT else argparse.SUPPRESS) options_group.add_argument('--version', '-v', diff --git a/tools_layouts/adb/prm/switch/ext/register_access_table.adb b/tools_layouts/adb/prm/switch/ext/register_access_table.adb index a25b4625..539de75e 100644 --- a/tools_layouts/adb/prm/switch/ext/register_access_table.adb +++ b/tools_layouts/adb/prm/switch/ext/register_access_table.adb @@ -35,7 +35,7 @@ - + @@ -44,17 +44,17 @@ + - - + - - - - + + + + @@ -71,7 +71,7 @@ - + @@ -79,7 +79,7 @@ - + @@ -118,7 +118,7 @@ - + @@ -179,21 +179,21 @@ - + - + - + - - + + @@ -203,18 +203,18 @@ - + - + - + @@ -224,17 +224,17 @@ - + - + - + @@ -585,6 +585,7 @@ + @@ -700,7 +701,7 @@ - + @@ -713,7 +714,7 @@ - + @@ -728,8 +729,8 @@ - - + + @@ -795,7 +796,7 @@ - + @@ -899,8 +900,8 @@ - - + + @@ -925,7 +926,7 @@ - + @@ -942,9 +943,9 @@ - + - + @@ -969,7 +970,7 @@ - + @@ -1013,9 +1014,9 @@ - - - + + + @@ -1409,14 +1410,14 @@ - + - + @@ -1427,30 +1428,30 @@ - - - - + + + + - - - + + + - + - + @@ -1458,11 +1459,11 @@ - - - - - + + + + + @@ -1514,7 +1515,7 @@ - + @@ -1558,8 +1559,8 @@ - - + + @@ -1627,7 +1628,7 @@ - + @@ -1637,7 +1638,7 @@ - + @@ -1657,19 +1658,19 @@ - + - + - + - + @@ -1683,11 +1684,11 @@ - - + + - + @@ -1720,27 +1721,27 @@ - + - + - + - + - + @@ -1765,7 +1766,7 @@ - + @@ -1789,17 +1790,17 @@ - + - + - + @@ -1807,14 +1808,14 @@ - + - + @@ -1826,13 +1827,13 @@ - + - + - + @@ -1851,7 +1852,7 @@ - + @@ -1877,7 +1878,7 @@ - + @@ -1890,11 +1891,11 @@ - + - + @@ -1940,7 +1941,7 @@ - + @@ -1950,7 +1951,7 @@ - + @@ -1968,13 +1969,13 @@ - + - + @@ -1990,7 +1991,7 @@ - + @@ -2000,11 +2001,11 @@ - + - + @@ -2049,7 +2050,7 @@ - + @@ -2150,7 +2151,7 @@ - + @@ -2158,8 +2159,8 @@ - - + + @@ -2181,7 +2182,7 @@ - + @@ -2215,7 +2216,7 @@ - + @@ -2224,7 +2225,7 @@ - + @@ -2305,8 +2306,8 @@ - - + + @@ -2326,7 +2327,7 @@ - + @@ -2355,7 +2356,7 @@ - + @@ -2425,9 +2426,9 @@ - - - + + + @@ -2457,16 +2458,16 @@ - + - + - + @@ -2499,8 +2500,8 @@ - - + + @@ -2510,7 +2511,7 @@ - + @@ -2519,7 +2520,7 @@ - + @@ -2527,7 +2528,7 @@ - + @@ -2552,7 +2553,7 @@ - + @@ -2611,11 +2612,11 @@ - + - + @@ -2629,7 +2630,7 @@ - + @@ -2639,7 +2640,7 @@ - + @@ -2651,15 +2652,18 @@ - + - - + + + + + @@ -2676,7 +2680,7 @@ - + @@ -2752,8 +2756,8 @@ - - + + @@ -2768,7 +2772,7 @@ - + @@ -2780,7 +2784,7 @@ - + @@ -2789,7 +2793,7 @@ - + @@ -2837,7 +2841,7 @@ - + @@ -2856,7 +2860,7 @@ - + @@ -2869,7 +2873,7 @@ - + @@ -2884,20 +2888,20 @@ - + - + - - - - + + + + @@ -2938,7 +2942,7 @@ - + @@ -2981,11 +2985,11 @@ - + - + @@ -2994,7 +2998,7 @@ - + @@ -3010,7 +3014,7 @@ - + @@ -3048,8 +3052,8 @@ - - + + @@ -3077,16 +3081,16 @@ - + - + - - - + + + @@ -3101,8 +3105,8 @@ - - + + @@ -3114,8 +3118,8 @@ - - + + @@ -3130,8 +3134,8 @@ - - + + @@ -3145,19 +3149,19 @@ - + - - - + + + - + @@ -3184,7 +3188,7 @@ - + @@ -3220,7 +3224,7 @@ - + @@ -3264,7 +3268,7 @@ - + @@ -3297,14 +3301,14 @@ - + - + @@ -3356,6 +3360,7 @@ + @@ -3377,11 +3382,11 @@ - + - + @@ -3399,7 +3404,7 @@ - + @@ -3448,7 +3453,7 @@ - + @@ -3480,18 +3485,18 @@ - + - + - + @@ -3514,8 +3519,8 @@ - - + + @@ -3526,7 +3531,7 @@ - + @@ -3601,7 +3606,7 @@ - + @@ -3904,10 +3909,10 @@ - - - - + + + + @@ -4040,7 +4045,7 @@ - + @@ -4061,7 +4066,7 @@ - + @@ -4072,7 +4077,7 @@ - + @@ -4093,7 +4098,7 @@ - + @@ -4107,7 +4112,7 @@ - + @@ -4115,8 +4120,8 @@ - - + + @@ -4161,14 +4166,14 @@ - + - + @@ -4205,7 +4210,7 @@ - + @@ -4224,7 +4229,7 @@ - + @@ -4349,7 +4354,7 @@ - + @@ -4570,7 +4575,7 @@ - + @@ -4578,17 +4583,35 @@ - + + + + + + + + + + + + + + + + + + + - + - - + + @@ -4596,6 +4619,11 @@ + + + + + @@ -4743,8 +4771,8 @@ - - + + @@ -4754,14 +4782,14 @@ - + - - + + @@ -4874,12 +4902,12 @@ - + - + @@ -4902,7 +4930,7 @@ - + @@ -4965,7 +4993,7 @@ - + @@ -5066,9 +5094,9 @@ - + - + @@ -5086,13 +5114,13 @@ - + - - - + + + @@ -5110,8 +5138,8 @@ - - + + @@ -5119,8 +5147,8 @@ - - + + @@ -5128,10 +5156,10 @@ - - + + - + @@ -5145,10 +5173,10 @@ - - + + - + @@ -5156,8 +5184,8 @@ - - + + @@ -5174,7 +5202,7 @@ - + @@ -5199,7 +5227,7 @@ - + @@ -5287,7 +5315,7 @@ - + @@ -5321,13 +5349,13 @@ - + - - + + @@ -5395,25 +5423,25 @@ - + - + - + - + @@ -5443,7 +5471,7 @@ - + @@ -5505,7 +5533,7 @@ - + @@ -5516,14 +5544,14 @@ - - - - + + + + - + @@ -5541,7 +5569,7 @@ - + @@ -5572,7 +5600,7 @@ - + @@ -5588,7 +5616,7 @@ - + @@ -5596,11 +5624,11 @@ - + - - - + + + @@ -5627,8 +5655,8 @@ - - + + @@ -5662,7 +5690,7 @@ - + @@ -5703,35 +5731,35 @@ - - - - + + + + - + - + - - - - + + + + - + - + - + @@ -5748,21 +5776,21 @@ - - - + + + - + - - + + @@ -5782,7 +5810,7 @@ - + @@ -5799,12 +5827,12 @@ - + - + @@ -5814,7 +5842,7 @@ - + @@ -5870,15 +5898,15 @@ - + - + - + @@ -5892,8 +5920,8 @@ - - + + @@ -5906,9 +5934,9 @@ - + - + @@ -5916,7 +5944,7 @@ - + @@ -5926,14 +5954,14 @@ - - + + - + - + @@ -5960,13 +5988,13 @@ - + - - - - + + + + @@ -5992,9 +6020,9 @@ - - - + + + @@ -6024,9 +6052,9 @@ - - - + + + @@ -6035,7 +6063,7 @@ - + @@ -6079,7 +6107,7 @@ - + @@ -6091,7 +6119,7 @@ - + @@ -6101,7 +6129,7 @@ - + @@ -6144,7 +6172,7 @@ - + @@ -6171,9 +6199,9 @@ - + - + @@ -6189,7 +6217,7 @@ - + @@ -6197,18 +6225,18 @@ - + - + - + @@ -6237,7 +6265,7 @@ - + @@ -6261,7 +6289,7 @@ - + @@ -6330,7 +6358,7 @@ - + @@ -6376,17 +6404,17 @@ - + - + - - + + @@ -6399,8 +6427,8 @@ - - + + @@ -6409,10 +6437,10 @@ - + - + @@ -6427,21 +6455,21 @@ - + - + - + - + @@ -6501,8 +6529,8 @@ - - + + @@ -6514,7 +6542,7 @@ - + @@ -6529,7 +6557,7 @@ - + @@ -6541,7 +6569,7 @@ - + @@ -6550,7 +6578,7 @@ - + @@ -6559,7 +6587,7 @@ - + @@ -6570,9 +6598,9 @@ - + - + @@ -6583,12 +6611,12 @@ - + - - + + @@ -6597,19 +6625,19 @@ - + - + - + - + - + @@ -6622,9 +6650,9 @@ - - - + + + @@ -6637,14 +6665,14 @@ - + - - + + @@ -6656,7 +6684,7 @@ - + @@ -6665,7 +6693,7 @@ - + @@ -6675,13 +6703,13 @@ - + - + @@ -6762,7 +6790,7 @@ - + @@ -6814,7 +6842,7 @@ - + @@ -6844,7 +6872,7 @@ - + @@ -6968,7 +6996,7 @@ - + @@ -6984,22 +7012,22 @@ - + - + - + - + @@ -7018,7 +7046,7 @@ - + @@ -7027,7 +7055,7 @@ - + @@ -7046,7 +7074,7 @@ - + @@ -7058,7 +7086,7 @@ - + @@ -7079,7 +7107,7 @@ - + @@ -7103,7 +7131,7 @@ - + @@ -7113,14 +7141,14 @@ - + - + @@ -7129,7 +7157,7 @@ - + @@ -7162,7 +7190,7 @@ - + @@ -7190,8 +7218,8 @@ - - + + @@ -7218,13 +7246,13 @@ - + - - - + + + @@ -7263,7 +7291,7 @@ - + @@ -7274,21 +7302,21 @@ - + - + - + - - + + - + @@ -7326,7 +7354,7 @@ - + @@ -7335,7 +7363,7 @@ - + @@ -7343,16 +7371,16 @@ - + - + - + - - + + @@ -7367,17 +7395,17 @@ - + - - - - + + + + @@ -7393,7 +7421,7 @@ - + @@ -7415,11 +7443,11 @@ - + - + @@ -7429,7 +7457,7 @@ - + @@ -7437,12 +7465,12 @@ - - + + - + @@ -7455,11 +7483,11 @@ - + - + - + @@ -7474,14 +7502,14 @@ - + - - - + + + @@ -7522,11 +7550,11 @@ - + - + @@ -7543,13 +7571,14 @@ - - + + - + + @@ -7570,7 +7599,7 @@ - + @@ -7605,9 +7634,9 @@ - - - + + + @@ -7643,7 +7672,7 @@ - + @@ -7710,9 +7739,9 @@ - + - + @@ -7764,7 +7793,7 @@ - + @@ -7787,15 +7816,15 @@ - + - + - - + + @@ -7806,8 +7835,8 @@ - - + + @@ -7821,7 +7850,7 @@ - + @@ -7839,7 +7868,7 @@ - + @@ -7890,13 +7919,13 @@ - + - + @@ -7919,11 +7948,11 @@ - - + + - - + + diff --git a/tools_layouts/reg_access_hca_layouts.c b/tools_layouts/reg_access_hca_layouts.c index 121ccb64..223faee8 100644 --- a/tools_layouts/reg_access_hca_layouts.c +++ b/tools_layouts/reg_access_hca_layouts.c @@ -999,107 +999,6 @@ void reg_access_hca_diagnostic_cntr_layout_dump(const struct reg_access_hca_diag reg_access_hca_diagnostic_cntr_layout_print(ptr_struct, fd, 0); } -void reg_access_hca_fpga_shell_caps_pack(const struct reg_access_hca_fpga_shell_caps *ptr_struct, u_int8_t *ptr_buff) -{ - u_int32_t offset; - - offset = 24; - adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->total_rcv_credits); - offset = 0; - adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->max_num_qps); - offset = 63; - adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->rc); - offset = 62; - adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->uc); - offset = 61; - adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->ud); - offset = 60; - adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->dc); - offset = 55; - adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->rre); - offset = 54; - adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->rwe); - offset = 53; - adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->rae); - offset = 46; - adb2c_push_bits_to_buff(ptr_buff, offset, 2, (u_int32_t)ptr_struct->qp_type); - offset = 90; - adb2c_push_bits_to_buff(ptr_buff, offset, 6, (u_int32_t)ptr_struct->log_ddr_size); - offset = 96; - adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->max_fpga_qp_msg_size); -} - -void reg_access_hca_fpga_shell_caps_unpack(struct reg_access_hca_fpga_shell_caps *ptr_struct, const u_int8_t *ptr_buff) -{ - u_int32_t offset; - - offset = 24; - ptr_struct->total_rcv_credits = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); - offset = 0; - ptr_struct->max_num_qps = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); - offset = 63; - ptr_struct->rc = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); - offset = 62; - ptr_struct->uc = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); - offset = 61; - ptr_struct->ud = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); - offset = 60; - ptr_struct->dc = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); - offset = 55; - ptr_struct->rre = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); - offset = 54; - ptr_struct->rwe = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); - offset = 53; - ptr_struct->rae = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); - offset = 46; - ptr_struct->qp_type = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 2); - offset = 90; - ptr_struct->log_ddr_size = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 6); - offset = 96; - ptr_struct->max_fpga_qp_msg_size = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); -} - -void reg_access_hca_fpga_shell_caps_print(const struct reg_access_hca_fpga_shell_caps *ptr_struct, FILE *fd, int indent_level) -{ - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "======== reg_access_hca_fpga_shell_caps ========\n"); - - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "total_rcv_credits : " UH_FMT "\n", ptr_struct->total_rcv_credits); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "max_num_qps : " UH_FMT "\n", ptr_struct->max_num_qps); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "rc : " UH_FMT "\n", ptr_struct->rc); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "uc : " UH_FMT "\n", ptr_struct->uc); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "ud : " UH_FMT "\n", ptr_struct->ud); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "dc : " UH_FMT "\n", ptr_struct->dc); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "rre : " UH_FMT "\n", ptr_struct->rre); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "rwe : " UH_FMT "\n", ptr_struct->rwe); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "rae : " UH_FMT "\n", ptr_struct->rae); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "qp_type : %s (" UH_FMT ")\n", (ptr_struct->qp_type == 1 ? ("Shell_qp") : ((ptr_struct->qp_type == 2 ? ("Sandbox_qp") : ("unknown")))), ptr_struct->qp_type); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "log_ddr_size : " UH_FMT "\n", ptr_struct->log_ddr_size); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "max_fpga_qp_msg_size : " U32H_FMT "\n", ptr_struct->max_fpga_qp_msg_size); -} - -unsigned int reg_access_hca_fpga_shell_caps_size(void) -{ - return REG_ACCESS_HCA_FPGA_SHELL_CAPS_SIZE; -} - -void reg_access_hca_fpga_shell_caps_dump(const struct reg_access_hca_fpga_shell_caps *ptr_struct, FILE *fd) -{ - reg_access_hca_fpga_shell_caps_print(ptr_struct, fd, 0); -} - void reg_access_hca_mcqi_reg_data_auto_pack(const union reg_access_hca_mcqi_reg_data_auto *ptr_struct, u_int8_t *ptr_buff) { reg_access_hca_mcqi_cap_pack(&(ptr_struct->mcqi_cap), ptr_buff); @@ -1833,233 +1732,6 @@ void reg_access_hca_debug_cap_dump(const struct reg_access_hca_debug_cap *ptr_st reg_access_hca_debug_cap_print(ptr_struct, fd, 0); } -void reg_access_hca_fpga_cap_pack(const struct reg_access_hca_fpga_cap *ptr_struct, u_int8_t *ptr_buff) -{ - u_int32_t offset; - - offset = 8; - adb2c_push_bits_to_buff(ptr_buff, offset, 24, (u_int32_t)ptr_struct->fpga_device); - offset = 0; - adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->fpga_id); - offset = 32; - adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->register_file_ver); - offset = 78; - adb2c_push_bits_to_buff(ptr_buff, offset, 2, (u_int32_t)ptr_struct->access_reg_modify_mode); - offset = 70; - adb2c_push_bits_to_buff(ptr_buff, offset, 2, (u_int32_t)ptr_struct->access_reg_query_mode); - offset = 66; - adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->disconnect_fpga); - offset = 65; - adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->flash_gw_lock); - offset = 64; - adb2c_push_bits_to_buff(ptr_buff, offset, 1, (u_int32_t)ptr_struct->fpga_ctrl_modify); - offset = 128; - adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->image_version); - offset = 160; - adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->image_date); - offset = 192; - adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->image_time); - offset = 224; - adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->shell_version); - offset = 384; - reg_access_hca_fpga_shell_caps_pack(&(ptr_struct->shell_caps), ptr_buff + offset / 8); - offset = 904; - adb2c_push_bits_to_buff(ptr_buff, offset, 24, (u_int32_t)ptr_struct->ieee_vendor_id); - offset = 944; - adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->sandbox_product_id); - offset = 928; - adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->sandbox_product_version); - offset = 960; - adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->sandbox_basic_caps); - offset = 1008; - adb2c_push_bits_to_buff(ptr_buff, offset, 16, (u_int32_t)ptr_struct->sandbox_extended_caps_len); - offset = 1024; - adb2c_push_integer_to_buff(ptr_buff, offset, 8, ptr_struct->sandbox_extended_caps_addr); - offset = 1088; - adb2c_push_integer_to_buff(ptr_buff, offset, 8, ptr_struct->fpga_ddr_start_addr); - offset = 1152; - adb2c_push_integer_to_buff(ptr_buff, offset, 8, ptr_struct->fpga_cr_space_start_addr); - offset = 1216; - adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->fpga_ddr_size); - offset = 1248; - adb2c_push_integer_to_buff(ptr_buff, offset, 4, (u_int32_t)ptr_struct->fpga_cr_space_size); -} - -void reg_access_hca_fpga_cap_unpack(struct reg_access_hca_fpga_cap *ptr_struct, const u_int8_t *ptr_buff) -{ - u_int32_t offset; - - offset = 8; - ptr_struct->fpga_device = (u_int32_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 24); - offset = 0; - ptr_struct->fpga_id = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); - offset = 32; - ptr_struct->register_file_ver = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); - offset = 78; - ptr_struct->access_reg_modify_mode = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 2); - offset = 70; - ptr_struct->access_reg_query_mode = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 2); - offset = 66; - ptr_struct->disconnect_fpga = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); - offset = 65; - ptr_struct->flash_gw_lock = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); - offset = 64; - ptr_struct->fpga_ctrl_modify = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 1); - offset = 128; - ptr_struct->image_version = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); - offset = 160; - ptr_struct->image_date = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); - offset = 192; - ptr_struct->image_time = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); - offset = 224; - ptr_struct->shell_version = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); - offset = 384; - reg_access_hca_fpga_shell_caps_unpack(&(ptr_struct->shell_caps), ptr_buff + offset / 8); - offset = 904; - ptr_struct->ieee_vendor_id = (u_int32_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 24); - offset = 944; - ptr_struct->sandbox_product_id = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); - offset = 928; - ptr_struct->sandbox_product_version = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); - offset = 960; - ptr_struct->sandbox_basic_caps = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); - offset = 1008; - ptr_struct->sandbox_extended_caps_len = (u_int16_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 16); - offset = 1024; - ptr_struct->sandbox_extended_caps_addr = adb2c_pop_integer_from_buff(ptr_buff, offset, 8); - offset = 1088; - ptr_struct->fpga_ddr_start_addr = adb2c_pop_integer_from_buff(ptr_buff, offset, 8); - offset = 1152; - ptr_struct->fpga_cr_space_start_addr = adb2c_pop_integer_from_buff(ptr_buff, offset, 8); - offset = 1216; - ptr_struct->fpga_ddr_size = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); - offset = 1248; - ptr_struct->fpga_cr_space_size = (u_int32_t)adb2c_pop_integer_from_buff(ptr_buff, offset, 4); -} - -void reg_access_hca_fpga_cap_print(const struct reg_access_hca_fpga_cap *ptr_struct, FILE *fd, int indent_level) -{ - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "======== reg_access_hca_fpga_cap ========\n"); - - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "fpga_device : %s (" UH_FMT ")\n", (ptr_struct->fpga_device == 0 ? ("UNKNOWN_DEVICE") : ((ptr_struct->fpga_device == 1 ? ("KU040") : ((ptr_struct->fpga_device == 2 ? ("KU060") : ((ptr_struct->fpga_device == 3 ? ("KU060_2") : ("unknown")))))))), ptr_struct->fpga_device); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "fpga_id : %s (" UH_FMT ")\n", (ptr_struct->fpga_id == 0 ? ("Newton_X") : ((ptr_struct->fpga_id == 1 ? ("Edison") : ("unknown")))), ptr_struct->fpga_id); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "register_file_ver : " U32H_FMT "\n", ptr_struct->register_file_ver); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "access_reg_modify_mode : %s (" UH_FMT ")\n", (ptr_struct->access_reg_modify_mode == 0 ? ("Not_allowed") : ((ptr_struct->access_reg_modify_mode == 1 ? ("All_range_allowed") : ("unknown")))), ptr_struct->access_reg_modify_mode); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "access_reg_query_mode : %s (" UH_FMT ")\n", (ptr_struct->access_reg_query_mode == 0 ? ("Not_allowed") : ((ptr_struct->access_reg_query_mode == 1 ? ("All_range_allowed") : ("unknown")))), ptr_struct->access_reg_query_mode); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "disconnect_fpga : " UH_FMT "\n", ptr_struct->disconnect_fpga); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "flash_gw_lock : " UH_FMT "\n", ptr_struct->flash_gw_lock); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "fpga_ctrl_modify : " UH_FMT "\n", ptr_struct->fpga_ctrl_modify); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "image_version : " U32H_FMT "\n", ptr_struct->image_version); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "image_date : " U32H_FMT "\n", ptr_struct->image_date); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "image_time : " U32H_FMT "\n", ptr_struct->image_time); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "shell_version : " U32H_FMT "\n", ptr_struct->shell_version); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "shell_caps:\n"); - reg_access_hca_fpga_shell_caps_print(&(ptr_struct->shell_caps), fd, indent_level + 1); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "ieee_vendor_id : " UH_FMT "\n", ptr_struct->ieee_vendor_id); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "sandbox_product_id : %s (" UH_FMT ")\n", (ptr_struct->sandbox_product_id == 0 ? ("unknown") : ((ptr_struct->sandbox_product_id == 1 ? ("example") : ((ptr_struct->sandbox_product_id == 2 ? ("IPsec") : ((ptr_struct->sandbox_product_id == 3 ? ("TLS") : ("unknown")))))))), ptr_struct->sandbox_product_id); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "sandbox_product_version : " UH_FMT "\n", ptr_struct->sandbox_product_version); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "sandbox_basic_caps : " U32H_FMT "\n", ptr_struct->sandbox_basic_caps); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "sandbox_extended_caps_len : " UH_FMT "\n", ptr_struct->sandbox_extended_caps_len); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "sandbox_extended_caps_addr : " U64H_FMT "\n", ptr_struct->sandbox_extended_caps_addr); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "fpga_ddr_start_addr : " U64H_FMT "\n", ptr_struct->fpga_ddr_start_addr); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "fpga_cr_space_start_addr : " U64H_FMT "\n", ptr_struct->fpga_cr_space_start_addr); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "fpga_ddr_size : " U32H_FMT "\n", ptr_struct->fpga_ddr_size); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "fpga_cr_space_size : " U32H_FMT "\n", ptr_struct->fpga_cr_space_size); -} - -unsigned int reg_access_hca_fpga_cap_size(void) -{ - return REG_ACCESS_HCA_FPGA_CAP_SIZE; -} - -void reg_access_hca_fpga_cap_dump(const struct reg_access_hca_fpga_cap *ptr_struct, FILE *fd) -{ - reg_access_hca_fpga_cap_print(ptr_struct, fd, 0); -} - -void reg_access_hca_fpga_ctrl_pack(const struct reg_access_hca_fpga_ctrl *ptr_struct, u_int8_t *ptr_buff) -{ - u_int32_t offset; - - offset = 24; - adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->status); - offset = 8; - adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->operation); - offset = 0; - adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->error_type); - offset = 56; - adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->flash_select_oper); - offset = 40; - adb2c_push_bits_to_buff(ptr_buff, offset, 8, (u_int32_t)ptr_struct->flash_select_admin); -} - -void reg_access_hca_fpga_ctrl_unpack(struct reg_access_hca_fpga_ctrl *ptr_struct, const u_int8_t *ptr_buff) -{ - u_int32_t offset; - - offset = 24; - ptr_struct->status = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); - offset = 8; - ptr_struct->operation = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); - offset = 0; - ptr_struct->error_type = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); - offset = 56; - ptr_struct->flash_select_oper = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); - offset = 40; - ptr_struct->flash_select_admin = (u_int8_t)adb2c_pop_bits_from_buff(ptr_buff, offset, 8); -} - -void reg_access_hca_fpga_ctrl_print(const struct reg_access_hca_fpga_ctrl *ptr_struct, FILE *fd, int indent_level) -{ - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "======== reg_access_hca_fpga_ctrl ========\n"); - - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "status : %s (" UH_FMT ")\n", (ptr_struct->status == 0 ? ("Success") : ((ptr_struct->status == 1 ? ("Failure") : ((ptr_struct->status == 2 ? ("In_progress") : ((ptr_struct->status == 3 ? ("DISCONNECTED") : ("unknown")))))))), ptr_struct->status); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "operation : %s (" UH_FMT ")\n", (ptr_struct->operation == 1 ? ("LOAD") : ((ptr_struct->operation == 2 ? ("RESET") : ((ptr_struct->operation == 3 ? ("FLASH_SELECT") : ((ptr_struct->operation == 4 ? ("Sandbox_Bypass_On") : ((ptr_struct->operation == 5 ? ("Sandbox_Bypass_Off") : ((ptr_struct->operation == 6 ? ("Reset_Sandbox") : ((ptr_struct->operation == 7 ? ("Flash_GW_Lock") : ((ptr_struct->operation == 8 ? ("Flash_GW_Unlock") : ((ptr_struct->operation == 9 ? ("DISCONNECT") : ((ptr_struct->operation == 10 ? ("CONNECT") : ("unknown")))))))))))))))))))), ptr_struct->operation); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "error_type : %s (" UH_FMT ")\n", (ptr_struct->error_type == 0 ? ("Error_unknown") : ((ptr_struct->error_type == 1 ? ("fpga_done_timeout") : ((ptr_struct->error_type == 2 ? ("gpio_sig_mismatch") : ((ptr_struct->error_type == 3 ? ("ddr_bist_timeout") : ((ptr_struct->error_type == 4 ? ("sadb_reset_done_timeout") : ((ptr_struct->error_type == 5 ? ("sadb_reset_success_timeout") : ((ptr_struct->error_type == 6 ? ("ips_flush_done_timeout") : ((ptr_struct->error_type == 7 ? ("flash_gw_lock_timeout") : ((ptr_struct->error_type == 8 ? ("flash_gw_unlock_error") : ((ptr_struct->error_type == 9 ? ("i2c_access_during_fpga_load") : ((ptr_struct->error_type == 10 ? ("fpga_user_img_done_timeout") : ("unknown")))))))))))))))))))))), ptr_struct->error_type); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "flash_select_oper : %s (" UH_FMT ")\n", (ptr_struct->flash_select_oper == 0 ? ("User") : ((ptr_struct->flash_select_oper == 1 ? ("Factory_default") : ((ptr_struct->flash_select_oper == 2 ? ("Factory_failover") : ("unknown")))))), ptr_struct->flash_select_oper); - adb2c_add_indentation(fd, indent_level); - fprintf(fd, "flash_select_admin : %s (" UH_FMT ")\n", (ptr_struct->flash_select_admin == 0 ? ("User") : ((ptr_struct->flash_select_admin == 1 ? ("Factory_default") : ("unknown")))), ptr_struct->flash_select_admin); -} - -unsigned int reg_access_hca_fpga_ctrl_size(void) -{ - return REG_ACCESS_HCA_FPGA_CTRL_SIZE; -} - -void reg_access_hca_fpga_ctrl_dump(const struct reg_access_hca_fpga_ctrl *ptr_struct, FILE *fd) -{ - reg_access_hca_fpga_ctrl_print(ptr_struct, fd, 0); -} - void reg_access_hca_mcc_reg_pack(const struct reg_access_hca_mcc_reg *ptr_struct, u_int8_t *ptr_buff) { u_int32_t offset; @@ -3619,18 +3291,12 @@ void reg_access_hca_reg_access_hca_Nodes_print(const union reg_access_hca_reg_ac fprintf(fd, "mcda_reg:\n"); reg_access_hca_mcda_reg_print(&(ptr_struct->mcda_reg), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); - fprintf(fd, "fpga_ctrl:\n"); - reg_access_hca_fpga_ctrl_print(&(ptr_struct->fpga_ctrl), fd, indent_level + 1); - adb2c_add_indentation(fd, indent_level); fprintf(fd, "mtrc_cap_reg:\n"); reg_access_hca_mtrc_cap_reg_print(&(ptr_struct->mtrc_cap_reg), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); fprintf(fd, "mpegc_reg:\n"); reg_access_hca_mpegc_reg_print(&(ptr_struct->mpegc_reg), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); - fprintf(fd, "fpga_cap:\n"); - reg_access_hca_fpga_cap_print(&(ptr_struct->fpga_cap), fd, indent_level + 1); - adb2c_add_indentation(fd, indent_level); fprintf(fd, "mfrl_reg_ext:\n"); reg_access_hca_mfrl_reg_ext_print(&(ptr_struct->mfrl_reg_ext), fd, indent_level + 1); adb2c_add_indentation(fd, indent_level); diff --git a/tools_layouts/reg_access_hca_layouts.h b/tools_layouts/reg_access_hca_layouts.h index b4b29bab..b136be7f 100644 --- a/tools_layouts/reg_access_hca_layouts.h +++ b/tools_layouts/reg_access_hca_layouts.h @@ -174,12 +174,12 @@ Other values are reserved */ u_int8_t category; /*---------------- DWORD[1] (Offset 0x4) ----------------*/ /* Description - LOCK_RESOURCE Modifier according to category field -For GENERAL_SEMAPHORE Table 1091, "GENERAL_SEMA -PHORE Category Layout," on page 1358 -For ICM_RESOURCE Table 1093, "ICM_RESOURCE Category -Layout," on page 1359 -For UAPP_RESOURCE Table 1095, "UAPP_RESOURCE Cate -gory Layout," on page 1359 */ +For GENERAL_SEMAPHORE Table 1102, "GENERAL_SEMA +PHORE Category Layout," on page 1388 +For ICM_RESOURCE Table 1104, "ICM_RESOURCE Category +Layout," on page 1389 +For UAPP_RESOURCE Table 1106, "UAPP_RESOURCE Cate +gory Layout," on page 1389 */ /* 0x4.0 - 0x1c.31 */ union reg_access_hca_lock_source_stop_toggle_modifier_category_modifier_auto category_modifier; }; @@ -281,7 +281,7 @@ ponent update. */ /* 0x10.30 - 0x10.30 */ u_int8_t signed_updates_only; /* Description - When set, this components may be read, see -Section 10.3.4, "Read Flow", on page 803. */ +Section 10.3.4, "Read Flow", on page 829. */ /* 0x10.31 - 0x10.31 */ u_int8_t rd_en; }; @@ -388,14 +388,14 @@ stamp in build_time */ u_int32_t version; /*---------------- DWORD[2] (Offset 0x8) ----------------*/ /* Description - Time of component creation. Valid only if build_ -time_valid is set. See Table 1847, "Date-Time Lay -out," on page 2078 */ +time_valid is set. See Table 1873, "Date-Time Lay +out," on page 2336 */ /* 0x8.0 - 0xc.31 */ u_int64_t build_time; /*---------------- DWORD[4] (Offset 0x10) ----------------*/ /* Description - User-defined time assigned to the component version. Valid only if user_defined_time_valid is set. See -Table 1847, "Date-Time Layout," on page 2078 */ +Table 1873, "Date-Time Layout," on page 2336 */ /* 0x10.0 - 0x14.31 */ u_int64_t user_defined_time; /*---------------- DWORD[6] (Offset 0x18) ----------------*/ @@ -542,54 +542,6 @@ Counters */ u_int8_t sync; }; -/* Description - */ -/* Size in bytes - 64 */ -struct reg_access_hca_fpga_shell_caps { -/*---------------- DWORD[0] (Offset 0x0) ----------------*/ - /* Description - Total size of shared QP buffer size in granularity of 2 KB. */ - /* 0x0.0 - 0x0.7 */ - u_int8_t total_rcv_credits; - /* Description - Maximum number of supported QPs. */ - /* 0x0.16 - 0x0.31 */ - u_int16_t max_num_qps; -/*---------------- DWORD[1] (Offset 0x4) ----------------*/ - /* Description - If set, RC transport service is supported. */ - /* 0x4.0 - 0x4.0 */ - u_int8_t rc; - /* Description - If set, UC transport service is supported. */ - /* 0x4.1 - 0x4.1 */ - u_int8_t uc; - /* Description - If set, UD transport service is supported. */ - /* 0x4.2 - 0x4.2 */ - u_int8_t ud; - /* Description - If set, DC transport service is supported. */ - /* 0x4.3 - 0x4.3 */ - u_int8_t dc; - /* Description - If set, RDMA READ operation is supported. */ - /* 0x4.8 - 0x4.8 */ - u_int8_t rre; - /* Description - If set, RDMA WRITE operation is supported. */ - /* 0x4.9 - 0x4.9 */ - u_int8_t rwe; - /* Description - If set, RDMA atomic operation is supported. */ - /* 0x4.10 - 0x4.10 */ - u_int8_t rae; - /* Description - Bit mask indicates which QP types are supported -Bit 0: Shell_qp - Shell QP supported -Bit 1: Sandbox_qp - Sandbox QP supported */ - /* 0x4.16 - 0x4.17 */ - u_int8_t qp_type; -/*---------------- DWORD[2] (Offset 0x8) ----------------*/ - /* Description - Log (base 2) of the DDR size in granularity of GB. */ - /* 0x8.0 - 0x8.5 */ - u_int8_t log_ddr_size; -/*---------------- DWORD[3] (Offset 0xc) ----------------*/ - /* Description - The maximum size of message size supported by FPGA -Shell QP. */ - /* 0xc.0 - 0xc.31 */ - u_int32_t max_fpga_qp_msg_size; -}; - /* Description - */ /* Size in bytes - 124 */ union reg_access_hca_mcqi_reg_data_auto { @@ -654,13 +606,29 @@ token that must be loaded to the device before installing the debug binary. */ /* 0x0.26 - 0x0.26 */ u_int8_t debug; - /* Description - When set, the device is running a development firm -ware version. */ + /* Description - *NOTE* this field has diff meaning for Switch vs. NIC + + +NIC: +The device is running: +0: a regular-secure firmware version +1: a development-secure firmware version + +Switch: +The device is running: +0: regular FW branch +1: development branch */ /* 0x0.27 - 0x0.27 */ u_int8_t dev; /* Description - When set, string-TLV is supported. */ /* 0x0.28 - 0x0.28 */ u_int8_t string_tlv; + /* Description - *NOTE* for NICs same as dev field +Development-secure: +The device is running: +0: a regular-secure firmware version +1: a development-secure firmware version */ + /* 0x0.30 - 0x0.30 */ u_int8_t dev_sc; /*---------------- DWORD[1] (Offset 0x4) ----------------*/ /* Description - Firmware Build ID. Optional. . */ @@ -747,8 +715,7 @@ struct reg_access_hca_mgir_hardware_info { /* Description - PCI device ID. */ /* 0x0.0 - 0x0.15 */ u_int16_t device_id; - /* Description - -SwitchX Devices: + /* Description - SwitchX Devices: 0x00A0: Device step A0, FCC package 0x00A1: Device step A1, FCC package 0x00A2: Device step A2, FCC package @@ -793,6 +760,9 @@ manufacturing_base_mac of value 0 means field is not supported. */ /* 0x10.0 - 0x10.15 */ u_int16_t manufacturing_base_mac_47_32; + /* Description - module base index +assiciated_module_id[0] = 32 * module_base */ + /* 0x10.28 - 0x10.31 */ u_int8_t module_base; /*---------------- DWORD[5] (Offset 0x14) ----------------*/ /* Description - LSB of the "base" MAC address of the NIC that was @@ -804,6 +774,11 @@ manufacturing_base_mac of value 0 means field is not supported. */ /* 0x14.0 - 0x14.31 */ u_int32_t manufacturing_base_mac_31_0; +/*---------------- DWORD[6] (Offset 0x18) ----------------*/ + /* Description - bitmask of associated module id. For each bit: +0: module is not managed by ASIC +1: module is managed by ASIC */ + /* 0x18.0 - 0x18.31 */ u_int32_t associated_module_id_31_0; /*---------------- DWORD[7] (Offset 0x1c) ----------------*/ /* Description - Time (in secs.) since last reset0 */ @@ -982,15 +957,15 @@ handle the resource_dump_event */ /* 0x0.16 - 0x0.20 */ u_int8_t log_min_resource_dump_eq; /* Description - If set, Resource_dump register is supported. -See Table 1115, "RESOURCE_DUMP Register Layout," on -page 1369 */ +See Table 1126, "RESOURCE_DUMP Register Layout," on +page 1399 */ /* 0x0.22 - 0x0.22 */ u_int8_t resource_dump; /* Description - Log(base 2) of the size in granularity of 4KB to be allo cated by host in order to accommodate cr_dump. 0 means feature is not supported. -See Table 1113, "CORE_DUMP Register Layout," on -page 1367 */ +See Table 1124, "CORE_DUMP Register Layout," on +page 1397 */ /* 0x0.23 - 0x0.27 */ u_int8_t log_cr_dump_to_mem_size; /* Description - If set, Core dump of type of specific QP is supported. @@ -1027,211 +1002,6 @@ by num_of_counters. */ struct reg_access_hca_diagnostic_cntr_layout *diagnostic_counter; }; -/* Description - */ -/* Size in bytes - 256 */ -struct reg_access_hca_fpga_cap { -/*---------------- DWORD[0] (Offset 0x0) ----------------*/ - /* Description - FPGA device type -0x0: UNKNOWN_DEVICE -0x1: KU040 -0x2: KU060 -0x3: KU060_2 */ - /* 0x0.0 - 0x0.23 */ - u_int32_t fpga_device; - /* Description - FPGA identifier. -0x0: Newton_X -0x1: Edison */ - /* 0x0.24 - 0x0.31 */ - u_int8_t fpga_id; -/*---------------- DWORD[1] (Offset 0x4) ----------------*/ - /* Description - Shell registers space file version. */ - /* 0x4.0 - 0x4.31 */ - u_int32_t register_file_ver; -/*---------------- DWORD[2] (Offset 0x8) ----------------*/ - /* Description - Indicates the MODIFY operation's permissions of FPGA_AC -CESS_REG. -0x0: Not_allowed - modify registers by FPGA_ACCESS_REG -not allowed. -0x1: All_range_allowed- modify registers by FPGA_AC -CESS_REG allowed for all addresses. */ - /* 0x8.16 - 0x8.17 */ - u_int8_t access_reg_modify_mode; - /* Description - Indicates the QUERY operation's permissions of FPGA_AC -CESS_REG. -0x0: Not_allowed - Query registers by FPGA_ACCESS_REG -not allowed. -0x1: All_range_allowed- Query registers by FPGA_AC -CESS_REG allowed for all addresses. */ - /* 0x8.24 - 0x8.25 */ - u_int8_t access_reg_query_mode; - /* Description - If set, DISCONNECT and CONNECT operations in FPGA_C -TRL are supported. */ - /* 0x8.29 - 0x8.29 */ - u_int8_t disconnect_fpga; - /* Description - If set, Flash_GW_Lock and Flash_GW_UnLock operations in -FPGA_CTRL are supported. */ - /* 0x8.30 - 0x8.30 */ - u_int8_t flash_gw_lock; - /* Description - If set, SW is allowed to modify FPGA_CTRL register. See -Table 1073, "FPGA_CTRL Register Layout," on page 1346 */ - /* 0x8.31 - 0x8.31 */ - u_int8_t fpga_ctrl_modify; -/*---------------- DWORD[4] (Offset 0x10) ----------------*/ - /* Description - Image version. */ - /* 0x10.0 - 0x10.31 */ - u_int32_t image_version; -/*---------------- DWORD[5] (Offset 0x14) ----------------*/ - /* Description - Creation date of current running image. -Format: DDMMYYYY. -For example: -0x12011995 means 12/01/1995 in DD/MM/YY. */ - /* 0x14.0 - 0x14.31 */ - u_int32_t image_date; -/*---------------- DWORD[6] (Offset 0x18) ----------------*/ - /* Description - Creation time of current running image. -Format: 00HHMMSS. -For example: -0x00015324 means 01:53:24 in HH:MM:SS */ - /* 0x18.0 - 0x18.31 */ - u_int32_t image_time; -/*---------------- DWORD[7] (Offset 0x1c) ----------------*/ - /* Description - Shell image version. */ - /* 0x1c.0 - 0x1c.31 */ - u_int32_t shell_version; -/*---------------- DWORD[12] (Offset 0x30) ----------------*/ - /* Description - Shell capabilities. */ - /* 0x30.0 - 0x6c.31 */ - struct reg_access_hca_fpga_shell_caps shell_caps; -/*---------------- DWORD[28] (Offset 0x70) ----------------*/ - /* Description - IEEE Vendor ID of sandbox user. -0x2C9: Mellanox */ - /* 0x70.0 - 0x70.23 */ - u_int32_t ieee_vendor_id; -/*---------------- DWORD[29] (Offset 0x74) ----------------*/ - /* Description - Sandbox product ID. -For Mellanox sandbox products -0x0: unknown -0x1: example -0x2: IPsec -0x3: TLS */ - /* 0x74.0 - 0x74.15 */ - u_int16_t sandbox_product_id; - /* Description - Sandbox version. */ - /* 0x74.16 - 0x74.31 */ - u_int16_t sandbox_product_version; -/*---------------- DWORD[30] (Offset 0x78) ----------------*/ - /* Description - Sandbox basic capabilities per sandbox product ID. -For Mellanox sandbox products, see Table 965, "IPsec_Basic_Ca -pabilities Structure Layout," on page 1236. */ - /* 0x78.0 - 0x78.31 */ - u_int32_t sandbox_basic_caps; -/*---------------- DWORD[31] (Offset 0x7c) ----------------*/ - /* Description - The length (in DWORDs) of sandbox extended capability -(equals 0 when such capability is not present). */ - /* 0x7c.0 - 0x7c.15 */ - u_int16_t sandbox_extended_caps_len; -/*---------------- DWORD[32] (Offset 0x80) ----------------*/ - /* Description - Extended capabilities address. -For Mellanox sandbox products, see Table 967, "IPsec_Extend -ed_Capabilities Structure Layout," on page 1236. */ - /* 0x80.0 - 0x84.31 */ - u_int64_t sandbox_extended_caps_addr; -/*---------------- DWORD[34] (Offset 0x88) ----------------*/ - /* Description - Start address of DDR */ - /* 0x88.0 - 0x8c.31 */ - u_int64_t fpga_ddr_start_addr; -/*---------------- DWORD[36] (Offset 0x90) ----------------*/ - /* Description - Start address of cr-space */ - /* 0x90.0 - 0x94.31 */ - u_int64_t fpga_cr_space_start_addr; -/*---------------- DWORD[38] (Offset 0x98) ----------------*/ - /* Description - Size of DDR in a granularity of 1KB */ - /* 0x98.0 - 0x98.31 */ - u_int32_t fpga_ddr_size; -/*---------------- DWORD[39] (Offset 0x9c) ----------------*/ - /* Description - Size of cr-space in a granularity of 1KB */ - /* 0x9c.0 - 0x9c.31 */ - u_int32_t fpga_cr_space_size; -}; - -/* Description - */ -/* Size in bytes - 16 */ -struct reg_access_hca_fpga_ctrl { -/*---------------- DWORD[0] (Offset 0x0) ----------------*/ - /* Description - Status of the last operation. -0x0: Success -0x1: Failure -0x2: In_progress -0x3: DISCONNECTED - FPGA is disconnect by DOSCONNECT -operation. -Valid only for query operation. */ - /* 0x0.0 - 0x0.7 */ - u_int8_t status; - /* Description - Indicates the control operation to be performed. Allowed -only when FPGA_CAP.fpga_ctrl_modify==1. Table 1069, -"FPGA_CAP Register Layout," on page 1341. -0x1: LOAD - when set, the FPGA will be forced to reload the -image from flash according to image_select_admin value. -0x2: RESET - when set, the FPGA internal logic state -(BRAMs, FFs, etc.) will be reset to the original state at load -ing time. -0x3: FLASH_SELECT - when set, map the flash GW accord -ing to flash_select_admin value. -0x4: Sandbox_Bypass_On - If set, sandbox logic is inactive -until Sandbox_Bypass_Off is set. Packets will skip the sand -box logic. -0x5: Sandbox_Bypass_Off - If set, sandbox logic is active. -Packets will be processed by the sandbox logic. -0x6: Reset_Sandbox - If set, the FPGA sandbox logic state -(BRAMs, FFs, etc.) will be reset to the original state at load -ing time (no shell state is affected). -0x7: Flash_GW_Lock - lock the flash gateway. Users must -take this lock before attempting to reads/writes to flash. -Supported only when FPGA_CAP.flash_gw_lock==1. -0x8: Flash_GW_Unlock - Unlock flash gateway. Users must -release this lock after completing their reads/writes to flash. -Supported only when FPGA_CAP.flash_gw_lock==1. -0x9: DISCONNECT - Disable the ConnectX to FPGA manage -ment interface. This mode is useful when upgrading the -FPGA via JTAG. supported only when FPGA_CAP.discon -nect_fpga==1. Note that on this mode no other operation can -be performed on the FPGA. -0xA: CONNECT - Enable the ConnectX to FPGA management -interface.supported only when FPGA_CAP.disconnect_f -pga==1. */ - /* 0x0.16 - 0x0.23 */ - u_int8_t operation; - /* Description - Error type. Valid only when status = failure(0x1) -0x0: Error_unknown -0x1: fpga_done_timeout -0x2: gpio_sig_mismatch -0x3: ddr_bist_timeout -0x4: sadb_reset_done_timeout -0x5: sadb_reset_success_timeout -0x6: ips_flush_done_timeout -0x7: flash_gw_lock_timeout -0x8: flash_gw_unlock_error -0x9: i2c_access_during_fpga_load -0xA: fpga_user_img_done_timeout */ - /* 0x0.24 - 0x0.31 */ - u_int8_t error_type; -/*---------------- DWORD[1] (Offset 0x4) ----------------*/ - /* Description - Current flashthat is used to loadimages to FPGA. -0x0: User -0x1: Factory_default -0x2: Factory_failover - The device tried to load the user -image, but due to a failure loaded the factory image. -Valid only if status is ok. */ - /* 0x4.0 - 0x4.7 */ - u_int8_t flash_select_oper; - /* Description - Used to select next flash to be usedto load the images. -0x0: User -0x1: Factory_default -Valid only for FLASH_SELECT and LOAD operations. */ - /* 0x4.16 - 0x4.23 */ - u_int8_t flash_select_admin; -}; - /* Description - */ /* Size in bytes - 32 */ struct reg_access_hca_mcc_reg { @@ -1275,7 +1045,7 @@ NENT instructions. Otherwise, this field is reserved. */ /* Description - Token representing the current flow executed by the FSM. See Section 10.2.1, "Component Update State", on -page 800. */ +page 826. */ /* 0x8.0 - 0x8.23 */ u_int32_t update_handle; /* Description - Auto-update to all matching downstream devices is @@ -1284,7 +1054,7 @@ requested. */ u_int8_t auto_update; /*---------------- DWORD[3] (Offset 0xc) ----------------*/ /* Description - Current Update FSM state, See Section 10.3.8, "FSM -States", on page 804 +States", on page 830 0x0: IDLE 0x1: LOCKED 0x2: INITIALIZE @@ -1300,7 +1070,7 @@ Other values are reserved */ u_int8_t control_state; /* Description - Indicates the successful completion of the instruction, or the reason it failed. See Section 10.3.7, "Error -Handling", on page 803 +Handling", on page 829 0x0: OK 0x1: ERROR 0x2: REJECTED_DIGEST_ERR @@ -1391,8 +1161,8 @@ struct reg_access_hca_mcda_reg { /*---------------- DWORD[1] (Offset 0x4) ----------------*/ /* Description - Offset of accessed address relative to component start. Accesses must be in accordance to log_mcda_word_ -size in Table 1843, "MCQI CAPABILITIES Info Lay -out," on page 2075 */ +size in Table 1869, "MCQI CAPABILITIES Info Lay +out," on page 2333 */ /* 0x4.0 - 0x4.31 */ u_int32_t offset; /*---------------- DWORD[2] (Offset 0x8) ----------------*/ @@ -1456,14 +1226,14 @@ zero padded. */ u_int16_t data_size; /*---------------- DWORD[6] (Offset 0x18) ----------------*/ /* Description - Properties set structure according to info_type. -CAPABILITIES - See Table 1843, "MCQI CAPABILI -TIES Info Layout," on page 2075 -VERSION - See Table 1845, "MCQI VERSION Info -Layout," on page 2077 -ACTIVATION_METHOD - See Table 1849, "MCQI -ACTIVATION_METHOD Info Layout," on page 2079 -LINKX_PREPERTIES - See Table 1851, "MCQI -LINKX_PROPERTIES Info Layout," on page 2080 */ +CAPABILITIES - See Table 1869, "MCQI CAPABILI +TIES Info Layout," on page 2333 +VERSION - See Table 1871, "MCQI VERSION Info +Layout," on page 2335 +ACTIVATION_METHOD - See Table 1875, "MCQI +ACTIVATION_METHOD Info Layout," on page 2337 +LINKX_PREPERTIES - See Table 1877, "MCQI +LINKX_PROPERTIES Info Layout," on page 2338 */ /* 0x18.0 - 0x90.31 */ union reg_access_hca_mcqi_reg_data_auto data; }; @@ -1504,7 +1274,7 @@ Other values are reserved */ u_int16_t identifier; /*---------------- DWORD[2] (Offset 0x8) ----------------*/ /* Description - Component state in update flow, see Section 10.2.1, -"Component Update State", on page 800: +"Component Update State", on page 826: 0x0: IDLE 0x1: IN_PROGRESS 0x2: APPLIED @@ -1638,18 +1408,18 @@ FW_sec_ver_stat is 1, it will program the EFUSEs as needed. */ /* Size in bytes - 160 */ struct reg_access_hca_mgir { /*---------------- DWORD[0] (Offset 0x0) ----------------*/ - /* Description - Hardware Information, see Table 1732, "Hardware Info -Layout," on page 1994 */ + /* Description - Hardware Information, see Table 1758, "Hardware Info +Layout," on page 2250 */ /* 0x0.0 - 0x1c.31 */ struct reg_access_hca_mgir_hardware_info hw_info; /*---------------- DWORD[8] (Offset 0x20) ----------------*/ - /* Description - Firmware Information, see Table 1734, "Firmware Info -Layout," on page 1996 */ + /* Description - Firmware Information, see Table 1760, "Firmware Info +Layout," on page 2252 */ /* 0x20.0 - 0x5c.31 */ struct reg_access_hca_mgir_fw_info fw_info; /*---------------- DWORD[24] (Offset 0x60) ----------------*/ - /* Description - Software Information, see Table 1736, "Software Info Lay -out," on page 1998 + /* Description - Software Information, see Table 1762, "Software Info Lay +out," on page 2255 This field indicates the oldest software version compati ble with the current firmware */ /* 0x60.0 - 0x7c.31 */ @@ -1872,8 +1642,8 @@ struct reg_access_hca_mtrc_cap_reg { /* 0x0.0 - 0x0.3 */ u_int8_t num_string_db; /* Description - Indicates the version of the tracing mechanism. -See, Section 27.3.4.1, "Timestamp Event Traces", on -page 1283 +See, Section 24.3.4.1, "Timestamp Event Traces", on +page 1321 0x0: VER_0 0x1: VER_1 other values are reserved */ @@ -2007,7 +1777,7 @@ formed. Used for debug. */ /* Size in bytes - 256 */ struct reg_access_hca_resource_dump { /*---------------- DWORD[0] (Offset 0x0) ----------------*/ - /* Description - See Section 24.8, "Resource Dump", on page 1299. */ + /* Description - See Section 24.8, "Resource Dump", on page 1329. */ /* 0x0.0 - 0x0.15 */ u_int16_t segment_type; /* Description - Sequence number. 0 on first call of dump and incre @@ -2159,8 +1929,8 @@ injected. */ u_int16_t num_repeat; /*---------------- DWORD[4] (Offset 0x10) ----------------*/ /* Description - stressor Modifier according to type field. -For SMBUS_FAILED,Table 1101, "SMBUS_FAILED Fault -Inject Modifier Layout," on page 1363 */ +For SMBUS_FAILED,Table 1112, "SMBUS_FAILED Fault +Inject Modifier Layout," on page 1393 */ /* 0x10.0 - 0x2c.31 */ struct reg_access_hca_smbus_failed_fault_inject_modifier per_type_modifier; }; @@ -2216,10 +1986,10 @@ Value 0x0 for freq indicates the Mini Flow will not be injected. */ u_int16_t num_repeat; /*---------------- DWORD[4] (Offset 0x10) ----------------*/ /* Description - stressor Modifier according to type field. -For IRISC_HANG Table 1105, "IRISC_HANG Mini-Flow Modi -fier Layout," on page 1364 -For PACKET_DROP Table 1107, "PACKET_DROP Mini-Flow -Modifier Layout," on page 1365 */ +For IRISC_HANG Table 1116, "IRISC_HANG Mini-Flow Modi +fier Layout," on page 1394 +For PACKET_DROP Table 1118, "PACKET_DROP Mini-Flow +Modifier Layout," on page 1395 */ /* 0x10.0 - 0x2c.31 */ union reg_access_hca_strs_mini_flow_reg_per_type_modifier_auto per_type_modifier; }; @@ -2328,16 +2098,16 @@ active. */ u_int8_t polarity; /*---------------- DWORD[4] (Offset 0x10) ----------------*/ /* Description - stressor Modifier according to type field. -For RXB_HANG Table 1083, "RXB_HANG Stop Toggle Modi -fier Layout," on page 1355 -For LOCK_RESOURCE Table 1089, "LOCK_RESOURCE Stop -Toggle Modifier Layout," on page 1357 -For SXP_HANG Table 1085, "SXP_HANG Stop Toggle Modi -fier Layout," on page 1356 -For RXB_HOST_HANG Table 1087, "RXB_HOST_HANG Stop -Toggle Modifier Layout," on page 1357 -For PAUSE_TX See Table Table 1097, "PAUSE_TX Stop Tog -gle Modifier Layout," on page 1360 */ +For RXB_HANG Table 1094, "RXB_HANG Stop Toggle Modi +fier Layout," on page 1385 +For LOCK_RESOURCE Table 1100, "LOCK_RESOURCE Stop +Toggle Modifier Layout," on page 1387 +For SXP_HANG Table 1096, "SXP_HANG Stop Toggle Modi +fier Layout," on page 1386 +For RXB_HOST_HANG Table 1098, "RXB_HOST_HANG Stop +Toggle Modifier Layout," on page 1387 +For PAUSE_TX See Table Table 1108, "PAUSE_TX Stop Tog +gle Modifier Layout," on page 1390 */ /* 0x10.0 - 0x2c.31 */ union reg_access_hca_strs_stop_toggle_reg_per_type_modifier_auto per_type_modifier; }; @@ -2377,18 +2147,12 @@ union reg_access_hca_reg_access_hca_Nodes { /* 0x0.0 - 0x8c.31 */ struct reg_access_hca_mcda_reg mcda_reg; /* Description - */ - /* 0x0.0 - 0xc.31 */ - struct reg_access_hca_fpga_ctrl fpga_ctrl; - /* Description - */ /* 0x0.0 - 0x80.31 */ struct reg_access_hca_mtrc_cap_reg mtrc_cap_reg; /* Description - */ /* 0x0.0 - 0x28.31 */ struct reg_access_hca_mpegc_reg mpegc_reg; /* Description - */ - /* 0x0.0 - 0xfc.31 */ - struct reg_access_hca_fpga_cap fpga_cap; - /* Description - */ /* 0x0.0 - 0x4.31 */ struct reg_access_hca_mfrl_reg_ext mfrl_reg_ext; /* Description - */ @@ -2554,13 +2318,6 @@ void reg_access_hca_diagnostic_cntr_layout_print(const struct reg_access_hca_dia unsigned int reg_access_hca_diagnostic_cntr_layout_size(void); #define REG_ACCESS_HCA_DIAGNOSTIC_CNTR_LAYOUT_SIZE (0x4) void reg_access_hca_diagnostic_cntr_layout_dump(const struct reg_access_hca_diagnostic_cntr_layout *ptr_struct, FILE *fd); -/* fpga_shell_caps */ -void reg_access_hca_fpga_shell_caps_pack(const struct reg_access_hca_fpga_shell_caps *ptr_struct, u_int8_t *ptr_buff); -void reg_access_hca_fpga_shell_caps_unpack(struct reg_access_hca_fpga_shell_caps *ptr_struct, const u_int8_t *ptr_buff); -void reg_access_hca_fpga_shell_caps_print(const struct reg_access_hca_fpga_shell_caps *ptr_struct, FILE *fd, int indent_level); -unsigned int reg_access_hca_fpga_shell_caps_size(void); -#define REG_ACCESS_HCA_FPGA_SHELL_CAPS_SIZE (0x40) -void reg_access_hca_fpga_shell_caps_dump(const struct reg_access_hca_fpga_shell_caps *ptr_struct, FILE *fd); /* mcqi_reg_data_auto */ void reg_access_hca_mcqi_reg_data_auto_pack(const union reg_access_hca_mcqi_reg_data_auto *ptr_struct, u_int8_t *ptr_buff); void reg_access_hca_mcqi_reg_data_auto_unpack(union reg_access_hca_mcqi_reg_data_auto *ptr_struct, const u_int8_t *ptr_buff); @@ -2631,20 +2388,6 @@ void reg_access_hca_debug_cap_print(const struct reg_access_hca_debug_cap *ptr_s unsigned int reg_access_hca_debug_cap_size(void); #define REG_ACCESS_HCA_DEBUG_CAP_SIZE (0x40) void reg_access_hca_debug_cap_dump(const struct reg_access_hca_debug_cap *ptr_struct, FILE *fd); -/* fpga_cap */ -void reg_access_hca_fpga_cap_pack(const struct reg_access_hca_fpga_cap *ptr_struct, u_int8_t *ptr_buff); -void reg_access_hca_fpga_cap_unpack(struct reg_access_hca_fpga_cap *ptr_struct, const u_int8_t *ptr_buff); -void reg_access_hca_fpga_cap_print(const struct reg_access_hca_fpga_cap *ptr_struct, FILE *fd, int indent_level); -unsigned int reg_access_hca_fpga_cap_size(void); -#define REG_ACCESS_HCA_FPGA_CAP_SIZE (0x100) -void reg_access_hca_fpga_cap_dump(const struct reg_access_hca_fpga_cap *ptr_struct, FILE *fd); -/* fpga_ctrl */ -void reg_access_hca_fpga_ctrl_pack(const struct reg_access_hca_fpga_ctrl *ptr_struct, u_int8_t *ptr_buff); -void reg_access_hca_fpga_ctrl_unpack(struct reg_access_hca_fpga_ctrl *ptr_struct, const u_int8_t *ptr_buff); -void reg_access_hca_fpga_ctrl_print(const struct reg_access_hca_fpga_ctrl *ptr_struct, FILE *fd, int indent_level); -unsigned int reg_access_hca_fpga_ctrl_size(void); -#define REG_ACCESS_HCA_FPGA_CTRL_SIZE (0x10) -void reg_access_hca_fpga_ctrl_dump(const struct reg_access_hca_fpga_ctrl *ptr_struct, FILE *fd); /* mcc_reg */ void reg_access_hca_mcc_reg_pack(const struct reg_access_hca_mcc_reg *ptr_struct, u_int8_t *ptr_buff); void reg_access_hca_mcc_reg_unpack(struct reg_access_hca_mcc_reg *ptr_struct, const u_int8_t *ptr_buff); From 4833b1fb8f7ca0881fbce0485a10f06eab954f53 Mon Sep 17 00:00:00 2001 From: Tzafrir Cohen Date: Tue, 26 Apr 2022 16:20:05 +0300 Subject: [PATCH 183/184] FIXUP: Symlink libmtcr_ul.a into the libdir Signed-off-by: Tzafrir Cohen --- debian/mstflint.links | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/mstflint.links b/debian/mstflint.links index c78833cb..885e3570 100644 --- a/debian/mstflint.links +++ b/debian/mstflint.links @@ -1 +1 @@ -usr/lib/mstflint/mstflint/libmtcr_ul.a usr/lib/mstflint/libmtcr_ul.a +usr/lib/mstflint/libmtcr_ul.a usr/lib/libmtcr_ul.a From 0e6583fdd0cc5d489bfa71d311bac357969e0618 Mon Sep 17 00:00:00 2001 From: Tzafrir Cohen Date: Tue, 26 Apr 2022 16:46:17 +0300 Subject: [PATCH 184/184] Symlink libmtcr_ul headers into the includedir Signed-off-by: Tzafrir Cohen --- debian/mstflint.links | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/mstflint.links b/debian/mstflint.links index 885e3570..3d7ea002 100644 --- a/debian/mstflint.links +++ b/debian/mstflint.links @@ -1 +1,3 @@ usr/lib/mstflint/libmtcr_ul.a usr/lib/libmtcr_ul.a +usr/include/mstflint/mtcr.h usr/include/mtcr_ul/mtcr.h +usr/include/mstflint/mtcr_com_defs.h usr/include/mtcr_ul/mtcr_com_defs.h