diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-07-01 13:23:52 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-07-01 11:25:08 +0000 |
commit | 5d013f5804a0d91fcf6c626b2d6fb6eca5c845b0 (patch) | |
tree | 49758e2556cca8f7d386b49a6c41b3bcb7c20b48 /chromium | |
parent | 189d4fd8fad9e3c776873be51938cd31a42b6177 (diff) | |
download | qtwebengine-chromium-5d013f5804a0d91fcf6c626b2d6fb6eca5c845b0.tar.gz |
BASELINE: Update Chromium to 90.0.4430.228
Change-Id: I2d24c073cefc4842980b84cc7e9c5419c107c501
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium')
164 files changed, 21755 insertions, 26168 deletions
diff --git a/chromium/DEPS b/chromium/DEPS index b62debb8758..9a138f5e0db 100644 --- a/chromium/DEPS +++ b/chromium/DEPS @@ -50,7 +50,7 @@ gclient_gn_args = [ vars = { - "buildspec_platforms": "all", + "buildspec_platforms": "chromeos", # Variable that can be used to support multiple build scenarios, like having # Chromium specific targets in a client project's GN file or sync dependencies # conditionally etc. @@ -205,11 +205,11 @@ vars = { # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'f1e4f21baf44e7c9cc0efbbba21c4ed6009686b3', + 'skia_revision': '2e4ca248d12752beb42a376a3f6282ccf9b90cf2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '8560c85efde5dc608772b2ecce91952fc4b09f65', + 'v8_revision': '8a75d543c7c92bc3a9efb7c01a40fd79a68b762c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -1068,7 +1068,7 @@ deps = { Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + '18e09b9197a3b1d771c077c530d1a4ebad04c167', 'src/third_party/icu': - Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'e05b663d1c50b4e9ecc3ff9325f5158f1d071471', + Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '7e128ffcd0919c956962366c7347cf4633785339', 'src/third_party/icu4j': { 'packages': [ @@ -1461,7 +1461,7 @@ deps = { Var('chromium_git') + '/external/github.com/google/snappy.git' + '@' + 'ea368c2f07de5f31146a10214f27d15091b09771', 'src/third_party/sqlite/src': - Var('chromium_git') + '/chromium/deps/sqlite.git' + '@' + '60efbb3584af2ba05e1935b3e07d3a861841db7c', + Var('chromium_git') + '/chromium/deps/sqlite.git' + '@' + '144e06fad93722336e6b066071b941b1763f6f18', 'src/third_party/sqlite4java': { 'packages': [ @@ -1507,7 +1507,7 @@ deps = { }, 'src/third_party/usrsctp/usrsctplib': - Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + 'a6647318b57c0a05d590c8c21fc22aba87f08749', + Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + 'a0b4ea32a38c3edb3416e2b8c19cd18c0ac632e6', 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@e71b9b3ad366d92c0e99d59a24649862f442470f', @@ -1608,7 +1608,7 @@ deps = { Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@582b7b38aaa0e339e3cd182c99ef758a4fd9b97d', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@1d72bff9a9fa47feda5069e535742743c1cb46e6', 'condition': 'checkout_src_internal', }, diff --git a/chromium/build/chromeos/test_runner.py b/chromium/build/chromeos/test_runner.py index 1a496d18ea6..00c5772de9b 100755 --- a/chromium/build/chromeos/test_runner.py +++ b/chromium/build/chromeos/test_runner.py @@ -992,6 +992,12 @@ def main(): return 1 args.cros_cache = os.path.abspath(args.cros_cache) + if args.flash and args.public_image: + # The flashing tools depend on being unauthenticated with GS when flashing + # public images, so make sure the env var GS uses to locate its creds is + # unset in that case. + os.environ.pop('BOTO_CONFIG', None) + return args.func(args, unknown_args) diff --git a/chromium/build/util/LASTCHANGE b/chromium/build/util/LASTCHANGE index 5de6b96412e..2942b55155e 100644 --- a/chromium/build/util/LASTCHANGE +++ b/chromium/build/util/LASTCHANGE @@ -1 +1 @@ -LASTCHANGE=b95b98628c9b149d2cc380ad45c4f0112593727c-refs/branch-heads/4430@{#1479} +LASTCHANGE=4be5e4894f1d31a23e5471b56014aa5a20dc70bb-refs/branch-heads/4430@{#1535} diff --git a/chromium/build/util/LASTCHANGE.committime b/chromium/build/util/LASTCHANGE.committime index 18946a2a0da..e928905b1a2 100644 --- a/chromium/build/util/LASTCHANGE.committime +++ b/chromium/build/util/LASTCHANGE.committime @@ -1 +1 @@ -1621210126
\ No newline at end of file +1624392283
\ No newline at end of file diff --git a/chromium/chrome/VERSION b/chromium/chrome/VERSION index cbbc4e60046..42e01e7fcf8 100644 --- a/chromium/chrome/VERSION +++ b/chromium/chrome/VERSION @@ -1,4 +1,4 @@ MAJOR=90 MINOR=0 BUILD=4430 -PATCH=221 +PATCH=228 diff --git a/chromium/chrome/browser/extensions/api/tab_groups/tab_groups_api.cc b/chromium/chrome/browser/extensions/api/tab_groups/tab_groups_api.cc index 2a624978225..a1079a10ec9 100644 --- a/chromium/chrome/browser/extensions/api/tab_groups/tab_groups_api.cc +++ b/chromium/chrome/browser/extensions/api/tab_groups/tab_groups_api.cc @@ -123,7 +123,10 @@ ExtensionFunction::ResponseAction TabGroupsQueryFunction::Run() { } } - TabStripModel* tab_strip = browser->tab_strip_model(); + TabStripModel* tab_strip = + ExtensionTabUtil::GetEditableTabStripModel(browser); + if (!tab_strip) + return RespondNow(Error(tabs_constants::kTabStripNotEditableQueryError)); for (const tab_groups::TabGroupId& id : tab_strip->group_model()->ListTabGroups()) { const tab_groups::TabGroupVisualData* visual_data = @@ -184,8 +187,11 @@ ExtensionFunction::ResponseAction TabGroupsUpdateFunction::Run() { if (params->update_properties.title.get()) title = base::UTF8ToUTF16(*params->update_properties.title); - TabGroup* tab_group = - browser->tab_strip_model()->group_model()->GetTabGroup(id); + TabStripModel* tab_strip_model = + ExtensionTabUtil::GetEditableTabStripModel(browser); + if (!tab_strip_model) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + TabGroup* tab_group = tab_strip_model->group_model()->GetTabGroup(id); tab_groups::TabGroupVisualData new_visual_data(title, color, collapsed); tab_group->SetVisualData(std::move(new_visual_data)); @@ -232,12 +238,12 @@ bool TabGroupsMoveFunction::MoveGroup(int group_id, return false; } - if (!source_browser->window()->IsTabStripEditable()) { + TabStripModel* source_tab_strip = + ExtensionTabUtil::GetEditableTabStripModel(source_browser); + if (!source_tab_strip) { *error = tabs_constants::kTabStripNotEditableError; return false; } - - TabStripModel* source_tab_strip = source_browser->tab_strip_model(); gfx::Range tabs = source_tab_strip->group_model()->GetTabGroup(*group)->ListTabs(); if (tabs.length() == 0) @@ -252,11 +258,6 @@ bool TabGroupsMoveFunction::MoveGroup(int group_id, return false; } - if (!target_browser->window()->IsTabStripEditable()) { - *error = tabs_constants::kTabStripNotEditableError; - return false; - } - // TODO(crbug.com/990158): Rather than calling is_type_normal(), should // this call SupportsWindowFeature(Browser::FEATURE_TABSTRIP)? if (!target_browser->is_type_normal()) { @@ -271,7 +272,12 @@ bool TabGroupsMoveFunction::MoveGroup(int group_id, // If windowId is different from the current window, move between windows. if (target_browser != source_browser) { - TabStripModel* target_tab_strip = target_browser->tab_strip_model(); + TabStripModel* target_tab_strip = + ExtensionTabUtil::GetEditableTabStripModel(target_browser); + if (!target_tab_strip) { + *error = tabs_constants::kTabStripNotEditableError; + return false; + } if (new_index > target_tab_strip->count() || new_index < 0) new_index = target_tab_strip->count(); diff --git a/chromium/chrome/browser/extensions/api/tab_groups/tab_groups_api_unittest.cc b/chromium/chrome/browser/extensions/api/tab_groups/tab_groups_api_unittest.cc index efebc9b2638..4934de996d4 100644 --- a/chromium/chrome/browser/extensions/api/tab_groups/tab_groups_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/tab_groups/tab_groups_api_unittest.cc @@ -17,6 +17,7 @@ #include "chrome/browser/extensions/api/tab_groups/tab_groups_event_router.h" #include "chrome/browser/extensions/api/tab_groups/tab_groups_event_router_factory.h" #include "chrome/browser/extensions/api/tab_groups/tab_groups_util.h" +#include "chrome/browser/extensions/api/tabs/tabs_constants.h" #include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/extensions/extension_service_test_base.h" #include "chrome/browser/extensions/extension_tab_util.h" @@ -124,13 +125,12 @@ void TabGroupsApiUnitTest::SetUp() { InitializeEmptyExtensionService(); // Create a browser window. - TestBrowserWindow* window = new TestBrowserWindow; + browser_window_ = std::make_unique<TestBrowserWindow>(); // TestBrowserWindowOwner handles its own lifetime, and also cleans up // |window2|. - new TestBrowserWindowOwner(window); Browser::CreateParams params(profile(), /* user_gesture */ true); params.type = Browser::TYPE_NORMAL; - params.window = window; + params.window = browser_window_.get(); browser_ = std::unique_ptr<Browser>(Browser::Create(params)); BrowserList::SetLastActive(browser_.get()); @@ -545,4 +545,32 @@ TEST_F(TabGroupsApiUnitTest, TabGroupsOnMoved) { api::tab_groups::OnMoved::kEventName)); } +// Test that tab groups aren't edited while dragging. +TEST_F(TabGroupsApiUnitTest, IsTabStripEditable) { + scoped_refptr<const Extension> extension = CreateTabGroupsExtension(); + int group_id = tab_groups_util::GetGroupId( + browser()->tab_strip_model()->AddToNewGroup({0})); + const std::string args = + base::StringPrintf(R"([%d, {"index": %d}])", group_id, 1); + + // Succeed moving group in normal case. + { + auto function = base::MakeRefCounted<TabGroupsMoveFunction>(); + function->set_extension(extension); + ASSERT_TRUE(extension_function_test_utils::RunFunction( + function.get(), args, browser(), api_test_utils::NONE)); + } + + // Gracefully cancel group tab drag if tab strip isn't editable. + { + browser_window()->SetIsTabStripEditable(false); + auto function = base::MakeRefCounted<TabGroupsMoveFunction>(); + function->set_extension(extension); + std::string error = + extension_function_test_utils::RunFunctionAndReturnError( + function.get(), args, browser()); + EXPECT_EQ(tabs_constants::kTabStripNotEditableError, error); + } +} + } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_api.cc b/chromium/chrome/browser/extensions/api/tabs/tabs_api.cc index 6c34a459aab..ddd17b8f91f 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_api.cc @@ -308,7 +308,7 @@ int MoveTabToWindow(ExtensionFunction* function, return -1; } - if (!target_browser->window()->IsTabStripEditable()) { + if (!ExtensionTabUtil::IsTabStripEditable()) { *error = tabs_constants::kTabStripNotEditableError; return -1; } @@ -333,7 +333,9 @@ int MoveTabToWindow(ExtensionFunction* function, return -1; } - TabStripModel* target_tab_strip = target_browser->tab_strip_model(); + TabStripModel* target_tab_strip = + ExtensionTabUtil::GetEditableTabStripModel(target_browser); + DCHECK(target_tab_strip); // Clamp move location to the last position. // This is ">" because it can append to a new index position. @@ -581,7 +583,7 @@ ExtensionFunction::ResponseAction WindowsCreateFunction::Run() { return RespondNow(Error(std::move(error))); } - if (!source_browser->window()->IsTabStripEditable()) + if (!ExtensionTabUtil::IsTabStripEditable()) return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); if (source_browser->profile() != window_profile) @@ -699,7 +701,10 @@ ExtensionFunction::ResponseAction WindowsCreateFunction::Run() { std::unique_ptr<content::WebContents> detached_tab = source_tab_strip->DetachWebContentsAt(tab_index); contents = detached_tab.get(); - TabStripModel* target_tab_strip = new_window->tab_strip_model(); + TabStripModel* target_tab_strip = + ExtensionTabUtil::GetEditableTabStripModel(new_window); + if (!target_tab_strip) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); target_tab_strip->InsertWebContentsAt( urls.size(), std::move(detached_tab), TabStripModel::ADD_NONE); } @@ -926,7 +931,10 @@ ExtensionFunction::ResponseAction TabsGetSelectedFunction::Run() { if (!GetBrowserFromWindowID(this, window_id, &browser, &error)) return RespondNow(Error(std::move(error))); - TabStripModel* tab_strip = browser->tab_strip_model(); + TabStripModel* tab_strip = + ExtensionTabUtil::GetEditableTabStripModel(browser); + if (!tab_strip) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); WebContents* contents = tab_strip->GetActiveWebContents(); if (!contents) return RespondNow(Error(tabs_constants::kNoSelectedTabError)); @@ -1044,6 +1052,7 @@ ExtensionFunction::ResponseAction TabsQueryFunction::Run() { } TabStripModel* tab_strip = browser->tab_strip_model(); + DCHECK(tab_strip); for (int i = 0; i < tab_strip->count(); ++i) { WebContents* web_contents = tab_strip->GetWebContentsAt(i); @@ -1193,6 +1202,9 @@ ExtensionFunction::ResponseAction TabsDuplicateFunction::Run() { return RespondNow(Error(std::move(error))); } + if (!ExtensionTabUtil::IsTabStripEditable()) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + WebContents* new_contents = chrome::DuplicateTabAt(browser, tab_index); if (!has_callback()) return RespondNow(NoArguments()); @@ -1261,7 +1273,10 @@ ExtensionFunction::ResponseAction TabsHighlightFunction::Run() { if (!GetBrowserFromWindowID(this, window_id, &browser, &error)) return RespondNow(Error(std::move(error))); - TabStripModel* tabstrip = browser->tab_strip_model(); + // Don't let the extension update the tab if the user is dragging tabs. + TabStripModel* tabstrip = ExtensionTabUtil::GetEditableTabStripModel(browser); + if (!tabstrip) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); ui::ListSelectionModel selection; int active_index = -1; @@ -1287,7 +1302,11 @@ ExtensionFunction::ResponseAction TabsHighlightFunction::Run() { return RespondNow(Error(tabs_constants::kNoHighlightedTabError)); selection.set_active(active_index); - browser->tab_strip_model()->SetSelectionFromModel(std::move(selection)); + TabStripModel* tab_strip_model = + ExtensionTabUtil::GetEditableTabStripModel(browser); + if (!tab_strip_model) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + tab_strip_model->SetSelectionFromModel(std::move(selection)); return RespondNow(OneArgument(base::Value::FromUniquePtrValue( ExtensionTabUtil::CreateWindowValueForExtension( *browser, extension(), ExtensionTabUtil::kPopulateTabs, @@ -1299,13 +1318,6 @@ bool TabsHighlightFunction::HighlightTab(TabStripModel* tabstrip, int* active_index, int index, std::string* error) { - // Cannot change tab highlight. This may for instance be due to user dragging - // in progress. - if (!tabstrip->delegate()->CanHighlightTabs()) { - *error = tabs_constants::kCannotHighlightTabs; - return false; - } - // Make sure the index is in range. if (!tabstrip->ContainsIndex(index)) { *error = ErrorUtils::FormatErrorMessage( @@ -1334,7 +1346,11 @@ ExtensionFunction::ResponseAction TabsUpdateFunction::Run() { Browser* browser = ChromeExtensionFunctionDetails(this).GetCurrentBrowser(); if (!browser) return RespondNow(Error(tabs_constants::kNoCurrentWindowError)); - contents = browser->tab_strip_model()->GetActiveWebContents(); + TabStripModel* tab_strip_model = + ExtensionTabUtil::GetEditableTabStripModel(browser); + if (!tab_strip_model) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + contents = tab_strip_model->GetActiveWebContents(); if (!contents) return RespondNow(Error(tabs_constants::kNoSelectedTabError)); tab_id = sessions::SessionTabHelper::IdForTab(contents).id(); @@ -1383,6 +1399,11 @@ ExtensionFunction::ResponseAction TabsUpdateFunction::Run() { active = *params->update_properties.active; if (active) { + // Bug fix for crbug.com/1197888. Don't let the extension update the tab if + // the user is dragging tabs. + if (!ExtensionTabUtil::IsTabStripEditable()) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + if (tab_strip->active_index() != tab_index) { tab_strip->ActivateTabAt(tab_index); DCHECK_EQ(contents, tab_strip->GetActiveWebContents()); @@ -1390,14 +1411,23 @@ ExtensionFunction::ResponseAction TabsUpdateFunction::Run() { } if (params->update_properties.highlighted.get()) { + // Bug fix for crbug.com/1197888. Don't let the extension update the tab if + // the user is dragging tabs. + if (!ExtensionTabUtil::IsTabStripEditable()) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + bool highlighted = *params->update_properties.highlighted; if (highlighted != tab_strip->IsTabSelected(tab_index)) { - if (!tab_strip->ToggleSelectionAt(tab_index)) - return RespondNow(Error(tabs_constants::kCannotHighlightTabs)); + tab_strip->ToggleSelectionAt(tab_index); } } if (params->update_properties.pinned.get()) { + // Bug fix for crbug.com/1197888. Don't let the extension update the tab if + // the user is dragging tabs. + if (!ExtensionTabUtil::IsTabStripEditable()) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + bool pinned = *params->update_properties.pinned; tab_strip->SetTabPinned(tab_index, pinned); @@ -1425,6 +1455,11 @@ ExtensionFunction::ResponseAction TabsUpdateFunction::Run() { tabs_constants::kTabNotFoundError, base::NumberToString(opener_id)))); } + // Bug fix for crbug.com/1197888. Don't let the extension update the tab if + // the user is dragging tabs. + if (!ExtensionTabUtil::IsTabStripEditable()) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + if (tab_strip->GetIndexOfWebContents(opener_contents) == TabStripModel::kNoTab) { return RespondNow( @@ -1569,7 +1604,7 @@ bool TabsMoveFunction::MoveTab(int tab_id, } // Don't let the extension move the tab if the user is dragging tabs. - if (!source_browser->window()->IsTabStripEditable()) { + if (!ExtensionTabUtil::IsTabStripEditable()) { *error = tabs_constants::kTabStripNotEditableError; return false; } @@ -1587,11 +1622,15 @@ bool TabsMoveFunction::MoveTab(int tab_id, *new_index = inserted_index; if (has_callback()) { + TabStripModel* tab_strip_model = + ExtensionTabUtil::GetEditableTabStripModel(target_browser); + DCHECK(tab_strip_model); content::WebContents* web_contents = - target_browser->tab_strip_model()->GetWebContentsAt(inserted_index); - tab_values->Append(CreateTabObjectHelper( - web_contents, extension(), source_context_type(), - target_browser->tab_strip_model(), inserted_index) + tab_strip_model->GetWebContentsAt(inserted_index); + + tab_values->Append(CreateTabObjectHelper(web_contents, extension(), + source_context_type(), + tab_strip_model, inserted_index) ->ToValue()); } @@ -1796,6 +1835,10 @@ ExtensionFunction::ResponseAction TabsGroupFunction::Run() { return RespondNow(Error(std::move(error))); } + DCHECK(target_browser); + if (!target_browser->window()->IsTabStripEditable()) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + // Get all tab IDs from parameters. std::vector<int> tab_ids; if (params->options.tab_ids.as_integers) { @@ -1848,7 +1891,10 @@ ExtensionFunction::ResponseAction TabsGroupFunction::Run() { // Get the remaining group metadata and add the tabs to the group. // At this point, we assume this is a valid action due to the checks above. - TabStripModel* tab_strip = target_browser->tab_strip_model(); + TabStripModel* tab_strip = + ExtensionTabUtil::GetEditableTabStripModel(target_browser); + if (!tab_strip) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); if (group.is_empty()) { group = tab_strip->AddToNewGroup(tab_indices); group_id = tab_groups_util::GetGroupId(group); @@ -1927,7 +1973,13 @@ WebContents* TabsCaptureVisibleTabFunction::GetWebContentsForID( if (!GetBrowserFromWindowID(chrome_details_, window_id, &browser, error)) return nullptr; - WebContents* contents = browser->tab_strip_model()->GetActiveWebContents(); + TabStripModel* tab_strip_model = + ExtensionTabUtil::GetEditableTabStripModel(browser); + if (!tab_strip_model) { + *error = tabs_constants::kTabStripNotEditableError; + return nullptr; + } + WebContents* contents = tab_strip_model->GetActiveWebContents(); if (!contents) { *error = "No active web contents to capture"; return nullptr; @@ -2044,7 +2096,11 @@ ExtensionFunction::ResponseAction TabsDetectLanguageFunction::Run() { browser = ChromeExtensionFunctionDetails(this).GetCurrentBrowser(); if (!browser) return RespondNow(Error(tabs_constants::kNoCurrentWindowError)); - contents = browser->tab_strip_model()->GetActiveWebContents(); + TabStripModel* tab_strip_model = + ExtensionTabUtil::GetEditableTabStripModel(browser); + if (!tab_strip_model) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + contents = tab_strip_model->GetActiveWebContents(); if (!contents) return RespondNow(Error(tabs_constants::kNoSelectedTabError)); } diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc b/chromium/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc index 65b6e93eeaa..bb33332d802 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc @@ -131,6 +131,119 @@ void TabsApiUnitTest::TearDown() { ExtensionServiceTestBase::TearDown(); } +// Bug fix for crbug.com/1196309. Ensure that an extension can't update the tab +// strip while a tab drag is in progress. +TEST_F(TabsApiUnitTest, IsTabStripEditable) { + // Add a couple of web contents to the browser and get their tab IDs. + constexpr int kNumTabs = 2; + std::vector<int> tab_ids; + std::vector<content::WebContents*> web_contentses; + for (int i = 0; i < kNumTabs; ++i) { + std::unique_ptr<content::WebContents> contents( + content::WebContentsTester::CreateTestWebContents(profile(), nullptr)); + CreateSessionServiceTabHelper(contents.get()); + tab_ids.push_back( + sessions::SessionTabHelper::IdForTab(contents.get()).id()); + web_contentses.push_back(contents.get()); + browser()->tab_strip_model()->AppendWebContents(std::move(contents), + /* foreground */ true); + } + ASSERT_EQ(kNumTabs, browser()->tab_strip_model()->count()); + + ASSERT_TRUE(browser_window()->IsTabStripEditable()); + auto extension = CreateTabsExtension(); + + // Succeed while tab drag not in progress. + { + std::string args = base::StringPrintf("[{\"tabs\": [%d]}]", 0); + scoped_refptr<TabsHighlightFunction> function = + base::MakeRefCounted<TabsHighlightFunction>(); + function->set_extension(extension); + ASSERT_TRUE(extension_function_test_utils::RunFunction( + function.get(), args, browser(), api_test_utils::NONE)); + } + + // Start logical drag. + browser_window()->SetIsTabStripEditable(false); + ASSERT_FALSE(browser_window()->IsTabStripEditable()); + + // Succeed with updates that don't interact with the tab strip model. + { + const char* url = "https://example.com/"; + std::string args = + base::StringPrintf("[%d, {\"url\": \"%s\"}]", tab_ids[0], url); + scoped_refptr<TabsUpdateFunction> function = + base::MakeRefCounted<TabsUpdateFunction>(); + function->set_extension(extension); + std::unique_ptr<base::Value> value( + extension_function_test_utils::RunFunctionAndReturnSingleResult( + function.get(), args, browser(), api_test_utils::NONE)); + EXPECT_TRUE(value && value->is_dict()); + EXPECT_EQ(*value->FindStringKey("pendingUrl"), url); + } + + // Succeed while edit in progress and calling chrome.tabs.query. + { + const char* args = "[{}]"; + scoped_refptr<TabsQueryFunction> function = + base::MakeRefCounted<TabsQueryFunction>(); + function->set_extension(extension); + ASSERT_TRUE(extension_function_test_utils::RunFunction( + function.get(), args, browser(), api_test_utils::NONE)); + } + + // Succeed while edit in progress and calling chrome.tabs.get. + { + std::string args = base::StringPrintf("[%d]", tab_ids[0]); + scoped_refptr<TabsGetFunction> function = + base::MakeRefCounted<TabsGetFunction>(); + function->set_extension(extension); + ASSERT_TRUE(extension_function_test_utils::RunFunction( + function.get(), args, browser(), api_test_utils::NONE)); + } + + // Bug fix for crbug.com/1198717. Error updating tabs while drag in progress. + { + std::string args = + base::StringPrintf("[%d, {\"highlighted\": true}]", tab_ids[0]); + auto function = base::MakeRefCounted<TabsUpdateFunction>(); + function->set_extension(extension); + std::string error = + extension_function_test_utils::RunFunctionAndReturnError( + function.get(), args, browser()); + EXPECT_EQ(tabs_constants::kTabStripNotEditableError, error); + } + + // Error highlighting tab while drag in progress. + { + std::string args = base::StringPrintf("[{\"tabs\": [%d]}]", tab_ids[0]); + auto function = base::MakeRefCounted<TabsHighlightFunction>(); + function->set_extension(extension); + std::string error = + extension_function_test_utils::RunFunctionAndReturnError( + function.get(), args, browser(), api_test_utils::NONE); + EXPECT_EQ(tabs_constants::kTabStripNotEditableError, error); + } + + // Bug fix for crbug.com/1197146. Tab group modification during drag. + { + std::string args = base::StringPrintf("[{\"tabIds\": [%d]}]", tab_ids[0]); + scoped_refptr<TabsGroupFunction> function = + base::MakeRefCounted<TabsGroupFunction>(); + function->set_extension(extension); + std::string error = + extension_function_test_utils::RunFunctionAndReturnError( + function.get(), args, browser()); + EXPECT_EQ(tabs_constants::kTabStripNotEditableError, error); + } + + // TODO(solomonkinard): Consider adding tests for drag cancellation. + + // Clean up. + while (!browser()->tab_strip_model()->empty()) + browser()->tab_strip_model()->DetachWebContentsAt(0); +} + TEST_F(TabsApiUnitTest, QueryWithoutTabsPermission) { GURL tab_urls[] = {GURL("http://www.google.com"), GURL("http://www.example.com"), diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_constants.cc b/chromium/chrome/browser/extensions/api/tabs/tabs_constants.cc index 8bd3d4edf2e..e438ed25f0a 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_constants.cc +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_constants.cc @@ -92,6 +92,8 @@ const char kCannotDiscardTab[] = "Cannot discard tab with id: *."; const char kCannotFindTabToDiscard[] = "Cannot find a tab to discard."; const char kTabStripNotEditableError[] = "Tabs cannot be edited right now (user may be dragging a tab)."; +const char kTabStripNotEditableQueryError[] = + "Tabs cannot be queried right now (user may be dragging a tab)."; const char kNoSelectedTabError[] = "No selected tab"; const char kNoHighlightedTabError[] = "No highlighted tab"; const char kIncognitoModeIsDisabled[] = "Incognito mode is disabled."; @@ -124,9 +126,6 @@ const char kGroupParamsError[] = const char kCannotNavigateToDevtools[] = "Cannot navigate to a devtools:// page without either the devtools or " "debugger permission."; -const char kCannotHighlightTabs[] = - "Cannot change tab highlight. This may for instance be due to user " - "dragging in progress."; } // namespace tabs_constants } // namespace extensions diff --git a/chromium/chrome/browser/extensions/api/tabs/tabs_constants.h b/chromium/chrome/browser/extensions/api/tabs/tabs_constants.h index 7278abcda41..3e257f524d8 100644 --- a/chromium/chrome/browser/extensions/api/tabs/tabs_constants.h +++ b/chromium/chrome/browser/extensions/api/tabs/tabs_constants.h @@ -91,6 +91,7 @@ extern const char kTabNotFoundError[]; extern const char kCannotDiscardTab[]; extern const char kCannotFindTabToDiscard[]; extern const char kTabStripNotEditableError[]; +extern const char kTabStripNotEditableQueryError[]; extern const char kNoHighlightedTabError[]; extern const char kNoSelectedTabError[]; extern const char kIncognitoModeIsDisabled[]; @@ -110,7 +111,6 @@ extern const char kBrowserWindowNotAllowed[]; extern const char kLockedFullscreenModeNewTabError[]; extern const char kGroupParamsError[]; extern const char kCannotNavigateToDevtools[]; -extern const char kCannotHighlightTabs[]; } // namespace tabs_constants } // namespace extensions diff --git a/chromium/chrome/browser/ui/webui/invalidations/invalidations_message_handler.cc b/chromium/chrome/browser/ui/webui/invalidations/invalidations_message_handler.cc index 5653f0c43e7..5b7b65716b1 100644 --- a/chromium/chrome/browser/ui/webui/invalidations/invalidations_message_handler.cc +++ b/chromium/chrome/browser/ui/webui/invalidations/invalidations_message_handler.cc @@ -33,7 +33,12 @@ invalidation::ProfileInvalidationProvider* GetInvalidationProvider( InvalidationsMessageHandler::InvalidationsMessageHandler() : logger_(nullptr) {} -InvalidationsMessageHandler::~InvalidationsMessageHandler() = default; +InvalidationsMessageHandler::~InvalidationsMessageHandler() { + // This handler can be destroyed without OnJavascriptDisallowed() ever being + // called (https://crbug.com/1199198). Call it to ensure that `this` is + // removed as an observer. + OnJavascriptDisallowed(); +} void InvalidationsMessageHandler::RegisterMessages() { web_ui()->RegisterMessageCallback( diff --git a/chromium/chrome/test/BUILD.gn b/chromium/chrome/test/BUILD.gn index c56c805da69..2e71e6a9ff2 100644 --- a/chromium/chrome/test/BUILD.gn +++ b/chromium/chrome/test/BUILD.gn @@ -1320,6 +1320,7 @@ if (!is_android) { "../browser/profiles/profile_theme_update_service_browsertest.cc", "../browser/push_messaging/push_messaging_browsertest.cc", "../browser/referrer_policy_browsertest.cc", + "../browser/renderer_context_menu/accessibility_labels_bubble_model_browsertest.cc", "../browser/renderer_context_menu/accessibility_labels_menu_observer_browsertest.cc", "../browser/renderer_context_menu/mock_render_view_context_menu.cc", "../browser/renderer_context_menu/mock_render_view_context_menu.h", @@ -1328,6 +1329,7 @@ if (!is_android) { "../browser/renderer_context_menu/render_view_context_menu_browsertest_util.h", "../browser/renderer_context_menu/render_view_context_menu_test_util.cc", "../browser/renderer_context_menu/render_view_context_menu_test_util.h", + "../browser/renderer_context_menu/spelling_bubble_model_browsertest.cc", "../browser/renderer_context_menu/spelling_menu_observer_browsertest.cc", "../browser/renderer_host/render_process_host_chrome_browsertest.cc", "../browser/repost_form_warning_browsertest.cc", diff --git a/chromium/components/sessions/core/tab_restore_service_helper.cc b/chromium/components/sessions/core/tab_restore_service_helper.cc index 6395bb9c072..0a87b063043 100644 --- a/chromium/components/sessions/core/tab_restore_service_helper.cc +++ b/chromium/components/sessions/core/tab_restore_service_helper.cc @@ -353,11 +353,36 @@ std::vector<LiveTab*> TabRestoreServiceHelper::RestoreEntryById( context = client_->CreateLiveTabContext( window.app_name, window.bounds, window.show_state, window.workspace, window.user_title); + + base::flat_map<tab_groups::TabGroupId, tab_groups::TabGroupId> + new_group_ids; + for (size_t tab_i = 0; tab_i < window.tabs.size(); ++tab_i) { const Tab& tab = *window.tabs[tab_i]; + + // Relabel group IDs to prevent duplicating groups, e.g. if the same + // window is restored twice or a tab of the same ID is restored + // elsewhere. See crbug.com/1202102. + base::Optional<tab_groups::TabGroupId> new_group; + if (tab.group) { + auto it = new_group_ids.find(*tab.group); + if (it == new_group_ids.end()) { + auto new_id = tab_groups::TabGroupId::GenerateNew(); + // Ensure the new ID does not collide with an existing group, + // failing silently if it does. This is extremely unlikely, + // given group IDs are 128 bit randomly generated numbers. + if (client_->FindLiveTabContextWithGroup(new_id)) { + return std::vector<LiveTab*>(); + } + it = new_group_ids.emplace(*tab.group, new_id).first; + } + + new_group = it->second; + } + LiveTab* restored_tab = context->AddRestoredTab( tab.navigations, context->GetTabCount(), - tab.current_navigation_index, tab.extension_app_id, tab.group, + tab.current_navigation_index, tab.extension_app_id, new_group, tab.group_visual_data.value_or(tab_groups::TabGroupVisualData()), static_cast<int>(tab_i) == window.selected_tab_index, tab.pinned, tab.platform_data.get(), tab.user_agent_override, nullptr); @@ -369,7 +394,8 @@ std::vector<LiveTab*> TabRestoreServiceHelper::RestoreEntryById( } for (const auto& tab_group : window.tab_groups) { - context->SetVisualDataForGroup(tab_group.first, tab_group.second); + context->SetVisualDataForGroup(new_group_ids.at(tab_group.first), + tab_group.second); } // All the window's tabs had the same former browser_id. diff --git a/chromium/content/browser/service_worker/service_worker_container_host.cc b/chromium/content/browser/service_worker/service_worker_container_host.cc index 0b1981efd9e..9a2193ac5a4 100644 --- a/chromium/content/browser/service_worker/service_worker_container_host.cc +++ b/chromium/content/browser/service_worker/service_worker_container_host.cc @@ -138,7 +138,7 @@ ServiceWorkerContainerHost::~ServiceWorkerContainerHost() { } if (IsContainerForClient() && controller_) - controller_->OnControlleeDestroyed(client_uuid()); + controller_->Uncontrol(client_uuid()); // Remove |this| as an observer of ServiceWorkerRegistrations. // TODO(falken): Use ScopedObserver instead of this explicit call. @@ -1244,7 +1244,7 @@ void ServiceWorkerContainerHost::UpdateController( } } if (previous_version) - previous_version->RemoveControllee(client_uuid()); + previous_version->Uncontrol(client_uuid()); // SetController message should be sent only for clients. DCHECK(IsContainerForClient()); diff --git a/chromium/content/browser/service_worker/service_worker_internals_ui.cc b/chromium/content/browser/service_worker/service_worker_internals_ui.cc index 3d989024405..28d406c7cd0 100644 --- a/chromium/content/browser/service_worker/service_worker_internals_ui.cc +++ b/chromium/content/browser/service_worker/service_worker_internals_ui.cc @@ -427,7 +427,12 @@ void ServiceWorkerInternalsHandler::OnJavascriptDisallowed() { weak_ptr_factory_.InvalidateWeakPtrs(); } -ServiceWorkerInternalsHandler::~ServiceWorkerInternalsHandler() = default; +ServiceWorkerInternalsHandler::~ServiceWorkerInternalsHandler() { + // ServiceWorkerInternalsHandler can be destroyed without + // OnJavascriptDisallowed() ever being called (https://crbug.com/1199198). + // Call it to ensure that `this` is removed as an observer. + OnJavascriptDisallowed(); +} void ServiceWorkerInternalsHandler::OnRunningStateChanged() { FireWebUIListener("running-state-changed"); diff --git a/chromium/content/browser/service_worker/service_worker_version.cc b/chromium/content/browser/service_worker/service_worker_version.cc index e394eb76b5b..236a8660d84 100644 --- a/chromium/content/browser/service_worker/service_worker_version.cc +++ b/chromium/content/browser/service_worker/service_worker_version.cc @@ -894,8 +894,7 @@ void ServiceWorkerVersion::RemoveControlleeFromBackForwardCacheMap( bfcached_controllee_map_.erase(client_uuid); } -void ServiceWorkerVersion::OnControlleeDestroyed( - const std::string& client_uuid) { +void ServiceWorkerVersion::Uncontrol(const std::string& client_uuid) { if (!IsBackForwardCacheEnabled()) { RemoveControllee(client_uuid); } else { diff --git a/chromium/content/browser/service_worker/service_worker_version.h b/chromium/content/browser/service_worker/service_worker_version.h index 2c14dea5aa2..055c46d06f6 100644 --- a/chromium/content/browser/service_worker/service_worker_version.h +++ b/chromium/content/browser/service_worker/service_worker_version.h @@ -394,9 +394,12 @@ class CONTENT_EXPORT ServiceWorkerVersion void RestoreControlleeFromBackForwardCacheMap(const std::string& client_uuid); // Called when a back-forward cached controllee is evicted or destroyed. void RemoveControlleeFromBackForwardCacheMap(const std::string& client_uuid); - // Called when a controllee is destroyed. Remove controllee from whichever - // map it belongs to, or do nothing when it is already removed. - void OnControlleeDestroyed(const std::string& client_uuid); + // Called when this version should no longer be the controller of this client. + // Called when the controllee is destroyed or it changes controller. Removes + // controllee from whichever map it belongs to, or do nothing when it is + // already removed. This function is different from RemoveController(), which + // can only be called if the controllee is not in the back-forward cache map. + void Uncontrol(const std::string& client_uuid); // Returns true if this version has a controllee. // Note regarding BackForwardCache: diff --git a/chromium/gpu/config/gpu_lists_version.h b/chromium/gpu/config/gpu_lists_version.h index 5c14153ff35..32592ddb244 100644 --- a/chromium/gpu/config/gpu_lists_version.h +++ b/chromium/gpu/config/gpu_lists_version.h @@ -3,6 +3,6 @@ #ifndef GPU_CONFIG_GPU_LISTS_VERSION_H_ #define GPU_CONFIG_GPU_LISTS_VERSION_H_ -#define GPU_LISTS_VERSION "b95b98628c9b149d2cc380ad45c4f0112593727c" +#define GPU_LISTS_VERSION "4be5e4894f1d31a23e5471b56014aa5a20dc70bb" #endif // GPU_CONFIG_GPU_LISTS_VERSION_H_ diff --git a/chromium/infra/config/generated/commit-queue.cfg b/chromium/infra/config/generated/commit-queue.cfg index 8d2dfe01266..b74832cb191 100644 --- a/chromium/infra/config/generated/commit-queue.cfg +++ b/chromium/infra/config/generated/commit-queue.cfg @@ -27,167 +27,6 @@ config_groups { } tryjob { builders { - name: "chrome-m90/try/linux-chrome" - includable_only: true - owner_whitelist_group: "googlers" - owner_whitelist_group: "project-chromium-robot-committers" - } - builders { - name: "chrome-m90/try/mac-chrome" - includable_only: true - owner_whitelist_group: "googlers" - owner_whitelist_group: "project-chromium-robot-committers" - } - builders { - name: "chrome-m90/try/win-chrome" - includable_only: true - owner_whitelist_group: "googlers" - owner_whitelist_group: "project-chromium-robot-committers" - } - builders { - name: "chrome-m90/try/win64-chrome" - includable_only: true - owner_whitelist_group: "googlers" - owner_whitelist_group: "project-chromium-robot-committers" - } - builders { - name: "chromium-m90/try/android-binary-size" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/android-cronet-arm-dbg" - location_regexp: ".+/[+]/components/cronet/.+" - location_regexp: ".+/[+]/components/grpc_support/.+" - location_regexp: ".+/[+]/build/android/.+" - location_regexp: ".+/[+]/build/config/android/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - location_regexp_exclude: ".+/[+]/components/cronet/ios/.+" - } - builders { - name: "chromium-m90/try/android-lollipop-arm-rel" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/android-marshmallow-arm64-rel" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/android-marshmallow-x86-rel" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/android-official" - includable_only: true - } - builders { - name: "chromium-m90/try/android-pie-arm64-dbg" - location_regexp: ".+/[+]/chrome/android/features/vr/.+" - location_regexp: ".+/[+]/chrome/android/java/src/org/chromium/chrome/browser/vr/.+" - location_regexp: ".+/[+]/chrome/android/javatests/src/org/chromium/chrome/browser/vr/.+" - location_regexp: ".+/[+]/chrome/browser/android/vr/.+" - location_regexp: ".+/[+]/chrome/browser/vr/.+" - location_regexp: ".+/[+]/content/browser/xr/.+" - location_regexp: ".+/[+]/device/vr/android/.+" - location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" - location_regexp: ".+/[+]/third_party/arcore-android-sdk/.+" - location_regexp: ".+/[+]/third_party/arcore-android-sdk-client/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/android-pie-arm64-rel" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/android_compile_dbg" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/android_compile_x64_dbg" - location_regexp: ".+/[+]/chrome/android/java/src/org/chromium/chrome/browser/vr/.+" - location_regexp: ".+/[+]/chrome/browser/vr/.+" - location_regexp: ".+/[+]/content/browser/xr/.+" - location_regexp: ".+/[+]/sandbox/linux/seccomp-bpf/.+" - location_regexp: ".+/[+]/sandbox/linux/seccomp-bpf-helpers/.+" - location_regexp: ".+/[+]/sandbox/linux/system_headers/.+" - location_regexp: ".+/[+]/sandbox/linux/tests/.+" - location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/android_compile_x86_dbg" - location_regexp: ".+/[+]/chrome/android/java/src/org/chromium/chrome/browser/vr/.+" - location_regexp: ".+/[+]/chrome/browser/vr/.+" - location_regexp: ".+/[+]/content/browser/xr/.+" - location_regexp: ".+/[+]/sandbox/linux/seccomp-bpf/.+" - location_regexp: ".+/[+]/sandbox/linux/seccomp-bpf-helpers/.+" - location_regexp: ".+/[+]/sandbox/linux/system_headers/.+" - location_regexp: ".+/[+]/sandbox/linux/tests/.+" - location_regexp: ".+/[+]/third_party/gvr-android-sdk/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/android_cronet" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/android_optional_gpu_tests_rel" - location_regexp: ".+/[+]/cc/.+" - location_regexp: ".+/[+]/chrome/browser/vr/.+" - location_regexp: ".+/[+]/content/browser/xr/.+" - location_regexp: ".+/[+]/components/viz/.+" - location_regexp: ".+/[+]/content/test/gpu/.+" - location_regexp: ".+/[+]/gpu/.+" - location_regexp: ".+/[+]/media/audio/.+" - location_regexp: ".+/[+]/media/filters/.+" - location_regexp: ".+/[+]/media/gpu/.+" - location_regexp: ".+/[+]/media/renderers/.+" - location_regexp: ".+/[+]/services/viz/.+" - location_regexp: ".+/[+]/testing/trigger_scripts/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/modules/webgl/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" - location_regexp: ".+/[+]/tools/clang/scripts/update.py" - location_regexp: ".+/[+]/ui/gl/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/cast_shell_android" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/cast_shell_linux" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/chromeos-amd64-generic-dbg" - location_regexp: ".+/[+]/content/gpu/.+" - location_regexp: ".+/[+]/media/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { name: "chromium-m90/try/chromeos-amd64-generic-rel" location_regexp: ".*" location_regexp_exclude: ".+/[+]/docs/.+" @@ -212,319 +51,11 @@ config_groups { disable_reuse: true } builders { - name: "chromium-m90/try/dawn-linux-x64-deps-rel" - location_regexp: ".+/[+]/gpu/.+" - location_regexp: ".+/[+]/testing/buildbot/chromium.dawn.json" - location_regexp: ".+/[+]/third_party/blink/renderer/modules/webgpu/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/external/wpt/webgpu/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/wpt_internal/webgpu/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/WebGPUExpectations" - location_regexp: ".+/[+]/third_party/dawn/.+" - location_regexp: ".+/[+]/tools/clang/scripts/update.py" - location_regexp: ".+/[+]/ui/gl/features.gni" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/dawn-mac-x64-deps-rel" - location_regexp: ".+/[+]/gpu/.+" - location_regexp: ".+/[+]/testing/buildbot/chromium.dawn.json" - location_regexp: ".+/[+]/third_party/blink/renderer/modules/webgpu/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/external/wpt/webgpu/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/wpt_internal/webgpu/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/WebGPUExpectations" - location_regexp: ".+/[+]/third_party/dawn/.+" - location_regexp: ".+/[+]/tools/clang/scripts/update.py" - location_regexp: ".+/[+]/ui/gl/features.gni" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/dawn-win10-x64-deps-rel" - location_regexp: ".+/[+]/gpu/.+" - location_regexp: ".+/[+]/testing/buildbot/chromium.dawn.json" - location_regexp: ".+/[+]/third_party/blink/renderer/modules/webgpu/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/external/wpt/webgpu/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/wpt_internal/webgpu/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/WebGPUExpectations" - location_regexp: ".+/[+]/third_party/dawn/.+" - location_regexp: ".+/[+]/tools/clang/scripts/update.py" - location_regexp: ".+/[+]/ui/gl/features.gni" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/dawn-win10-x86-deps-rel" - location_regexp: ".+/[+]/gpu/.+" - location_regexp: ".+/[+]/testing/buildbot/chromium.dawn.json" - location_regexp: ".+/[+]/third_party/blink/renderer/modules/webgpu/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/external/wpt/webgpu/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/wpt_internal/webgpu/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/WebGPUExpectations" - location_regexp: ".+/[+]/third_party/dawn/.+" - location_regexp: ".+/[+]/tools/clang/scripts/update.py" - location_regexp: ".+/[+]/ui/gl/features.gni" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/fuchsia-arm64-cast" - location_regexp: ".+/[+]/chromecast/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/fuchsia-official" - includable_only: true - } - builders { - name: "chromium-m90/try/fuchsia-x64-cast" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/fuchsia_arm64" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/fuchsia_x64" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/ios-simulator" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/ios-simulator-cronet" - location_regexp: ".+/[+]/components/cronet/.+" - location_regexp: ".+/[+]/components/grpc_support/.+" - location_regexp: ".+/[+]/ios/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - location_regexp_exclude: ".+/[+]/components/cronet/android/.+" - } - builders { - name: "chromium-m90/try/ios-simulator-full-configs" - location_regexp: ".+/[+]/ios/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/linux-blink-rel" - location_regexp: ".+/[+]/cc/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/core/paint/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/core/svg/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/linux-chromeos-compile-dbg" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { name: "chromium-m90/try/linux-chromeos-rel" location_regexp: ".*" location_regexp_exclude: ".+/[+]/docs/.+" location_regexp_exclude: ".+/[+]/infra/config/.+" } - builders { - name: "chromium-m90/try/linux-libfuzzer-asan-rel" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/linux-official" - includable_only: true - } - builders { - name: "chromium-m90/try/linux-ozone-rel" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/linux-rel" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/linux_chromium_asan_rel_ng" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/linux_chromium_compile_dbg_ng" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/linux_chromium_dbg_ng" - location_regexp: ".+/[+]/build/.*check_gn_headers.*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/linux_chromium_tsan_rel_ng" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/linux_layout_tests_composite_after_paint" - location_regexp: ".+/[+]/third_party/blink/renderer/core/paint/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/core/svg/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/linux_layout_tests_layout_ng_disabled" - location_regexp: ".+/[+]/third_party/blink/renderer/core/editing/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/core/layout/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/core/paint/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/core/svg/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/platform/fonts/shaping/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/.+" - location_regexp: ".+/[+]/third_party/blink/web_tests/FlagExpectations/disable-layout-ng" - location_regexp: ".+/[+]/third_party/blink/web_tests/flag-specific/disable-layout-ng/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/linux_optional_gpu_tests_rel" - location_regexp: ".+/[+]/chrome/browser/vr/.+" - location_regexp: ".+/[+]/content/browser/xr/.+" - location_regexp: ".+/[+]/content/test/gpu/.+" - location_regexp: ".+/[+]/gpu/.+" - location_regexp: ".+/[+]/media/audio/.+" - location_regexp: ".+/[+]/media/filters/.+" - location_regexp: ".+/[+]/media/gpu/.+" - location_regexp: ".+/[+]/media/renderers/.+" - location_regexp: ".+/[+]/testing/buildbot/chromium.gpu.fyi.json" - location_regexp: ".+/[+]/testing/trigger_scripts/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/modules/webgl/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" - location_regexp: ".+/[+]/tools/clang/scripts/update.py" - location_regexp: ".+/[+]/ui/gl/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/linux_vr" - location_regexp: ".+/[+]/chrome/browser/vr/.+" - location_regexp: ".+/[+]/content/browser/xr/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/mac-arm64-rel" - includable_only: true - } - builders { - name: "chromium-m90/try/mac-official" - includable_only: true - } - builders { - name: "chromium-m90/try/mac-rel" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/mac_chromium_compile_dbg_ng" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/mac_optional_gpu_tests_rel" - location_regexp: ".+/[+]/chrome/browser/vr/.+" - location_regexp: ".+/[+]/content/browser/xr/.+" - location_regexp: ".+/[+]/content/test/gpu/.+" - location_regexp: ".+/[+]/gpu/.+" - location_regexp: ".+/[+]/media/audio/.+" - location_regexp: ".+/[+]/media/filters/.+" - location_regexp: ".+/[+]/media/gpu/.+" - location_regexp: ".+/[+]/media/renderers/.+" - location_regexp: ".+/[+]/services/shape_detection/.+" - location_regexp: ".+/[+]/testing/buildbot/chromium.gpu.fyi.json" - location_regexp: ".+/[+]/testing/trigger_scripts/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/modules/webgl/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" - location_regexp: ".+/[+]/tools/clang/scripts/update.py" - location_regexp: ".+/[+]/ui/gl/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/win-libfuzzer-asan-rel" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/win-official" - includable_only: true - } - builders { - name: "chromium-m90/try/win10_chromium_x64_rel_ng" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/win32-official" - includable_only: true - } - builders { - name: "chromium-m90/try/win7-rel" - location_regexp: ".+/[+]/sandbox/win/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/win_chromium_compile_dbg_ng" - location_regexp: ".*" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } - builders { - name: "chromium-m90/try/win_optional_gpu_tests_rel" - location_regexp: ".+/[+]/chrome/browser/vr/.+" - location_regexp: ".+/[+]/content/browser/xr/.+" - location_regexp: ".+/[+]/content/test/gpu/.+" - location_regexp: ".+/[+]/device/vr/.+" - location_regexp: ".+/[+]/gpu/.+" - location_regexp: ".+/[+]/media/audio/.+" - location_regexp: ".+/[+]/media/filters/.+" - location_regexp: ".+/[+]/media/gpu/.+" - location_regexp: ".+/[+]/media/renderers/.+" - location_regexp: ".+/[+]/testing/buildbot/chromium.gpu.fyi.json" - location_regexp: ".+/[+]/testing/trigger_scripts/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/modules/vr/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/modules/webgl/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/modules/xr/.+" - location_regexp: ".+/[+]/third_party/blink/renderer/platform/graphics/gpu/.+" - location_regexp: ".+/[+]/tools/clang/scripts/update.py" - location_regexp: ".+/[+]/ui/gl/.+" - location_regexp_exclude: ".+/[+]/docs/.+" - location_regexp_exclude: ".+/[+]/infra/config/.+" - } retry_config { single_quota: 1 global_quota: 2 diff --git a/chromium/infra/config/generated/cr-buildbucket.cfg b/chromium/infra/config/generated/cr-buildbucket.cfg index 01778d91630..630a222f8d9 100644 --- a/chromium/infra/config/generated/cr-buildbucket.cfg +++ b/chromium/infra/config/generated/cr-buildbucket.cfg @@ -19,4766 +19,6 @@ buckets { } swarming { builders { - name: "Android Release (Nexus 5X)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.gpu\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Android WebView M (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Android WebView N (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Android WebView O (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Android WebView P (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Android arm Builder (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 14400 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Android arm64 Builder (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 18000 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Android x64 Builder (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 18000 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Android x86 Builder (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 14400 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Cast Android (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Cast Linux" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":50,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Dawn Linux x64 DEPS Builder" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.dawn\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Dawn Linux x64 DEPS Release (Intel HD 630)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:2" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.dawn\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Dawn Linux x64 DEPS Release (NVIDIA)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:2" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.dawn\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Dawn Mac x64 DEPS Builder" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:Dawn Mac x64 DEPS Builder" - dimensions: "cpu:x86-64" - dimensions: "os:Mac" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.dawn\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Dawn Mac x64 DEPS Release (AMD)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:2" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.dawn\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Dawn Mac x64 DEPS Release (Intel)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:2" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.dawn\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Dawn Win10 x64 DEPS Builder" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.dawn\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Dawn Win10 x64 DEPS Release (Intel HD 630)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:2" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.dawn\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Dawn Win10 x64 DEPS Release (NVIDIA)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:2" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.dawn\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Dawn Win10 x86 DEPS Builder" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.dawn\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Dawn Win10 x86 DEPS Release (Intel HD 630)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:2" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.dawn\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Dawn Win10 x86 DEPS Release (NVIDIA)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:2" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.dawn\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Fuchsia ARM64" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Fuchsia x64" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "GPU Linux Builder" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.gpu\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "GPU Mac Builder" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:GPU Mac Builder" - dimensions: "cpu:x86-64" - dimensions: "os:Mac" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.gpu\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "GPU Win x64 Builder" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.gpu\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux ASan LSan Builder" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:1" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.memory\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux ASan LSan Tests (1)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.memory\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux ASan Tests (sandboxed)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.memory\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux Builder" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux Builder (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux Ozone Tester (Headless)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux Ozone Tester (Wayland)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux Ozone Tester (X11)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux Release (NVIDIA)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:2" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.gpu\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux TSan Builder" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.memory\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux TSan Tests" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.memory\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux Tester (Ozone Headless)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux Tester (Ozone Wayland)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux Tester (Ozone X11)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux Tests" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"jobs\":500,\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Linux Tests (dbg)(1)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Mac Builder" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:Mac Builder" - dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.mac\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Mac Builder (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:Mac Builder (dbg)" - dimensions: "cpu:x86-64" - dimensions: "os:Mac" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.mac\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Mac Release (Intel)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:2" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.gpu\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Mac Retina Release (AMD)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:2" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.gpu\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Mac10.11 Tests" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.mac\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Mac10.12 Tests" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.mac\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Mac10.13 Tests" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.mac\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Mac10.14 Tests" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.mac\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Mac10.15 Tests" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.mac\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Mac10.15 Tests (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.mac\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Marshmallow 64 bit Tester" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Nougat Phone Tester" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Oreo Phone Tester" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "VR Linux" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 36000 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Win 7 Tests x64 (1)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:Win 7 Tests x64 (1)" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-7" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.win\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Win Builder (dbg)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:Win Builder (dbg)" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Windows" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.win\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Win x64 Builder" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:Win x64 Builder" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Windows" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.win\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Win10 Tests x64" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:Win10 Tests x64" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.win\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Win10 x64 Release (NVIDIA)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:2" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.gpu.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.gpu\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "Win7 Tests (dbg)(1)" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:Win7 Tests (dbg)(1)" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-7" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.win\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-cronet-arm-dbg" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-cronet-arm-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-cronet-arm-rel-kitkat-tests" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-cronet-arm-rel-lollipop-tests" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-lollipop-arm-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-marshmallow-arm64-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 14400 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-marshmallow-x86-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-nougat-arm64-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-official" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:android-official" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 25200 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-pie-arm64-dbg" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-pie-arm64-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.android\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "chromeos-amd64-generic-dbg" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.chromiumos\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "chromeos-amd64-generic-lacros-dbg" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.chromiumos\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "chromeos-amd64-generic-rel" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -4965,446 +205,6 @@ buckets { } } builders { - name: "fuchsia-arm64-cast" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "fuchsia-official" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 36000 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "fuchsia-x64-cast" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "ios-simulator" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:ios-simulator" - dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.mac\",\"recipe\":\"chromium\",\"xcode_build_version\":\"12d4e\"}" - execution_timeout_secs: 10800 - caches { - name: "xcode_ios_12d4e" - path: "xcode_ios_12d4e.app" - } - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "ios-simulator-cronet" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:ios-simulator-cronet" - dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.fyi\",\"recipe\":\"chromium\",\"xcode_build_version\":\"11e146\"}" - execution_timeout_secs: 36000 - caches { - name: "xcode_ios_11e146" - path: "xcode_ios_11e146.app" - } - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "ios-simulator-full-configs" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:ios-simulator-full-configs" - dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.mac\",\"recipe\":\"chromium\",\"xcode_build_version\":\"12d4e\"}" - execution_timeout_secs: 10800 - caches { - name: "xcode_ios_12d4e" - path: "xcode_ios_12d4e.app" - } - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux-chromeos-dbg" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.chromiumos\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "linux-chromeos-rel" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -5466,435 +266,6 @@ buckets { } } } - builders { - name: "linux-lacros-builder-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.chromiumos\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux-lacros-tester-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.chromiumos\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux-official" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:linux-official" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 36000 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux-ozone-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.ci" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"jobs\":500,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.linux\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "mac-arm64-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:mac-arm64-rel" - dimensions: "cpu:x86-64" - dimensions: "os:Mac" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium.mac\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 10800 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win-official" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:win-official" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 25200 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win32-official" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:win32-official" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.ci" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/chromium_tests\":{\"project_trigger_overrides\":{\"chromium\":\"chromium-m90\"}},\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"chromium\",\"recipe\":\"chromium\"}" - execution_timeout_secs: 25200 - build_numbers: YES - service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.gtests_local" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.buildbucket.use_bbagent" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "ci_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_ci_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } } } buckets { @@ -5928,1045 +299,6 @@ buckets { } swarming { builders { - name: "android-binary-size" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/binary_size\":{\"analyze_targets\":[\"//chrome/android:monochrome_public_minimal_apks\",\"//chrome/android:trichrome_minimal_apks\",\"//chrome/android:validate_expectations\",\"//tools/binary_size:binary_size_trybot_py\"],\"compile_targets\":[\"monochrome_public_minimal_apks\",\"monochrome_static_initializers\",\"trichrome_minimal_apks\",\"validate_expectations\"]},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"binary_size_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-cronet-arm-dbg" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-lollipop-arm-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-marshmallow-arm64-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:16" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:1" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/code_coverage\":{\"use_java_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-marshmallow-x86-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:16" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:1" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-official" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-pie-arm64-dbg" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android-pie-arm64-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:16" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:1" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android_compile_dbg" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android_compile_x64_dbg" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android_compile_x86_dbg" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android_cronet" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "android_optional_gpu_tests_rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:android_optional_gpu_tests_rel" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 21600 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "cast_shell_android" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.android\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "cast_shell_linux" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "chromeos-amd64-generic-dbg" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.chromiumos\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "chromeos-amd64-generic-rel" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -7228,914 +560,6 @@ buckets { } } builders { - name: "dawn-linux-x64-deps-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:dawn-linux-x64-deps-rel" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.dawn\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "dawn-mac-x64-deps-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:dawn-mac-x64-deps-rel" - dimensions: "cpu:x86-64" - dimensions: "os:Mac" - dimensions: "pool:luci.chromium.try" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.dawn\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "dawn-win10-x64-deps-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:dawn-win10-x64-deps-rel" - dimensions: "cpu:x86-64" - dimensions: "os:Windows" - dimensions: "pool:luci.chromium.try" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.dawn\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "dawn-win10-x86-deps-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:dawn-win10-x86-deps-rel" - dimensions: "cpu:x86-64" - dimensions: "os:Windows" - dimensions: "pool:luci.chromium.try" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.dawn\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "fuchsia-arm64-cast" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "fuchsia-official" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "fuchsia-x64-cast" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "fuchsia_arm64" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "fuchsia_x64" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "ios-simulator" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:ios-simulator" - dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" - dimensions: "pool:luci.chromium.try" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/code_coverage\":{\"coverage_exclude_sources\":\"ios_test_files_and_test_utils\",\"coverage_test_types\":[\"unit\"],\"use_clang_coverage\":true},\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.mac\",\"recipe\":\"chromium_trybot\",\"xcode_build_version\":\"12d4e\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - caches { - name: "xcode_ios_12d4e" - path: "xcode_ios_12d4e.app" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "ios-simulator-cronet" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:ios-simulator-cronet" - dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" - dimensions: "pool:luci.chromium.try" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.mac\",\"recipe\":\"chromium_trybot\",\"xcode_build_version\":\"11e146\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - caches { - name: "xcode_ios_11e146" - path: "xcode_ios_11e146.app" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "ios-simulator-full-configs" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:ios-simulator-full-configs" - dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" - dimensions: "pool:luci.chromium.try" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/code_coverage\":{\"coverage_exclude_sources\":\"ios_test_files_and_test_utils\",\"coverage_test_types\":[\"unit\"],\"use_clang_coverage\":true},\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.mac\",\"recipe\":\"chromium_trybot\",\"xcode_build_version\":\"12d4e\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - caches { - name: "xcode_ios_12d4e" - path: "xcode_ios_12d4e.app" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux-blink-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.blink\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux-chromeos-compile-dbg" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.chromiumos\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { name: "linux-chromeos-rel" swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" @@ -8200,1564 +624,5 @@ buckets { } } } - builders { - name: "linux-libfuzzer-asan-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_libfuzzer_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux-official" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux-ozone-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/code_coverage\":{\"use_clang_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux_chromium_asan_rel_ng" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:1" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux_chromium_compile_dbg_ng" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "builder" - path: "linux_debug" - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux_chromium_dbg_ng" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "builder" - path: "linux_debug" - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux_chromium_tsan_rel_ng" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux_layout_tests_composite_after_paint" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux_layout_tests_layout_ng_disabled" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux_optional_gpu_tests_rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:linux_optional_gpu_tests_rel" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04|Ubuntu-18.04" - dimensions: "pool:luci.chromium.try" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 21600 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "linux_vr" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-16.04" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.linux\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "mac-arm64-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:1" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.mac\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "mac-official" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cpu:x86-64" - dimensions: "os:Mac" - dimensions: "pool:luci.chromium.try" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "mac-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:1" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/code_coverage\":{\"use_clang_coverage\":true},\"$build/goma\":{\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.mac\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "mac_chromium_compile_dbg_ng" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cpu:x86-64" - dimensions: "os:Mac-10.15" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:1" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.mac\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "mac_optional_gpu_tests_rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:mac_optional_gpu_tests_rel" - dimensions: "cpu:x86-64" - dimensions: "os:Mac" - dimensions: "pool:luci.chromium.try" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.mac\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 21600 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win-libfuzzer-asan-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builder:win-libfuzzer-asan-rel" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows" - dimensions: "pool:luci.chromium.try" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_libfuzzer_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win-official" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 21600 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win10_chromium_x64_rel_ng" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:16" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:1" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/code_coverage\":{\"use_clang_coverage\":true},\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win32-official" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:32" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 21600 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win7-rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:16" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:1" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":300,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 16200 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win_chromium_compile_dbg_ng" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"jobs\":150,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 14400 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } - builders { - name: "win_optional_gpu_tests_rel" - swarming_host: "chromium-swarm.appspot.com" - swarming_tags: "vpython:native-python-wrapper" - dimensions: "builderless:1" - dimensions: "cores:8" - dimensions: "cpu:x86-64" - dimensions: "os:Windows-10" - dimensions: "pool:luci.chromium.try" - dimensions: "ssd:0" - exe { - cipd_package: "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build" - cipd_version: "refs/heads/master" - cmd: "recipes" - } - properties: "{\"$build/goma\":{\"enable_ats\":true,\"rpc_extra_params\":\"?prod\",\"server_host\":\"goma.chromium.org\",\"use_luci_auth\":true},\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"$recipe_engine/isolated\":{\"server\":\"https://isolateserver.appspot.com\"},\"builder_group\":\"tryserver.chromium.win\",\"recipe\":\"chromium_trybot\"}" - execution_timeout_secs: 21600 - expiration_secs: 7200 - grace_period { - seconds: 120 - } - caches { - name: "win_toolchain" - path: "win_toolchain" - } - build_numbers: YES - service_account: "chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - task_template_canary_percentage { - value: 5 - } - experiments { - key: "chromium.resultdb.result_sink" - value: 100 - } - experiments { - key: "chromium.resultdb.result_sink.junit_tests" - value: 100 - } - experiments { - key: "luci.use_realms" - value: 100 - } - resultdb { - enable: true - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "try_test_results" - test_results {} - } - bq_exports { - project: "luci-resultdb" - dataset: "chromium" - table: "gpu_try_test_results" - test_results { - predicate { - test_id_regexp: "ninja://(chrome/test:|content/test:fuchsia_)telemetry_gpu_integration_test/.+" - } - } - } - history_options { - use_invocation_timestamp: true - } - } - } } } diff --git a/chromium/infra/config/generated/luci-milo.cfg b/chromium/infra/config/generated/luci-milo.cfg index ad4788b70e8..49379a2aef6 100644 --- a/chromium/infra/config/generated/luci-milo.cfg +++ b/chromium/infra/config/generated/luci-milo.cfg @@ -11,196 +11,11 @@ consoles { refs: "regexp:refs/branch-heads/4430" manifest_name: "REVISION" builders { - name: "buildbucket/luci.chromium-m90.ci/android-official" - category: "chromium|android" - short_name: "off" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/fuchsia-official" - category: "chromium|fuchsia" - short_name: "off" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/win32-official" - category: "chromium|win|off" - short_name: "32" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/win-official" - category: "chromium|win|off" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win x64 Builder" - category: "chromium.win|release|builder" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win 7 Tests x64 (1)" - category: "chromium.win|release|tester" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win10 Tests x64" - category: "chromium.win|release|tester" - short_name: "w10" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win Builder (dbg)" - category: "chromium.win|debug|builder" - short_name: "32" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win7 Tests (dbg)(1)" - category: "chromium.win|debug|tester" - short_name: "7" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac Builder" - category: "chromium.mac|release" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.11 Tests" - category: "chromium.mac|release" - short_name: "11" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.12 Tests" - category: "chromium.mac|release" - short_name: "12" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.13 Tests" - category: "chromium.mac|release" - short_name: "13" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.14 Tests" - category: "chromium.mac|release" - short_name: "14" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.15 Tests" - category: "chromium.mac|release" - short_name: "15" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/mac-arm64-rel" - category: "chromium.mac|release|arm64" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac Builder (dbg)" - category: "chromium.mac|debug" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.15 Tests (dbg)" - category: "chromium.mac|debug" - short_name: "15" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/ios-simulator" - category: "chromium.mac|ios|default" - short_name: "sim" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/ios-simulator-full-configs" - category: "chromium.mac|ios|default" - short_name: "ful" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Builder" - category: "chromium.linux|release" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tests" - category: "chromium.linux|release" - short_name: "tst" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/linux-ozone-rel" - category: "chromium.linux|release" - short_name: "ozo" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tester (Ozone Headless)" - category: "chromium.linux|release|ozone" - short_name: "ltoh" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tester (Ozone Wayland)" - category: "chromium.linux|release|ozone" - short_name: "ltow" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tester (Ozone X11)" - category: "chromium.linux|release|ozone" - short_name: "ltox" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Builder (dbg)" - category: "chromium.linux|debug|builder" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tests (dbg)(1)" - category: "chromium.linux|debug|tester" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Cast Linux" - category: "chromium.linux|cast" - short_name: "vid" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Fuchsia ARM64" - category: "chromium.linux|fuchsia|a64" - short_name: "rel" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/fuchsia-arm64-cast" - category: "chromium.linux|fuchsia|cast" - short_name: "a64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/fuchsia-x64-cast" - category: "chromium.linux|fuchsia|cast" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Fuchsia x64" - category: "chromium.linux|fuchsia|x64" - short_name: "rel" - } - builders { name: "buildbucket/luci.chromium-m90.ci/linux-chromeos-rel" category: "chromium.chromiumos|default" short_name: "rel" } builders { - name: "buildbucket/luci.chromium-m90.ci/linux-chromeos-dbg" - category: "chromium.chromiumos|default" - short_name: "dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/linux-lacros-builder-rel" - category: "chromium.chromiumos|default" - short_name: "lcr" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/linux-lacros-tester-rel" - category: "chromium.chromiumos|default" - short_name: "lcr" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/chromeos-amd64-generic-lacros-dbg" - category: "chromium.chromiumos|lacros|x64" - short_name: "dbg" - } - builders { name: "buildbucket/luci.chromium-m90.ci/chromeos-arm-generic-rel" category: "chromium.chromiumos|simple|release" short_name: "arm" @@ -215,285 +30,14 @@ consoles { category: "chromium.chromiumos|simple|release|x64" short_name: "rel" } - builders { - name: "buildbucket/luci.chromium-m90.ci/chromeos-amd64-generic-dbg" - category: "chromium.chromiumos|simple|debug|x64" - short_name: "dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-cronet-arm-dbg" - category: "chromium.android|cronet|arm" - short_name: "dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-cronet-arm-rel" - category: "chromium.android|cronet|arm" - short_name: "rel" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-cronet-arm-rel-kitkat-tests" - category: "chromium.android|cronet|test" - short_name: "k" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-cronet-arm-rel-lollipop-tests" - category: "chromium.android|cronet|test" - short_name: "l" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android arm Builder (dbg)" - category: "chromium.android|builder|arm" - short_name: "32" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android arm64 Builder (dbg)" - category: "chromium.android|builder|arm" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android x86 Builder (dbg)" - category: "chromium.android|builder|x86" - short_name: "32" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android x64 Builder (dbg)" - category: "chromium.android|builder|x86" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Marshmallow 64 bit Tester" - category: "chromium.android|tester|phone" - short_name: "M" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Nougat Phone Tester" - category: "chromium.android|tester|phone" - short_name: "N" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Oreo Phone Tester" - category: "chromium.android|tester|phone" - short_name: "O" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-pie-arm64-dbg" - category: "chromium.android|tester|phone" - short_name: "P" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android WebView M (dbg)" - category: "chromium.android|tester|webview" - short_name: "M" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android WebView N (dbg)" - category: "chromium.android|tester|webview" - short_name: "N" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android WebView O (dbg)" - category: "chromium.android|tester|webview" - short_name: "O" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android WebView P (dbg)" - category: "chromium.android|tester|webview" - short_name: "P" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-nougat-arm64-rel" - category: "chromium.android|builder_tester|arm64" - short_name: "N" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-marshmallow-x86-rel" - category: "chromium.android|builder_tester|x86" - short_name: "M" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-lollipop-arm-rel" - category: "chromium.android|on_cq" - short_name: "L" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-marshmallow-arm64-rel" - category: "chromium.android|on_cq" - short_name: "M" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-pie-arm64-rel" - category: "chromium.android|on_cq" - short_name: "P" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Cast Android (dbg)" - category: "chromium.android|on_cq" - short_name: "cst" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux TSan Builder" - category: "chromium.memory|linux|TSan v2" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux TSan Tests" - category: "chromium.memory|linux|TSan v2" - short_name: "tst" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux ASan LSan Builder" - category: "chromium.memory|linux|asan lsan" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux ASan LSan Tests (1)" - category: "chromium.memory|linux|asan lsan" - short_name: "tst" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux ASan Tests (sandboxed)" - category: "chromium.memory|linux|asan lsan" - short_name: "sbx" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Linux x64 DEPS Builder" - category: "chromium.dawn|DEPS|Linux|Builder" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Linux x64 DEPS Release (Intel HD 630)" - category: "chromium.dawn|DEPS|Linux|Intel" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Linux x64 DEPS Release (NVIDIA)" - category: "chromium.dawn|DEPS|Linux|Nvidia" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Mac x64 DEPS Builder" - category: "chromium.dawn|DEPS|Mac|Builder" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Mac x64 DEPS Release (AMD)" - category: "chromium.dawn|DEPS|Mac|AMD" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Mac x64 DEPS Release (Intel)" - category: "chromium.dawn|DEPS|Mac|Intel" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x86 DEPS Builder" - category: "chromium.dawn|DEPS|Windows|Builder" - short_name: "x86" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x64 DEPS Builder" - category: "chromium.dawn|DEPS|Windows|Builder" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x86 DEPS Release (Intel HD 630)" - category: "chromium.dawn|DEPS|Windows|Intel" - short_name: "x86" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x64 DEPS Release (Intel HD 630)" - category: "chromium.dawn|DEPS|Windows|Intel" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x86 DEPS Release (NVIDIA)" - category: "chromium.dawn|DEPS|Windows|Nvidia" - short_name: "x86" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x64 DEPS Release (NVIDIA)" - category: "chromium.dawn|DEPS|Windows|Nvidia" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/GPU Win x64 Builder" - category: "chromium.gpu|Windows" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win10 x64 Release (NVIDIA)" - category: "chromium.gpu|Windows" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/GPU Mac Builder" - category: "chromium.gpu|Mac" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac Release (Intel)" - category: "chromium.gpu|Mac" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac Retina Release (AMD)" - category: "chromium.gpu|Mac" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/GPU Linux Builder" - category: "chromium.gpu|Linux" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Release (NVIDIA)" - category: "chromium.gpu|Linux" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android Release (Nexus 5X)" - category: "chromium.gpu|Android" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/ios-simulator-cronet" - category: "chromium.fyi|cronet" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/VR Linux" - category: "chromium.fyi|linux" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Ozone Tester (Headless)" - category: "chromium.fyi|linux" - short_name: "loh" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Ozone Tester (Wayland)" - category: "chromium.fyi|linux" - short_name: "low" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Ozone Tester (X11)" - category: "chromium.fyi|linux" - short_name: "lox" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/linux-official" - category: "chromium.fyi|linux" - short_name: "off" - } header { oncalls { - name: "Chromium Branches" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-branch-sheriff" - } - oncalls { name: "Trooper" url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" show_primary_secondary_labels: true } console_groups { - console_ids: "chromium-m90/chromium" - console_ids: "chromium-m90/chromium.win" - console_ids: "chromium-m90/chromium.mac" - console_ids: "chromium-m90/chromium.linux" console_ids: "chromium-m90/chromium.chromiumos" - console_ids: "chromium-m90/chromium.memory" - console_ids: "chromium-m90/chromium.gpu" - console_ids: "chromium-m90/chromium.android" } } } @@ -504,171 +48,11 @@ consoles { refs: "regexp:refs/branch-heads/4430" manifest_name: "REVISION" builders { - name: "buildbucket/luci.chromium-m90.ci/Win x64 Builder" - category: "chromium.win|release|builder" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win 7 Tests x64 (1)" - category: "chromium.win|release|tester" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win10 Tests x64" - category: "chromium.win|release|tester" - short_name: "w10" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win Builder (dbg)" - category: "chromium.win|debug|builder" - short_name: "32" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win7 Tests (dbg)(1)" - category: "chromium.win|debug|tester" - short_name: "7" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac Builder" - category: "chromium.mac|release" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.11 Tests" - category: "chromium.mac|release" - short_name: "11" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.12 Tests" - category: "chromium.mac|release" - short_name: "12" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.13 Tests" - category: "chromium.mac|release" - short_name: "13" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.14 Tests" - category: "chromium.mac|release" - short_name: "14" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.15 Tests" - category: "chromium.mac|release" - short_name: "15" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac Builder (dbg)" - category: "chromium.mac|debug" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.15 Tests (dbg)" - category: "chromium.mac|debug" - short_name: "15" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/ios-simulator" - category: "chromium.mac|ios|default" - short_name: "sim" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/ios-simulator-full-configs" - category: "chromium.mac|ios|default" - short_name: "ful" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Builder" - category: "chromium.linux|release" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tests" - category: "chromium.linux|release" - short_name: "tst" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/linux-ozone-rel" - category: "chromium.linux|release" - short_name: "ozo" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tester (Ozone Headless)" - category: "chromium.linux|release|ozone" - short_name: "ltoh" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tester (Ozone Wayland)" - category: "chromium.linux|release|ozone" - short_name: "ltow" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tester (Ozone X11)" - category: "chromium.linux|release|ozone" - short_name: "ltox" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Builder (dbg)" - category: "chromium.linux|debug|builder" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tests (dbg)(1)" - category: "chromium.linux|debug|tester" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Cast Linux" - category: "chromium.linux|cast" - short_name: "vid" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Fuchsia ARM64" - category: "chromium.linux|fuchsia|a64" - short_name: "rel" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/fuchsia-arm64-cast" - category: "chromium.linux|fuchsia|cast" - short_name: "a64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/fuchsia-x64-cast" - category: "chromium.linux|fuchsia|cast" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Fuchsia x64" - category: "chromium.linux|fuchsia|x64" - short_name: "rel" - } - builders { name: "buildbucket/luci.chromium-m90.ci/linux-chromeos-rel" category: "chromium.chromiumos|default" short_name: "rel" } builders { - name: "buildbucket/luci.chromium-m90.ci/linux-chromeos-dbg" - category: "chromium.chromiumos|default" - short_name: "dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/linux-lacros-builder-rel" - category: "chromium.chromiumos|default" - short_name: "lcr" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/linux-lacros-tester-rel" - category: "chromium.chromiumos|default" - short_name: "lcr" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/chromeos-amd64-generic-lacros-dbg" - category: "chromium.chromiumos|lacros|x64" - short_name: "dbg" - } - builders { name: "buildbucket/luci.chromium-m90.ci/chromeos-arm-generic-rel" category: "chromium.chromiumos|simple|release" short_name: "arm" @@ -678,280 +62,14 @@ consoles { category: "chromium.chromiumos|simple|release|x64" short_name: "rel" } - builders { - name: "buildbucket/luci.chromium-m90.ci/chromeos-amd64-generic-dbg" - category: "chromium.chromiumos|simple|debug|x64" - short_name: "dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-cronet-arm-dbg" - category: "chromium.android|cronet|arm" - short_name: "dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-cronet-arm-rel" - category: "chromium.android|cronet|arm" - short_name: "rel" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-cronet-arm-rel-kitkat-tests" - category: "chromium.android|cronet|test" - short_name: "k" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-cronet-arm-rel-lollipop-tests" - category: "chromium.android|cronet|test" - short_name: "l" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android arm Builder (dbg)" - category: "chromium.android|builder|arm" - short_name: "32" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android arm64 Builder (dbg)" - category: "chromium.android|builder|arm" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android x86 Builder (dbg)" - category: "chromium.android|builder|x86" - short_name: "32" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android x64 Builder (dbg)" - category: "chromium.android|builder|x86" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Marshmallow 64 bit Tester" - category: "chromium.android|tester|phone" - short_name: "M" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Nougat Phone Tester" - category: "chromium.android|tester|phone" - short_name: "N" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Oreo Phone Tester" - category: "chromium.android|tester|phone" - short_name: "O" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-pie-arm64-dbg" - category: "chromium.android|tester|phone" - short_name: "P" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android WebView M (dbg)" - category: "chromium.android|tester|webview" - short_name: "M" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android WebView N (dbg)" - category: "chromium.android|tester|webview" - short_name: "N" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android WebView O (dbg)" - category: "chromium.android|tester|webview" - short_name: "O" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android WebView P (dbg)" - category: "chromium.android|tester|webview" - short_name: "P" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-nougat-arm64-rel" - category: "chromium.android|builder_tester|arm64" - short_name: "N" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-marshmallow-x86-rel" - category: "chromium.android|builder_tester|x86" - short_name: "M" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-lollipop-arm-rel" - category: "chromium.android|on_cq" - short_name: "L" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-marshmallow-arm64-rel" - category: "chromium.android|on_cq" - short_name: "M" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-pie-arm64-rel" - category: "chromium.android|on_cq" - short_name: "P" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Cast Android (dbg)" - category: "chromium.android|on_cq" - short_name: "cst" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux TSan Builder" - category: "chromium.memory|linux|TSan v2" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux TSan Tests" - category: "chromium.memory|linux|TSan v2" - short_name: "tst" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux ASan LSan Builder" - category: "chromium.memory|linux|asan lsan" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux ASan LSan Tests (1)" - category: "chromium.memory|linux|asan lsan" - short_name: "tst" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux ASan Tests (sandboxed)" - category: "chromium.memory|linux|asan lsan" - short_name: "sbx" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Linux x64 DEPS Builder" - category: "chromium.dawn|DEPS|Linux|Builder" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Linux x64 DEPS Release (Intel HD 630)" - category: "chromium.dawn|DEPS|Linux|Intel" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Linux x64 DEPS Release (NVIDIA)" - category: "chromium.dawn|DEPS|Linux|Nvidia" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Mac x64 DEPS Builder" - category: "chromium.dawn|DEPS|Mac|Builder" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Mac x64 DEPS Release (AMD)" - category: "chromium.dawn|DEPS|Mac|AMD" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Mac x64 DEPS Release (Intel)" - category: "chromium.dawn|DEPS|Mac|Intel" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x86 DEPS Builder" - category: "chromium.dawn|DEPS|Windows|Builder" - short_name: "x86" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x64 DEPS Builder" - category: "chromium.dawn|DEPS|Windows|Builder" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x86 DEPS Release (Intel HD 630)" - category: "chromium.dawn|DEPS|Windows|Intel" - short_name: "x86" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x64 DEPS Release (Intel HD 630)" - category: "chromium.dawn|DEPS|Windows|Intel" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x86 DEPS Release (NVIDIA)" - category: "chromium.dawn|DEPS|Windows|Nvidia" - short_name: "x86" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x64 DEPS Release (NVIDIA)" - category: "chromium.dawn|DEPS|Windows|Nvidia" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/GPU Win x64 Builder" - category: "chromium.gpu|Windows" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win10 x64 Release (NVIDIA)" - category: "chromium.gpu|Windows" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/GPU Mac Builder" - category: "chromium.gpu|Mac" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac Release (Intel)" - category: "chromium.gpu|Mac" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac Retina Release (AMD)" - category: "chromium.gpu|Mac" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/GPU Linux Builder" - category: "chromium.gpu|Linux" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Release (NVIDIA)" - category: "chromium.gpu|Linux" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android Release (Nexus 5X)" - category: "chromium.gpu|Android" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/ios-simulator-cronet" - category: "chromium.fyi|cronet" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/VR Linux" - category: "chromium.fyi|linux" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Ozone Tester (Headless)" - category: "chromium.fyi|linux" - short_name: "loh" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Ozone Tester (Wayland)" - category: "chromium.fyi|linux" - short_name: "low" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Ozone Tester (X11)" - category: "chromium.fyi|linux" - short_name: "lox" - } header { oncalls { - name: "Chromium Branches" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-branch-sheriff" - } - oncalls { name: "Trooper" url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" show_primary_secondary_labels: true } console_groups { - console_ids: "chromium-m90/chromium" - console_ids: "chromium-m90/chromium.win" - console_ids: "chromium-m90/chromium.mac" - console_ids: "chromium-m90/chromium.linux" console_ids: "chromium-m90/chromium.chromiumos" - console_ids: "chromium-m90/chromium.memory" - console_ids: "chromium-m90/chromium.gpu" - console_ids: "chromium-m90/chromium.android" } } } @@ -959,48 +77,6 @@ consoles { id: "try" name: "Chromium M90 CQ Console" builders { - name: "buildbucket/luci.chromium-m90.try/android-binary-size" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-cronet-arm-dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-lollipop-arm-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-marshmallow-arm64-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-pie-arm64-dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-pie-arm64-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_compile_dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_compile_x64_dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_compile_x86_dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_cronet" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_optional_gpu_tests_rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/cast_shell_android" - } - builders { - name: "buildbucket/luci.chromium-m90.try/cast_shell_linux" - } - builders { - name: "buildbucket/luci.chromium-m90.try/chromeos-amd64-generic-dbg" - } - builders { name: "buildbucket/luci.chromium-m90.try/chromeos-amd64-generic-rel" } builders { @@ -1013,294 +89,11 @@ consoles { name: "buildbucket/luci.chromium-m90.try/chromium_presubmit" } builders { - name: "buildbucket/luci.chromium-m90.try/dawn-linux-x64-deps-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/dawn-mac-x64-deps-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/dawn-win10-x64-deps-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/dawn-win10-x86-deps-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia-arm64-cast" - } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia-x64-cast" - } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia_arm64" - } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia_x64" - } - builders { - name: "buildbucket/luci.chromium-m90.try/ios-simulator" - } - builders { - name: "buildbucket/luci.chromium-m90.try/ios-simulator-cronet" - } - builders { - name: "buildbucket/luci.chromium-m90.try/ios-simulator-full-configs" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-blink-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-chromeos-compile-dbg" - } - builders { name: "buildbucket/luci.chromium-m90.try/linux-chromeos-rel" } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-libfuzzer-asan-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-ozone-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_chromium_asan_rel_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_chromium_compile_dbg_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_chromium_dbg_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_chromium_tsan_rel_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_layout_tests_composite_after_paint" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_layout_tests_layout_ng_disabled" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_optional_gpu_tests_rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_vr" - } - builders { - name: "buildbucket/luci.chromium-m90.try/mac-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/mac_chromium_compile_dbg_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/mac_optional_gpu_tests_rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win-libfuzzer-asan-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win10_chromium_x64_rel_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win7-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win_chromium_compile_dbg_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win_optional_gpu_tests_rel" - } builder_view_only: true } consoles { - id: "chromium" - name: "chromium" - repo_url: "https://chromium.googlesource.com/chromium/src" - refs: "regexp:refs/branch-heads/4430" - manifest_name: "REVISION" - builders { - name: "buildbucket/luci.chromium-m90.ci/android-official" - category: "android" - short_name: "off" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/fuchsia-official" - category: "fuchsia" - short_name: "off" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/win32-official" - category: "win|off" - short_name: "32" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/win-official" - category: "win|off" - short_name: "64" - } - header { - oncalls { - name: "Chromium Branches" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-branch-sheriff" - } - oncalls { - name: "Trooper" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" - show_primary_secondary_labels: true - } - console_groups { - console_ids: "chromium-m90/chromium" - console_ids: "chromium-m90/chromium.win" - console_ids: "chromium-m90/chromium.mac" - console_ids: "chromium-m90/chromium.linux" - console_ids: "chromium-m90/chromium.chromiumos" - console_ids: "chromium-m90/chromium.memory" - console_ids: "chromium-m90/chromium.gpu" - console_ids: "chromium-m90/chromium.android" - } - } - include_experimental_builds: true -} -consoles { - id: "chromium.android" - name: "chromium.android" - repo_url: "https://chromium.googlesource.com/chromium/src" - refs: "regexp:refs/branch-heads/4430" - manifest_name: "REVISION" - builders { - name: "buildbucket/luci.chromium-m90.ci/android-cronet-arm-dbg" - category: "cronet|arm" - short_name: "dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-cronet-arm-rel" - category: "cronet|arm" - short_name: "rel" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-cronet-arm-rel-kitkat-tests" - category: "cronet|test" - short_name: "k" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-cronet-arm-rel-lollipop-tests" - category: "cronet|test" - short_name: "l" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android arm Builder (dbg)" - category: "builder|arm" - short_name: "32" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android arm64 Builder (dbg)" - category: "builder|arm" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android x86 Builder (dbg)" - category: "builder|x86" - short_name: "32" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android x64 Builder (dbg)" - category: "builder|x86" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Marshmallow 64 bit Tester" - category: "tester|phone" - short_name: "M" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Nougat Phone Tester" - category: "tester|phone" - short_name: "N" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Oreo Phone Tester" - category: "tester|phone" - short_name: "O" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-pie-arm64-dbg" - category: "tester|phone" - short_name: "P" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android WebView M (dbg)" - category: "tester|webview" - short_name: "M" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android WebView N (dbg)" - category: "tester|webview" - short_name: "N" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android WebView O (dbg)" - category: "tester|webview" - short_name: "O" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android WebView P (dbg)" - category: "tester|webview" - short_name: "P" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-nougat-arm64-rel" - category: "builder_tester|arm64" - short_name: "N" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-marshmallow-x86-rel" - category: "builder_tester|x86" - short_name: "M" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-lollipop-arm-rel" - category: "on_cq" - short_name: "L" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-marshmallow-arm64-rel" - category: "on_cq" - short_name: "M" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/android-pie-arm64-rel" - category: "on_cq" - short_name: "P" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Cast Android (dbg)" - category: "on_cq" - short_name: "cst" - } - header { - oncalls { - name: "Chromium Branches" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-branch-sheriff" - } - oncalls { - name: "Trooper" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" - show_primary_secondary_labels: true - } - console_groups { - console_ids: "chromium-m90/chromium" - console_ids: "chromium-m90/chromium.win" - console_ids: "chromium-m90/chromium.mac" - console_ids: "chromium-m90/chromium.linux" - console_ids: "chromium-m90/chromium.chromiumos" - console_ids: "chromium-m90/chromium.memory" - console_ids: "chromium-m90/chromium.gpu" - console_ids: "chromium-m90/chromium.android" - } - } -} -consoles { id: "chromium.chromiumos" name: "chromium.chromiumos" repo_url: "https://chromium.googlesource.com/chromium/src" @@ -1312,26 +105,6 @@ consoles { short_name: "rel" } builders { - name: "buildbucket/luci.chromium-m90.ci/linux-chromeos-dbg" - category: "default" - short_name: "dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/linux-lacros-builder-rel" - category: "default" - short_name: "lcr" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/linux-lacros-tester-rel" - category: "default" - short_name: "lcr" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/chromeos-amd64-generic-lacros-dbg" - category: "lacros|x64" - short_name: "dbg" - } - builders { name: "buildbucket/luci.chromium-m90.ci/chromeos-arm-generic-rel" category: "simple|release" short_name: "arm" @@ -1346,516 +119,14 @@ consoles { category: "simple|release|x64" short_name: "rel" } - builders { - name: "buildbucket/luci.chromium-m90.ci/chromeos-amd64-generic-dbg" - category: "simple|debug|x64" - short_name: "dbg" - } - header { - oncalls { - name: "Chromium Branches" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-branch-sheriff" - } - oncalls { - name: "Trooper" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" - show_primary_secondary_labels: true - } - console_groups { - console_ids: "chromium-m90/chromium" - console_ids: "chromium-m90/chromium.win" - console_ids: "chromium-m90/chromium.mac" - console_ids: "chromium-m90/chromium.linux" - console_ids: "chromium-m90/chromium.chromiumos" - console_ids: "chromium-m90/chromium.memory" - console_ids: "chromium-m90/chromium.gpu" - console_ids: "chromium-m90/chromium.android" - } - } -} -consoles { - id: "chromium.dawn" - name: "chromium.dawn" - repo_url: "https://chromium.googlesource.com/chromium/src" - refs: "regexp:refs/branch-heads/4430" - manifest_name: "REVISION" - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Linux x64 DEPS Builder" - category: "DEPS|Linux|Builder" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Linux x64 DEPS Release (Intel HD 630)" - category: "DEPS|Linux|Intel" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Linux x64 DEPS Release (NVIDIA)" - category: "DEPS|Linux|Nvidia" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Mac x64 DEPS Builder" - category: "DEPS|Mac|Builder" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Mac x64 DEPS Release (AMD)" - category: "DEPS|Mac|AMD" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Mac x64 DEPS Release (Intel)" - category: "DEPS|Mac|Intel" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x86 DEPS Builder" - category: "DEPS|Windows|Builder" - short_name: "x86" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x64 DEPS Builder" - category: "DEPS|Windows|Builder" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x86 DEPS Release (Intel HD 630)" - category: "DEPS|Windows|Intel" - short_name: "x86" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x64 DEPS Release (Intel HD 630)" - category: "DEPS|Windows|Intel" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x86 DEPS Release (NVIDIA)" - category: "DEPS|Windows|Nvidia" - short_name: "x86" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Dawn Win10 x64 DEPS Release (NVIDIA)" - category: "DEPS|Windows|Nvidia" - short_name: "x64" - } - header { - oncalls { - name: "Chromium Branches" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-branch-sheriff" - } - oncalls { - name: "Trooper" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" - show_primary_secondary_labels: true - } - console_groups { - console_ids: "chromium-m90/chromium" - console_ids: "chromium-m90/chromium.win" - console_ids: "chromium-m90/chromium.mac" - console_ids: "chromium-m90/chromium.linux" - console_ids: "chromium-m90/chromium.chromiumos" - console_ids: "chromium-m90/chromium.memory" - console_ids: "chromium-m90/chromium.gpu" - console_ids: "chromium-m90/chromium.android" - } - } -} -consoles { - id: "chromium.fyi" - name: "chromium.fyi" - repo_url: "https://chromium.googlesource.com/chromium/src" - refs: "regexp:refs/branch-heads/4430" - manifest_name: "REVISION" - builders { - name: "buildbucket/luci.chromium-m90.ci/ios-simulator-cronet" - category: "cronet" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/VR Linux" - category: "linux" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Ozone Tester (Headless)" - category: "linux" - short_name: "loh" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Ozone Tester (Wayland)" - category: "linux" - short_name: "low" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Ozone Tester (X11)" - category: "linux" - short_name: "lox" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/linux-official" - category: "linux" - short_name: "off" - } - header { - oncalls { - name: "Chromium Branches" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-branch-sheriff" - } - oncalls { - name: "Trooper" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" - show_primary_secondary_labels: true - } - console_groups { - console_ids: "chromium-m90/chromium" - console_ids: "chromium-m90/chromium.win" - console_ids: "chromium-m90/chromium.mac" - console_ids: "chromium-m90/chromium.linux" - console_ids: "chromium-m90/chromium.chromiumos" - console_ids: "chromium-m90/chromium.memory" - console_ids: "chromium-m90/chromium.gpu" - console_ids: "chromium-m90/chromium.android" - } - } -} -consoles { - id: "chromium.gpu" - name: "chromium.gpu" - repo_url: "https://chromium.googlesource.com/chromium/src" - refs: "regexp:refs/branch-heads/4430" - manifest_name: "REVISION" - builders { - name: "buildbucket/luci.chromium-m90.ci/GPU Win x64 Builder" - category: "Windows" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win10 x64 Release (NVIDIA)" - category: "Windows" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/GPU Mac Builder" - category: "Mac" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac Release (Intel)" - category: "Mac" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac Retina Release (AMD)" - category: "Mac" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/GPU Linux Builder" - category: "Linux" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Release (NVIDIA)" - category: "Linux" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Android Release (Nexus 5X)" - category: "Android" - } - header { - oncalls { - name: "Chromium Branches" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-branch-sheriff" - } - oncalls { - name: "Trooper" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" - show_primary_secondary_labels: true - } - console_groups { - console_ids: "chromium-m90/chromium" - console_ids: "chromium-m90/chromium.win" - console_ids: "chromium-m90/chromium.mac" - console_ids: "chromium-m90/chromium.linux" - console_ids: "chromium-m90/chromium.chromiumos" - console_ids: "chromium-m90/chromium.memory" - console_ids: "chromium-m90/chromium.gpu" - console_ids: "chromium-m90/chromium.android" - } - } -} -consoles { - id: "chromium.linux" - name: "chromium.linux" - repo_url: "https://chromium.googlesource.com/chromium/src" - refs: "regexp:refs/branch-heads/4430" - manifest_name: "REVISION" - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Builder" - category: "release" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tests" - category: "release" - short_name: "tst" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/linux-ozone-rel" - category: "release" - short_name: "ozo" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tester (Ozone Headless)" - category: "release|ozone" - short_name: "ltoh" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tester (Ozone Wayland)" - category: "release|ozone" - short_name: "ltow" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tester (Ozone X11)" - category: "release|ozone" - short_name: "ltox" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Builder (dbg)" - category: "debug|builder" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux Tests (dbg)(1)" - category: "debug|tester" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Cast Linux" - category: "cast" - short_name: "vid" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Fuchsia ARM64" - category: "fuchsia|a64" - short_name: "rel" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/fuchsia-arm64-cast" - category: "fuchsia|cast" - short_name: "a64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/fuchsia-x64-cast" - category: "fuchsia|cast" - short_name: "x64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Fuchsia x64" - category: "fuchsia|x64" - short_name: "rel" - } - header { - oncalls { - name: "Chromium Branches" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-branch-sheriff" - } - oncalls { - name: "Trooper" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" - show_primary_secondary_labels: true - } - console_groups { - console_ids: "chromium-m90/chromium" - console_ids: "chromium-m90/chromium.win" - console_ids: "chromium-m90/chromium.mac" - console_ids: "chromium-m90/chromium.linux" - console_ids: "chromium-m90/chromium.chromiumos" - console_ids: "chromium-m90/chromium.memory" - console_ids: "chromium-m90/chromium.gpu" - console_ids: "chromium-m90/chromium.android" - } - } -} -consoles { - id: "chromium.mac" - name: "chromium.mac" - repo_url: "https://chromium.googlesource.com/chromium/src" - refs: "regexp:refs/branch-heads/4430" - manifest_name: "REVISION" - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac Builder" - category: "release" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.11 Tests" - category: "release" - short_name: "11" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.12 Tests" - category: "release" - short_name: "12" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.13 Tests" - category: "release" - short_name: "13" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.14 Tests" - category: "release" - short_name: "14" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.15 Tests" - category: "release" - short_name: "15" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/mac-arm64-rel" - category: "release|arm64" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac Builder (dbg)" - category: "debug" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Mac10.15 Tests (dbg)" - category: "debug" - short_name: "15" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/ios-simulator" - category: "ios|default" - short_name: "sim" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/ios-simulator-full-configs" - category: "ios|default" - short_name: "ful" - } - header { - oncalls { - name: "Chromium Branches" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-branch-sheriff" - } - oncalls { - name: "Trooper" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" - show_primary_secondary_labels: true - } - console_groups { - console_ids: "chromium-m90/chromium" - console_ids: "chromium-m90/chromium.win" - console_ids: "chromium-m90/chromium.mac" - console_ids: "chromium-m90/chromium.linux" - console_ids: "chromium-m90/chromium.chromiumos" - console_ids: "chromium-m90/chromium.memory" - console_ids: "chromium-m90/chromium.gpu" - console_ids: "chromium-m90/chromium.android" - } - } -} -consoles { - id: "chromium.memory" - name: "chromium.memory" - repo_url: "https://chromium.googlesource.com/chromium/src" - refs: "regexp:refs/branch-heads/4430" - manifest_name: "REVISION" - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux TSan Builder" - category: "linux|TSan v2" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux TSan Tests" - category: "linux|TSan v2" - short_name: "tst" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux ASan LSan Builder" - category: "linux|asan lsan" - short_name: "bld" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux ASan LSan Tests (1)" - category: "linux|asan lsan" - short_name: "tst" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Linux ASan Tests (sandboxed)" - category: "linux|asan lsan" - short_name: "sbx" - } - header { - oncalls { - name: "Chromium Branches" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-branch-sheriff" - } - oncalls { - name: "Trooper" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" - show_primary_secondary_labels: true - } - console_groups { - console_ids: "chromium-m90/chromium" - console_ids: "chromium-m90/chromium.win" - console_ids: "chromium-m90/chromium.mac" - console_ids: "chromium-m90/chromium.linux" - console_ids: "chromium-m90/chromium.chromiumos" - console_ids: "chromium-m90/chromium.memory" - console_ids: "chromium-m90/chromium.gpu" - console_ids: "chromium-m90/chromium.android" - } - } -} -consoles { - id: "chromium.win" - name: "chromium.win" - repo_url: "https://chromium.googlesource.com/chromium/src" - refs: "regexp:refs/branch-heads/4430" - manifest_name: "REVISION" - builders { - name: "buildbucket/luci.chromium-m90.ci/Win x64 Builder" - category: "release|builder" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win 7 Tests x64 (1)" - category: "release|tester" - short_name: "64" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win10 Tests x64" - category: "release|tester" - short_name: "w10" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win Builder (dbg)" - category: "debug|builder" - short_name: "32" - } - builders { - name: "buildbucket/luci.chromium-m90.ci/Win7 Tests (dbg)(1)" - category: "debug|tester" - short_name: "7" - } header { oncalls { - name: "Chromium Branches" - url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-branch-sheriff" - } - oncalls { name: "Trooper" url: "https://chrome-ops-rotation-proxy.appspot.com/current/oncallator:chrome-ops-client-infra" show_primary_secondary_labels: true } console_groups { - console_ids: "chromium-m90/chromium" - console_ids: "chromium-m90/chromium.win" - console_ids: "chromium-m90/chromium.mac" - console_ids: "chromium-m90/chromium.linux" console_ids: "chromium-m90/chromium.chromiumos" - console_ids: "chromium-m90/chromium.memory" - console_ids: "chromium-m90/chromium.gpu" - console_ids: "chromium-m90/chromium.android" } } } @@ -1863,54 +134,6 @@ consoles { id: "luci.chromium.try" name: "luci.chromium.try" builders { - name: "buildbucket/luci.chromium-m90.try/android-binary-size" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-cronet-arm-dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-lollipop-arm-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-marshmallow-arm64-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-marshmallow-x86-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-official" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-pie-arm64-dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-pie-arm64-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_compile_dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_compile_x64_dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_compile_x86_dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_cronet" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_optional_gpu_tests_rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/cast_shell_android" - } - builders { - name: "buildbucket/luci.chromium-m90.try/cast_shell_linux" - } - builders { - name: "buildbucket/luci.chromium-m90.try/chromeos-amd64-generic-dbg" - } - builders { name: "buildbucket/luci.chromium-m90.try/chromeos-amd64-generic-rel" } builders { @@ -1923,206 +146,14 @@ consoles { name: "buildbucket/luci.chromium-m90.try/chromium_presubmit" } builders { - name: "buildbucket/luci.chromium-m90.try/dawn-linux-x64-deps-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/dawn-mac-x64-deps-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/dawn-win10-x64-deps-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/dawn-win10-x86-deps-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia-arm64-cast" - } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia-official" - } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia-x64-cast" - } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia_arm64" - } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia_x64" - } - builders { - name: "buildbucket/luci.chromium-m90.try/ios-simulator" - } - builders { - name: "buildbucket/luci.chromium-m90.try/ios-simulator-cronet" - } - builders { - name: "buildbucket/luci.chromium-m90.try/ios-simulator-full-configs" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-blink-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-chromeos-compile-dbg" - } - builders { name: "buildbucket/luci.chromium-m90.try/linux-chromeos-rel" } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-libfuzzer-asan-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-official" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-ozone-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_chromium_asan_rel_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_chromium_compile_dbg_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_chromium_dbg_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_chromium_tsan_rel_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_layout_tests_composite_after_paint" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_layout_tests_layout_ng_disabled" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_optional_gpu_tests_rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_vr" - } - builders { - name: "buildbucket/luci.chromium-m90.try/mac-arm64-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/mac-official" - } - builders { - name: "buildbucket/luci.chromium-m90.try/mac-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/mac_chromium_compile_dbg_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/mac_optional_gpu_tests_rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win-libfuzzer-asan-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win-official" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win10_chromium_x64_rel_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win32-official" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win7-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win_chromium_compile_dbg_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win_optional_gpu_tests_rel" - } - builder_view_only: true -} -consoles { - id: "tryserver.blink" - name: "tryserver.blink" - builders { - name: "buildbucket/luci.chromium-m90.try/linux-blink-rel" - } - builder_view_only: true -} -consoles { - id: "tryserver.chromium" - name: "tryserver.chromium" - builders { - name: "buildbucket/luci.chromium-m90.try/android-official" - } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia-official" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-official" - } - builders { - name: "buildbucket/luci.chromium-m90.try/mac-official" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win-official" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win32-official" - } - builder_view_only: true -} -consoles { - id: "tryserver.chromium.android" - name: "tryserver.chromium.android" - builders { - name: "buildbucket/luci.chromium-m90.try/android-binary-size" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-cronet-arm-dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-lollipop-arm-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-marshmallow-arm64-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-marshmallow-x86-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-pie-arm64-dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android-pie-arm64-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_compile_dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_compile_x64_dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_compile_x86_dbg" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_cronet" - } - builders { - name: "buildbucket/luci.chromium-m90.try/android_optional_gpu_tests_rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/cast_shell_android" - } builder_view_only: true } consoles { id: "tryserver.chromium.chromiumos" name: "tryserver.chromium.chromiumos" builders { - name: "buildbucket/luci.chromium-m90.try/chromeos-amd64-generic-dbg" - } - builders { name: "buildbucket/luci.chromium-m90.try/chromeos-amd64-generic-rel" } builders { @@ -2132,130 +163,16 @@ consoles { name: "buildbucket/luci.chromium-m90.try/chromeos-kevin-rel" } builders { - name: "buildbucket/luci.chromium-m90.try/linux-chromeos-compile-dbg" - } - builders { name: "buildbucket/luci.chromium-m90.try/linux-chromeos-rel" } builder_view_only: true } consoles { - id: "tryserver.chromium.dawn" - name: "tryserver.chromium.dawn" - builders { - name: "buildbucket/luci.chromium-m90.try/dawn-linux-x64-deps-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/dawn-mac-x64-deps-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/dawn-win10-x64-deps-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/dawn-win10-x86-deps-rel" - } - builder_view_only: true -} -consoles { id: "tryserver.chromium.linux" name: "tryserver.chromium.linux" builders { - name: "buildbucket/luci.chromium-m90.try/cast_shell_linux" - } - builders { name: "buildbucket/luci.chromium-m90.try/chromium_presubmit" } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia-arm64-cast" - } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia-x64-cast" - } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia_arm64" - } - builders { - name: "buildbucket/luci.chromium-m90.try/fuchsia_x64" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-libfuzzer-asan-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-ozone-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_chromium_asan_rel_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_chromium_compile_dbg_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_chromium_dbg_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_chromium_tsan_rel_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_layout_tests_composite_after_paint" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_layout_tests_layout_ng_disabled" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_optional_gpu_tests_rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/linux_vr" - } - builder_view_only: true -} -consoles { - id: "tryserver.chromium.mac" - name: "tryserver.chromium.mac" - builders { - name: "buildbucket/luci.chromium-m90.try/ios-simulator" - } - builders { - name: "buildbucket/luci.chromium-m90.try/ios-simulator-cronet" - } - builders { - name: "buildbucket/luci.chromium-m90.try/ios-simulator-full-configs" - } - builders { - name: "buildbucket/luci.chromium-m90.try/mac-arm64-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/mac-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/mac_chromium_compile_dbg_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/mac_optional_gpu_tests_rel" - } - builder_view_only: true -} -consoles { - id: "tryserver.chromium.win" - name: "tryserver.chromium.win" - builders { - name: "buildbucket/luci.chromium-m90.try/win-libfuzzer-asan-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win10_chromium_x64_rel_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win7-rel" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win_chromium_compile_dbg_ng" - } - builders { - name: "buildbucket/luci.chromium-m90.try/win_optional_gpu_tests_rel" - } builder_view_only: true } logo_url: "https://storage.googleapis.com/chrome-infra-public/logo/chromium.svg" diff --git a/chromium/infra/config/generated/luci-notify.cfg b/chromium/infra/config/generated/luci-notify.cfg index eb5774104d1..917ce3ee2bc 100644 --- a/chromium/infra/config/generated/luci-notify.cfg +++ b/chromium/infra/config/generated/luci-notify.cfg @@ -11,717 +11,6 @@ notifiers { notifications { on_new_status: INFRA_FAILURE } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Android Release (Nexus 5X)" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Android arm Builder (dbg)" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Android arm64 Builder (dbg)" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Cast Android (dbg)" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Cast Linux" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_change: true - email { - recipients: "cr-fuchsia+bot@chromium.org" - recipients: "chrome-fuchsia-gardener@grotations.appspotmail.com" - } - } - builders { - bucket: "ci" - name: "Fuchsia ARM64" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_change: true - email { - recipients: "cr-fuchsia+bot@chromium.org" - recipients: "chrome-fuchsia-gardener@grotations.appspotmail.com" - } - } - builders { - bucket: "ci" - name: "Fuchsia x64" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "GPU Linux Builder" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "GPU Mac Builder" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "GPU Win x64 Builder" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux ASan LSan Builder" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux ASan LSan Tests (1)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux ASan Tests (sandboxed)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux Builder" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux Builder (dbg)" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux Ozone Tester (Headless)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux Ozone Tester (Wayland)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux Ozone Tester (X11)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux Release (NVIDIA)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux TSan Builder" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux TSan Tests" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux Tester (Ozone Headless)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux Tester (Ozone Wayland)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux Tester (Ozone X11)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux Tests" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Linux Tests (dbg)(1)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Mac Builder" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Mac Builder (dbg)" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Mac Release (Intel)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Mac Retina Release (AMD)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Mac10.11 Tests" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Mac10.12 Tests" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Mac10.13 Tests" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Mac10.14 Tests" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Mac10.15 Tests" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Mac10.15 Tests (dbg)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Win 7 Tests x64 (1)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Win Builder (dbg)" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Win x64 Builder" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Win10 Tests x64" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Win10 x64 Release (NVIDIA)" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "Win7 Tests (dbg)(1)" - } -} -notifiers { - notifications { - on_change: true - email { - recipients: "cronet-bots-observer@google.com" - } - } - builders { - bucket: "ci" - name: "android-cronet-arm-dbg" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_change: true - email { - recipients: "cronet-bots-observer@google.com" - } - } - builders { - bucket: "ci" - name: "android-cronet-arm-rel" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_change: true - email { - recipients: "cronet-bots-observer@google.com" - } - } - builders { - bucket: "ci" - name: "android-cronet-arm-rel-kitkat-tests" - } -} -notifiers { - notifications { - on_change: true - email { - recipients: "cronet-bots-observer@google.com" - } - } - builders { - bucket: "ci" - name: "android-cronet-arm-rel-lollipop-tests" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "android-lollipop-arm-rel" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "android-marshmallow-arm64-rel" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "android-pie-arm64-rel" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "chromeos-amd64-generic-dbg" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "chromeos-amd64-generic-lacros-dbg" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } builders { bucket: "ci" name: "chromeos-amd64-generic-rel" @@ -761,144 +50,10 @@ notifiers { notifications { on_new_status: INFRA_FAILURE } - notifications { - on_change: true - email { - recipients: "cr-fuchsia+bot@chromium.org" - recipients: "chrome-fuchsia-gardener@grotations.appspotmail.com" - } - } - builders { - bucket: "ci" - name: "fuchsia-arm64-cast" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_change: true - email { - recipients: "cr-fuchsia+bot@chromium.org" - recipients: "chrome-fuchsia-gardener@grotations.appspotmail.com" - } - } - builders { - bucket: "ci" - name: "fuchsia-x64-cast" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "ios-simulator" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_change: true - email { - recipients: "cronet-bots-observer@google.com" - } - } - builders { - bucket: "ci" - name: "ios-simulator-cronet" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "ios-simulator-full-configs" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "linux-chromeos-dbg" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } builders { bucket: "ci" name: "linux-chromeos-rel" repository: "https://chromium.googlesource.com/chromium/src" } } -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "linux-lacros-builder-rel" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "linux-ozone-rel" - repository: "https://chromium.googlesource.com/chromium/src" - } -} -notifiers { - notifications { - on_new_status: INFRA_FAILURE - } - notifications { - on_new_status: INFRA_FAILURE - } - builders { - bucket: "ci" - name: "mac-arm64-rel" - repository: "https://chromium.googlesource.com/chromium/src" - } -} tree_closing_enabled: true diff --git a/chromium/infra/config/generated/luci-scheduler.cfg b/chromium/infra/config/generated/luci-scheduler.cfg index 7bea2bb5b7f..3b49d6446d5 100644 --- a/chromium/infra/config/generated/luci-scheduler.cfg +++ b/chromium/infra/config/generated/luci-scheduler.cfg @@ -5,944 +5,6 @@ # https://luci-config.appspot.com/schemas/projects:luci-scheduler.cfg job { - id: "Android Release (Nexus 5X)" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Android Release (Nexus 5X)" - } -} -job { - id: "Android WebView M (dbg)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Android WebView M (dbg)" - } -} -job { - id: "Android WebView N (dbg)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Android WebView N (dbg)" - } -} -job { - id: "Android WebView O (dbg)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Android WebView O (dbg)" - } -} -job { - id: "Android WebView P (dbg)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Android WebView P (dbg)" - } -} -job { - id: "Android arm Builder (dbg)" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Android arm Builder (dbg)" - } -} -job { - id: "Android arm64 Builder (dbg)" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Android arm64 Builder (dbg)" - } -} -job { - id: "Android x64 Builder (dbg)" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Android x64 Builder (dbg)" - } -} -job { - id: "Android x86 Builder (dbg)" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Android x86 Builder (dbg)" - } -} -job { - id: "Cast Android (dbg)" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Cast Android (dbg)" - } -} -job { - id: "Cast Linux" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Cast Linux" - } -} -job { - id: "Dawn Linux x64 DEPS Builder" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Dawn Linux x64 DEPS Builder" - } -} -job { - id: "Dawn Linux x64 DEPS Release (Intel HD 630)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Dawn Linux x64 DEPS Release (Intel HD 630)" - } -} -job { - id: "Dawn Linux x64 DEPS Release (NVIDIA)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Dawn Linux x64 DEPS Release (NVIDIA)" - } -} -job { - id: "Dawn Mac x64 DEPS Builder" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Dawn Mac x64 DEPS Builder" - } -} -job { - id: "Dawn Mac x64 DEPS Release (AMD)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Dawn Mac x64 DEPS Release (AMD)" - } -} -job { - id: "Dawn Mac x64 DEPS Release (Intel)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Dawn Mac x64 DEPS Release (Intel)" - } -} -job { - id: "Dawn Win10 x64 DEPS Builder" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Dawn Win10 x64 DEPS Builder" - } -} -job { - id: "Dawn Win10 x64 DEPS Release (Intel HD 630)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Dawn Win10 x64 DEPS Release (Intel HD 630)" - } -} -job { - id: "Dawn Win10 x64 DEPS Release (NVIDIA)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Dawn Win10 x64 DEPS Release (NVIDIA)" - } -} -job { - id: "Dawn Win10 x86 DEPS Builder" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Dawn Win10 x86 DEPS Builder" - } -} -job { - id: "Dawn Win10 x86 DEPS Release (Intel HD 630)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Dawn Win10 x86 DEPS Release (Intel HD 630)" - } -} -job { - id: "Dawn Win10 x86 DEPS Release (NVIDIA)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Dawn Win10 x86 DEPS Release (NVIDIA)" - } -} -job { - id: "Fuchsia ARM64" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Fuchsia ARM64" - } -} -job { - id: "Fuchsia x64" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Fuchsia x64" - } -} -job { - id: "GPU Linux Builder" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "GPU Linux Builder" - } -} -job { - id: "GPU Mac Builder" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "GPU Mac Builder" - } -} -job { - id: "GPU Win x64 Builder" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "GPU Win x64 Builder" - } -} -job { - id: "Linux ASan LSan Builder" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux ASan LSan Builder" - } -} -job { - id: "Linux ASan LSan Tests (1)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux ASan LSan Tests (1)" - } -} -job { - id: "Linux ASan Tests (sandboxed)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux ASan Tests (sandboxed)" - } -} -job { - id: "Linux Builder" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux Builder" - } -} -job { - id: "Linux Builder (dbg)" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux Builder (dbg)" - } -} -job { - id: "Linux Ozone Tester (Headless)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux Ozone Tester (Headless)" - } -} -job { - id: "Linux Ozone Tester (Wayland)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux Ozone Tester (Wayland)" - } -} -job { - id: "Linux Ozone Tester (X11)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux Ozone Tester (X11)" - } -} -job { - id: "Linux Release (NVIDIA)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux Release (NVIDIA)" - } -} -job { - id: "Linux TSan Builder" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux TSan Builder" - } -} -job { - id: "Linux TSan Tests" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux TSan Tests" - } -} -job { - id: "Linux Tester (Ozone Headless)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux Tester (Ozone Headless)" - } -} -job { - id: "Linux Tester (Ozone Wayland)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux Tester (Ozone Wayland)" - } -} -job { - id: "Linux Tester (Ozone X11)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux Tester (Ozone X11)" - } -} -job { - id: "Linux Tests" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux Tests" - } -} -job { - id: "Linux Tests (dbg)(1)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Linux Tests (dbg)(1)" - } -} -job { - id: "Mac Builder" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Mac Builder" - } -} -job { - id: "Mac Builder (dbg)" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Mac Builder (dbg)" - } -} -job { - id: "Mac Release (Intel)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Mac Release (Intel)" - } -} -job { - id: "Mac Retina Release (AMD)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Mac Retina Release (AMD)" - } -} -job { - id: "Mac10.11 Tests" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Mac10.11 Tests" - } -} -job { - id: "Mac10.12 Tests" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Mac10.12 Tests" - } -} -job { - id: "Mac10.13 Tests" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Mac10.13 Tests" - } -} -job { - id: "Mac10.14 Tests" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Mac10.14 Tests" - } -} -job { - id: "Mac10.15 Tests" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Mac10.15 Tests" - } -} -job { - id: "Mac10.15 Tests (dbg)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Mac10.15 Tests (dbg)" - } -} -job { - id: "Marshmallow 64 bit Tester" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Marshmallow 64 bit Tester" - } -} -job { - id: "Nougat Phone Tester" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Nougat Phone Tester" - } -} -job { - id: "Oreo Phone Tester" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Oreo Phone Tester" - } -} -job { - id: "VR Linux" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "VR Linux" - } -} -job { - id: "Win 7 Tests x64 (1)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Win 7 Tests x64 (1)" - } -} -job { - id: "Win Builder (dbg)" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Win Builder (dbg)" - } -} -job { - id: "Win x64 Builder" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Win x64 Builder" - } -} -job { - id: "Win10 Tests x64" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Win10 Tests x64" - } -} -job { - id: "Win10 x64 Release (NVIDIA)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Win10 x64 Release (NVIDIA)" - } -} -job { - id: "Win7 Tests (dbg)(1)" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "Win7 Tests (dbg)(1)" - } -} -job { - id: "android-cronet-arm-dbg" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "android-cronet-arm-dbg" - } -} -job { - id: "android-cronet-arm-rel" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "android-cronet-arm-rel" - } -} -job { - id: "android-cronet-arm-rel-kitkat-tests" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "android-cronet-arm-rel-kitkat-tests" - } -} -job { - id: "android-cronet-arm-rel-lollipop-tests" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "android-cronet-arm-rel-lollipop-tests" - } -} -job { - id: "android-lollipop-arm-rel" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "android-lollipop-arm-rel" - } -} -job { - id: "android-marshmallow-arm64-rel" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "android-marshmallow-arm64-rel" - } -} -job { - id: "android-marshmallow-x86-rel" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "android-marshmallow-x86-rel" - } -} -job { - id: "android-nougat-arm64-rel" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "android-nougat-arm64-rel" - } -} -job { - id: "android-official" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "android-official" - } -} -job { - id: "android-pie-arm64-dbg" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "android-pie-arm64-dbg" - } -} -job { - id: "android-pie-arm64-rel" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "android-pie-arm64-rel" - } -} -job { - id: "chromeos-amd64-generic-dbg" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "chromeos-amd64-generic-dbg" - } -} -job { - id: "chromeos-amd64-generic-lacros-dbg" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "chromeos-amd64-generic-lacros-dbg" - } -} -job { id: "chromeos-amd64-generic-rel" realm: "ci" acl_sets: "ci" @@ -973,76 +35,6 @@ job { } } job { - id: "fuchsia-arm64-cast" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "fuchsia-arm64-cast" - } -} -job { - id: "fuchsia-official" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "fuchsia-official" - } -} -job { - id: "fuchsia-x64-cast" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "fuchsia-x64-cast" - } -} -job { - id: "ios-simulator" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "ios-simulator" - } -} -job { - id: "ios-simulator-cronet" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "ios-simulator-cronet" - } -} -job { - id: "ios-simulator-full-configs" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "ios-simulator-full-configs" - } -} -job { - id: "linux-chromeos-dbg" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "linux-chromeos-dbg" - } -} -job { id: "linux-chromeos-rel" realm: "ci" acl_sets: "ci" @@ -1053,80 +45,6 @@ job { } } job { - id: "linux-lacros-builder-rel" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "linux-lacros-builder-rel" - } -} -job { - id: "linux-lacros-tester-rel" - realm: "ci" - acls { - role: TRIGGERER - granted_to: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - } - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "linux-lacros-tester-rel" - } -} -job { - id: "linux-official" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "linux-official" - } -} -job { - id: "linux-ozone-rel" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "linux-ozone-rel" - } -} -job { - id: "mac-arm64-rel" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "mac-arm64-rel" - } -} -job { - id: "win-official" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "win-official" - } -} -job { - id: "win32-official" - realm: "ci" - acl_sets: "ci" - buildbucket { - server: "cr-buildbucket.appspot.com" - bucket: "luci.chromium-m90.ci" - builder: "win32-official" - } -} -job { id: "mac-osxbeta-rel" schedule: "triggered" acls { @@ -1220,58 +138,10 @@ trigger { id: "chromium-gitiles-trigger" realm: "ci" acl_sets: "ci" - triggers: "Android Release (Nexus 5X)" - triggers: "Android arm Builder (dbg)" - triggers: "Android arm64 Builder (dbg)" - triggers: "Android x64 Builder (dbg)" - triggers: "Android x86 Builder (dbg)" - triggers: "Cast Android (dbg)" - triggers: "Cast Linux" - triggers: "Dawn Linux x64 DEPS Builder" - triggers: "Dawn Mac x64 DEPS Builder" - triggers: "Dawn Win10 x64 DEPS Builder" - triggers: "Dawn Win10 x86 DEPS Builder" - triggers: "Fuchsia ARM64" - triggers: "Fuchsia x64" - triggers: "GPU Linux Builder" - triggers: "GPU Mac Builder" - triggers: "GPU Win x64 Builder" - triggers: "Linux ASan LSan Builder" - triggers: "Linux Builder" - triggers: "Linux Builder (dbg)" - triggers: "Linux TSan Builder" - triggers: "Mac Builder" - triggers: "Mac Builder (dbg)" - triggers: "VR Linux" - triggers: "Win Builder (dbg)" - triggers: "Win x64 Builder" - triggers: "android-cronet-arm-dbg" - triggers: "android-cronet-arm-rel" - triggers: "android-lollipop-arm-rel" - triggers: "android-marshmallow-arm64-rel" - triggers: "android-marshmallow-x86-rel" - triggers: "android-nougat-arm64-rel" - triggers: "android-official" - triggers: "android-pie-arm64-rel" - triggers: "chromeos-amd64-generic-dbg" - triggers: "chromeos-amd64-generic-lacros-dbg" triggers: "chromeos-amd64-generic-rel" triggers: "chromeos-arm-generic-rel" triggers: "chromeos-kevin-rel" - triggers: "fuchsia-arm64-cast" - triggers: "fuchsia-official" - triggers: "fuchsia-x64-cast" - triggers: "ios-simulator" - triggers: "ios-simulator-cronet" - triggers: "ios-simulator-full-configs" - triggers: "linux-chromeos-dbg" triggers: "linux-chromeos-rel" - triggers: "linux-lacros-builder-rel" - triggers: "linux-official" - triggers: "linux-ozone-rel" - triggers: "mac-arm64-rel" - triggers: "win-official" - triggers: "win32-official" gitiles { repo: "https://chromium.googlesource.com/chromium/src" refs: "regexp:refs/branch-heads/4430" diff --git a/chromium/infra/config/generated/realms.cfg b/chromium/infra/config/generated/realms.cfg index cc073635ab3..d49f835d1b2 100644 --- a/chromium/infra/config/generated/realms.cfg +++ b/chromium/infra/config/generated/realms.cfg @@ -42,7 +42,6 @@ realms { bindings { role: "role/buildbucket.builderServiceAccount" principals: "user:chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com" - principals: "user:chromium-ci-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" } bindings { role: "role/buildbucket.owner" @@ -82,7 +81,6 @@ realms { bindings { role: "role/buildbucket.builderServiceAccount" principals: "user:chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com" - principals: "user:chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com" } bindings { role: "role/buildbucket.owner" diff --git a/chromium/infra/config/lib/builders.star b/chromium/infra/config/lib/builders.star index 06a3f84ca9d..20204467f27 100644 --- a/chromium/infra/config/lib/builders.star +++ b/chromium/infra/config/lib/builders.star @@ -91,7 +91,11 @@ os = struct( MAC_10_13 = os_enum("Mac-10.13", os_category.MAC), MAC_10_14 = os_enum("Mac-10.14", os_category.MAC), MAC_10_15 = os_enum("Mac-10.15", os_category.MAC), - MAC_11_0 = os_enum("Mac-11.0|Mac-10.16", os_category.MAC), + # Staged switch to Mac 11: we can gradually shift the matching capacity + # towards Mac 11 and the builder will continue to run on whatever is + # available + MAC_10_15_OR_11 = os_enum("Mac-10.15|Mac-11", os_category.MAC), + MAC_11 = os_enum("Mac-11|Mac-10.16", os_category.MAC), MAC_DEFAULT = os_enum("Mac-10.15", os_category.MAC), MAC_ANY = os_enum("Mac", os_category.MAC), WINDOWS_7 = os_enum("Windows-7", os_category.WINDOWS), diff --git a/chromium/infra/config/lib/ci.star b/chromium/infra/config/lib/ci.star index 8b785ca04ab..3f2368d9caf 100644 --- a/chromium/infra/config/lib/ci.star +++ b/chromium/infra/config/lib/ci.star @@ -388,6 +388,7 @@ def fyi_builder( execution_timeout = 10 * time.hour, goma_backend = builders.goma.backend.RBE_PROD, **kwargs): + kwargs.setdefault("os", os.LINUX_BIONIC_REMOVE) return ci.builder( name = name, builder_group = "chromium.fyi", @@ -432,7 +433,7 @@ def fyi_ios_builder( name, executable = "recipe:chromium", goma_backend = builders.goma.backend.RBE_PROD, - os = builders.os.MAC_10_15, + os = builders.os.MAC_10_15_OR_11, xcode = builders.xcode.x12d4e, **kwargs): return fyi_builder( @@ -633,13 +634,14 @@ def mac_ios_builder( name, executable = "recipe:chromium", goma_backend = builders.goma.backend.RBE_PROD, + os = builders.os.MAC_10_15_OR_11, xcode = builders.xcode.x12d4e, **kwargs): return mac_builder( name = name, goma_backend = goma_backend, executable = executable, - os = builders.os.MAC_10_15, + os = os, xcode = xcode, **kwargs ) @@ -652,6 +654,7 @@ def memory_builder( tree_closing = True, **kwargs): if name.startswith("Linux"): + kwargs.setdefault("os", builders.os.LINUX_BIONIC_REMOVE) notifies = (notifies or []) + ["linux-memory"] return ci.builder( diff --git a/chromium/infra/config/lib/try.star b/chromium/infra/config/lib/try.star index 6b8f89ff085..fc91fcc4c34 100644 --- a/chromium/infra/config/lib/try.star +++ b/chromium/infra/config/lib/try.star @@ -317,7 +317,7 @@ def chromium_mac_ios_builder( name, executable = "recipe:chromium_trybot", goma_backend = builders.goma.backend.RBE_PROD, - os = builders.os.MAC_10_15, + os = builders.os.MAC_10_15_OR_11, xcode = builders.xcode.x12d4e, **kwargs): return try_builder( diff --git a/chromium/infra/config/settings.json b/chromium/infra/config/settings.json index 1d46b32946b..4246012de81 100644 --- a/chromium/infra/config/settings.json +++ b/chromium/infra/config/settings.json @@ -2,7 +2,7 @@ "project": "chromium-m90", "project_title": "Chromium M90", "is_main": false, - "is_lts_branch": false, + "is_lts_branch": true, "ref": "refs/branch-heads/4430", "chrome_project": "chrome-m90" } diff --git a/chromium/infra/config/subprojects/chromium/ci.star b/chromium/infra/config/subprojects/chromium/ci.star index 0074978a2ba..8b11a95b278 100644 --- a/chromium/infra/config/subprojects/chromium/ci.star +++ b/chromium/infra/config/subprojects/chromium/ci.star @@ -2150,7 +2150,7 @@ ci.clang_builder( short_name = "sim", ), cores = None, - os = os.MAC_10_15, + os = os.MAC_10_15_OR_11, ssd = True, xcode = xcode.x12d4e, ) @@ -2163,7 +2163,7 @@ ci.clang_builder( short_name = "dev", ), cores = None, - os = os.MAC_10_15, + os = os.MAC_10_15_OR_11, ssd = True, xcode = xcode.x12d4e, ) @@ -3082,7 +3082,7 @@ ci.fyi_builder( short_name = "64rel", ), notifies = ["chrome-memory-safety"], - os = os.LINUX_DEFAULT, + os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, ) ci.fyi_builder( @@ -3401,7 +3401,7 @@ ci.fyi_builder( console_view_entry = consoles.console_view_entry( category = "win10", ), - os = None, + os = os.LINUX_BIONIC_REMOVE, triggered_by = ["win-pixel-builder-rel"], ) @@ -3411,7 +3411,7 @@ ci.fyi_builder( category = "perfetto", short_name = "lnx", ), - os = os.LINUX_DEFAULT, + os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, ) ci.fyi_builder( @@ -3444,7 +3444,7 @@ ci.fyi_builder( category = "linux", short_name = "tgc", ), - os = os.LINUX_DEFAULT, + os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, ) ci.fyi_builder( @@ -3457,7 +3457,7 @@ ci.fyi_builder( reclient_instance = "goma-rbe-chromium", configure_kitchen = True, kitchen_emulate_gce = True, - os = os.LINUX_DEFAULT, + os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, ) ci.fyi_builder( @@ -3471,7 +3471,7 @@ ci.fyi_builder( reclient_rewrapper_env = {"RBE_cache_silo": "Linux TSan Builder (reclient)"}, configure_kitchen = True, kitchen_emulate_gce = True, - os = os.LINUX_DEFAULT, + os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, ) ci.fyi_builder( @@ -3488,7 +3488,7 @@ ci.fyi_builder( reclient_rewrapper_env = {"RBE_cache_silo": "Linux TSan Builder (reclient)"}, configure_kitchen = True, kitchen_emulate_gce = True, - os = os.LINUX_DEFAULT, + os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, ) ci.fyi_builder( @@ -3505,7 +3505,7 @@ ci.fyi_builder( reclient_rewrapper_env = {"RBE_cache_silo": "Linux TSan Builder (reclient)"}, configure_kitchen = True, kitchen_emulate_gce = True, - os = os.LINUX_DEFAULT, + os = os.LINUX_BIONIC_SWITCH_TO_DEFAULT, ) ci.fyi_celab_builder( @@ -3563,7 +3563,7 @@ ci.fyi_coverage_builder( short_name = "ios", ), cores = None, - os = os.MAC_10_15, + os = os.MAC_10_15_OR_11, use_clang_coverage = True, coverage_exclude_sources = "ios_test_files_and_test_utils", coverage_test_types = ["overall", "unit"], diff --git a/chromium/infra/config/subprojects/chromium/try.star b/chromium/infra/config/subprojects/chromium/try.star index de042a9f62a..8f13b9dea22 100644 --- a/chromium/infra/config/subprojects/chromium/try.star +++ b/chromium/infra/config/subprojects/chromium/try.star @@ -1272,6 +1272,7 @@ try_.chromium_linux_builder( goma_jobs = goma.jobs.J150, main_list_view = "try", tryjob = try_.job(), + os = os.LINUX_BIONIC_REMOVE, ) try_.chromium_linux_builder( diff --git a/chromium/net/BUILD.gn b/chromium/net/BUILD.gn index 216ed593dae..dbe81a7a6dd 100644 --- a/chromium/net/BUILD.gn +++ b/chromium/net/BUILD.gn @@ -1891,6 +1891,7 @@ bundle_data("test_support_bundle_data") { "data/ssl/certificates/bad_validity.pem", "data/ssl/certificates/can_sign_http_exchanges_draft_extension.pem", "data/ssl/certificates/can_sign_http_exchanges_draft_extension_invalid.pem", + "data/ssl/certificates/cert-manager.com-chain.pem", "data/ssl/certificates/client-empty-password.p12", "data/ssl/certificates/client-nokey.p12", "data/ssl/certificates/client-null-password.p12", @@ -1940,7 +1941,6 @@ bundle_data("test_support_bundle_data") { "data/ssl/certificates/ct-test-embedded-with-intermediate-chain.pem", "data/ssl/certificates/ct-test-embedded-with-intermediate-preca-chain.pem", "data/ssl/certificates/ct-test-embedded-with-preca-chain.pem", - "data/ssl/certificates/daltonridgeapts.com-chain.pem", "data/ssl/certificates/dec_2017.pem", "data/ssl/certificates/diginotar_cyber_ca.pem", "data/ssl/certificates/diginotar_pkioverheid.pem", diff --git a/chromium/net/cert/cert_verify_proc_unittest.cc b/chromium/net/cert/cert_verify_proc_unittest.cc index 067320d6d3e..b49ef3a4f67 100644 --- a/chromium/net/cert/cert_verify_proc_unittest.cc +++ b/chromium/net/cert/cert_verify_proc_unittest.cc @@ -1485,7 +1485,6 @@ TEST(CertVerifyProcTest, TestHasTooLongValidity) { const char* const file; bool is_valid_too_long; } tests[] = { - {"daltonridgeapts.com-chain.pem", false}, {"start_after_expiry.pem", true}, {"pre_br_validity_ok.pem", false}, {"pre_br_validity_bad_121.pem", true}, @@ -1521,16 +1520,16 @@ TEST(CertVerifyProcTest, TestHasTooLongValidity) { TEST_P(CertVerifyProcInternalTest, TestKnownRoot) { base::FilePath certs_dir = GetTestCertsDirectory(); scoped_refptr<X509Certificate> cert_chain = CreateCertificateChainFromFile( - certs_dir, "daltonridgeapts.com-chain.pem", X509Certificate::FORMAT_AUTO); + certs_dir, "cert-manager.com-chain.pem", X509Certificate::FORMAT_AUTO); ASSERT_TRUE(cert_chain); int flags = 0; CertVerifyResult verify_result; int error = - Verify(cert_chain.get(), "daltonridgeapts.com", flags, + Verify(cert_chain.get(), "ov-validation.cert-manager.com", flags, CRLSet::BuiltinCRLSet().get(), CertificateList(), &verify_result); EXPECT_THAT(error, IsOk()) << "This test relies on a real certificate that " - << "expires on May 28, 2021. If failing on/after " + << "expires on June 2, 2022. If failing on/after " << "that date, please disable and file a bug " << "against rsleevi."; EXPECT_TRUE(verify_result.is_issued_by_known_root); diff --git a/chromium/net/data/ssl/certificates/README b/chromium/net/data/ssl/certificates/README index 23485acf76c..8ebddb06335 100644 --- a/chromium/net/data/ssl/certificates/README +++ b/chromium/net/data/ssl/certificates/README @@ -51,9 +51,9 @@ unit tests. All files are from the src/test/testdada directory in https://code.google.com/p/certificate-transparency/ -- daltonridgeapts.com-chain.pem : A long-lived (39 month), BR compliant, - non-EV certificate, issued by a public trust anchor, and valid for the - domain daltonridgeapts.com. +- cert-manager.com-chain.pem : An OV certificate issued by a public trust + anchor valid for the domain ov-validation.cert-manager.com, and which + expires on 2022-06-22. - gms.hongleong.com.my-verisign-chain.pem: A certificate chain for gms.hongleong.com.my issued by VeriSign Class 3 Public Primary Certification diff --git a/chromium/net/data/ssl/certificates/cert-manager.com-chain.pem b/chromium/net/data/ssl/certificates/cert-manager.com-chain.pem new file mode 100644 index 00000000000..5160d58e91f --- /dev/null +++ b/chromium/net/data/ssl/certificates/cert-manager.com-chain.pem @@ -0,0 +1,133 @@ +-----BEGIN CERTIFICATE----- +MIIHOzCCBiOgAwIBAgIRAIWeFEqrk27xKKnZgPjlsSgwDQYJKoZIhvcNAQELBQAw +gZUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO +BgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDE9MDsGA1UE +AxM0U2VjdGlnbyBSU0EgT3JnYW5pemF0aW9uIFZhbGlkYXRpb24gU2VjdXJlIFNl +cnZlciBDQTAeFw0yMTA2MDIwMDAwMDBaFw0yMjA2MDIyMzU5NTlaMIGPMQswCQYD +VQQGEwJERTETMBEGA1UEBwwKR8O2dHRpbmdlbjFCMEAGA1UEChM5R2VzZWxsc2No +YWZ0IGZ1ZXIgd2lzc2Vuc2NoYWZ0bGljaGUgRGF0ZW52ZXJhcmJlaXR1bmcgbWJI +MScwJQYDVQQDEx5vdi12YWxpZGF0aW9uLmNlcnQtbWFuYWdlci5jb20wggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCayY1pJLAqmoVOJ1UWGfo//jiCJFBd +fjs0fblshyxi1oyd8pUaMflgzkGFC4rs949ovbeQQ66bsuSTN2h+q3qaTAnZ5APD +cFCpBsvxwQB0XwRkcTFGynANhXL3kJLAwpdU/oAcN46RA+rDXRz9ZFYwXf30IbCd +AAVldAFZNwh3Zo2UdjElerC4PoMsk2vdcayep3Xh9YpNhaeaBiFckoRJ+jPnYdoD +QTr4eLvVOeTcjSUmFzrqmmItJbplo8ZVk8O4X7ImLCXzsxtvx5GlAsaGGc9z1/uj +lOl+w8hXf3wfPWXwacZ5XL+ewZD4+qSbr2NpC3sxv8C8dEdzMH+t3nstAgMBAAGj +ggOIMIIDhDAfBgNVHSMEGDAWgBQX2dYlJ2f5McJJQ9kwNkSMbKlP6zAdBgNVHQ4E +FgQUelyvC2sF6TNHcy9PXU1XtECFqEwwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB +/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMEoGA1UdIARDMEEw +NQYMKwYBBAGyMQECAQMEMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5j +b20vQ1BTMAgGBmeBDAECAjBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLnNl +Y3RpZ28uY29tL1NlY3RpZ29SU0FPcmdhbml6YXRpb25WYWxpZGF0aW9uU2VjdXJl +U2VydmVyQ0EuY3JsMIGKBggrBgEFBQcBAQR+MHwwVQYIKwYBBQUHMAKGSWh0dHA6 +Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1JTQU9yZ2FuaXphdGlvblZhbGlkYXRp +b25TZWN1cmVTZXJ2ZXJDQS5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNl +Y3RpZ28uY29tME0GA1UdEQRGMESCHm92LXZhbGlkYXRpb24uY2VydC1tYW5hZ2Vy +LmNvbYIid3d3Lm92LXZhbGlkYXRpb24uY2VydC1tYW5hZ2VyLmNvbTCCAX8GCisG +AQQB1nkCBAIEggFvBIIBawFpAHcARqVV63X6kSAwtaKJafTzfREsQXS+/Um4havy +/HD+bUcAAAF5zXRtkQAABAMASDBGAiEAkF6ook74Xg6nSxBNKJcGw9/xPOUj3Uqk +Tpb4Lq0aV9UCIQDxK/mVll3m1RdOG10txMADyM3hCLGirgH+Ka+Xf5QZiAB2AEHI +yrHfIkZKEMahOglCh15OMYsbA+vrS8do8JBilgb2AAABec10bU4AAAQDAEcwRQIg +AtJ/uzcRqV9fi+kTzC+2pcVgRfm5fbcMeSPqsPLQE6MCIQCv363LIbnFKqCy6P1A +psgPD7GPbQNN15rLYJJFHIBg/gB2ACl5vvCeOTkh8FZzn2Old+W+V32cYAr4+U1d +JlwlXceEAAABec10bSkAAAQDAEcwRQIgGMS9cGiANBz52/6QmgcBgkBZZOifgqB3 +BNOmxUzpcAACIQCL039lwP9tZu7TX4ESSVo/M+dxls3S1dRTb6/5lS/J3zANBgkq +hkiG9w0BAQsFAAOCAQEAZvI38uuTRilCDmoYpmgT2vPDb6lZ6qCP6rOKDYUT+QXC +joA0Y97SNoVQiSEtgwFwfvUsrjwcC9XZvIQ6D4HWJCeqV47Mkq+kfOJ+IsDyfyYd +ehCDoJSVmUA+ULwt419V7KDPmgroViSAwEwKgvUocNkMCVkk4zniWFq2LSMETSbZ +yI/uRcF24Gx4YYRoBf6Wxei7fkZuRhd/JhOH7ULEM+7PVqur7Gdj9qW0zzsHDJp6 +cTvB1Tz0ZmV8Js4d8hOU7K8GGvtEgS28pUn03PrV2cxgUur4PaqWTez+V6fXcWaH +E77devYJHdegqyOZHLTtxXlM+pEpxYm9fsJ9Rf3iDg== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGGTCCBAGgAwIBAgIQE31TnKp8MamkM3AZaIR6jTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgx +MTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjCBlTELMAkGA1UEBhMCR0IxGzAZBgNV +BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE +ChMPU2VjdGlnbyBMaW1pdGVkMT0wOwYDVQQDEzRTZWN0aWdvIFJTQSBPcmdhbml6 +YXRpb24gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAnJMCRkVKUkiS/FeN+S3qU76zLNXYqKXsW2kDwB0Q +9lkz3v4HSKjojHpnSvH1jcM3ZtAykffEnQRgxLVK4oOLp64m1F06XvjRFnG7ir1x +on3IzqJgJLBSoDpFUd54k2xiYPHkVpy3O/c8Vdjf1XoxfDV/ElFw4Sy+BKzL+k/h +fGVqwECn2XylY4QZ4ffK76q06Fha2ZnjJt+OErK43DOyNtoUHZZYQkBuCyKFHFEi +rsTIBkVtkuZntxkj5Ng2a4XQf8dS48+wdQHgibSov4o2TqPgbOuEQc6lL0giE5dQ +YkUeCaXMn2xXcEAG2yDoG9bzk4unMp63RBUJ16/9fAEc2wIDAQABo4IBbjCCAWow +HwYDVR0jBBgwFoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFBfZ1iUn +Z/kxwklD2TA2RIxsqU/rMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/ +AgEAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAbBgNVHSAEFDASMAYG +BFUdIAAwCAYGZ4EMAQICMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNl +cnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNy +bDB2BggrBgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRy +dXN0LmNvbS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZ +aHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAThNA +lsnD5m5bwOO69Bfhrgkfyb/LDCUW8nNTs3Yat6tIBtbNAHwgRUNFbBZaGxNh10m6 +pAKkrOjOzi3JKnSj3N6uq9BoNviRrzwB93fVC8+Xq+uH5xWo+jBaYXEgscBDxLmP +bYox6xU2JPti1Qucj+lmveZhUZeTth2HvbC1bP6mESkGYTQxMD0gJ3NR0N6Fg9N3 +OSBGltqnxloWJ4Wyz04PToxcvr44APhL+XJ71PJ616IphdAEutNCLFGIUi7RPSRn +R+xVzBv0yjTqJsHe3cQhifa6ezIejpZehEU4z4CqN2mLYBd0FUiRnG3wTqN3yhsc +SPr5z0noX0+FCuKPkBurcEya67emP7SsXaRfz+bYipaQ908mgWB2XQ8kd5GzKjGf +FlqyXYwcKapInI5v03hAcNt37N3j0VcFcC3mSZiIBYRiBXBWdoY5TtMibx3+bfEO +s2LEPMvAhblhHrrhFYBZlAyuBbuMf1a+HNJav5fyakywxnB2sJCNwQs2uRHY1ihc +6k/+JLcYCpsM0MF8XPtpvcyiTcaQvKZN8rG61ppnW5YCUtCC+cQKXA0o4D/I+pWV +idWkvklsQLI+qGu41SWyxP7x09fn1txDAXYw+zuLXfdKiXyaNb78yvBXAfCNP6CH +MntHWpdLgtJmwsQt6j8k9Kf5qLnjatkYYaA7jBU= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFgTCCBGmgAwIBAgIQOXJEOvkit1HX02wQ3TE1lTANBgkqhkiG9w0BAQwFADB7 +MQswCQYDVQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD +VQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UE +AwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTE5MDMxMjAwMDAwMFoXDTI4 +MTIzMTIzNTk1OVowgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5 +MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBO +ZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgBJlFzYOw9sI +s9CsVw127c0n00ytUINh4qogTQktZAnczomfzD2p7PbPwdzx07HWezcoEStH2jnG +vDoZtF+mvX2do2NCtnbyqTsrkfjib9DsFiCQCT7i6HTJGLSR1GJk23+jBvGIGGqQ +Ijy8/hPwhxR79uQfjtTkUcYRZ0YIUcuGFFQ/vDP+fmyc/xadGL1RjjWmp2bIcmfb +IWax1Jt4A8BQOujM8Ny8nkz+rwWWNR9XWrf/zvk9tyy29lTdyOcSOk2uTIq3XJq0 +tyA9yn8iNK5+O2hmAUTnAU5GU5szYPeUvlM3kHND8zLDU+/bqv50TmnHa4xgk97E +xwzf4TKuzJM7UXiVZ4vuPVb+DNBpDxsP8yUmazNt925H+nND5X4OpWaxKXwyhGNV +icQNwZNUMBkTrNN9N6frXTpsNVzbQdcS2qlJC9/YgIoJk2KOtWbPJYjNhLixP6Q5 +D9kCnusSTJV882sFqV4Wg8y4Z+LoE53MW4LTTLPtW//e5XOsIzstAL81VXQJSdhJ +WBp/kjbmUZIO8yZ9HE0XvMnsQybQv0FfQKlERPSZ51eHnlAfV1SoPv10Yy+xUGUJ +5lhCLkMaTLTwJUdZ+gQek9QmRkpQgbLevni3/GcV4clXhB4PY9bpYrrWX1Uu6lzG +KAgEJTm4Diup8kyXHAc/DVL17e8vgg8CAwEAAaOB8jCB7zAfBgNVHSMEGDAWgBSg +EQojPpbxB+zirynvgqV/0DCktDAdBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rID +ZsswDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAG +BgRVHSAAMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29t +L0FBQUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDQGCCsGAQUFBwEBBCgwJjAkBggr +BgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEBDAUA +A4IBAQAYh1HcdCE9nIrgJ7cz0C7M7PDmy14R3iJvm3WOnnL+5Nb+qh+cli3vA0p+ +rvSNb3I8QzvAP+u431yqqcau8vzY7qN7Q/aGNnwU4M309z/+3ri0ivCRlv79Q2R+ +/czSAaF9ffgZGclCKxO/WIu6pKJmBHaIkU4MiRTOok3JMrO66BQavHHxW/BBC5gA +CiIDEOUMsfnNkjcZ7Tvx5Dq2+UUTJnWvu6rvP3t3O9LEApE9GQDTF1w52z97GA1F +zZOFli9d31kWTz9RvdVFGD/tSo7oBmF0Ixa1DVBzJ0RHfxBdiSprhTEUxOipakyA +vGp4z7h/jnZymQyd/teRCBaho1+V +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- diff --git a/chromium/net/data/ssl/certificates/daltonridgeapts.com-chain.pem b/chromium/net/data/ssl/certificates/daltonridgeapts.com-chain.pem deleted file mode 100644 index dee9cff39ca..00000000000 --- a/chromium/net/data/ssl/certificates/daltonridgeapts.com-chain.pem +++ /dev/null @@ -1,110 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFRTCCBC2gAwIBAgIJAJFVij12QTNzMA0GCSqGSIb3DQEBCwUAMIG0MQswCQYD -VQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEa -MBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xLTArBgNVBAsTJGh0dHA6Ly9jZXJ0 -cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzEzMDEGA1UEAxMqR28gRGFkZHkgU2Vj -dXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTE4MDIyODE5NDUwNloX -DTIxMDUyODE5NDUwNlowQTEhMB8GA1UECxMYRG9tYWluIENvbnRyb2wgVmFsaWRh -dGVkMRwwGgYDVQQDExNkYWx0b25yaWRnZWFwdHMuY29tMIIBIjANBgkqhkiG9w0B -AQEFAAOCAQ8AMIIBCgKCAQEAqwLMdmbWVNeA7EHm6XCy6PbJpzNsuu0tXvVIbwbF -UID2QU/1sABgGGf/etL3m2WUn7hA3Mqzu38ZA+A115w9ATQ6CpLvNNysNPNBcVRt -jfKkH6PTx2s3BIQ9nDeZK04RPDeqrLZpexJ6RuCqNdH1+8HeP56s8M3g+ZU/azRt -G3Xml32bunoDBK+KlJIgCSQpsqmRfwgQqzPMZj3X0oJt7fdf8bE2uXP55W4WRuu7 -q738To282Zrb3m+HgrUHk2cz8fePlLLIN8xrKXru8k+oxtgi9hsNLxsORGnCLnE/ -KW4oHoNhPLqO5pd00u5ZwHGuHuvwDY+417hJaXNVSXVVAQIDAQABo4IByjCCAcYw -DAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDgYD -VR0PAQH/BAQDAgWgMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly9jcmwuZ29kYWRk -eS5jb20vZ2RpZzJzMS04MTEuY3JsMF0GA1UdIARWMFQwSAYLYIZIAYb9bQEHFwEw -OTA3BggrBgEFBQcCARYraHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9y -ZXBvc2l0b3J5LzAIBgZngQwBAgEwdgYIKwYBBQUHAQEEajBoMCQGCCsGAQUFBzAB -hhhodHRwOi8vb2NzcC5nb2RhZGR5LmNvbS8wQAYIKwYBBQUHMAKGNGh0dHA6Ly9j -ZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS9nZGlnMi5jcnQwHwYD -VR0jBBgwFoAUQMK9J47MNIMwojPX+2yz8LQsgM4wNwYDVR0RBDAwLoITZGFsdG9u -cmlkZ2VhcHRzLmNvbYIXd3d3LmRhbHRvbnJpZGdlYXB0cy5jb20wHQYDVR0OBBYE -FG7ojZg+vlPb8iPiyN0oeSAYaW+8MA0GCSqGSIb3DQEBCwUAA4IBAQCvLidW3At+ -fBN8JJBzL8rM/fVk80033A70EKt4O0+DSk+a6AwMcn0SIC3N6/y3pE+XvqnDaL2F -jvuOgO16H6hhmRyknx+ejIzLa/NKrhAhwgAIOSGXRNoOHThZe8Apnv07j61LPLr4 -SV4RF06zU8TgkltU4WodyCikeADwbIH/W0LnJ3JVxXKrtlYTGqd47LMHlSNRoZeg -g8pdIxBr4DfZlxhmmyEyGGloLABRzsBQWx2wlbWtpL95ot0FoTnJRc7Z933mzmsT -OTG6S24vzMEG7zziz1GWsZnUaSjE4OAvv4yBprLN7zp7MkKCzzddWh9nZTXudjXO -YS6/ctGzpcFO ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT -EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp -ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3 -MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH -EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE -CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD -EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD -BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv -K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e -cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY -pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n -eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB -AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV -HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv -9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v -b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n -b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG -CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv -MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz -91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2 -RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi -DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11 -GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x -LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEfTCCA2WgAwIBAgIDG+cVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVT -MSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIEluYy4xMTAvBgNVBAsTKEdv -IERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMTAx -MDcwMDAwWhcNMzEwNTMwMDcwMDAwWjCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHku -Y29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1 -dGhvcml0eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3Fi -CPH6WTT3G8kYo/eASVjpIoMTpsUgQwE7hPHmhUmfJ+r2hBtOoLTbcJjHMgGxBT4H -Tu70+k8vWTAi56sZVmvigAf88xZ1gDlRe+X5NbZ0TqmNghPktj+pA4P6or6KFWp/ -3gvDthkUBcrqw6gElDtGfDIN8wBmIsiNaW02jBEYt9OyHGC0OPoCjM7T3UYH3go+ -6118yHz7sCtTpJJiaVElBWEaRIGMLKlDliPfrDqBmg4pxRyp6V0etp6eMAo5zvGI -gPtLXcwy7IViQyU0AlYnAZG0O3AqP26x6JyIAX2f1PnbU21gnb8s51iruF9G/M7E -GwM8CetJMVxpRrPgRwIDAQABo4IBFzCCARMwDwYDVR0TAQH/BAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9BUFuIMGU2g/eMB8GA1Ud -IwQYMBaAFNLEsNKR1EwRcbNhyz2h/t2oatTjMDQGCCsGAQUFBwEBBCgwJjAkBggr -BgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMDIGA1UdHwQrMCkwJ6Al -oCOGIWh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Ryb290LmNybDBGBgNVHSAEPzA9 -MDsGBFUdIAAwMzAxBggrBgEFBQcCARYlaHR0cHM6Ly9jZXJ0cy5nb2RhZGR5LmNv -bS9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAWQtTvZKGEacke+1bMc8d -H2xwxbhuvk679r6XUOEwf7ooXGKUwuN+M/f7QnaF25UcjCJYdQkMiGVnOQoWCcWg -OJekxSOTP7QYpgEGRJHjp2kntFolfzq3Ms3dhP8qOCkzpN1nsoX+oYggHFCJyNwq -9kIDN0zmiN/VryTyscPfzLXs4Jlet0lUIDyUGAzHHFIYSaRt4bNYC8nY7NmuHDKO -KHAN4v6mF56ED71XcLNa6R+ghlO773z/aQvgSMO3kwvIClTErF0UZzdsyqUvMQg3 -qm5vjLyb4lddJIGvl5echK1srDdMZvNhkREg5L4wn3qkKQmw4TRfZHcYQFHfjDCm -rw== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh -MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE -YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 -MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo -ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg -MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN -ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA -PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w -wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi -EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY -avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ -YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE -sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h -/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 -IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD -ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy -OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P -TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ -HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER -dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf -ReYNnyicsbkqWletNw+vHX/bvZ8= ------END CERTIFICATE----- diff --git a/chromium/net/http/http_cache_transaction.cc b/chromium/net/http/http_cache_transaction.cc index bb0b938e71f..6a1ccb4657f 100644 --- a/chromium/net/http/http_cache_transaction.cc +++ b/chromium/net/http/http_cache_transaction.cc @@ -2115,6 +2115,8 @@ int HttpCache::Transaction::DoHeadersPhaseCannotProceed(int result) { entry_ = nullptr; new_entry_ = nullptr; + SetResponse(HttpResponseInfo()); + // Bypass the cache for timeout scenario. if (result == ERR_CACHE_LOCK_TIMEOUT) effective_load_flags_ |= LOAD_DISABLE_CACHE; diff --git a/chromium/services/network/cors/cors_url_loader_factory.cc b/chromium/services/network/cors/cors_url_loader_factory.cc index a9f5d702dc1..6e23074a0fa 100644 --- a/chromium/services/network/cors/cors_url_loader_factory.cc +++ b/chromium/services/network/cors/cors_url_loader_factory.cc @@ -220,7 +220,17 @@ CorsURLLoaderFactory::CorsURLLoaderFactory( &CorsURLLoaderFactory::DeleteIfNeeded, base::Unretained(this))); } -CorsURLLoaderFactory::~CorsURLLoaderFactory() = default; +CorsURLLoaderFactory::~CorsURLLoaderFactory() { + // Delete loaders one at a time, since deleting one loader can cause another + // loader waiting on it to fail synchronously, which could result in the other + // loader calling DestroyURLLoader(). + while (!loaders_.empty()) { + // No need to call context_->LoaderDestroyed(), since this method is only + // called from the NetworkContext's destructor, or when there are no + // remaining URLLoaders. + loaders_.erase(loaders_.begin()); + } +} void CorsURLLoaderFactory::OnLoaderCreated( std::unique_ptr<mojom::URLLoader> loader) { diff --git a/chromium/services/network/cors/cors_url_loader_factory_unittest.cc b/chromium/services/network/cors/cors_url_loader_factory_unittest.cc index 13811282f5b..dd3361f8185 100644 --- a/chromium/services/network/cors/cors_url_loader_factory_unittest.cc +++ b/chromium/services/network/cors/cors_url_loader_factory_unittest.cc @@ -7,7 +7,9 @@ #include "base/macros.h" #include "base/test/task_environment.h" #include "mojo/public/cpp/bindings/remote.h" +#include "net/base/load_flags.h" #include "net/proxy_resolution/configured_proxy_resolution_service.h" +#include "net/test/embedded_test_server/embedded_test_server.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_builder.h" @@ -49,6 +51,9 @@ class CorsURLLoaderFactoryTest : public testing::Test { protected: // testing::Test implementation. void SetUp() override { + test_server_.AddDefaultHandlers(); + ASSERT_TRUE(test_server_.Start()); + network_service_ = NetworkService::CreateForTesting(); auto context_params = mojom::NetworkContextParams::New(); @@ -68,7 +73,7 @@ class CorsURLLoaderFactoryTest : public testing::Test { auto factory_params = network::mojom::URLLoaderFactoryParams::New(); factory_params->process_id = kProcessId; factory_params->request_initiator_origin_lock = - url::Origin::Create(GURL("http://localhost")); + url::Origin::Create(test_server_.base_url()); auto resource_scheduler_client = base::MakeRefCounted<ResourceSchedulerClient>( kProcessId, kRouteId, &resource_scheduler_, @@ -81,15 +86,25 @@ class CorsURLLoaderFactoryTest : public testing::Test { } void CreateLoaderAndStart(const ResourceRequest& request) { + url_loaders_.emplace_back(mojo::Remote<mojom::URLLoader>()); + test_cors_loader_clients_.emplace_back( + std::make_unique<TestURLLoaderClient>()); cors_url_loader_factory_->CreateLoaderAndStart( - url_loader_.BindNewPipeAndPassReceiver(), kRouteId, kRequestId, + url_loaders_.back().BindNewPipeAndPassReceiver(), kRouteId, kRequestId, mojom::kURLLoadOptionNone, request, - test_cors_loader_client_.CreateRemote(), + test_cors_loader_clients_.back()->CreateRemote(), net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); } void ResetFactory() { cors_url_loader_factory_.reset(); } + net::test_server::EmbeddedTestServer* test_server() { return &test_server_; } + + std::vector<std::unique_ptr<TestURLLoaderClient>>& + test_cors_loader_clients() { + return test_cors_loader_clients_; + } + private: // Test environment. base::test::TaskEnvironment task_environment_; @@ -99,15 +114,17 @@ class CorsURLLoaderFactoryTest : public testing::Test { std::unique_ptr<NetworkContext> network_context_; mojo::Remote<mojom::NetworkContext> network_context_remote_; + net::test_server::EmbeddedTestServer test_server_; + // CorsURLLoaderFactory instance under tests. std::unique_ptr<mojom::URLLoaderFactory> cors_url_loader_factory_; mojo::Remote<mojom::URLLoaderFactory> cors_url_loader_factory_remote_; - // Holds URLLoader that CreateLoaderAndStart() creates. - mojo::Remote<mojom::URLLoader> url_loader_; + // Holds the URLLoaders that CreateLoaderAndStart() creates. + std::vector<mojo::Remote<mojom::URLLoader>> url_loaders_; - // TestURLLoaderClient that records callback activities. - TestURLLoaderClient test_cors_loader_client_; + // TestURLLoaderClients that record callback activities. + std::vector<std::unique_ptr<TestURLLoaderClient>> test_cors_loader_clients_; // Holds for allowed origin access lists. OriginAccessList origin_access_list_; @@ -118,7 +135,7 @@ class CorsURLLoaderFactoryTest : public testing::Test { // Regression test for https://crbug.com/906305. TEST_F(CorsURLLoaderFactoryTest, DestructionOrder) { ResourceRequest request; - GURL url("http://localhost"); + GURL url = test_server()->GetURL("/hung"); request.mode = mojom::RequestMode::kNoCors; request.credentials_mode = mojom::CredentialsMode::kOmit; request.method = net::HttpRequestHeaders::kGetMethod; @@ -141,5 +158,36 @@ TEST_F(CorsURLLoaderFactoryTest, DestructionOrder) { ResetFactory(); } +TEST_F(CorsURLLoaderFactoryTest, CleanupWithSharedCacheObjectInUse) { + // Create a loader for a response that hangs after receiving headers, and run + // it until headers are received. + ResourceRequest request; + GURL url = test_server()->GetURL("/hung-after-headers"); + request.mode = mojom::RequestMode::kNoCors; + request.credentials_mode = mojom::CredentialsMode::kOmit; + request.method = net::HttpRequestHeaders::kGetMethod; + request.url = url; + request.request_initiator = url::Origin::Create(url); + CreateLoaderAndStart(request); + test_cors_loader_clients().back()->RunUntilResponseReceived(); + + // Read only requests will fail synchonously on destruction of the request + // they're waiting on if they're in the |done_headers_queue| when the other + // request fails. Make a large number of such requests, spin the message loop + // so they end up blocked on the hung request, and then destroy all loads. A + // large number of loaders is needed because they're stored in a set, indexed + // by address, so teardown order is random. + request.load_flags = + net::LOAD_ONLY_FROM_CACHE | net::LOAD_SKIP_CACHE_VALIDATION; + for (int i = 0; i < 10; ++i) + CreateLoaderAndStart(request); + base::RunLoop().RunUntilIdle(); + + // This should result in a crash if tearing down one URLLoaderFactory + // resulting in a another one failing causes a crash during teardown. See + // https://crbug.com/1209769. + ResetFactory(); +} + } // namespace cors } // namespace network diff --git a/chromium/skia/ext/skia_commit_hash.h b/chromium/skia/ext/skia_commit_hash.h index c8e086208d0..892b7de89d3 100644 --- a/chromium/skia/ext/skia_commit_hash.h +++ b/chromium/skia/ext/skia_commit_hash.h @@ -3,6 +3,6 @@ #ifndef SKIA_EXT_SKIA_COMMIT_HASH_H_ #define SKIA_EXT_SKIA_COMMIT_HASH_H_ -#define SKIA_COMMIT_HASH "f1e4f21baf44e7c9cc0efbbba21c4ed6009686b3" +#define SKIA_COMMIT_HASH "2e4ca248d12752beb42a376a3f6282ccf9b90cf2" #endif // SKIA_EXT_SKIA_COMMIT_HASH_H_ diff --git a/chromium/testing/test_env.py b/chromium/testing/test_env.py index 699134906a2..dc1f231266d 100755 --- a/chromium/testing/test_env.py +++ b/chromium/testing/test_env.py @@ -94,6 +94,10 @@ def get_sanitizer_env(cmd, asan, lsan, msan, tsan, cfi_diag): asan_options = symbolization_options[:] if lsan: asan_options.append('detect_leaks=1') + # LSan appears to have trouble with later versions of glibc. + # See https://github.com/google/sanitizers/issues/1322 + if 'linux' in sys.platform: + asan_options.append('intercept_tls_get_addr=0') if asan_options: extra_env['ASAN_OPTIONS'] = ' '.join(asan_options) diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame.cc b/chromium/third_party/blink/renderer/core/frame/local_frame.cc index 74d1e79e332..f4c5046411e 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame.cc +++ b/chromium/third_party/blink/renderer/core/frame/local_frame.cc @@ -752,22 +752,25 @@ const SecurityContext* LocalFrame::GetSecurityContext() const { return DomWindow() ? &DomWindow()->GetSecurityContext() : nullptr; } -void LocalFrame::PrintNavigationErrorMessage(const Frame& target_frame, - const char* reason) { +// Provides a string description of the Frame as either its URL or origin if +// remote. +static String FrameDescription(const Frame& frame) { // URLs aren't available for RemoteFrames, so the error message uses their // origin instead. - auto* target_local_frame = DynamicTo<LocalFrame>(&target_frame); - String target_frame_description = - target_local_frame - ? "with URL '" + - target_local_frame->GetDocument()->Url().GetString() + "'" - : "with origin '" + - target_frame.GetSecurityContext() - ->GetSecurityOrigin() - ->ToString() + - "'"; + const LocalFrame* local_frame = DynamicTo<LocalFrame>(&frame); + return local_frame + ? "with URL '" + local_frame->GetDocument()->Url().GetString() + "'" + : "with origin '" + + frame.GetSecurityContext() + ->GetSecurityOrigin() + ->ToString() + + "'"; +} + +void LocalFrame::PrintNavigationErrorMessage(const Frame& target_frame, + const String& reason) { String message = "Unsafe attempt to initiate navigation for frame " + - target_frame_description + " from frame with URL '" + + FrameDescription(target_frame)+ " from frame with URL '" + GetDocument()->Url().GetString() + "'. " + reason + "\n"; DomWindow()->PrintErrorMessage(message); @@ -1635,100 +1638,152 @@ static bool CanAccessAncestor(const SecurityOrigin& active_security_origin, return false; } -bool LocalFrame::CanNavigate(const Frame& target_frame, - const KURL& destination_url) { - if (&target_frame == this) +// `initiating_frame` - The frame that CanNavigate was initially requested for. +// `source_frame` - The frame that is currently being tested to see if it can +// navigate `target_frame`. +// `target_frame` - The frame to be navigated. +// `destination_url` - The URL to navigate to on `target_frame`. +static bool CanNavigateHelper(LocalFrame& initiating_frame, + const Frame& source_frame, + const Frame& target_frame, + const KURL& destination_url) { + // The only time the helper is called with a different `initiating_frame` from + // its `source_frame` is to recursively check if ancestors can navigate the + // top frame. + DCHECK(&initiating_frame == &source_frame || + target_frame == initiating_frame.Tree().Top()); + + // Only report navigation blocking on the initial call to CanNavigateHelper, + // not the recursive calls. + bool should_report = &initiating_frame == &source_frame; + + if (&target_frame == &source_frame) return true; // Navigating window.opener cross origin, without user activation. See // https://crbug.com/813643. - if (Opener() == target_frame && !HasTransientUserActivation(this) && + if (should_report && source_frame.Opener() == target_frame && + !source_frame.HasTransientUserActivation() && !target_frame.GetSecurityContext()->GetSecurityOrigin()->CanAccess( SecurityOrigin::Create(destination_url).get())) { - UseCounter::Count(GetDocument(), + UseCounter::Count(initiating_frame.GetDocument(), WebFeature::kOpenerNavigationWithoutGesture); } if (destination_url.ProtocolIsJavaScript() && - !GetSecurityContext()->GetSecurityOrigin()->CanAccess( + !source_frame.GetSecurityContext()->GetSecurityOrigin()->CanAccess( target_frame.GetSecurityContext()->GetSecurityOrigin())) { - PrintNavigationErrorMessage( - target_frame, - "The frame attempting navigation must be same-origin with the target " - "if navigating to a javascript: url"); + if (should_report) { + initiating_frame.PrintNavigationErrorMessage( + target_frame, + "The frame attempting navigation must be same-origin with the target " + "if navigating to a javascript: url"); + } return false; } - if (GetSecurityContext()->IsSandboxed( + if (source_frame.GetSecurityContext()->IsSandboxed( network::mojom::blink::WebSandboxFlags::kNavigation)) { - if (!target_frame.Tree().IsDescendantOf(this) && + if (!target_frame.Tree().IsDescendantOf(&source_frame) && !target_frame.IsMainFrame()) { - PrintNavigationErrorMessage( - target_frame, - "The frame attempting navigation is sandboxed, and is therefore " - "disallowed from navigating its ancestors."); + if (should_report) { + initiating_frame.PrintNavigationErrorMessage( + target_frame, + "The frame attempting navigation is sandboxed, and is therefore " + "disallowed from navigating its ancestors."); + } return false; } // Sandboxed frames can also navigate popups, if the // 'allow-sandbox-escape-via-popup' flag is specified, or if // 'allow-popups' flag is specified, or if the - if (target_frame.IsMainFrame() && target_frame != Tree().Top() && - GetSecurityContext()->IsSandboxed( + if (target_frame.IsMainFrame() && + target_frame != source_frame.Tree().Top() && + source_frame.GetSecurityContext()->IsSandboxed( network::mojom::blink::WebSandboxFlags:: kPropagatesToAuxiliaryBrowsingContexts) && - (GetSecurityContext()->IsSandboxed( + (source_frame.GetSecurityContext()->IsSandboxed( network::mojom::blink::WebSandboxFlags::kPopups) || - target_frame.Opener() != this)) { - PrintNavigationErrorMessage( - target_frame, - "The frame attempting navigation is sandboxed and is trying " - "to navigate a popup, but is not the popup's opener and is not " - "set to propagate sandboxing to popups."); + target_frame.Opener() != &source_frame)) { + if (should_report) { + initiating_frame.PrintNavigationErrorMessage( + target_frame, + "The frame attempting navigation is sandboxed and is trying " + "to navigate a popup, but is not the popup's opener and is not " + "set to propagate sandboxing to popups."); + } return false; } - // Top navigation is forbidden unless opted-in. allow-top-navigation or - // allow-top-navigation-by-user-activation will also skips origin checks. - if (target_frame == Tree().Top()) { - if (GetSecurityContext()->IsSandboxed( + // Top navigation is forbidden in sandboxed frames unless opted-in, and only + // then if the ancestor chain allowed to navigate the top frame. + if (target_frame == source_frame.Tree().Top()) { + if (source_frame.GetSecurityContext()->IsSandboxed( network::mojom::blink::WebSandboxFlags::kTopNavigation) && - GetSecurityContext()->IsSandboxed( + source_frame.GetSecurityContext()->IsSandboxed( network::mojom::blink::WebSandboxFlags:: kTopNavigationByUserActivation)) { - PrintNavigationErrorMessage( - target_frame, - "The frame attempting navigation of the top-level window is " - "sandboxed, but the flag of 'allow-top-navigation' or " - "'allow-top-navigation-by-user-activation' is not set."); + if (should_report) { + initiating_frame.PrintNavigationErrorMessage( + target_frame, + "The frame attempting navigation of the top-level window is " + "sandboxed, but the flag of 'allow-top-navigation' or " + "'allow-top-navigation-by-user-activation' is not set."); + } return false; } - if (GetSecurityContext()->IsSandboxed( + if (source_frame.GetSecurityContext()->IsSandboxed( network::mojom::blink::WebSandboxFlags::kTopNavigation) && - !GetSecurityContext()->IsSandboxed( + !source_frame.GetSecurityContext()->IsSandboxed( network::mojom::blink::WebSandboxFlags:: kTopNavigationByUserActivation) && - !LocalFrame::HasTransientUserActivation(this)) { - // With only 'allow-top-navigation-by-user-activation' (but not - // 'allow-top-navigation'), top navigation requires a user gesture. - GetLocalFrameHostRemote().DidBlockNavigation( - destination_url, GetDocument()->Url(), - mojom::NavigationBlockedReason::kRedirectWithNoUserGestureSandbox); - PrintNavigationErrorMessage( - target_frame, - "The frame attempting navigation of the top-level window is " - "sandboxed with the 'allow-top-navigation-by-user-activation' " - "flag, but has no user activation (aka gesture). See " - "https://www.chromestatus.com/feature/5629582019395584."); + !source_frame.HasTransientUserActivation()) { + if (should_report) { + // With only 'allow-top-navigation-by-user-activation' (but not + // 'allow-top-navigation'), top navigation requires a user gesture. + initiating_frame.GetLocalFrameHostRemote().DidBlockNavigation( + destination_url, initiating_frame.GetDocument()->Url(), + mojom::NavigationBlockedReason:: + kRedirectWithNoUserGestureSandbox); + initiating_frame.PrintNavigationErrorMessage( + target_frame, + "The frame attempting navigation of the top-level window is " + "sandboxed with the 'allow-top-navigation-by-user-activation' " + "flag, but has no user activation (aka gesture). See " + "https://www.chromestatus.com/feature/5629582019395584."); + } return false; } + + // If the nearest non-sandboxed ancestor frame is not allowed to navigate, + // then this sandboxed frame can't either. This prevents a cross-origin + // frame from embedding a sandboxed iframe with kTopNavigate from + // navigating the top frame. See (crbug.com/1145553) + if (Frame* parent_frame = source_frame.Tree().Parent()) { + bool parent_can_navigate = CanNavigateHelper( + initiating_frame, *parent_frame, target_frame, destination_url); + if (!parent_can_navigate) { + if (should_report) { + String message = + "The frame attempting navigation of the top-level window is " + "sandboxed and is not allowed to navigate since its ancestor " + "frame " + + FrameDescription(*parent_frame) + + " is unable to navigate the top frame.\n"; + initiating_frame.PrintNavigationErrorMessage(target_frame, message); + } + return false; + } + } return true; } } - DCHECK(GetSecurityContext()->GetSecurityOrigin()); - const SecurityOrigin& origin = *GetSecurityContext()->GetSecurityOrigin(); + DCHECK(source_frame.GetSecurityContext()->GetSecurityOrigin()); + const SecurityOrigin& origin = + *source_frame.GetSecurityContext()->GetSecurityOrigin(); // This is the normal case. A document can navigate its decendant frames, // or, more generally, a document can navigate a frame if the document is @@ -1752,17 +1807,17 @@ bool LocalFrame::CanNavigate(const Frame& target_frame, // and/or "parent" relation). Requiring some sort of relation prevents a // document from navigating arbitrary, unrelated top-level frames. if (!target_frame.Tree().Parent()) { - if (target_frame == Opener()) + if (target_frame == source_frame.Opener()) return true; if (CanAccessAncestor(origin, target_frame.Opener())) return true; } - if (target_frame == Tree().Top()) { + if (target_frame == source_frame.Tree().Top()) { // A frame navigating its top may blocked if the document initiating // the navigation has never received a user gesture and the navigation // isn't same-origin with the target. - if (HasStickyUserActivation() || + if (source_frame.HasStickyUserActivation() || target_frame.GetSecurityContext()->GetSecurityOrigin()->CanAccess( SecurityOrigin::Create(destination_url).get())) { return true; @@ -1774,32 +1829,50 @@ bool LocalFrame::CanNavigate(const Frame& target_frame, String destination_domain = network_utils::GetDomainAndRegistry( destination_url.Host(), network_utils::kIncludePrivateRegistries); if (!target_domain.IsEmpty() && !destination_domain.IsEmpty() && - target_domain == destination_domain) { + target_domain == destination_domain && + target_frame.GetSecurityContext()->GetSecurityOrigin()->Protocol() == + destination_url.Protocol()) { return true; } - if (auto* settings_client = Client()->GetContentSettingsClient()) { - if (settings_client->AllowPopupsAndRedirects(false /* default_value*/)) - return true; + + // We skip this check for recursive calls on remote frames, in which case + // we're less permissive. + if (const LocalFrame* local_frame = DynamicTo<LocalFrame>(&source_frame)) { + if (auto* settings_client = + local_frame->Client()->GetContentSettingsClient()) { + if (settings_client->AllowPopupsAndRedirects(false /* default_value*/)) + return true; + } + } + + if (should_report) { + initiating_frame.PrintNavigationErrorMessage( + target_frame, + "The frame attempting navigation is targeting its top-level window, " + "but is neither same-origin with its target nor has it received a " + "user gesture. See " + "https://www.chromestatus.com/features/5851021045661696."); + initiating_frame.GetLocalFrameHostRemote().DidBlockNavigation( + destination_url, initiating_frame.GetDocument()->Url(), + mojom::NavigationBlockedReason::kRedirectWithNoUserGesture); } - PrintNavigationErrorMessage( - target_frame, - "The frame attempting navigation is targeting its top-level window, " - "but is neither same-origin with its target nor has it received a " - "user gesture. See " - "https://www.chromestatus.com/features/5851021045661696."); - GetLocalFrameHostRemote().DidBlockNavigation( - destination_url, GetDocument()->Url(), - mojom::NavigationBlockedReason::kRedirectWithNoUserGesture); } else { - PrintNavigationErrorMessage(target_frame, - "The frame attempting navigation is neither " - "same-origin with the target, " - "nor is it the target's parent or opener."); + if (should_report) { + initiating_frame.PrintNavigationErrorMessage( + target_frame, + "The frame attempting navigation is neither same-origin with the " + "target, nor is it the target's parent or opener."); + } } return false; } +bool LocalFrame::CanNavigate(const Frame& target_frame, + const KURL& destination_url) { + return CanNavigateHelper(*this, *this, target_frame, destination_url); +} + ContentCaptureManager* LocalFrame::GetContentCaptureManager() { DCHECK(Client()); if (!IsLocalRoot()) diff --git a/chromium/third_party/blink/renderer/core/frame/local_frame.h b/chromium/third_party/blink/renderer/core/frame/local_frame.h index 38153330251..ec4edbd6f4c 100644 --- a/chromium/third_party/blink/renderer/core/frame/local_frame.h +++ b/chromium/third_party/blink/renderer/core/frame/local_frame.h @@ -186,7 +186,7 @@ class CORE_EXPORT LocalFrame final void Navigate(FrameLoadRequest&, WebFrameLoadType) override; bool ShouldClose() override; const SecurityContext* GetSecurityContext() const override; - void PrintNavigationErrorMessage(const Frame&, const char* reason); + void PrintNavigationErrorMessage(const Frame&, const String& reason); void PrintNavigationWarning(const String&); bool DetachDocument() override; void CheckCompleted() override; diff --git a/chromium/third_party/blink/renderer/core/loader/long_task_detector.cc b/chromium/third_party/blink/renderer/core/loader/long_task_detector.cc index 7e1499b1ddd..3816779cfaf 100644 --- a/chromium/third_party/blink/renderer/core/loader/long_task_detector.cc +++ b/chromium/third_party/blink/renderer/core/loader/long_task_detector.cc @@ -24,6 +24,7 @@ LongTaskDetector::LongTaskDetector() = default; void LongTaskDetector::RegisterObserver(LongTaskObserver* observer) { DCHECK(IsMainThread()); DCHECK(observer); + DCHECK(!iterating_); if (observers_.insert(observer).is_new_entry && observers_.size() == 1) { // Number of observers just became non-zero. Thread::Current()->AddTaskTimeObserver(this); @@ -32,6 +33,10 @@ void LongTaskDetector::RegisterObserver(LongTaskObserver* observer) { void LongTaskDetector::UnregisterObserver(LongTaskObserver* observer) { DCHECK(IsMainThread()); + if (iterating_) { + observers_to_be_removed_.push_back(observer); + return; + } observers_.erase(observer); if (observers_.size() == 0) { Thread::Current()->RemoveTaskTimeObserver(this); @@ -43,13 +48,21 @@ void LongTaskDetector::DidProcessTask(base::TimeTicks start_time, if ((end_time - start_time) < LongTaskDetector::kLongTaskThreshold) return; + iterating_ = true; for (auto& observer : observers_) { observer->OnLongTaskDetected(start_time, end_time); } + iterating_ = false; + + for (const auto& observer : observers_to_be_removed_) { + UnregisterObserver(observer); + } + observers_to_be_removed_.clear(); } void LongTaskDetector::Trace(Visitor* visitor) const { visitor->Trace(observers_); + visitor->Trace(observers_to_be_removed_); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/loader/long_task_detector.h b/chromium/third_party/blink/renderer/core/loader/long_task_detector.h index dc6f0dbab5c..5fd4bb8d2ab 100644 --- a/chromium/third_party/blink/renderer/core/loader/long_task_detector.h +++ b/chromium/third_party/blink/renderer/core/loader/long_task_detector.h @@ -49,6 +49,8 @@ class CORE_EXPORT LongTaskDetector final base::TimeTicks end_time) override; HeapHashSet<Member<LongTaskObserver>> observers_; + HeapVector<Member<LongTaskObserver>> observers_to_be_removed_; + bool iterating_ = false; DISALLOW_COPY_AND_ASSIGN(LongTaskDetector); }; diff --git a/chromium/third_party/blink/renderer/core/loader/long_task_detector_test.cc b/chromium/third_party/blink/renderer/core/loader/long_task_detector_test.cc index 3384fa8ebfb..403ba452362 100644 --- a/chromium/third_party/blink/renderer/core/loader/long_task_detector_test.cc +++ b/chromium/third_party/blink/renderer/core/loader/long_task_detector_test.cc @@ -27,9 +27,26 @@ class TestLongTaskObserver : last_long_task_start = start_time; last_long_task_end = end_time; } -}; // Anonymous namespace +}; + +class SelfUnregisteringObserver + : public GarbageCollected<SelfUnregisteringObserver>, + public LongTaskObserver { + public: + void OnLongTaskDetected(base::TimeTicks, base::TimeTicks) override { + called_ = true; + LongTaskDetector::Instance().UnregisterObserver(this); + } + bool IsCalled() const { return called_; } + + void Reset() { called_ = false; } + + private: + bool called_ = false; +}; } // namespace + class LongTaskDetectorTest : public testing::Test { public: // Public because it's executed on a task queue. @@ -126,4 +143,18 @@ TEST_F(LongTaskDetectorTest, RegisterSameObserverTwice) { long_task_end_when_registered); } +TEST_F(LongTaskDetectorTest, SelfUnregisteringObserver) { + auto* observer = MakeGarbageCollected<SelfUnregisteringObserver>(); + + LongTaskDetector::Instance().RegisterObserver(observer); + SimulateTask(LongTaskDetector::kLongTaskThreshold + + base::TimeDelta::FromMilliseconds(10)); + EXPECT_TRUE(observer->IsCalled()); + observer->Reset(); + + SimulateTask(LongTaskDetector::kLongTaskThreshold + + base::TimeDelta::FromMilliseconds(10)); + EXPECT_FALSE(observer->IsCalled()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc index 0b014b67ff4..4264c8d1127 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_node.cc @@ -614,13 +614,13 @@ void AudioNode::Dispose() { BaseAudioContext::GraphAutoLocker locker(context()); Handler().Dispose(); - // Add the handler to the orphan list if the context is pulling on the audio - // graph. This keeps the handler alive until it can be deleted at a safe - // point (in pre/post handler task). If graph isn't being pulled, we can - // delete the handler now since nothing on the audio thread will be touching - // it. + // Add the handler to the orphan list. This keeps the handler alive until it + // can be deleted at a safe point (in pre/post handler task). If the graph is + // being processed, the handler must be added. If the context is suspended, + // the handler still needs to be added in case the context is resumed. DCHECK(context()); - if (context()->IsPullingAudioGraph()) { + if (context()->IsPullingAudioGraph() || + context()->ContextState() == BaseAudioContext::kSuspended) { context()->GetDeferredTaskHandler().AddRenderingOrphanHandler( std::move(handler_)); } diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc index 5583b8fd885..e68b1c1b2f6 100644 --- a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc +++ b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc @@ -180,11 +180,14 @@ bool AudioWorkletProcessor::PortTopologyMatches( if (audio_port_2.IsEmpty()) return false; - // Two AudioPorts are supposed to have the same length because the number of - // inputs and outputs of AudioNode cannot change after construction. v8::Local<v8::Array> port_2_local = audio_port_2.NewLocal(isolate); DCHECK(port_2_local->IsArray()); - DCHECK_EQ(audio_port_1.size(), port_2_local->Length()); + + // Two audio ports may have a different number of inputs or outputs. See + // crbug.com/1202060 + if (audio_port_1.size() != port_2_local->Length()) { + return false; + } v8::TryCatch try_catch(isolate); diff --git a/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc b/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc index eaa8603c735..aa30a4cec88 100644 --- a/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc +++ b/chromium/third_party/blink/renderer/modules/xr/xr_layer.cc @@ -21,7 +21,7 @@ const AtomicString& XRLayer::InterfaceName() const { void XRLayer::Trace(Visitor* visitor) const { visitor->Trace(session_); - ScriptWrappable::Trace(visitor); + EventTargetWithInlineData::Trace(visitor); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/audio/fft_frame.h b/chromium/third_party/blink/renderer/platform/audio/fft_frame.h index 149b94c52f7..5474597147c 100644 --- a/chromium/third_party/blink/renderer/platform/audio/fft_frame.h +++ b/chromium/third_party/blink/renderer/platform/audio/fft_frame.h @@ -41,7 +41,7 @@ #if defined(WTF_USE_WEBAUDIO_FFMPEG) struct RDFTContext; #elif defined(WTF_USE_WEBAUDIO_PFFFT) -#include "third_party/blink/renderer/platform/wtf/vector.h" +#include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/pffft/src/pffft.h" #elif defined(OS_MAC) #include <Accelerate/Accelerate.h> @@ -113,8 +113,14 @@ class PLATFORM_EXPORT FFTFrame { const FFTFrame& frame2, double x); - unsigned fft_size_; - unsigned log2fft_size_; + unsigned fft_size_ = 0; + + // When using PFFFT, this slot is not irrelevant and not used because PFFFT + // supports sizes that aren't a power of 2. + // TODO(https://crbug.com/988121) Look into whether Mac vDSP really needs + // this. + unsigned log2fft_size_ = 0; + // These two arrays contain the transformed data. Instead of a single array // of complex numbers, we split the complex data into an array of the real // part and the imaginary part. @@ -188,10 +194,10 @@ class PLATFORM_EXPORT FFTFrame { PFFFT_Setup* setup_; }; - // Returns the vector that holds all of the possible FFTSetup objects. This + // Returns the HashMap that holds all of the possible FFTSetup objects. This // should be setup in the |Initialize()| method that is called when a context // is created. - static Vector<std::unique_ptr<FFTSetup>>& FFTSetups(); + static HashMap<unsigned, std::unique_ptr<FFTSetup>>& FFTSetups(); // Initialize an entry in FFTSetups for an FFT of order |fft_order|. This can // be called from any thread, but if a new FFTSetup needs to be allocated, diff --git a/chromium/third_party/blink/renderer/platform/audio/pffft/fft_frame_pffft.cc b/chromium/third_party/blink/renderer/platform/audio/pffft/fft_frame_pffft.cc index 620188fff08..3317e8ad054 100644 --- a/chromium/third_party/blink/renderer/platform/audio/pffft/fft_frame_pffft.cc +++ b/chromium/third_party/blink/renderer/platform/audio/pffft/fft_frame_pffft.cc @@ -10,6 +10,7 @@ #include "third_party/blink/renderer/platform/audio/hrtf_panner.h" #include "third_party/blink/renderer/platform/audio/vector_math.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" +#include "third_party/blink/renderer/platform/wtf/threading_primitives.h" #include "third_party/pffft/src/pffft.h" namespace blink { @@ -38,45 +39,81 @@ FFTFrame::FFTSetup::~FFTSetup() { pffft_destroy_setup(setup_); } -Vector<std::unique_ptr<FFTFrame::FFTSetup>>& FFTFrame::FFTSetups() { +HashMap<unsigned, std::unique_ptr<FFTFrame::FFTSetup>>& FFTFrame::FFTSetups() { // TODO(rtoy): Let this bake for a bit and then remove the assertions after // we're confident the first call is from the main thread. static bool first_call = true; + // A HashMap to hold all of the possible FFT setups we need. The setups are + // initialized lazily. The key is the fft size, and the value is the setup + // data. + typedef HashMap<unsigned, std::unique_ptr<FFTSetup>> FFTHashMap_t; + + DEFINE_THREAD_SAFE_STATIC_LOCAL(FFTHashMap_t, fft_setups, ()); + if (first_call) { + DEFINE_STATIC_LOCAL(Mutex, setup_lock, ()); + // Make sure we construct the fft_setups vector below on the main thread. // Once constructed, we can access it from any thread. DCHECK(IsMainThread()); first_call = false; - } - // A vector to hold all of the possible FFT setups we need. The setups are - // initialized lazily. - DEFINE_STATIC_LOCAL(Vector<std::unique_ptr<FFTSetup>>, fft_setups, - (kMaxFFTPow2Size)); + MutexLocker locker(setup_lock); + + // Initialize the hash map with all the possible keys (FFT sizes), with a + // value of nullptr because we want to initialize the setup data lazily. The + // set of valid FFT sizes for PFFFT are of the form 2^k*3^m*5*n where k >= + // 5, m >= 0, n >= 0. We only go up to a max size of 32768, because we need + // at least an FFT size of 32768 for the convolver node. + + // TODO(crbug.com/988121): Sync this with kMaxFFTPow2Size. + const int kMaxConvolverFFTSize = 32768; + + for (int n = 1; n <= kMaxConvolverFFTSize; n *= 5) { + for (int m = 1; m <= kMaxConvolverFFTSize / n; m *= 3) { + for (int k = 32; k <= kMaxConvolverFFTSize / (n * m); k *= 2) { + int size = k * m * n; + if (size <= kMaxConvolverFFTSize && !fft_setups.Contains(size)) { + fft_setups.insert(size, nullptr); + } + } + } + } + + // There should be 87 entries when we're done. + DCHECK_EQ(fft_setups.size(), 87u); + } return fft_setups; } -void FFTFrame::InitializeFFTSetupForSize(wtf_size_t log2fft_size) { +void FFTFrame::InitializeFFTSetupForSize(wtf_size_t fft_size) { auto& setup = FFTSetups(); - if (!setup[log2fft_size]) { + DCHECK(setup.Contains(fft_size)); + + if (setup.find(fft_size)->value == nullptr) { + DEFINE_STATIC_LOCAL(Mutex, setup_lock, ()); + // Make sure allocation of a new setup only occurs on the main thread so we // don't have a race condition with multiple threads trying to write to the // same element of the vector. DCHECK(IsMainThread()); - setup[log2fft_size] = std::make_unique<FFTSetup>(1 << log2fft_size); + auto fft_data = std::make_unique<FFTSetup>(fft_size); + MutexLocker locker(setup_lock); + setup.find(fft_size)->value = std::move(fft_data); } } -PFFFT_Setup* FFTFrame::FFTSetupForSize(wtf_size_t log2fft_size) { +PFFFT_Setup* FFTFrame::FFTSetupForSize(wtf_size_t fft_size) { auto& setup = FFTSetups(); - DCHECK(setup[log2fft_size]); + DCHECK(setup.Contains(fft_size)); + DCHECK(setup.find(fft_size)->value); - return setup[log2fft_size]->GetSetup(); + return setup.find(fft_size)->value->GetSetup(); } FFTFrame::FFTFrame(unsigned fft_size) @@ -86,12 +123,10 @@ FFTFrame::FFTFrame(unsigned fft_size) imag_data_(fft_size / 2), complex_data_(fft_size), pffft_work_(fft_size) { - // We only allow power of two. - DCHECK_EQ(1UL << log2fft_size_, fft_size_); // Initialize the PFFFT_Setup object here so that it will be ready when we // compute FFTs. - InitializeFFTSetupForSize(log2fft_size_); + InitializeFFTSetupForSize(fft_size); } // Creates a blank/empty frame (interpolate() must later be called). @@ -107,7 +142,7 @@ FFTFrame::FFTFrame(const FFTFrame& frame) pffft_work_(frame.fft_size_) { // Initialize the PFFFT_Setup object here wo that it will be ready when we // compute FFTs. - InitializeFFTSetupForSize(log2fft_size_); + InitializeFFTSetupForSize(fft_size_); // Copy/setup frame data. unsigned nbytes = sizeof(float) * (fft_size_ / 2); @@ -134,21 +169,19 @@ void FFTFrame::Initialize(float sample_rate) { // // TODO(rtoy): Try to come up with some way so that |Initialize()| doesn't // need to know about how the HRTF panner uses FFTs. - unsigned hrtf_order = static_cast<unsigned>( - log2(HRTFPanner::FftSizeForSampleRate(sample_rate))); + unsigned hrtf_fft_size = + static_cast<unsigned>(HRTFPanner::FftSizeForSampleRate(sample_rate)); - DCHECK_GT(hrtf_order, kMinFFTPow2Size); - DCHECK_LE(hrtf_order, kMaxFFTPow2Size); + DCHECK_GT(hrtf_fft_size, 1U << kMinFFTPow2Size); + DCHECK_LE(hrtf_fft_size, 1U << kMaxFFTPow2Size); - InitializeFFTSetupForSize(hrtf_order); - InitializeFFTSetupForSize(hrtf_order - 1); + InitializeFFTSetupForSize(hrtf_fft_size); + InitializeFFTSetupForSize(hrtf_fft_size / 2); } void FFTFrame::Cleanup() { - auto& setups = FFTSetups(); - - for (wtf_size_t k = 0; k < setups.size(); ++k) { - setups[k].reset(); + for (auto& setup : FFTSetups()) { + setup.value.reset(); } } @@ -158,7 +191,7 @@ FFTFrame::~FFTFrame() { void FFTFrame::DoFFT(const float* data) { DCHECK_EQ(pffft_work_.size(), fft_size_); - PFFFT_Setup* setup = FFTSetupForSize(log2fft_size_); + PFFFT_Setup* setup = FFTSetupForSize(fft_size_); DCHECK(setup); pffft_transform_ordered(setup, data, complex_data_.Data(), pffft_work_.Data(), @@ -195,7 +228,7 @@ void FFTFrame::DoInverseFFT(float* data) { fft_data[index + 1] = imag[k]; } - PFFFT_Setup* setup = FFTSetupForSize(log2fft_size_); + PFFFT_Setup* setup = FFTSetupForSize(fft_size_); DCHECK(setup); pffft_transform_ordered(setup, fft_data, data, pffft_work_.Data(), diff --git a/chromium/third_party/icu/README.chromium b/chromium/third_party/icu/README.chromium index 59d4d1cd403..cb96105d1aa 100644 --- a/chromium/third_party/icu/README.chromium +++ b/chromium/third_party/icu/README.chromium @@ -311,3 +311,10 @@ D. Local Modifications https://unicode-org.atlassian.net/browse/ICU-21492 - updatream PR: https://github.com/unicode-org/icu/pull/1577 + +18. Patch locale to fix assign and assing move operators: + patches/locid_operators.patch + - upstream bug: + https://unicode-org.atlassian.net/browse/ICU-21587 + - upstream PR: + https://github.com/unicode-org/icu/pull/1698 diff --git a/chromium/third_party/icu/patches/locid_operators.patch b/chromium/third_party/icu/patches/locid_operators.patch new file mode 100644 index 00000000000..74285580f50 --- /dev/null +++ b/chromium/third_party/icu/patches/locid_operators.patch @@ -0,0 +1,35 @@ +diff --git a/source/common/locid.cpp b/source/common/locid.cpp +index 0d506293..4743db53 100644 +--- a/source/common/locid.cpp ++++ b/source/common/locid.cpp +@@ -469,14 +469,18 @@ Locale& Locale::operator=(Locale&& other) U_NOEXCEPT { + if ((baseName != fullName) && (baseName != fullNameBuffer)) uprv_free(baseName); + if (fullName != fullNameBuffer) uprv_free(fullName); + +- if (other.fullName == other.fullNameBuffer) { ++ if (other.fullName == other.fullNameBuffer || other.baseName == other.fullNameBuffer) { + uprv_strcpy(fullNameBuffer, other.fullNameBuffer); ++ } ++ if (other.fullName == other.fullNameBuffer) { + fullName = fullNameBuffer; + } else { + fullName = other.fullName; + } + +- if (other.baseName == other.fullName) { ++ if (other.baseName == other.fullNameBuffer) { ++ baseName = fullNameBuffer; ++ } else if (other.baseName == other.fullName) { + baseName = fullName; + } else { + baseName = other.baseName; +@@ -2696,6 +2700,9 @@ Locale::setKeywordValue(const char* keywordName, const char* keywordValue, UErro + if (fullName != fullNameBuffer) { + // if full Name is already on the heap, need to free it. + uprv_free(fullName); ++ if (baseName == fullName) { ++ baseName = newFullName; // baseName should not point to freed memory. ++ } + } + fullName = newFullName; + status = U_ZERO_ERROR; diff --git a/chromium/third_party/icu/source/common/locid.cpp b/chromium/third_party/icu/source/common/locid.cpp index 08750f9c783..8c499bdd8b7 100644 --- a/chromium/third_party/icu/source/common/locid.cpp +++ b/chromium/third_party/icu/source/common/locid.cpp @@ -469,14 +469,18 @@ Locale& Locale::operator=(Locale&& other) U_NOEXCEPT { if (baseName != fullName) uprv_free(baseName); if (fullName != fullNameBuffer) uprv_free(fullName); - if (other.fullName == other.fullNameBuffer) { + if (other.fullName == other.fullNameBuffer || other.baseName == other.fullNameBuffer) { uprv_strcpy(fullNameBuffer, other.fullNameBuffer); + } + if (other.fullName == other.fullNameBuffer) { fullName = fullNameBuffer; } else { fullName = other.fullName; } - if (other.baseName == other.fullName) { + if (other.baseName == other.fullNameBuffer) { + baseName = fullNameBuffer; + } else if (other.baseName == other.fullName) { baseName = fullName; } else { baseName = other.baseName; @@ -2679,6 +2683,9 @@ Locale::setKeywordValue(const char* keywordName, const char* keywordValue, UErro if (fullName != fullNameBuffer) { // if full Name is already on the heap, need to free it. uprv_free(fullName); + if (baseName == fullName) { + baseName = newFullName; // baseName should not point to freed memory. + } } fullName = newFullName; status = U_ZERO_ERROR; diff --git a/chromium/third_party/sqlite/src/Makefile.in b/chromium/third_party/sqlite/src/Makefile.in index 6ab49dbe9ae..a88f7f4cfe6 100644 --- a/chromium/third_party/sqlite/src/Makefile.in +++ b/chromium/third_party/sqlite/src/Makefile.in @@ -440,6 +440,7 @@ TESTSRC += \ $(TOP)/ext/expert/sqlite3expert.c \ $(TOP)/ext/expert/test_expert.c \ $(TOP)/ext/misc/amatch.c \ + $(TOP)/ext/misc/appendvfs.c \ $(TOP)/ext/misc/carray.c \ $(TOP)/ext/misc/cksumvfs.c \ $(TOP)/ext/misc/closure.c \ @@ -1267,7 +1268,7 @@ fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuz ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db - valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA) + valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA) valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db # The veryquick.test TCL tests. @@ -1378,6 +1379,9 @@ wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo speedtest1$(TEXE): $(TOP)/test/speedtest1.c sqlite3.c $(LTLINK) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(TLIBS) +startup$(TEXE): $(TOP)/test/startup.c sqlite3.c + $(CC) -Os -g -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(TLIBS) + KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ kvtest$(TEXE): $(TOP)/test/kvtest.c sqlite3.c diff --git a/chromium/third_party/sqlite/src/Makefile.msc b/chromium/third_party/sqlite/src/Makefile.msc index 404e3b23603..545719e41b6 100644 --- a/chromium/third_party/sqlite/src/Makefile.msc +++ b/chromium/third_party/sqlite/src/Makefile.msc @@ -380,6 +380,9 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1 !ENDIF +# Always enable math functions on Windows +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MATH_FUNCTIONS + # Should the rbu extension be enabled? If so, add compilation options # to enable it. # @@ -1557,6 +1560,7 @@ TESTEXT = \ $(TOP)\ext\expert\sqlite3expert.c \ $(TOP)\ext\expert\test_expert.c \ $(TOP)\ext\misc\amatch.c \ + $(TOP)\ext\misc\appendvfs.c \ $(TOP)\ext\misc\carray.c \ $(TOP)\ext\misc\cksumvfs.c \ $(TOP)\ext\misc\closure.c \ diff --git a/chromium/third_party/sqlite/src/VERSION b/chromium/third_party/sqlite/src/VERSION index 5c0e0534177..d208ad1803a 100644 --- a/chromium/third_party/sqlite/src/VERSION +++ b/chromium/third_party/sqlite/src/VERSION @@ -1 +1 @@ -3.34.0 +3.35.5 diff --git a/chromium/third_party/sqlite/src/amalgamation/rename_exports.h b/chromium/third_party/sqlite/src/amalgamation/rename_exports.h index cd7e4ad3e79..09cab91526f 100644 --- a/chromium/third_party/sqlite/src/amalgamation/rename_exports.h +++ b/chromium/third_party/sqlite/src/amalgamation/rename_exports.h @@ -7,335 +7,336 @@ #ifndef THIRD_PARTY_SQLITE_AMALGAMATION_RENAME_EXPORTS_H_ #define THIRD_PARTY_SQLITE_AMALGAMATION_RENAME_EXPORTS_H_ -#define sqlite3_activate_cerod chrome_sqlite3_activate_cerod // Lines 5957-5959 -#define sqlite3_aggregate_context chrome_sqlite3_aggregate_context // Line 5518 -#define sqlite3_aggregate_count chrome_sqlite3_aggregate_count // Line 5293 -#define sqlite3_auto_extension chrome_sqlite3_auto_extension // Line 6707 -#define sqlite3_backup_finish chrome_sqlite3_backup_finish // Line 8739 -#define sqlite3_backup_init chrome_sqlite3_backup_init // Lines 8732-8737 -#define sqlite3_backup_pagecount chrome_sqlite3_backup_pagecount // Line 8741 -#define sqlite3_backup_remaining chrome_sqlite3_backup_remaining // Line 8740 -#define sqlite3_backup_step chrome_sqlite3_backup_step // Line 8738 -#define sqlite3_bind_blob chrome_sqlite3_bind_blob // Line 4397 -#define sqlite3_bind_blob64 chrome_sqlite3_bind_blob64 // Lines 4398-4399 -#define sqlite3_bind_double chrome_sqlite3_bind_double // Line 4400 -#define sqlite3_bind_int chrome_sqlite3_bind_int // Line 4401 -#define sqlite3_bind_int64 chrome_sqlite3_bind_int64 // Line 4402 -#define sqlite3_bind_null chrome_sqlite3_bind_null // Line 4403 -#define sqlite3_bind_parameter_count chrome_sqlite3_bind_parameter_count // Line 4432 -#define sqlite3_bind_parameter_index chrome_sqlite3_bind_parameter_index // Line 4478 -#define sqlite3_bind_parameter_name chrome_sqlite3_bind_parameter_name // Line 4460 -#define sqlite3_bind_pointer chrome_sqlite3_bind_pointer // Line 4409 -#define sqlite3_bind_text chrome_sqlite3_bind_text // Line 4404 -#define sqlite3_bind_text16 chrome_sqlite3_bind_text16 // Line 4405 -#define sqlite3_bind_text64 chrome_sqlite3_bind_text64 // Lines 4406-4407 -#define sqlite3_bind_value chrome_sqlite3_bind_value // Line 4408 -#define sqlite3_bind_zeroblob chrome_sqlite3_bind_zeroblob // Line 4410 -#define sqlite3_bind_zeroblob64 chrome_sqlite3_bind_zeroblob64 // Line 4411 -#define sqlite3_blob_bytes chrome_sqlite3_blob_bytes // Line 7285 -#define sqlite3_blob_close chrome_sqlite3_blob_close // Line 7269 -#define sqlite3_blob_open chrome_sqlite3_blob_open // Lines 7213-7221 -#define sqlite3_blob_read chrome_sqlite3_blob_read // Line 7314 -#define sqlite3_blob_reopen chrome_sqlite3_blob_reopen // Line 7246 -#define sqlite3_blob_write chrome_sqlite3_blob_write // Line 7356 -#define sqlite3_busy_handler chrome_sqlite3_busy_handler // Line 2659 -#define sqlite3_busy_timeout chrome_sqlite3_busy_timeout // Line 2682 -#define sqlite3_cancel_auto_extension chrome_sqlite3_cancel_auto_extension // Line 6719 -#define sqlite3_changes chrome_sqlite3_changes // Line 2488 -#define sqlite3_clear_bindings chrome_sqlite3_clear_bindings // Line 4488 +#define sqlite3_activate_cerod chrome_sqlite3_activate_cerod // Lines 5970-5972 +#define sqlite3_aggregate_context chrome_sqlite3_aggregate_context // Line 5531 +#define sqlite3_aggregate_count chrome_sqlite3_aggregate_count // Line 5306 +#define sqlite3_auto_extension chrome_sqlite3_auto_extension // Line 6720 +#define sqlite3_backup_finish chrome_sqlite3_backup_finish // Line 8753 +#define sqlite3_backup_init chrome_sqlite3_backup_init // Lines 8746-8751 +#define sqlite3_backup_pagecount chrome_sqlite3_backup_pagecount // Line 8755 +#define sqlite3_backup_remaining chrome_sqlite3_backup_remaining // Line 8754 +#define sqlite3_backup_step chrome_sqlite3_backup_step // Line 8752 +#define sqlite3_bind_blob chrome_sqlite3_bind_blob // Line 4410 +#define sqlite3_bind_blob64 chrome_sqlite3_bind_blob64 // Lines 4411-4412 +#define sqlite3_bind_double chrome_sqlite3_bind_double // Line 4413 +#define sqlite3_bind_int chrome_sqlite3_bind_int // Line 4414 +#define sqlite3_bind_int64 chrome_sqlite3_bind_int64 // Line 4415 +#define sqlite3_bind_null chrome_sqlite3_bind_null // Line 4416 +#define sqlite3_bind_parameter_count chrome_sqlite3_bind_parameter_count // Line 4445 +#define sqlite3_bind_parameter_index chrome_sqlite3_bind_parameter_index // Line 4491 +#define sqlite3_bind_parameter_name chrome_sqlite3_bind_parameter_name // Line 4473 +#define sqlite3_bind_pointer chrome_sqlite3_bind_pointer // Line 4422 +#define sqlite3_bind_text chrome_sqlite3_bind_text // Line 4417 +#define sqlite3_bind_text16 chrome_sqlite3_bind_text16 // Line 4418 +#define sqlite3_bind_text64 chrome_sqlite3_bind_text64 // Lines 4419-4420 +#define sqlite3_bind_value chrome_sqlite3_bind_value // Line 4421 +#define sqlite3_bind_zeroblob chrome_sqlite3_bind_zeroblob // Line 4423 +#define sqlite3_bind_zeroblob64 chrome_sqlite3_bind_zeroblob64 // Line 4424 +#define sqlite3_blob_bytes chrome_sqlite3_blob_bytes // Line 7298 +#define sqlite3_blob_close chrome_sqlite3_blob_close // Line 7282 +#define sqlite3_blob_open chrome_sqlite3_blob_open // Lines 7226-7234 +#define sqlite3_blob_read chrome_sqlite3_blob_read // Line 7327 +#define sqlite3_blob_reopen chrome_sqlite3_blob_reopen // Line 7259 +#define sqlite3_blob_write chrome_sqlite3_blob_write // Line 7369 +#define sqlite3_busy_handler chrome_sqlite3_busy_handler // Line 2671 +#define sqlite3_busy_timeout chrome_sqlite3_busy_timeout // Line 2694 +#define sqlite3_cancel_auto_extension chrome_sqlite3_cancel_auto_extension // Line 6732 +#define sqlite3_changes chrome_sqlite3_changes // Line 2500 +#define sqlite3_clear_bindings chrome_sqlite3_clear_bindings // Line 4501 #define sqlite3_close chrome_sqlite3_close // Line 330 #define sqlite3_close_v2 chrome_sqlite3_close_v2 // Line 331 -#define sqlite3_collation_needed chrome_sqlite3_collation_needed // Lines 5941-5945 -#define sqlite3_collation_needed16 chrome_sqlite3_collation_needed16 // Lines 5946-5950 -#define sqlite3_column_blob chrome_sqlite3_column_blob // Line 4964 -#define sqlite3_column_bytes chrome_sqlite3_column_bytes // Line 4971 -#define sqlite3_column_bytes16 chrome_sqlite3_column_bytes16 // Line 4972 -#define sqlite3_column_count chrome_sqlite3_column_count // Line 4504 -#define sqlite3_column_database_name chrome_sqlite3_column_database_name // Line 4578 -#define sqlite3_column_database_name16 chrome_sqlite3_column_database_name16 // Line 4579 -#define sqlite3_column_decltype chrome_sqlite3_column_decltype // Line 4615 -#define sqlite3_column_decltype16 chrome_sqlite3_column_decltype16 // Line 4616 -#define sqlite3_column_double chrome_sqlite3_column_double // Line 4965 -#define sqlite3_column_int chrome_sqlite3_column_int // Line 4966 -#define sqlite3_column_int64 chrome_sqlite3_column_int64 // Line 4967 -#define sqlite3_column_name chrome_sqlite3_column_name // Line 4533 -#define sqlite3_column_name16 chrome_sqlite3_column_name16 // Line 4534 -#define sqlite3_column_origin_name chrome_sqlite3_column_origin_name // Line 4582 -#define sqlite3_column_origin_name16 chrome_sqlite3_column_origin_name16 // Line 4583 -#define sqlite3_column_table_name chrome_sqlite3_column_table_name // Line 4580 -#define sqlite3_column_table_name16 chrome_sqlite3_column_table_name16 // Line 4581 -#define sqlite3_column_text chrome_sqlite3_column_text // Line 4968 -#define sqlite3_column_text16 chrome_sqlite3_column_text16 // Line 4969 -#define sqlite3_column_type chrome_sqlite3_column_type // Line 4973 -#define sqlite3_column_value chrome_sqlite3_column_value // Line 4970 -#define sqlite3_commit_hook chrome_sqlite3_commit_hook // Line 6304 +#define sqlite3_collation_needed chrome_sqlite3_collation_needed // Lines 5954-5958 +#define sqlite3_collation_needed16 chrome_sqlite3_collation_needed16 // Lines 5959-5963 +#define sqlite3_column_blob chrome_sqlite3_column_blob // Line 4977 +#define sqlite3_column_bytes chrome_sqlite3_column_bytes // Line 4984 +#define sqlite3_column_bytes16 chrome_sqlite3_column_bytes16 // Line 4985 +#define sqlite3_column_count chrome_sqlite3_column_count // Line 4517 +#define sqlite3_column_database_name chrome_sqlite3_column_database_name // Line 4591 +#define sqlite3_column_database_name16 chrome_sqlite3_column_database_name16 // Line 4592 +#define sqlite3_column_decltype chrome_sqlite3_column_decltype // Line 4628 +#define sqlite3_column_decltype16 chrome_sqlite3_column_decltype16 // Line 4629 +#define sqlite3_column_double chrome_sqlite3_column_double // Line 4978 +#define sqlite3_column_int chrome_sqlite3_column_int // Line 4979 +#define sqlite3_column_int64 chrome_sqlite3_column_int64 // Line 4980 +#define sqlite3_column_name chrome_sqlite3_column_name // Line 4546 +#define sqlite3_column_name16 chrome_sqlite3_column_name16 // Line 4547 +#define sqlite3_column_origin_name chrome_sqlite3_column_origin_name // Line 4595 +#define sqlite3_column_origin_name16 chrome_sqlite3_column_origin_name16 // Line 4596 +#define sqlite3_column_table_name chrome_sqlite3_column_table_name // Line 4593 +#define sqlite3_column_table_name16 chrome_sqlite3_column_table_name16 // Line 4594 +#define sqlite3_column_text chrome_sqlite3_column_text // Line 4981 +#define sqlite3_column_text16 chrome_sqlite3_column_text16 // Line 4982 +#define sqlite3_column_type chrome_sqlite3_column_type // Line 4986 +#define sqlite3_column_value chrome_sqlite3_column_value // Line 4983 +#define sqlite3_commit_hook chrome_sqlite3_commit_hook // Line 6317 #define sqlite3_compileoption_get chrome_sqlite3_compileoption_get // Line 191 #define sqlite3_compileoption_used chrome_sqlite3_compileoption_used // Line 190 -#define sqlite3_complete chrome_sqlite3_complete // Line 2597 -#define sqlite3_complete16 chrome_sqlite3_complete16 // Line 2598 +#define sqlite3_complete chrome_sqlite3_complete // Line 2609 +#define sqlite3_complete16 chrome_sqlite3_complete16 // Line 2610 #define sqlite3_config chrome_sqlite3_config // Line 1582 -#define sqlite3_context_db_handle chrome_sqlite3_context_db_handle // Line 5545 -#define sqlite3_create_collation chrome_sqlite3_create_collation // Lines 5891-5897 -#define sqlite3_create_collation16 chrome_sqlite3_create_collation16 // Lines 5906-5912 -#define sqlite3_create_collation_v2 chrome_sqlite3_create_collation_v2 // Lines 5898-5905 -#define sqlite3_create_filename chrome_sqlite3_create_filename // Lines 3706-3712 -#define sqlite3_create_function chrome_sqlite3_create_function // Lines 5155-5164 -#define sqlite3_create_function16 chrome_sqlite3_create_function16 // Lines 5165-5174 -#define sqlite3_create_function_v2 chrome_sqlite3_create_function_v2 // Lines 5175-5185 -#define sqlite3_create_module chrome_sqlite3_create_module // Lines 6999-7004 -#define sqlite3_create_module_v2 chrome_sqlite3_create_module_v2 // Lines 7005-7011 -#define sqlite3_create_window_function chrome_sqlite3_create_window_function // Lines 5186-5197 -#define sqlite3_data_count chrome_sqlite3_data_count // Line 4721 -#define sqlite3_data_directory chrome_sqlite3_data_directory // Line 6074 -#define sqlite3_database_file_object chrome_sqlite3_database_file_object // Line 3659 -#define sqlite3_db_cacheflush chrome_sqlite3_db_cacheflush // Line 9437 +#define sqlite3_context_db_handle chrome_sqlite3_context_db_handle // Line 5558 +#define sqlite3_create_collation chrome_sqlite3_create_collation // Lines 5904-5910 +#define sqlite3_create_collation16 chrome_sqlite3_create_collation16 // Lines 5919-5925 +#define sqlite3_create_collation_v2 chrome_sqlite3_create_collation_v2 // Lines 5911-5918 +#define sqlite3_create_filename chrome_sqlite3_create_filename // Lines 3719-3725 +#define sqlite3_create_function chrome_sqlite3_create_function // Lines 5168-5177 +#define sqlite3_create_function16 chrome_sqlite3_create_function16 // Lines 5178-5187 +#define sqlite3_create_function_v2 chrome_sqlite3_create_function_v2 // Lines 5188-5198 +#define sqlite3_create_module chrome_sqlite3_create_module // Lines 7012-7017 +#define sqlite3_create_module_v2 chrome_sqlite3_create_module_v2 // Lines 7018-7024 +#define sqlite3_create_window_function chrome_sqlite3_create_window_function // Lines 5199-5210 +#define sqlite3_data_count chrome_sqlite3_data_count // Line 4734 +#define sqlite3_data_directory chrome_sqlite3_data_directory // Line 6087 +#define sqlite3_database_file_object chrome_sqlite3_database_file_object // Line 3672 +#define sqlite3_db_cacheflush chrome_sqlite3_db_cacheflush // Line 9451 #define sqlite3_db_config chrome_sqlite3_db_config // Line 1601 -#define sqlite3_db_filename chrome_sqlite3_db_filename // Line 6178 -#define sqlite3_db_handle chrome_sqlite3_db_handle // Line 6146 -#define sqlite3_db_mutex chrome_sqlite3_db_mutex // Line 7664 -#define sqlite3_db_readonly chrome_sqlite3_db_readonly // Line 6188 -#define sqlite3_db_release_memory chrome_sqlite3_db_release_memory // Line 6431 -#define sqlite3_db_status chrome_sqlite3_db_status // Line 8089 -#define sqlite3_declare_vtab chrome_sqlite3_declare_vtab // Line 7085 -#define sqlite3_deserialize chrome_sqlite3_deserialize // Lines 9833-9840 -#define sqlite3_drop_modules chrome_sqlite3_drop_modules // Lines 7025-7028 -#define sqlite3_enable_load_extension chrome_sqlite3_enable_load_extension // Line 6669 -#define sqlite3_enable_shared_cache chrome_sqlite3_enable_shared_cache // Line 6401 -#define sqlite3_errcode chrome_sqlite3_errcode // Line 3767 -#define sqlite3_errmsg chrome_sqlite3_errmsg // Line 3769 -#define sqlite3_errmsg16 chrome_sqlite3_errmsg16 // Line 3770 -#define sqlite3_errstr chrome_sqlite3_errstr // Line 3771 +#define sqlite3_db_filename chrome_sqlite3_db_filename // Line 6191 +#define sqlite3_db_handle chrome_sqlite3_db_handle // Line 6159 +#define sqlite3_db_mutex chrome_sqlite3_db_mutex // Line 7677 +#define sqlite3_db_readonly chrome_sqlite3_db_readonly // Line 6201 +#define sqlite3_db_release_memory chrome_sqlite3_db_release_memory // Line 6444 +#define sqlite3_db_status chrome_sqlite3_db_status // Line 8103 +#define sqlite3_declare_vtab chrome_sqlite3_declare_vtab // Line 7098 +#define sqlite3_deserialize chrome_sqlite3_deserialize // Lines 9847-9854 +#define sqlite3_drop_modules chrome_sqlite3_drop_modules // Lines 7038-7041 +#define sqlite3_enable_load_extension chrome_sqlite3_enable_load_extension // Line 6682 +#define sqlite3_enable_shared_cache chrome_sqlite3_enable_shared_cache // Line 6414 +#define sqlite3_errcode chrome_sqlite3_errcode // Line 3780 +#define sqlite3_errmsg chrome_sqlite3_errmsg // Line 3782 +#define sqlite3_errmsg16 chrome_sqlite3_errmsg16 // Line 3783 +#define sqlite3_errstr chrome_sqlite3_errstr // Line 3784 #define sqlite3_exec chrome_sqlite3_exec // Lines 402-408 -#define sqlite3_expanded_sql chrome_sqlite3_expanded_sql // Line 4133 -#define sqlite3_expired chrome_sqlite3_expired // Line 5294 -#define sqlite3_extended_errcode chrome_sqlite3_extended_errcode // Line 3768 -#define sqlite3_extended_result_codes chrome_sqlite3_extended_result_codes // Line 2358 -#define sqlite3_file_control chrome_sqlite3_file_control // Line 7707 -#define sqlite3_filename_database chrome_sqlite3_filename_database // Line 3638 -#define sqlite3_filename_journal chrome_sqlite3_filename_journal // Line 3639 -#define sqlite3_filename_wal chrome_sqlite3_filename_wal // Line 3640 -#define sqlite3_finalize chrome_sqlite3_finalize // Line 5001 -#define sqlite3_free chrome_sqlite3_free // Line 2891 -#define sqlite3_free_filename chrome_sqlite3_free_filename // Line 3713 -#define sqlite3_free_table chrome_sqlite3_free_table // Line 2765 -#define sqlite3_get_autocommit chrome_sqlite3_get_autocommit // Line 6133 -#define sqlite3_get_auxdata chrome_sqlite3_get_auxdata // Line 5604 -#define sqlite3_get_table chrome_sqlite3_get_table // Lines 2757-2764 -#define sqlite3_global_recover chrome_sqlite3_global_recover // Line 5296 -#define sqlite3_hard_heap_limit64 chrome_sqlite3_hard_heap_limit64 // Line 6498 +#define sqlite3_expanded_sql chrome_sqlite3_expanded_sql // Line 4146 +#define sqlite3_expired chrome_sqlite3_expired // Line 5307 +#define sqlite3_extended_errcode chrome_sqlite3_extended_errcode // Line 3781 +#define sqlite3_extended_result_codes chrome_sqlite3_extended_result_codes // Line 2370 +#define sqlite3_file_control chrome_sqlite3_file_control // Line 7720 +#define sqlite3_filename_database chrome_sqlite3_filename_database // Line 3651 +#define sqlite3_filename_journal chrome_sqlite3_filename_journal // Line 3652 +#define sqlite3_filename_wal chrome_sqlite3_filename_wal // Line 3653 +#define sqlite3_finalize chrome_sqlite3_finalize // Line 5014 +#define sqlite3_free chrome_sqlite3_free // Line 2903 +#define sqlite3_free_filename chrome_sqlite3_free_filename // Line 3726 +#define sqlite3_free_table chrome_sqlite3_free_table // Line 2777 +#define sqlite3_get_autocommit chrome_sqlite3_get_autocommit // Line 6146 +#define sqlite3_get_auxdata chrome_sqlite3_get_auxdata // Line 5617 +#define sqlite3_get_table chrome_sqlite3_get_table // Lines 2769-2776 +#define sqlite3_global_recover chrome_sqlite3_global_recover // Line 5309 +#define sqlite3_hard_heap_limit64 chrome_sqlite3_hard_heap_limit64 // Line 6511 #define sqlite3_initialize chrome_sqlite3_initialize // Line 1546 -#define sqlite3_interrupt chrome_sqlite3_interrupt // Line 2562 -#define sqlite3_keyword_check chrome_sqlite3_keyword_check // Line 7819 -#define sqlite3_keyword_count chrome_sqlite3_keyword_count // Line 7817 -#define sqlite3_keyword_name chrome_sqlite3_keyword_name // Line 7818 -#define sqlite3_last_insert_rowid chrome_sqlite3_last_insert_rowid // Line 2420 +#define sqlite3_interrupt chrome_sqlite3_interrupt // Line 2574 +#define sqlite3_keyword_check chrome_sqlite3_keyword_check // Line 7833 +#define sqlite3_keyword_count chrome_sqlite3_keyword_count // Line 7831 +#define sqlite3_keyword_name chrome_sqlite3_keyword_name // Line 7832 +#define sqlite3_last_insert_rowid chrome_sqlite3_last_insert_rowid // Line 2432 #define sqlite3_libversion chrome_sqlite3_libversion // Line 163 #define sqlite3_libversion_number chrome_sqlite3_libversion_number // Line 165 -#define sqlite3_limit chrome_sqlite3_limit // Line 3839 -#define sqlite3_load_extension chrome_sqlite3_load_extension // Lines 6637-6642 -#define sqlite3_log chrome_sqlite3_log // Line 8937 -#define sqlite3_malloc chrome_sqlite3_malloc // Line 2887 -#define sqlite3_malloc64 chrome_sqlite3_malloc64 // Line 2888 -#define sqlite3_memory_alarm chrome_sqlite3_memory_alarm // Lines 5298-5299 -#define sqlite3_memory_highwater chrome_sqlite3_memory_highwater // Line 2918 -#define sqlite3_memory_used chrome_sqlite3_memory_used // Line 2917 -#define sqlite3_mprintf chrome_sqlite3_mprintf // Line 2807 -#define sqlite3_msize chrome_sqlite3_msize // Line 2892 -#define sqlite3_mutex_alloc chrome_sqlite3_mutex_alloc // Line 7505 -#define sqlite3_mutex_enter chrome_sqlite3_mutex_enter // Line 7507 -#define sqlite3_mutex_free chrome_sqlite3_mutex_free // Line 7506 -#define sqlite3_mutex_held chrome_sqlite3_mutex_held // Line 7619 -#define sqlite3_mutex_leave chrome_sqlite3_mutex_leave // Line 7509 -#define sqlite3_mutex_notheld chrome_sqlite3_mutex_notheld // Line 7620 -#define sqlite3_mutex_try chrome_sqlite3_mutex_try // Line 7508 -#define sqlite3_next_stmt chrome_sqlite3_next_stmt // Line 6255 -#define sqlite3_normalized_sql chrome_sqlite3_normalized_sql // Line 4134 -#define sqlite3_open chrome_sqlite3_open // Lines 3525-3528 -#define sqlite3_open16 chrome_sqlite3_open16 // Lines 3529-3532 -#define sqlite3_open_v2 chrome_sqlite3_open_v2 // Lines 3533-3538 +#define sqlite3_limit chrome_sqlite3_limit // Line 3852 +#define sqlite3_load_extension chrome_sqlite3_load_extension // Lines 6650-6655 +#define sqlite3_log chrome_sqlite3_log // Line 8951 +#define sqlite3_malloc chrome_sqlite3_malloc // Line 2899 +#define sqlite3_malloc64 chrome_sqlite3_malloc64 // Line 2900 +#define sqlite3_memory_alarm chrome_sqlite3_memory_alarm // Lines 5311-5312 +#define sqlite3_memory_highwater chrome_sqlite3_memory_highwater // Line 2930 +#define sqlite3_memory_used chrome_sqlite3_memory_used // Line 2929 +#define sqlite3_mprintf chrome_sqlite3_mprintf // Line 2819 +#define sqlite3_msize chrome_sqlite3_msize // Line 2904 +#define sqlite3_mutex_alloc chrome_sqlite3_mutex_alloc // Line 7518 +#define sqlite3_mutex_enter chrome_sqlite3_mutex_enter // Line 7520 +#define sqlite3_mutex_free chrome_sqlite3_mutex_free // Line 7519 +#define sqlite3_mutex_held chrome_sqlite3_mutex_held // Line 7632 +#define sqlite3_mutex_leave chrome_sqlite3_mutex_leave // Line 7522 +#define sqlite3_mutex_notheld chrome_sqlite3_mutex_notheld // Line 7633 +#define sqlite3_mutex_try chrome_sqlite3_mutex_try // Line 7521 +#define sqlite3_next_stmt chrome_sqlite3_next_stmt // Line 6268 +#define sqlite3_normalized_sql chrome_sqlite3_normalized_sql // Line 4147 +#define sqlite3_open chrome_sqlite3_open // Lines 3538-3541 +#define sqlite3_open16 chrome_sqlite3_open16 // Lines 3542-3545 +#define sqlite3_open_v2 chrome_sqlite3_open_v2 // Lines 3546-3551 #define sqlite3_os_end chrome_sqlite3_os_end // Line 1549 #define sqlite3_os_init chrome_sqlite3_os_init // Line 1548 -#define sqlite3_overload_function chrome_sqlite3_overload_function // Line 7104 -#define sqlite3_prepare chrome_sqlite3_prepare // Lines 4049-4055 -#define sqlite3_prepare16 chrome_sqlite3_prepare16 // Lines 4071-4077 -#define sqlite3_prepare16_v2 chrome_sqlite3_prepare16_v2 // Lines 4078-4084 -#define sqlite3_prepare16_v3 chrome_sqlite3_prepare16_v3 // Lines 4085-4092 -#define sqlite3_prepare_v2 chrome_sqlite3_prepare_v2 // Lines 4056-4062 -#define sqlite3_prepare_v3 chrome_sqlite3_prepare_v3 // Lines 4063-4070 -#define sqlite3_preupdate_count chrome_sqlite3_preupdate_count // Line 9537 -#define sqlite3_preupdate_depth chrome_sqlite3_preupdate_depth // Line 9538 -#define sqlite3_preupdate_hook chrome_sqlite3_preupdate_hook // Lines 9523-9535 -#define sqlite3_preupdate_new chrome_sqlite3_preupdate_new // Line 9539 -#define sqlite3_preupdate_old chrome_sqlite3_preupdate_old // Line 9536 -#define sqlite3_profile chrome_sqlite3_profile // Lines 3142-3143 -#define sqlite3_progress_handler chrome_sqlite3_progress_handler // Line 3270 -#define sqlite3_randomness chrome_sqlite3_randomness // Line 2941 -#define sqlite3_realloc chrome_sqlite3_realloc // Line 2889 -#define sqlite3_realloc64 chrome_sqlite3_realloc64 // Line 2890 -#define sqlite3_release_memory chrome_sqlite3_release_memory // Line 6417 -#define sqlite3_reset chrome_sqlite3_reset // Line 5028 -#define sqlite3_reset_auto_extension chrome_sqlite3_reset_auto_extension // Line 6727 -#define sqlite3_result_blob chrome_sqlite3_result_blob // Line 5772 -#define sqlite3_result_blob64 chrome_sqlite3_result_blob64 // Lines 5773-5774 -#define sqlite3_result_double chrome_sqlite3_result_double // Line 5775 -#define sqlite3_result_error chrome_sqlite3_result_error // Line 5776 -#define sqlite3_result_error16 chrome_sqlite3_result_error16 // Line 5777 -#define sqlite3_result_error_code chrome_sqlite3_result_error_code // Line 5780 -#define sqlite3_result_error_nomem chrome_sqlite3_result_error_nomem // Line 5779 -#define sqlite3_result_error_toobig chrome_sqlite3_result_error_toobig // Line 5778 -#define sqlite3_result_int chrome_sqlite3_result_int // Line 5781 -#define sqlite3_result_int64 chrome_sqlite3_result_int64 // Line 5782 -#define sqlite3_result_null chrome_sqlite3_result_null // Line 5783 -#define sqlite3_result_pointer chrome_sqlite3_result_pointer // Line 5791 -#define sqlite3_result_subtype chrome_sqlite3_result_subtype // Line 5808 -#define sqlite3_result_text chrome_sqlite3_result_text // Line 5784 -#define sqlite3_result_text16 chrome_sqlite3_result_text16 // Line 5787 -#define sqlite3_result_text16be chrome_sqlite3_result_text16be // Line 5789 -#define sqlite3_result_text16le chrome_sqlite3_result_text16le // Line 5788 -#define sqlite3_result_text64 chrome_sqlite3_result_text64 // Lines 5785-5786 -#define sqlite3_result_value chrome_sqlite3_result_value // Line 5790 -#define sqlite3_result_zeroblob chrome_sqlite3_result_zeroblob // Line 5792 -#define sqlite3_result_zeroblob64 chrome_sqlite3_result_zeroblob64 // Line 5793 -#define sqlite3_rollback_hook chrome_sqlite3_rollback_hook // Line 6305 -#define sqlite3_rtree_geometry_callback chrome_sqlite3_rtree_geometry_callback // Lines 9920-9925 -#define sqlite3_rtree_query_callback chrome_sqlite3_rtree_query_callback // Lines 9946-9952 -#define sqlite3_serialize chrome_sqlite3_serialize // Lines 9781-9786 -#define sqlite3_set_authorizer chrome_sqlite3_set_authorizer // Lines 3032-3036 -#define sqlite3_set_auxdata chrome_sqlite3_set_auxdata // Line 5605 -#define sqlite3_set_last_insert_rowid chrome_sqlite3_set_last_insert_rowid // Line 2430 +#define sqlite3_overload_function chrome_sqlite3_overload_function // Line 7117 +#define sqlite3_prepare chrome_sqlite3_prepare // Lines 4062-4068 +#define sqlite3_prepare16 chrome_sqlite3_prepare16 // Lines 4084-4090 +#define sqlite3_prepare16_v2 chrome_sqlite3_prepare16_v2 // Lines 4091-4097 +#define sqlite3_prepare16_v3 chrome_sqlite3_prepare16_v3 // Lines 4098-4105 +#define sqlite3_prepare_v2 chrome_sqlite3_prepare_v2 // Lines 4069-4075 +#define sqlite3_prepare_v3 chrome_sqlite3_prepare_v3 // Lines 4076-4083 +#define sqlite3_preupdate_count chrome_sqlite3_preupdate_count // Line 9551 +#define sqlite3_preupdate_depth chrome_sqlite3_preupdate_depth // Line 9552 +#define sqlite3_preupdate_hook chrome_sqlite3_preupdate_hook // Lines 9537-9549 +#define sqlite3_preupdate_new chrome_sqlite3_preupdate_new // Line 9553 +#define sqlite3_preupdate_old chrome_sqlite3_preupdate_old // Line 9550 +#define sqlite3_profile chrome_sqlite3_profile // Lines 3154-3155 +#define sqlite3_progress_handler chrome_sqlite3_progress_handler // Line 3282 +#define sqlite3_randomness chrome_sqlite3_randomness // Line 2953 +#define sqlite3_realloc chrome_sqlite3_realloc // Line 2901 +#define sqlite3_realloc64 chrome_sqlite3_realloc64 // Line 2902 +#define sqlite3_release_memory chrome_sqlite3_release_memory // Line 6430 +#define sqlite3_reset chrome_sqlite3_reset // Line 5041 +#define sqlite3_reset_auto_extension chrome_sqlite3_reset_auto_extension // Line 6740 +#define sqlite3_result_blob chrome_sqlite3_result_blob // Line 5785 +#define sqlite3_result_blob64 chrome_sqlite3_result_blob64 // Lines 5786-5787 +#define sqlite3_result_double chrome_sqlite3_result_double // Line 5788 +#define sqlite3_result_error chrome_sqlite3_result_error // Line 5789 +#define sqlite3_result_error16 chrome_sqlite3_result_error16 // Line 5790 +#define sqlite3_result_error_code chrome_sqlite3_result_error_code // Line 5793 +#define sqlite3_result_error_nomem chrome_sqlite3_result_error_nomem // Line 5792 +#define sqlite3_result_error_toobig chrome_sqlite3_result_error_toobig // Line 5791 +#define sqlite3_result_int chrome_sqlite3_result_int // Line 5794 +#define sqlite3_result_int64 chrome_sqlite3_result_int64 // Line 5795 +#define sqlite3_result_null chrome_sqlite3_result_null // Line 5796 +#define sqlite3_result_pointer chrome_sqlite3_result_pointer // Line 5804 +#define sqlite3_result_subtype chrome_sqlite3_result_subtype // Line 5821 +#define sqlite3_result_text chrome_sqlite3_result_text // Line 5797 +#define sqlite3_result_text16 chrome_sqlite3_result_text16 // Line 5800 +#define sqlite3_result_text16be chrome_sqlite3_result_text16be // Line 5802 +#define sqlite3_result_text16le chrome_sqlite3_result_text16le // Line 5801 +#define sqlite3_result_text64 chrome_sqlite3_result_text64 // Lines 5798-5799 +#define sqlite3_result_value chrome_sqlite3_result_value // Line 5803 +#define sqlite3_result_zeroblob chrome_sqlite3_result_zeroblob // Line 5805 +#define sqlite3_result_zeroblob64 chrome_sqlite3_result_zeroblob64 // Line 5806 +#define sqlite3_rollback_hook chrome_sqlite3_rollback_hook // Line 6318 +#define sqlite3_rtree_geometry_callback chrome_sqlite3_rtree_geometry_callback // Lines 9934-9939 +#define sqlite3_rtree_query_callback chrome_sqlite3_rtree_query_callback // Lines 9960-9966 +#define sqlite3_serialize chrome_sqlite3_serialize // Lines 9795-9800 +#define sqlite3_set_authorizer chrome_sqlite3_set_authorizer // Lines 3044-3048 +#define sqlite3_set_auxdata chrome_sqlite3_set_auxdata // Line 5618 +#define sqlite3_set_last_insert_rowid chrome_sqlite3_set_last_insert_rowid // Line 2442 #define sqlite3_shutdown chrome_sqlite3_shutdown // Line 1547 -#define sqlite3_sleep chrome_sqlite3_sleep // Line 5979 -#define sqlite3_snapshot_cmp chrome_sqlite3_snapshot_cmp // Lines 9715-9718 -#define sqlite3_snapshot_free chrome_sqlite3_snapshot_free // Line 9688 -#define sqlite3_snapshot_get chrome_sqlite3_snapshot_get // Lines 9622-9626 -#define sqlite3_snapshot_open chrome_sqlite3_snapshot_open // Lines 9671-9675 -#define sqlite3_snapshot_recover chrome_sqlite3_snapshot_recover // Line 9743 -#define sqlite3_snprintf chrome_sqlite3_snprintf // Line 2809 -#define sqlite3_soft_heap_limit chrome_sqlite3_soft_heap_limit // Line 6509 -#define sqlite3_soft_heap_limit64 chrome_sqlite3_soft_heap_limit64 // Line 6497 +#define sqlite3_sleep chrome_sqlite3_sleep // Line 5992 +#define sqlite3_snapshot_cmp chrome_sqlite3_snapshot_cmp // Lines 9729-9732 +#define sqlite3_snapshot_free chrome_sqlite3_snapshot_free // Line 9702 +#define sqlite3_snapshot_get chrome_sqlite3_snapshot_get // Lines 9636-9640 +#define sqlite3_snapshot_open chrome_sqlite3_snapshot_open // Lines 9685-9689 +#define sqlite3_snapshot_recover chrome_sqlite3_snapshot_recover // Line 9757 +#define sqlite3_snprintf chrome_sqlite3_snprintf // Line 2821 +#define sqlite3_soft_heap_limit chrome_sqlite3_soft_heap_limit // Line 6522 +#define sqlite3_soft_heap_limit64 chrome_sqlite3_soft_heap_limit64 // Line 6510 #define sqlite3_sourceid chrome_sqlite3_sourceid // Line 164 -#define sqlite3_sql chrome_sqlite3_sql // Line 4132 -#define sqlite3_status chrome_sqlite3_status // Line 7979 -#define sqlite3_status64 chrome_sqlite3_status64 // Lines 7980-7985 -#define sqlite3_step chrome_sqlite3_step // Line 4700 -#define sqlite3_stmt_busy chrome_sqlite3_stmt_busy // Line 4203 -#define sqlite3_stmt_isexplain chrome_sqlite3_stmt_isexplain // Line 4182 -#define sqlite3_stmt_readonly chrome_sqlite3_stmt_readonly // Line 4170 -#define sqlite3_stmt_scanstatus chrome_sqlite3_stmt_scanstatus // Lines 9388-9393 -#define sqlite3_stmt_scanstatus_reset chrome_sqlite3_stmt_scanstatus_reset // Line 9404 -#define sqlite3_stmt_status chrome_sqlite3_stmt_status // Line 8242 -#define sqlite3_str_append chrome_sqlite3_str_append // Line 7915 -#define sqlite3_str_appendall chrome_sqlite3_str_appendall // Line 7916 -#define sqlite3_str_appendchar chrome_sqlite3_str_appendchar // Line 7917 -#define sqlite3_str_appendf chrome_sqlite3_str_appendf // Line 7913 -#define sqlite3_str_errcode chrome_sqlite3_str_errcode // Line 7949 -#define sqlite3_str_finish chrome_sqlite3_str_finish // Line 7879 -#define sqlite3_str_length chrome_sqlite3_str_length // Line 7950 -#define sqlite3_str_new chrome_sqlite3_str_new // Line 7864 -#define sqlite3_str_reset chrome_sqlite3_str_reset // Line 7918 -#define sqlite3_str_value chrome_sqlite3_str_value // Line 7951 -#define sqlite3_str_vappendf chrome_sqlite3_str_vappendf // Line 7914 -#define sqlite3_strglob chrome_sqlite3_strglob // Line 8891 -#define sqlite3_stricmp chrome_sqlite3_stricmp // Line 8873 -#define sqlite3_strlike chrome_sqlite3_strlike // Line 8914 -#define sqlite3_strnicmp chrome_sqlite3_strnicmp // Line 8874 -#define sqlite3_system_errno chrome_sqlite3_system_errno // Line 9553 -#define sqlite3_table_column_metadata chrome_sqlite3_table_column_metadata // Lines 6581-6591 -#define sqlite3_temp_directory chrome_sqlite3_temp_directory // Line 6037 -#define sqlite3_test_control chrome_sqlite3_test_control // Line 7726 -#define sqlite3_thread_cleanup chrome_sqlite3_thread_cleanup // Line 5297 +#define sqlite3_sql chrome_sqlite3_sql // Line 4145 +#define sqlite3_status chrome_sqlite3_status // Line 7993 +#define sqlite3_status64 chrome_sqlite3_status64 // Lines 7994-7999 +#define sqlite3_step chrome_sqlite3_step // Line 4713 +#define sqlite3_stmt_busy chrome_sqlite3_stmt_busy // Line 4216 +#define sqlite3_stmt_isexplain chrome_sqlite3_stmt_isexplain // Line 4195 +#define sqlite3_stmt_readonly chrome_sqlite3_stmt_readonly // Line 4183 +#define sqlite3_stmt_scanstatus chrome_sqlite3_stmt_scanstatus // Lines 9402-9407 +#define sqlite3_stmt_scanstatus_reset chrome_sqlite3_stmt_scanstatus_reset // Line 9418 +#define sqlite3_stmt_status chrome_sqlite3_stmt_status // Line 8256 +#define sqlite3_str_append chrome_sqlite3_str_append // Line 7929 +#define sqlite3_str_appendall chrome_sqlite3_str_appendall // Line 7930 +#define sqlite3_str_appendchar chrome_sqlite3_str_appendchar // Line 7931 +#define sqlite3_str_appendf chrome_sqlite3_str_appendf // Line 7927 +#define sqlite3_str_errcode chrome_sqlite3_str_errcode // Line 7963 +#define sqlite3_str_finish chrome_sqlite3_str_finish // Line 7893 +#define sqlite3_str_length chrome_sqlite3_str_length // Line 7964 +#define sqlite3_str_new chrome_sqlite3_str_new // Line 7878 +#define sqlite3_str_reset chrome_sqlite3_str_reset // Line 7932 +#define sqlite3_str_value chrome_sqlite3_str_value // Line 7965 +#define sqlite3_str_vappendf chrome_sqlite3_str_vappendf // Line 7928 +#define sqlite3_strglob chrome_sqlite3_strglob // Line 8905 +#define sqlite3_stricmp chrome_sqlite3_stricmp // Line 8887 +#define sqlite3_strlike chrome_sqlite3_strlike // Line 8928 +#define sqlite3_strnicmp chrome_sqlite3_strnicmp // Line 8888 +#define sqlite3_system_errno chrome_sqlite3_system_errno // Line 9567 +#define sqlite3_table_column_metadata chrome_sqlite3_table_column_metadata // Lines 6594-6604 +#define sqlite3_temp_directory chrome_sqlite3_temp_directory // Line 6050 +#define sqlite3_test_control chrome_sqlite3_test_control // Line 7739 +#define sqlite3_thread_cleanup chrome_sqlite3_thread_cleanup // Line 5310 #define sqlite3_threadsafe chrome_sqlite3_threadsafe // Line 233 -#define sqlite3_total_changes chrome_sqlite3_total_changes // Line 2525 -#define sqlite3_trace chrome_sqlite3_trace // Lines 3140-3141 -#define sqlite3_trace_v2 chrome_sqlite3_trace_v2 // Lines 3231-3236 -#define sqlite3_transfer_bindings chrome_sqlite3_transfer_bindings // Line 5295 -#define sqlite3_txn_state chrome_sqlite3_txn_state // Line 6206 -#define sqlite3_unlock_notify chrome_sqlite3_unlock_notify // Lines 8858-8862 -#define sqlite3_update_hook chrome_sqlite3_update_hook // Lines 6356-6360 -#define sqlite3_uri_boolean chrome_sqlite3_uri_boolean // Line 3607 -#define sqlite3_uri_int64 chrome_sqlite3_uri_int64 // Line 3608 -#define sqlite3_uri_key chrome_sqlite3_uri_key // Line 3609 -#define sqlite3_uri_parameter chrome_sqlite3_uri_parameter // Line 3606 -#define sqlite3_user_data chrome_sqlite3_user_data // Line 5533 -#define sqlite3_value_blob chrome_sqlite3_value_blob // Line 5430 -#define sqlite3_value_bytes chrome_sqlite3_value_bytes // Line 5439 -#define sqlite3_value_bytes16 chrome_sqlite3_value_bytes16 // Line 5440 -#define sqlite3_value_double chrome_sqlite3_value_double // Line 5431 -#define sqlite3_value_dup chrome_sqlite3_value_dup // Line 5472 -#define sqlite3_value_free chrome_sqlite3_value_free // Line 5473 -#define sqlite3_value_frombind chrome_sqlite3_value_frombind // Line 5444 -#define sqlite3_value_int chrome_sqlite3_value_int // Line 5432 -#define sqlite3_value_int64 chrome_sqlite3_value_int64 // Line 5433 -#define sqlite3_value_nochange chrome_sqlite3_value_nochange // Line 5443 -#define sqlite3_value_numeric_type chrome_sqlite3_value_numeric_type // Line 5442 -#define sqlite3_value_pointer chrome_sqlite3_value_pointer // Line 5434 -#define sqlite3_value_subtype chrome_sqlite3_value_subtype // Line 5456 -#define sqlite3_value_text chrome_sqlite3_value_text // Line 5435 -#define sqlite3_value_text16 chrome_sqlite3_value_text16 // Line 5436 -#define sqlite3_value_text16be chrome_sqlite3_value_text16be // Line 5438 -#define sqlite3_value_text16le chrome_sqlite3_value_text16le // Line 5437 -#define sqlite3_value_type chrome_sqlite3_value_type // Line 5441 +#define sqlite3_total_changes chrome_sqlite3_total_changes // Line 2537 +#define sqlite3_trace chrome_sqlite3_trace // Lines 3152-3153 +#define sqlite3_trace_v2 chrome_sqlite3_trace_v2 // Lines 3243-3248 +#define sqlite3_transfer_bindings chrome_sqlite3_transfer_bindings // Line 5308 +#define sqlite3_txn_state chrome_sqlite3_txn_state // Line 6219 +#define sqlite3_unlock_notify chrome_sqlite3_unlock_notify // Lines 8872-8876 +#define sqlite3_update_hook chrome_sqlite3_update_hook // Lines 6369-6373 +#define sqlite3_uri_boolean chrome_sqlite3_uri_boolean // Line 3620 +#define sqlite3_uri_int64 chrome_sqlite3_uri_int64 // Line 3621 +#define sqlite3_uri_key chrome_sqlite3_uri_key // Line 3622 +#define sqlite3_uri_parameter chrome_sqlite3_uri_parameter // Line 3619 +#define sqlite3_user_data chrome_sqlite3_user_data // Line 5546 +#define sqlite3_value_blob chrome_sqlite3_value_blob // Line 5443 +#define sqlite3_value_bytes chrome_sqlite3_value_bytes // Line 5452 +#define sqlite3_value_bytes16 chrome_sqlite3_value_bytes16 // Line 5453 +#define sqlite3_value_double chrome_sqlite3_value_double // Line 5444 +#define sqlite3_value_dup chrome_sqlite3_value_dup // Line 5485 +#define sqlite3_value_free chrome_sqlite3_value_free // Line 5486 +#define sqlite3_value_frombind chrome_sqlite3_value_frombind // Line 5457 +#define sqlite3_value_int chrome_sqlite3_value_int // Line 5445 +#define sqlite3_value_int64 chrome_sqlite3_value_int64 // Line 5446 +#define sqlite3_value_nochange chrome_sqlite3_value_nochange // Line 5456 +#define sqlite3_value_numeric_type chrome_sqlite3_value_numeric_type // Line 5455 +#define sqlite3_value_pointer chrome_sqlite3_value_pointer // Line 5447 +#define sqlite3_value_subtype chrome_sqlite3_value_subtype // Line 5469 +#define sqlite3_value_text chrome_sqlite3_value_text // Line 5448 +#define sqlite3_value_text16 chrome_sqlite3_value_text16 // Line 5449 +#define sqlite3_value_text16be chrome_sqlite3_value_text16be // Line 5451 +#define sqlite3_value_text16le chrome_sqlite3_value_text16le // Line 5450 +#define sqlite3_value_type chrome_sqlite3_value_type // Line 5454 #define sqlite3_version chrome_sqlite3_version // Line 162 -#define sqlite3_vfs_find chrome_sqlite3_vfs_find // Line 7387 -#define sqlite3_vfs_register chrome_sqlite3_vfs_register // Line 7388 -#define sqlite3_vfs_unregister chrome_sqlite3_vfs_unregister // Line 7389 -#define sqlite3_vmprintf chrome_sqlite3_vmprintf // Line 2808 -#define sqlite3_vsnprintf chrome_sqlite3_vsnprintf // Line 2810 -#define sqlite3_vtab_collation chrome_sqlite3_vtab_collation // Line 9283 -#define sqlite3_vtab_config chrome_sqlite3_vtab_config // Line 9164 -#define sqlite3_vtab_nochange chrome_sqlite3_vtab_nochange // Line 9268 -#define sqlite3_vtab_on_conflict chrome_sqlite3_vtab_on_conflict // Line 9242 -#define sqlite3_wal_autocheckpoint chrome_sqlite3_wal_autocheckpoint // Line 9008 -#define sqlite3_wal_checkpoint chrome_sqlite3_wal_checkpoint // Line 9030 -#define sqlite3_wal_checkpoint_v2 chrome_sqlite3_wal_checkpoint_v2 // Lines 9124-9130 -#define sqlite3_wal_hook chrome_sqlite3_wal_hook // Lines 8973-8977 -#define sqlite3_win32_set_directory chrome_sqlite3_win32_set_directory // Lines 6095-6098 -#define sqlite3_win32_set_directory16 chrome_sqlite3_win32_set_directory16 // Line 6100 -#define sqlite3_win32_set_directory8 chrome_sqlite3_win32_set_directory8 // Line 6099 -#define sqlite3changegroup_add chrome_sqlite3changegroup_add // Line 10933 -#define sqlite3changegroup_add_strm chrome_sqlite3changegroup_add_strm // Lines 11595-11598 -#define sqlite3changegroup_delete chrome_sqlite3changegroup_delete // Line 10970 -#define sqlite3changegroup_new chrome_sqlite3changegroup_new // Line 10855 -#define sqlite3changegroup_output chrome_sqlite3changegroup_output // Lines 10960-10964 -#define sqlite3changegroup_output_strm chrome_sqlite3changegroup_output_strm // Lines 11599-11602 -#define sqlite3changeset_apply chrome_sqlite3changeset_apply // Lines 11130-11144 -#define sqlite3changeset_apply_strm chrome_sqlite3changeset_apply_strm // Lines 11528-11542 -#define sqlite3changeset_apply_v2 chrome_sqlite3changeset_apply_v2 // Lines 11145-11161 -#define sqlite3changeset_apply_v2_strm chrome_sqlite3changeset_apply_v2_strm // Lines 11543-11559 -#define sqlite3changeset_concat chrome_sqlite3changeset_concat // Lines 10801-10808 -#define sqlite3changeset_concat_strm chrome_sqlite3changeset_concat_strm // Lines 11560-11567 -#define sqlite3changeset_conflict chrome_sqlite3changeset_conflict // Lines 10687-10691 -#define sqlite3changeset_finalize chrome_sqlite3changeset_finalize // Line 10740 -#define sqlite3changeset_fk_conflicts chrome_sqlite3changeset_fk_conflicts // Lines 10704-10707 -#define sqlite3changeset_invert chrome_sqlite3changeset_invert // Lines 10770-10773 -#define sqlite3changeset_invert_strm chrome_sqlite3changeset_invert_strm // Lines 11568-11573 -#define sqlite3changeset_new chrome_sqlite3changeset_new // Lines 10659-10663 -#define sqlite3changeset_next chrome_sqlite3changeset_next // Line 10531 -#define sqlite3changeset_old chrome_sqlite3changeset_old // Lines 10625-10629 -#define sqlite3changeset_op chrome_sqlite3changeset_op // Lines 10560-10566 -#define sqlite3changeset_pk chrome_sqlite3changeset_pk // Lines 10594-10598 -#define sqlite3changeset_start chrome_sqlite3changeset_start // Lines 10482-10486 -#define sqlite3changeset_start_strm chrome_sqlite3changeset_start_strm // Lines 11574-11578 -#define sqlite3changeset_start_v2 chrome_sqlite3changeset_start_v2 // Lines 10487-10492 -#define sqlite3changeset_start_v2_strm chrome_sqlite3changeset_start_v2_strm // Lines 11579-11584 -#define sqlite3rebaser_configure chrome_sqlite3rebaser_configure // Lines 11403-11406 -#define sqlite3rebaser_create chrome_sqlite3rebaser_create // Line 11392 -#define sqlite3rebaser_delete chrome_sqlite3rebaser_delete // Line 11436 -#define sqlite3rebaser_rebase chrome_sqlite3rebaser_rebase // Lines 11422-11426 -#define sqlite3rebaser_rebase_strm chrome_sqlite3rebaser_rebase_strm // Lines 11603-11609 -#define sqlite3session_attach chrome_sqlite3session_attach // Lines 10189-10192 -#define sqlite3session_changeset chrome_sqlite3session_changeset // Lines 10318-10322 -#define sqlite3session_changeset_strm chrome_sqlite3session_changeset_strm // Lines 11585-11589 -#define sqlite3session_config chrome_sqlite3session_config // Line 11644 -#define sqlite3session_create chrome_sqlite3session_create // Lines 10059-10063 -#define sqlite3session_delete chrome_sqlite3session_delete // Line 10078 -#define sqlite3session_diff chrome_sqlite3session_diff // Lines 10381-10386 -#define sqlite3session_enable chrome_sqlite3session_enable // Line 10099 -#define sqlite3session_indirect chrome_sqlite3session_indirect // Line 10129 -#define sqlite3session_isempty chrome_sqlite3session_isempty // Line 10439 -#define sqlite3session_patchset chrome_sqlite3session_patchset // Lines 10418-10422 -#define sqlite3session_patchset_strm chrome_sqlite3session_patchset_strm // Lines 11590-11594 -#define sqlite3session_table_filter chrome_sqlite3session_table_filter // Lines 10204-10211 +#define sqlite3_vfs_find chrome_sqlite3_vfs_find // Line 7400 +#define sqlite3_vfs_register chrome_sqlite3_vfs_register // Line 7401 +#define sqlite3_vfs_unregister chrome_sqlite3_vfs_unregister // Line 7402 +#define sqlite3_vmprintf chrome_sqlite3_vmprintf // Line 2820 +#define sqlite3_vsnprintf chrome_sqlite3_vsnprintf // Line 2822 +#define sqlite3_vtab_collation chrome_sqlite3_vtab_collation // Line 9297 +#define sqlite3_vtab_config chrome_sqlite3_vtab_config // Line 9178 +#define sqlite3_vtab_nochange chrome_sqlite3_vtab_nochange // Line 9282 +#define sqlite3_vtab_on_conflict chrome_sqlite3_vtab_on_conflict // Line 9256 +#define sqlite3_wal_autocheckpoint chrome_sqlite3_wal_autocheckpoint // Line 9022 +#define sqlite3_wal_checkpoint chrome_sqlite3_wal_checkpoint // Line 9044 +#define sqlite3_wal_checkpoint_v2 chrome_sqlite3_wal_checkpoint_v2 // Lines 9138-9144 +#define sqlite3_wal_hook chrome_sqlite3_wal_hook // Lines 8987-8991 +#define sqlite3_win32_set_directory chrome_sqlite3_win32_set_directory // Lines 6108-6111 +#define sqlite3_win32_set_directory16 chrome_sqlite3_win32_set_directory16 // Line 6113 +#define sqlite3_win32_set_directory8 chrome_sqlite3_win32_set_directory8 // Line 6112 +#define sqlite3changegroup_add chrome_sqlite3changegroup_add // Line 10960 +#define sqlite3changegroup_add_strm chrome_sqlite3changegroup_add_strm // Lines 11622-11625 +#define sqlite3changegroup_delete chrome_sqlite3changegroup_delete // Line 10997 +#define sqlite3changegroup_new chrome_sqlite3changegroup_new // Line 10882 +#define sqlite3changegroup_output chrome_sqlite3changegroup_output // Lines 10987-10991 +#define sqlite3changegroup_output_strm chrome_sqlite3changegroup_output_strm // Lines 11626-11629 +#define sqlite3changeset_apply chrome_sqlite3changeset_apply // Lines 11157-11171 +#define sqlite3changeset_apply_strm chrome_sqlite3changeset_apply_strm // Lines 11555-11569 +#define sqlite3changeset_apply_v2 chrome_sqlite3changeset_apply_v2 // Lines 11172-11188 +#define sqlite3changeset_apply_v2_strm chrome_sqlite3changeset_apply_v2_strm // Lines 11570-11586 +#define sqlite3changeset_concat chrome_sqlite3changeset_concat // Lines 10828-10835 +#define sqlite3changeset_concat_strm chrome_sqlite3changeset_concat_strm // Lines 11587-11594 +#define sqlite3changeset_conflict chrome_sqlite3changeset_conflict // Lines 10714-10718 +#define sqlite3changeset_finalize chrome_sqlite3changeset_finalize // Line 10767 +#define sqlite3changeset_fk_conflicts chrome_sqlite3changeset_fk_conflicts // Lines 10731-10734 +#define sqlite3changeset_invert chrome_sqlite3changeset_invert // Lines 10797-10800 +#define sqlite3changeset_invert_strm chrome_sqlite3changeset_invert_strm // Lines 11595-11600 +#define sqlite3changeset_new chrome_sqlite3changeset_new // Lines 10686-10690 +#define sqlite3changeset_next chrome_sqlite3changeset_next // Line 10553 +#define sqlite3changeset_old chrome_sqlite3changeset_old // Lines 10652-10656 +#define sqlite3changeset_op chrome_sqlite3changeset_op // Lines 10587-10593 +#define sqlite3changeset_pk chrome_sqlite3changeset_pk // Lines 10621-10625 +#define sqlite3changeset_start chrome_sqlite3changeset_start // Lines 10504-10508 +#define sqlite3changeset_start_strm chrome_sqlite3changeset_start_strm // Lines 11601-11605 +#define sqlite3changeset_start_v2 chrome_sqlite3changeset_start_v2 // Lines 10509-10514 +#define sqlite3changeset_start_v2_strm chrome_sqlite3changeset_start_v2_strm // Lines 11606-11611 +#define sqlite3rebaser_configure chrome_sqlite3rebaser_configure // Lines 11430-11433 +#define sqlite3rebaser_create chrome_sqlite3rebaser_create // Line 11419 +#define sqlite3rebaser_delete chrome_sqlite3rebaser_delete // Line 11463 +#define sqlite3rebaser_rebase chrome_sqlite3rebaser_rebase // Lines 11449-11453 +#define sqlite3rebaser_rebase_strm chrome_sqlite3rebaser_rebase_strm // Lines 11630-11636 +#define sqlite3session_attach chrome_sqlite3session_attach // Lines 10203-10206 +#define sqlite3session_changeset chrome_sqlite3session_changeset // Lines 10332-10336 +#define sqlite3session_changeset_strm chrome_sqlite3session_changeset_strm // Lines 11612-11616 +#define sqlite3session_config chrome_sqlite3session_config // Line 11671 +#define sqlite3session_create chrome_sqlite3session_create // Lines 10073-10077 +#define sqlite3session_delete chrome_sqlite3session_delete // Line 10092 +#define sqlite3session_diff chrome_sqlite3session_diff // Lines 10395-10400 +#define sqlite3session_enable chrome_sqlite3session_enable // Line 10113 +#define sqlite3session_indirect chrome_sqlite3session_indirect // Line 10143 +#define sqlite3session_isempty chrome_sqlite3session_isempty // Line 10453 +#define sqlite3session_memory_used chrome_sqlite3session_memory_used // Line 10461 +#define sqlite3session_patchset chrome_sqlite3session_patchset // Lines 10432-10436 +#define sqlite3session_patchset_strm chrome_sqlite3session_patchset_strm // Lines 11617-11621 +#define sqlite3session_table_filter chrome_sqlite3session_table_filter // Lines 10218-10225 #endif // THIRD_PARTY_SQLITE_AMALGAMATION_RENAME_EXPORTS_H_ diff --git a/chromium/third_party/sqlite/src/amalgamation/shell/shell.c b/chromium/third_party/sqlite/src/amalgamation/shell/shell.c index c13769f5e96..27de22a3819 100644 --- a/chromium/third_party/sqlite/src/amalgamation/shell/shell.c +++ b/chromium/third_party/sqlite/src/amalgamation/shell/shell.c @@ -1424,7 +1424,10 @@ SQLITE_EXTENSION_INIT1 #include <assert.h> #include <string.h> #include <stdarg.h> + +#ifndef SQLITE_AMALGAMATION /* typedef sqlite3_uint64 u64; */ +#endif /* SQLITE_AMALGAMATION */ /****************************************************************************** ** The Hash Engine @@ -2014,9 +2017,11 @@ static void sha3QueryFunc( } nCol = sqlite3_column_count(pStmt); z = sqlite3_sql(pStmt); - n = (int)strlen(z); - hash_step_vformat(&cx,"S%d:",n); - SHA3Update(&cx,(unsigned char*)z,n); + if( z ){ + n = (int)strlen(z); + hash_step_vformat(&cx,"S%d:",n); + SHA3Update(&cx,(unsigned char*)z,n); + } /* Compute a hash over the result of the query */ while( SQLITE_ROW==sqlite3_step(pStmt) ){ @@ -3635,24 +3640,23 @@ int sqlite3_completion_init( ** appended onto the end of some other file, such as an executable. ** ** A special record must appear at the end of the file that identifies the -** file as an appended database and provides an offset to page 1. For -** best performance page 1 should be located at a disk page boundary, though -** that is not required. +** file as an appended database and provides the offset to the first page +** of the exposed content. (Or, it is the length of the content prefix.) +** For best performance page 1 should be located at a disk page boundary, +** though that is not required. ** ** When opening a database using this VFS, the connection might treat -** the file as an ordinary SQLite database, or it might treat is as a -** database appended onto some other file. Here are the rules: +** the file as an ordinary SQLite database, or it might treat it as a +** database appended onto some other file. The decision is made by +** applying the following rules in order: ** -** (1) When opening a new empty file, that file is treated as an ordinary -** database. +** (1) An empty file is an ordinary database. ** -** (2) When opening a file that begins with the standard SQLite prefix -** string "SQLite format 3", that file is treated as an ordinary -** database. +** (2) If the file ends with the appendvfs trailer string +** "Start-Of-SQLite3-NNNNNNNN" that file is an appended database. ** -** (3) When opening a file that ends with the appendvfs trailer string -** "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended -** database. +** (3) If the file begins with the standard SQLite prefix string +** "SQLite format 3", that file is an ordinary database. ** ** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is ** set, then a new database is appended to the already existing file. @@ -3660,13 +3664,13 @@ int sqlite3_completion_init( ** (5) Otherwise, SQLITE_CANTOPEN is returned. ** ** To avoid unnecessary complications with the PENDING_BYTE, the size of -** the file containing the database is limited to 1GB. This VFS will refuse -** to read or write past the 1GB mark. This restriction might be lifted in -** future versions. For now, if you need a large database, then keep the -** database in a separate file. +** the file containing the database is limited to 1GiB. (1073741824 bytes) +** This VFS will not read or write past the 1GiB mark. This restriction +** might be lifted in future versions. For now, if you need a larger +** database, then keep it in a separate file. ** -** If the file being opened is not an appended database, then this shim is -** a pass-through into the default underlying VFS. +** If the file being opened is a plain database (not an appended one), then +** this shim is a pass-through into the default underlying VFS. (rule 3) **/ /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 @@ -3679,17 +3683,27 @@ SQLITE_EXTENSION_INIT1 ** 123456789 123456789 12345 ** ** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is -** the offset to page 1. +** the offset to page 1, and also the length of the prefix content. */ #define APND_MARK_PREFIX "Start-Of-SQLite3-" #define APND_MARK_PREFIX_SZ 17 -#define APND_MARK_SIZE 25 +#define APND_MARK_FOS_SZ 8 +#define APND_MARK_SIZE (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ) /* ** Maximum size of the combined prefix + database + append-mark. This ** must be less than 0x40000000 to avoid locking issues on Windows. */ -#define APND_MAX_SIZE (65536*15259) +#define APND_MAX_SIZE (0x40000000) + +/* +** Try to align the database to an even multiple of APND_ROUNDUP bytes. +*/ +#ifndef APND_ROUNDUP +#define APND_ROUNDUP 4096 +#endif +#define APND_ALIGN_MASK ((sqlite3_int64)(APND_ROUNDUP-1)) +#define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK) /* ** Forward declaration of objects used by this utility @@ -3703,11 +3717,45 @@ typedef struct ApndFile ApndFile; #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) #define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1)) -/* An open file */ +/* An open appendvfs file +** +** An instance of this structure describes the appended database file. +** A separate sqlite3_file object is always appended. The appended +** sqlite3_file object (which can be accessed using ORIGFILE()) describes +** the entire file, including the prefix, the database, and the +** append-mark. +** +** The structure of an AppendVFS database is like this: +** +** +-------------+---------+----------+-------------+ +** | prefix-file | padding | database | append-mark | +** +-------------+---------+----------+-------------+ +** ^ ^ +** | | +** iPgOne iMark +** +** +** "prefix file" - file onto which the database has been appended. +** "padding" - zero or more bytes inserted so that "database" +** starts on an APND_ROUNDUP boundary +** "database" - The SQLite database file +** "append-mark" - The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates +** the offset from the start of prefix-file to the start +** of "database". +** +** The size of the database is iMark - iPgOne. +** +** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value +** of iPgOne stored as a big-ending 64-bit integer. +** +** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE). +** Or, iMark is -1 to indicate that it has not yet been written. +*/ struct ApndFile { - sqlite3_file base; /* IO methods */ - sqlite3_int64 iPgOne; /* File offset to page 1 */ - sqlite3_int64 iMark; /* Start of the append-mark */ + sqlite3_file base; /* Subclass. MUST BE FIRST! */ + sqlite3_int64 iPgOne; /* Offset to the start of the database */ + sqlite3_int64 iMark; /* Offset of the append mark. -1 if unwritten */ + /* Always followed by another sqlite3_file that describes the whole file */ }; /* @@ -3799,8 +3847,6 @@ static const sqlite3_io_methods apnd_io_methods = { apndUnfetch /* xUnfetch */ }; - - /* ** Close an apnd-file. */ @@ -3818,22 +3864,37 @@ static int apndRead( int iAmt, sqlite_int64 iOfst ){ - ApndFile *p = (ApndFile *)pFile; + ApndFile *paf = (ApndFile *)pFile; pFile = ORIGFILE(pFile); - return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst+p->iPgOne); + return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst); } /* -** Add the append-mark onto the end of the file. +** Add the append-mark onto what should become the end of the file. +* If and only if this succeeds, internal ApndFile.iMark is updated. +* Parameter iWriteEnd is the appendvfs-relative offset of the new mark. */ -static int apndWriteMark(ApndFile *p, sqlite3_file *pFile){ - int i; +static int apndWriteMark( + ApndFile *paf, + sqlite3_file *pFile, + sqlite_int64 iWriteEnd +){ + sqlite_int64 iPgOne = paf->iPgOne; unsigned char a[APND_MARK_SIZE]; + int i = APND_MARK_FOS_SZ; + int rc; + assert(pFile == ORIGFILE(paf)); memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ); - for(i=0; i<8; i++){ - a[APND_MARK_PREFIX_SZ+i] = (p->iPgOne >> (56 - i*8)) & 0xff; + while( --i >= 0 ){ + a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff); + iPgOne >>= 8; } - return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark); + iWriteEnd += paf->iPgOne; + if( SQLITE_OK==(rc = pFile->pMethods->xWrite + (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){ + paf->iMark = iWriteEnd; + } + return rc; } /* @@ -3845,38 +3906,28 @@ static int apndWrite( int iAmt, sqlite_int64 iOfst ){ - int rc; - ApndFile *p = (ApndFile *)pFile; + ApndFile *paf = (ApndFile *)pFile; + sqlite_int64 iWriteEnd = iOfst + iAmt; + if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL; pFile = ORIGFILE(pFile); - if( iOfst+iAmt>=APND_MAX_SIZE ) return SQLITE_FULL; - rc = pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst+p->iPgOne); - if( rc==SQLITE_OK && iOfst + iAmt + p->iPgOne > p->iMark ){ - sqlite3_int64 sz = 0; - rc = pFile->pMethods->xFileSize(pFile, &sz); - if( rc==SQLITE_OK ){ - p->iMark = sz - APND_MARK_SIZE; - if( iOfst + iAmt + p->iPgOne > p->iMark ){ - p->iMark = p->iPgOne + iOfst + iAmt; - rc = apndWriteMark(p, pFile); - } - } + /* If append-mark is absent or will be overwritten, write it. */ + if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){ + int rc = apndWriteMark(paf, pFile, iWriteEnd); + if( SQLITE_OK!=rc ) return rc; } - return rc; + return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst); } /* ** Truncate an apnd-file. */ static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){ - int rc; - ApndFile *p = (ApndFile *)pFile; + ApndFile *paf = (ApndFile *)pFile; pFile = ORIGFILE(pFile); - rc = pFile->pMethods->xTruncate(pFile, size+p->iPgOne+APND_MARK_SIZE); - if( rc==SQLITE_OK ){ - p->iMark = p->iPgOne+size; - rc = apndWriteMark(p, pFile); - } - return rc; + /* The append mark goes out first so truncate failure does not lose it. */ + if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR; + /* Truncate underlying file just past append mark */ + return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE); } /* @@ -3889,16 +3940,12 @@ static int apndSync(sqlite3_file *pFile, int flags){ /* ** Return the current file-size of an apnd-file. +** If the append mark is not yet there, the file-size is 0. */ static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ - ApndFile *p = (ApndFile *)pFile; - int rc; - pFile = ORIGFILE(p); - rc = pFile->pMethods->xFileSize(pFile, pSize); - if( rc==SQLITE_OK && p->iPgOne ){ - *pSize -= p->iPgOne + APND_MARK_SIZE; - } - return rc; + ApndFile *paf = (ApndFile *)pFile; + *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0; + return SQLITE_OK; } /* @@ -3929,12 +3976,13 @@ static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){ ** File control method. For custom operations on an apnd-file. */ static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){ - ApndFile *p = (ApndFile *)pFile; + ApndFile *paf = (ApndFile *)pFile; int rc; pFile = ORIGFILE(pFile); + if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne; rc = pFile->pMethods->xFileControl(pFile, op, pArg); if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){ - *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", p->iPgOne, *(char**)pArg); + *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg); } return rc; } @@ -3993,6 +4041,9 @@ static int apndFetch( void **pp ){ ApndFile *p = (ApndFile *)pFile; + if( p->iMark < 0 || iOfst+iAmt > p->iMark ){ + return SQLITE_IOERR; /* Cannot read what is not yet there. */ + } pFile = ORIGFILE(pFile); return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp); } @@ -4005,94 +4056,152 @@ static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ } /* -** Check to see if the file is an ordinary SQLite database file. -*/ -static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){ - int rc; - char zHdr[16]; - static const char aSqliteHdr[] = "SQLite format 3"; - if( sz<512 ) return 0; - rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0); - if( rc ) return 0; - return memcmp(zHdr, aSqliteHdr, sizeof(zHdr))==0; -} - -/* ** Try to read the append-mark off the end of a file. Return the -** start of the appended database if the append-mark is present. If -** there is no append-mark, return -1; +** start of the appended database if the append-mark is present. +** If there is no valid append-mark, return -1; +** +** An append-mark is only valid if the NNNNNNNN start-of-database offset +** indicates that the appended database contains at least one page. The +** start-of-database value must be a multiple of 512. */ static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){ int rc, i; sqlite3_int64 iMark; + int msbs = 8 * (APND_MARK_FOS_SZ-1); unsigned char a[APND_MARK_SIZE]; - if( sz<=APND_MARK_SIZE ) return -1; + if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1; rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE); if( rc ) return -1; if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1; - iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ]&0x7f))<<56; - for(i=1; i<8; i++){ - iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<(56-8*i); + iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs; + for(i=1; i<8; i++){ + msbs -= 8; + iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs; } + if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1; + if( iMark & 0x1ff ) return -1; return iMark; } +static const char apvfsSqliteHdr[] = "SQLite format 3"; +/* +** Check to see if the file is an appendvfs SQLite database file. +** Return true iff it is such. Parameter sz is the file's size. +*/ +static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){ + int rc; + char zHdr[16]; + sqlite3_int64 iMark = apndReadMark(sz, pFile); + if( iMark>=0 ){ + /* If file has the correct end-marker, the expected odd size, and the + ** SQLite DB type marker where the end-marker puts it, then it + ** is an appendvfs database. + */ + rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark); + if( SQLITE_OK==rc + && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0 + && (sz & 0x1ff) == APND_MARK_SIZE + && sz>=512+APND_MARK_SIZE + ){ + return 1; /* It's an appendvfs database */ + } + } + return 0; +} + +/* +** Check to see if the file is an ordinary SQLite database file. +** Return true iff so. Parameter sz is the file's size. +*/ +static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){ + char zHdr[16]; + if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */ + || (sz & 0x1ff) != 0 + || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0) + || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0 + ){ + return 0; + }else{ + return 1; + } +} + /* ** Open an apnd file handle. */ static int apndOpen( - sqlite3_vfs *pVfs, + sqlite3_vfs *pApndVfs, const char *zName, sqlite3_file *pFile, int flags, int *pOutFlags ){ - ApndFile *p; - sqlite3_file *pSubFile; - sqlite3_vfs *pSubVfs; + ApndFile *pApndFile = (ApndFile*)pFile; + sqlite3_file *pBaseFile = ORIGFILE(pFile); + sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs); int rc; - sqlite3_int64 sz; - pSubVfs = ORIGVFS(pVfs); + sqlite3_int64 sz = 0; if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){ - return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags); + /* The appendvfs is not to be used for transient or temporary databases. + ** Just use the base VFS open to initialize the given file object and + ** open the underlying file. (Appendvfs is then unused for this file.) + */ + return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags); } - p = (ApndFile*)pFile; - memset(p, 0, sizeof(*p)); - pSubFile = ORIGFILE(pFile); + memset(pApndFile, 0, sizeof(ApndFile)); pFile->pMethods = &apnd_io_methods; - rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags); - if( rc ) goto apnd_open_done; - rc = pSubFile->pMethods->xFileSize(pSubFile, &sz); + pApndFile->iMark = -1; /* Append mark not yet written */ + + rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags); + if( rc==SQLITE_OK ){ + rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz); + } if( rc ){ - pSubFile->pMethods->xClose(pSubFile); - goto apnd_open_done; + pBaseFile->pMethods->xClose(pBaseFile); + pFile->pMethods = 0; + return rc; } - if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){ - memmove(pFile, pSubFile, pSubVfs->szOsFile); + if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){ + /* The file being opened appears to be just an ordinary DB. Copy + ** the base dispatch-table so this instance mimics the base VFS. + */ + memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile); return SQLITE_OK; } - p->iMark = 0; - p->iPgOne = apndReadMark(sz, pFile); - if( p->iPgOne>0 ){ + pApndFile->iPgOne = apndReadMark(sz, pFile); + if( pApndFile->iPgOne>=0 ){ + pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */ return SQLITE_OK; } if( (flags & SQLITE_OPEN_CREATE)==0 ){ - pSubFile->pMethods->xClose(pSubFile); + pBaseFile->pMethods->xClose(pBaseFile); rc = SQLITE_CANTOPEN; + pFile->pMethods = 0; + }else{ + /* Round newly added appendvfs location to #define'd page boundary. + ** Note that nothing has yet been written to the underlying file. + ** The append mark will be written along with first content write. + ** Until then, paf->iMark value indicates it is not yet written. + */ + pApndFile->iPgOne = APND_START_ROUNDUP(sz); } - p->iPgOne = (sz+0xfff) & ~(sqlite3_int64)0xfff; -apnd_open_done: - if( rc ) pFile->pMethods = 0; return rc; } /* -** All other VFS methods are pass-thrus. +** Delete an apnd file. +** For an appendvfs, this could mean delete the appendvfs portion, +** leaving the appendee as it was before it gained an appendvfs. +** For now, this code deletes the underlying file too. */ static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync); } + +/* +** All other VFS methods are pass-thrus. +*/ static int apndAccess( sqlite3_vfs *pVfs, const char *zPath, @@ -5199,6 +5308,14 @@ static void ieee754func( int isNeg = 0; m = sqlite3_value_int64(argv[0]); e = sqlite3_value_int64(argv[1]); + + /* Limit the range of e. Ticket 22dea1cfdb9151e4 2021-03-02 */ + if( e>10000 ){ + e = 10000; + }else if( e<-10000 ){ + e = -10000; + } + if( m<0 ){ isNeg = 1; m = -m; @@ -5563,7 +5680,8 @@ static int seriesEof(sqlite3_vtab_cursor *cur){ ** 4: step=VALUE ** ** Also, if bit 8 is set, that means that the series should be output -** in descending order rather than in ascending order. +** in descending order rather than in ascending order. If bit 16 is +** set, then output must appear in ascending order. ** ** This routine should initialize the cursor and position it so that it ** is pointing at the first row, or pointing off the end of the table @@ -5589,7 +5707,12 @@ static int seriesFilter( } if( idxNum & 4 ){ pCur->iStep = sqlite3_value_int64(argv[i++]); - if( pCur->iStep<1 ) pCur->iStep = 1; + if( pCur->iStep==0 ){ + pCur->iStep = 1; + }else if( pCur->iStep<0 ){ + pCur->iStep = -pCur->iStep; + if( (idxNum & 16)==0 ) idxNum |= 8; + } }else{ pCur->iStep = 1; } @@ -5683,7 +5806,11 @@ static int seriesBestIndex( pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0)); pIdxInfo->estimatedRows = 1000; if( pIdxInfo->nOrderBy==1 ){ - if( pIdxInfo->aOrderBy[0].desc ) idxNum |= 8; + if( pIdxInfo->aOrderBy[0].desc ){ + idxNum |= 8; + }else{ + idxNum |= 16; + } pIdxInfo->orderByConsumed = 1; } }else{ @@ -8934,7 +9061,7 @@ static int idxGetTableInfo( char *pCsr = 0; int nPk = 0; - rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab); + rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_xinfo=%Q", zTab); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ const char *zCol = (const char*)sqlite3_column_text(p1, 1); nByte += 1 + STRLEN(zCol); @@ -9968,10 +10095,12 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){ idxFinalize(&rc, pIndexXInfo); idxFinalize(&rc, pWrite); - for(i=0; i<pCtx->nSlot; i++){ - sqlite3_free(pCtx->aSlot[i].z); + if( pCtx ){ + for(i=0; i<pCtx->nSlot; i++){ + sqlite3_free(pCtx->aSlot[i].z); + } + sqlite3_free(pCtx); } - sqlite3_free(pCtx); if( rc==SQLITE_OK ){ rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0); @@ -11112,12 +11241,12 @@ struct ShellState { u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ u8 autoEQPtest; /* autoEQP is in test mode */ u8 autoEQPtrace; /* autoEQP is in trace mode */ - u8 statsOn; /* True to display memory stats before each finalize */ u8 scanstatsOn; /* True to display scan stats before each finalize */ u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */ u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */ u8 nEqpLevel; /* Depth of the EQP output graph */ u8 eTraceType; /* SHELL_TRACE_* value for type of trace */ + unsigned statsOn; /* True to display memory stats before each finalize */ unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */ int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ @@ -12054,6 +12183,7 @@ static int shell_callback( if( azArg==0 ) break; for(i=0; i<nArg; i++){ int w = aExplainWidth[i]; + if( i==nArg-1 ) w = 0; if( azArg[i] && strlenChar(azArg[i])>w ){ w = strlenChar(azArg[i]); } @@ -12618,7 +12748,7 @@ static int display_stats( if( pArg==0 || pArg->out==0 ) return 0; out = pArg->out; - if( pArg->pStmt && (pArg->statsOn & 2) ){ + if( pArg->pStmt && pArg->statsOn==2 ){ int nCol, i, x; sqlite3_stmt *pStmt = pArg->pStmt; char z[100]; @@ -12642,6 +12772,14 @@ static int display_stats( } } + if( pArg->statsOn==3 ){ + if( pArg->pStmt ){ + iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); + raw_printf(pArg->out, "VM-steps: %d\n", iCur); + } + return 0; + } + displayStatLine(pArg, "Memory Used:", "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); displayStatLine(pArg, "Number of Outstanding Allocations:", @@ -12908,31 +13046,18 @@ static void explain_data_delete(ShellState *p){ /* ** Disable and restore .wheretrace and .selecttrace settings. */ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) -extern unsigned int sqlite3_unsupported_selecttrace; -static int savedSelectTrace; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) -extern int sqlite3WhereTrace; -static int savedWhereTrace; -#endif +static unsigned int savedSelectTrace; +static unsigned int savedWhereTrace; static void disable_debug_trace_modes(void){ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - savedSelectTrace = sqlite3_unsupported_selecttrace; - sqlite3_unsupported_selecttrace = 0; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - savedWhereTrace = sqlite3WhereTrace; - sqlite3WhereTrace = 0; -#endif + unsigned int zero = 0; + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 0, &savedSelectTrace); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &zero); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 2, &savedWhereTrace); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &zero); } static void restore_debug_trace_modes(void){ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - sqlite3_unsupported_selecttrace = savedSelectTrace; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - sqlite3WhereTrace = savedWhereTrace; -#endif + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &savedSelectTrace); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &savedWhereTrace); } /* Create the TEMP table used to store parameter bindings */ @@ -13094,6 +13219,7 @@ static void exec_prepared_stmt_columnar( if( rc!=SQLITE_ROW ) return; nColumn = sqlite3_column_count(pStmt); nAlloc = nColumn*4; + if( nAlloc<=0 ) nAlloc = 1; azData = sqlite3_malloc64( nAlloc*sizeof(char*) ); if( azData==0 ) shell_out_of_memory(); for(i=0; i<nColumn; i++){ @@ -13133,6 +13259,7 @@ static void exec_prepared_stmt_columnar( if( n>p->actualWidth[j] ) p->actualWidth[j] = n; } if( seenInterrupt ) goto columnar_end; + if( nColumn==0 ) goto columnar_end; switch( p->cMode ){ case MODE_Column: { colSep = " "; @@ -13922,13 +14049,13 @@ static const char *(azHelp[]) = { ".databases List names and files of attached databases", ".dbconfig ?op? ?val? List or change sqlite3_db_config() options", ".dbinfo ?DB? Show status information about the database", - ".dump ?TABLE? Render database content as SQL", + ".dump ?OBJECTS? Render database content as SQL", " Options:", " --data-only Output only INSERT statements", " --newlines Allow unescaped newline characters in output", " --nosys Omit system tables (ex: \"sqlite_stat1\")", " --preserve-rowids Include ROWID values in the output", - " TABLE is a LIKE pattern for the tables to dump", + " OBJECTS is a LIKE pattern for tables, indexes, triggers or views to dump", " Additional LIKE patterns can be given in subsequent arguments", ".echo on|off Turn command echo on or off", ".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN", @@ -14087,7 +14214,11 @@ static const char *(azHelp[]) = { ".shell CMD ARGS... Run CMD ARGS... in a system shell", #endif ".show Show the current values for various settings", - ".stats ?on|off? Show stats or turn stats on or off", + ".stats ?ARG? Show stats or turn stats on or off", + " off Turn off automatic stat display", + " on Turn on automatic stat display", + " stmt Show statement stats", + " vmstep Show the virtual machine step count only", #ifndef SQLITE_NOHAVE_SYSTEM ".system CMD ARGS... Run CMD ARGS... in a system shell", #endif @@ -17903,16 +18034,17 @@ static int do_meta_command(char *zLine, ShellState *p){ int ctrlCode; /* Integer code for that option */ const char *zUsage; /* Usage notes */ } aCtrl[] = { - { "size_limit", SQLITE_FCNTL_SIZE_LIMIT, "[LIMIT]" }, { "chunk_size", SQLITE_FCNTL_CHUNK_SIZE, "SIZE" }, - /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY, "COUNT DELAY" },*/ - { "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" }, - { "psow", SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]" }, - /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/ - { "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" }, + { "data_version", SQLITE_FCNTL_DATA_VERSION, "" }, { "has_moved", SQLITE_FCNTL_HAS_MOVED, "" }, { "lock_timeout", SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" }, + { "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" }, + /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/ + { "psow", SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]" }, { "reserve_bytes", SQLITE_FCNTL_RESERVE_BYTES, "[N]" }, + { "size_limit", SQLITE_FCNTL_SIZE_LIMIT, "[LIMIT]" }, + { "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" }, + /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY, "COUNT DELAY" },*/ }; int filectrl = -1; int iCtrl = -1; @@ -17999,6 +18131,7 @@ static int do_meta_command(char *zLine, ShellState *p){ isOk = 1; break; } + case SQLITE_FCNTL_DATA_VERSION: case SQLITE_FCNTL_HAS_MOVED: { int x; if( nArg!=2 ) break; @@ -18707,9 +18840,9 @@ static int do_meta_command(char *zLine, ShellState *p){ #endif /* SQLITE_DEBUG */ if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){ - char *zNewFilename; /* Name of the database file to open */ - int iName = 1; /* Index in azArg[] of the filename */ - int newFlag = 0; /* True to delete file before opening */ + char *zNewFilename = 0; /* Name of the database file to open */ + int iName = 1; /* Index in azArg[] of the filename */ + int newFlag = 0; /* True to delete file before opening */ /* Close the existing database */ session_close_all(p); close_db(p->db); @@ -18721,7 +18854,7 @@ static int do_meta_command(char *zLine, ShellState *p){ p->openFlags = 0; p->szMax = 0; /* Check for command-line arguments */ - for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){ + for(iName=1; iName<nArg; iName++){ const char *z = azArg[iName]; if( optionMatch(z,"new") ){ newFlag = 1; @@ -18747,10 +18880,15 @@ static int do_meta_command(char *zLine, ShellState *p){ utf8_printf(stderr, "unknown option: %s\n", z); rc = 1; goto meta_command_exit; + }else if( zNewFilename ){ + utf8_printf(stderr, "extra argument: \"%s\"\n", z); + rc = 1; + goto meta_command_exit; + }else{ + zNewFilename = sqlite3_mprintf("%s", z); } } /* If a filename is specified, try to open it first */ - zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0; if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){ if( newFlag ) shellDeleteFile(zNewFilename); p->zDbFilename = zNewFilename; @@ -18773,7 +18911,7 @@ static int do_meta_command(char *zLine, ShellState *p){ && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0)) || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0) ){ - const char *zFile = 0; + char *zFile = 0; int bTxtMode = 0; int i; int eMode = 0; @@ -18803,17 +18941,22 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; } - }else if( zFile==0 ){ - zFile = z; + }else if( zFile==0 && eMode!='e' && eMode!='x' ){ + zFile = sqlite3_mprintf("%s", z); + if( zFile[0]=='|' ){ + while( i+1<nArg ) zFile = sqlite3_mprintf("%z %s", zFile, azArg[++i]); + break; + } }else{ utf8_printf(p->out,"ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]); showHelp(p->out, azArg[0]); rc = 1; + sqlite3_free(zFile); goto meta_command_exit; } } - if( zFile==0 ) zFile = "stdout"; + if( zFile==0 ) zFile = sqlite3_mprintf("stdout"); if( bOnce ){ p->outCount = 2; }else{ @@ -18836,7 +18979,8 @@ static int do_meta_command(char *zLine, ShellState *p){ newTempFile(p, "txt"); bTxtMode = 1; } - zFile = p->zTempFile; + sqlite3_free(zFile); + zFile = sqlite3_mprintf("%s", p->zTempFile); } #endif /* SQLITE_NOHAVE_SYSTEM */ if( zFile[0]=='|' ){ @@ -18868,6 +19012,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } } + sqlite3_free(zFile); }else if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){ @@ -19051,6 +19196,11 @@ static int do_meta_command(char *zLine, ShellState *p){ goto meta_command_exit; } if( azArg[1][0]=='|' ){ +#ifdef SQLITE_OMIT_POPEN + raw_printf(stderr, "Error: pipes are not supported in this OS\n"); + rc = 1; + p->out = stdout; +#else p->in = popen(azArg[1]+1, "r"); if( p->in==0 ){ utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]); @@ -19059,6 +19209,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = process_input(p); pclose(p->in); } +#endif }else if( notNormalFile(azArg[1]) || (p->in = fopen(azArg[1], "rb"))==0 ){ utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); rc = 1; @@ -19273,11 +19424,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ - sqlite3_unsupported_selecttrace = nArg>=2 ? (int)integerValue(azArg[1]) : 0xffff; + unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x); }else -#endif #if defined(SQLITE_ENABLE_SESSION) if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){ @@ -19758,6 +19908,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='s' && strncmp(azArg[0], "show", n)==0 ){ static const char *azBool[] = { "off", "on", "trigger", "full"}; + const char *zOut; int i; if( nArg!=1 ){ raw_printf(stderr, "Usage: .show\n"); @@ -19782,7 +19933,13 @@ static int do_meta_command(char *zLine, ShellState *p){ utf8_printf(p->out,"%12.12s: ", "rowseparator"); output_c_string(p->out, p->rowSeparator); raw_printf(p->out, "\n"); - utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]); + switch( p->statsOn ){ + case 0: zOut = "off"; break; + default: zOut = "on"; break; + case 2: zOut = "stmt"; break; + case 3: zOut = "vmstep"; break; + } + utf8_printf(p->out, "%12.12s: %s\n","stats", zOut); utf8_printf(p->out, "%12.12s: ", "width"); for (i=0;i<p->nWidth;i++) { raw_printf(p->out, "%d ", p->colWidth[i]); @@ -19794,11 +19951,17 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ if( nArg==2 ){ - p->statsOn = (u8)booleanValue(azArg[1]); + if( strcmp(azArg[1],"stmt")==0 ){ + p->statsOn = 2; + }else if( strcmp(azArg[1],"vmstep")==0 ){ + p->statsOn = 3; + }else{ + p->statsOn = (u8)booleanValue(azArg[1]); + } }else if( nArg==1 ){ display_stats(p->db, p, 0); }else{ - raw_printf(stderr, "Usage: .stats ?on|off?\n"); + raw_printf(stderr, "Usage: .stats ?on|off|stmt|vmstep?\n"); rc = 1; } }else @@ -20003,7 +20166,7 @@ static int do_meta_command(char *zLine, ShellState *p){ /* sqlite3_test_control(int, db, int) */ case SQLITE_TESTCTRL_OPTIMIZATIONS: if( nArg==3 ){ - int opt = (int)strtol(azArg[2], 0, 0); + unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0); rc2 = sqlite3_test_control(testctrl, p->db, opt); isOk = 3; } @@ -20332,11 +20495,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ - sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; + unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x); }else -#endif if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ int j; @@ -20825,7 +20987,8 @@ static char *cmdline_option_value(int argc, char **argv, int i){ } #ifndef SQLITE_SHELL_IS_UTF8 -# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER) +# if (defined(_WIN32) || defined(WIN32)) \ + && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__))) # define SQLITE_SHELL_IS_UTF8 (0) # else # define SQLITE_SHELL_IS_UTF8 (1) diff --git a/chromium/third_party/sqlite/src/amalgamation/sqlite3.c b/chromium/third_party/sqlite/src/amalgamation/sqlite3.c index f22c51cd758..776580f23b8 100644 --- a/chromium/third_party/sqlite/src/amalgamation/sqlite3.c +++ b/chromium/third_party/sqlite/src/amalgamation/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.34.0. By combining all the individual C code files into this +** version 3.35.5. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -284,6 +284,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ENABLE_LOCKING_STYLE "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), #endif +#if SQLITE_ENABLE_MATH_FUNCTIONS + "ENABLE_MATH_FUNCTIONS", +#endif #if SQLITE_ENABLE_MEMORY_MANAGEMENT "ENABLE_MEMORY_MANAGEMENT", #endif @@ -990,6 +993,18 @@ SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){ # define MSVC_VERSION 0 #endif +/* +** Some C99 functions in "math.h" are only present for MSVC when its version +** is associated with Visual Studio 2013 or higher. +*/ +#ifndef SQLITE_HAVE_C99_MATH_FUNCS +# if MSVC_VERSION==0 || MSVC_VERSION>=1800 +# define SQLITE_HAVE_C99_MATH_FUNCS (1) +# else +# define SQLITE_HAVE_C99_MATH_FUNCS (0) +# endif +#endif + /* Needed for various definitions... */ #if defined(__GNUC__) && !defined(_GNU_SOURCE) # define _GNU_SOURCE @@ -1171,9 +1186,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.34.0" -#define SQLITE_VERSION_NUMBER 3034000 -#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 b7738010bc8ef02ba84820368e557306390a33c38adaa5c7703154bae3edalt1" +#define SQLITE_VERSION "3.35.5" +#define SQLITE_VERSION_NUMBER 3035005 +#define SQLITE_SOURCE_ID "2021-04-19 18:32:05 1b256d97b553a9611efca188a3d995a2fff712759044ba480f9a0c9e98fae886" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -3163,7 +3178,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. </dd> +** which case the trigger setting is not reported back. +** +** <p>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.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] ** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt> @@ -3174,7 +3195,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. </dd> +** which case the view setting is not reported back. +** +** <p>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.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> @@ -4547,6 +4574,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** that uses dot-files in place of posix advisory locking. ** <tr><td> file:data.db?mode=readonly <td> ** An error. "readonly" is not a valid option for the "mode" parameter. +** Use "ro" instead: "file:data.db?mode=ro". ** </table> ** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and @@ -4745,7 +4773,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 @@ -8813,7 +8841,8 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 #define SQLITE_TESTCTRL_SEEK_COUNT 30 -#define SQLITE_TESTCTRL_LAST 30 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_TRACEFLAGS 31 +#define SQLITE_TESTCTRL_LAST 31 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -11487,6 +11516,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 ** @@ -11588,18 +11625,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 @@ -13528,7 +13570,8 @@ struct fts5_api { #ifndef __has_extension # define __has_extension(x) 0 /* compatibility with non-clang compilers */ #endif -#if GCC_VERSION>=4007000 || __has_extension(c_atomic) +#if GCC_VERSION>=4007000 || \ + (__has_extension(c_atomic) && __has_extension(c_atomic_store_n)) # define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED) # define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED) #else @@ -14085,87 +14128,89 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_LAST 84 #define TK_GENERATED 85 #define TK_ALWAYS 86 -#define TK_REINDEX 87 -#define TK_RENAME 88 -#define TK_CTIME_KW 89 -#define TK_ANY 90 -#define TK_BITAND 91 -#define TK_BITOR 92 -#define TK_LSHIFT 93 -#define TK_RSHIFT 94 -#define TK_PLUS 95 -#define TK_MINUS 96 -#define TK_STAR 97 -#define TK_SLASH 98 -#define TK_REM 99 -#define TK_CONCAT 100 -#define TK_COLLATE 101 -#define TK_BITNOT 102 -#define TK_ON 103 -#define TK_INDEXED 104 -#define TK_STRING 105 -#define TK_JOIN_KW 106 -#define TK_CONSTRAINT 107 -#define TK_DEFAULT 108 -#define TK_NULL 109 -#define TK_PRIMARY 110 -#define TK_UNIQUE 111 -#define TK_CHECK 112 -#define TK_REFERENCES 113 -#define TK_AUTOINCR 114 -#define TK_INSERT 115 -#define TK_DELETE 116 -#define TK_UPDATE 117 -#define TK_SET 118 -#define TK_DEFERRABLE 119 -#define TK_FOREIGN 120 -#define TK_DROP 121 -#define TK_UNION 122 -#define TK_ALL 123 -#define TK_EXCEPT 124 -#define TK_INTERSECT 125 -#define TK_SELECT 126 -#define TK_VALUES 127 -#define TK_DISTINCT 128 -#define TK_DOT 129 -#define TK_FROM 130 -#define TK_JOIN 131 -#define TK_USING 132 -#define TK_ORDER 133 -#define TK_GROUP 134 -#define TK_HAVING 135 -#define TK_LIMIT 136 -#define TK_WHERE 137 -#define TK_INTO 138 -#define TK_NOTHING 139 -#define TK_FLOAT 140 -#define TK_BLOB 141 -#define TK_INTEGER 142 -#define TK_VARIABLE 143 -#define TK_CASE 144 -#define TK_WHEN 145 -#define TK_THEN 146 -#define TK_ELSE 147 -#define TK_INDEX 148 -#define TK_ALTER 149 -#define TK_ADD 150 -#define TK_COLUMN 151 -#define TK_AGG_FUNCTION 152 -#define TK_AGG_COLUMN 153 -#define TK_TRUEFALSE 154 -#define TK_ISNOT 155 -#define TK_FUNCTION 156 -#define TK_UMINUS 157 -#define TK_UPLUS 158 -#define TK_TRUTH 159 -#define TK_REGISTER 160 -#define TK_VECTOR 161 -#define TK_SELECT_COLUMN 162 -#define TK_IF_NULL_ROW 163 -#define TK_ASTERISK 164 -#define TK_SPAN 165 -#define TK_SPACE 166 -#define TK_ILLEGAL 167 +#define TK_MATERIALIZED 87 +#define TK_REINDEX 88 +#define TK_RENAME 89 +#define TK_CTIME_KW 90 +#define TK_ANY 91 +#define TK_BITAND 92 +#define TK_BITOR 93 +#define TK_LSHIFT 94 +#define TK_RSHIFT 95 +#define TK_PLUS 96 +#define TK_MINUS 97 +#define TK_STAR 98 +#define TK_SLASH 99 +#define TK_REM 100 +#define TK_CONCAT 101 +#define TK_COLLATE 102 +#define TK_BITNOT 103 +#define TK_ON 104 +#define TK_INDEXED 105 +#define TK_STRING 106 +#define TK_JOIN_KW 107 +#define TK_CONSTRAINT 108 +#define TK_DEFAULT 109 +#define TK_NULL 110 +#define TK_PRIMARY 111 +#define TK_UNIQUE 112 +#define TK_CHECK 113 +#define TK_REFERENCES 114 +#define TK_AUTOINCR 115 +#define TK_INSERT 116 +#define TK_DELETE 117 +#define TK_UPDATE 118 +#define TK_SET 119 +#define TK_DEFERRABLE 120 +#define TK_FOREIGN 121 +#define TK_DROP 122 +#define TK_UNION 123 +#define TK_ALL 124 +#define TK_EXCEPT 125 +#define TK_INTERSECT 126 +#define TK_SELECT 127 +#define TK_VALUES 128 +#define TK_DISTINCT 129 +#define TK_DOT 130 +#define TK_FROM 131 +#define TK_JOIN 132 +#define TK_USING 133 +#define TK_ORDER 134 +#define TK_GROUP 135 +#define TK_HAVING 136 +#define TK_LIMIT 137 +#define TK_WHERE 138 +#define TK_RETURNING 139 +#define TK_INTO 140 +#define TK_NOTHING 141 +#define TK_FLOAT 142 +#define TK_BLOB 143 +#define TK_INTEGER 144 +#define TK_VARIABLE 145 +#define TK_CASE 146 +#define TK_WHEN 147 +#define TK_THEN 148 +#define TK_ELSE 149 +#define TK_INDEX 150 +#define TK_ALTER 151 +#define TK_ADD 152 +#define TK_COLUMN 153 +#define TK_AGG_FUNCTION 154 +#define TK_AGG_COLUMN 155 +#define TK_TRUEFALSE 156 +#define TK_ISNOT 157 +#define TK_FUNCTION 158 +#define TK_UMINUS 159 +#define TK_UPLUS 160 +#define TK_TRUTH 161 +#define TK_REGISTER 162 +#define TK_VECTOR 163 +#define TK_SELECT_COLUMN 164 +#define TK_IF_NULL_ROW 165 +#define TK_ASTERISK 166 +#define TK_SPAN 167 +#define TK_SPACE 168 +#define TK_ILLEGAL 169 /************** End of parse.h ***********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -14581,15 +14626,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 @@ -14598,6 +14642,19 @@ typedef INT16_TYPE LogEst; #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. ** @@ -14708,7 +14765,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; @@ -14726,14 +14786,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; @@ -15305,6 +15368,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. @@ -15404,6 +15468,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 @@ -15703,103 +15769,105 @@ typedef struct VdbeOpList VdbeOpList; #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_BitAnd 91 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ -#define OP_BitOr 92 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ -#define OP_ShiftLeft 93 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ -#define OP_ShiftRight 94 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ -#define OP_Add 95 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ -#define OP_Subtract 96 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ -#define OP_Multiply 97 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ -#define OP_Divide 98 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ -#define OP_Remainder 99 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ -#define OP_Concat 100 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ -#define OP_MakeRecord 101 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ -#define OP_BitNot 102 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ -#define OP_Count 103 /* synopsis: r[P2]=count() */ -#define OP_ReadCookie 104 -#define OP_String8 105 /* same as TK_STRING, synopsis: r[P2]='P4' */ -#define OP_SetCookie 106 -#define OP_ReopenIdx 107 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenRead 108 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenWrite 109 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenDup 110 -#define OP_OpenAutoindex 111 /* synopsis: nColumn=P2 */ -#define OP_OpenEphemeral 112 /* synopsis: nColumn=P2 */ -#define OP_SorterOpen 113 -#define OP_SequenceTest 114 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ -#define OP_OpenPseudo 115 /* synopsis: P3 columns in r[P2] */ -#define OP_Close 116 -#define OP_ColumnsUsed 117 -#define OP_SeekScan 118 /* synopsis: Scan-ahead up to P1 rows */ -#define OP_SeekHit 119 /* synopsis: set P2<=seekHit<=P3 */ -#define OP_Sequence 120 /* synopsis: r[P2]=cursor[P1].ctr++ */ -#define OP_NewRowid 121 /* synopsis: r[P2]=rowid */ -#define OP_Insert 122 /* synopsis: intkey=r[P3] data=r[P2] */ -#define OP_Delete 123 -#define OP_ResetCount 124 -#define OP_SorterCompare 125 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ -#define OP_SorterData 126 /* synopsis: r[P2]=data */ -#define OP_RowData 127 /* synopsis: r[P2]=data */ -#define OP_Rowid 128 /* synopsis: r[P2]=rowid */ -#define OP_NullRow 129 -#define OP_SeekEnd 130 -#define OP_IdxInsert 131 /* synopsis: key=r[P2] */ -#define OP_SorterInsert 132 /* synopsis: key=r[P2] */ -#define OP_IdxDelete 133 /* synopsis: key=r[P2@P3] */ -#define OP_DeferredSeek 134 /* synopsis: Move P3 to P1.rowid if needed */ -#define OP_IdxRowid 135 /* synopsis: r[P2]=rowid */ -#define OP_FinishSeek 136 -#define OP_Destroy 137 -#define OP_Clear 138 -#define OP_ResetSorter 139 -#define OP_Real 140 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_CreateBtree 141 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ -#define OP_SqlExec 142 -#define OP_ParseSchema 143 -#define OP_LoadAnalysis 144 -#define OP_DropTable 145 -#define OP_DropIndex 146 -#define OP_DropTrigger 147 -#define OP_IntegrityCk 148 -#define OP_RowSetAdd 149 /* synopsis: rowset(P1)=r[P2] */ -#define OP_Param 150 -#define OP_FkCounter 151 /* synopsis: fkctr[P1]+=P2 */ -#define OP_MemMax 152 /* synopsis: r[P1]=max(r[P1],r[P2]) */ -#define OP_OffsetLimit 153 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -#define OP_AggInverse 154 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ -#define OP_AggStep 155 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggStep1 156 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggValue 157 /* synopsis: r[P3]=value N=P2 */ -#define OP_AggFinal 158 /* synopsis: accum=r[P1] N=P2 */ -#define OP_Expire 159 -#define OP_CursorLock 160 -#define OP_CursorUnlock 161 -#define OP_TableLock 162 /* synopsis: iDb=P1 root=P2 write=P3 */ -#define OP_VBegin 163 -#define OP_VCreate 164 -#define OP_VDestroy 165 -#define OP_VOpen 166 -#define OP_VColumn 167 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VRename 168 -#define OP_Pagecount 169 -#define OP_MaxPgcnt 170 -#define OP_Trace 171 -#define OP_CursorHint 172 -#define OP_ReleaseReg 173 /* synopsis: release r[P1@P2] mask P3 */ -#define OP_Noop 174 -#define OP_Explain 175 -#define OP_Abortable 176 +#define OP_ChngCntRow 80 /* synopsis: output=r[P1] */ +#define OP_ResultRow 81 /* synopsis: output=r[P1@P2] */ +#define OP_CollSeq 82 +#define OP_AddImm 83 /* synopsis: r[P1]=r[P1]+P2 */ +#define OP_RealAffinity 84 +#define OP_Cast 85 /* synopsis: affinity(r[P1]) */ +#define OP_Permutation 86 +#define OP_Compare 87 /* synopsis: r[P1@P3] <-> r[P2@P3] */ +#define OP_IsTrue 88 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ +#define OP_Offset 89 /* synopsis: r[P3] = sqlite_offset(P1) */ +#define OP_Column 90 /* synopsis: r[P3]=PX */ +#define OP_Affinity 91 /* synopsis: affinity(r[P1@P2]) */ +#define OP_BitAnd 92 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ +#define OP_BitOr 93 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ +#define OP_ShiftLeft 94 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */ +#define OP_ShiftRight 95 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */ +#define OP_Add 96 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ +#define OP_Subtract 97 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ +#define OP_Multiply 98 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ +#define OP_Divide 99 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ +#define OP_Remainder 100 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ +#define OP_Concat 101 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ +#define OP_MakeRecord 102 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ +#define OP_BitNot 103 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ +#define OP_Count 104 /* synopsis: r[P2]=count() */ +#define OP_ReadCookie 105 +#define OP_String8 106 /* same as TK_STRING, synopsis: r[P2]='P4' */ +#define OP_SetCookie 107 +#define OP_ReopenIdx 108 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenRead 109 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenWrite 110 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenDup 111 +#define OP_OpenAutoindex 112 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 113 /* synopsis: nColumn=P2 */ +#define OP_SorterOpen 114 +#define OP_SequenceTest 115 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ +#define OP_OpenPseudo 116 /* synopsis: P3 columns in r[P2] */ +#define OP_Close 117 +#define OP_ColumnsUsed 118 +#define OP_SeekScan 119 /* synopsis: Scan-ahead up to P1 rows */ +#define OP_SeekHit 120 /* synopsis: set P2<=seekHit<=P3 */ +#define OP_Sequence 121 /* synopsis: r[P2]=cursor[P1].ctr++ */ +#define OP_NewRowid 122 /* synopsis: r[P2]=rowid */ +#define OP_Insert 123 /* synopsis: intkey=r[P3] data=r[P2] */ +#define OP_RowCell 124 +#define OP_Delete 125 +#define OP_ResetCount 126 +#define OP_SorterCompare 127 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ +#define OP_SorterData 128 /* synopsis: r[P2]=data */ +#define OP_RowData 129 /* synopsis: r[P2]=data */ +#define OP_Rowid 130 /* synopsis: r[P2]=rowid */ +#define OP_NullRow 131 +#define OP_SeekEnd 132 +#define OP_IdxInsert 133 /* synopsis: key=r[P2] */ +#define OP_SorterInsert 134 /* synopsis: key=r[P2] */ +#define OP_IdxDelete 135 /* synopsis: key=r[P2@P3] */ +#define OP_DeferredSeek 136 /* synopsis: Move P3 to P1.rowid if needed */ +#define OP_IdxRowid 137 /* synopsis: r[P2]=rowid */ +#define OP_FinishSeek 138 +#define OP_Destroy 139 +#define OP_Clear 140 +#define OP_ResetSorter 141 +#define OP_Real 142 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ +#define OP_CreateBtree 143 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ +#define OP_SqlExec 144 +#define OP_ParseSchema 145 +#define OP_LoadAnalysis 146 +#define OP_DropTable 147 +#define OP_DropIndex 148 +#define OP_DropTrigger 149 +#define OP_IntegrityCk 150 +#define OP_RowSetAdd 151 /* synopsis: rowset(P1)=r[P2] */ +#define OP_Param 152 +#define OP_FkCounter 153 /* synopsis: fkctr[P1]+=P2 */ +#define OP_MemMax 154 /* synopsis: r[P1]=max(r[P1],r[P2]) */ +#define OP_OffsetLimit 155 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ +#define OP_AggInverse 156 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ +#define OP_AggStep 157 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggStep1 158 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggValue 159 /* synopsis: r[P3]=value N=P2 */ +#define OP_AggFinal 160 /* synopsis: accum=r[P1] N=P2 */ +#define OP_Expire 161 +#define OP_CursorLock 162 +#define OP_CursorUnlock 163 +#define OP_TableLock 164 /* synopsis: iDb=P1 root=P2 write=P3 */ +#define OP_VBegin 165 +#define OP_VCreate 166 +#define OP_VDestroy 167 +#define OP_VOpen 168 +#define OP_VColumn 169 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VRename 170 +#define OP_Pagecount 171 +#define OP_MaxPgcnt 172 +#define OP_Trace 173 +#define OP_CursorHint 174 +#define OP_ReleaseReg 175 /* synopsis: release r[P1@P2] mask P3 */ +#define OP_Noop 176 +#define OP_Explain 177 +#define OP_Abortable 178 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c @@ -15822,19 +15890,19 @@ typedef struct VdbeOpList VdbeOpList; /* 56 */ 0x01, 0x03, 0x03, 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, 0x26, 0x26, 0x26, 0x26, 0x26,\ -/* 96 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12, 0x10,\ -/* 104 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 80 */ 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\ +/* 88 */ 0x12, 0x20, 0x00, 0x00, 0x26, 0x26, 0x26, 0x26,\ +/* 96 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00, 0x12,\ +/* 104 */ 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 128 */ 0x10, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10,\ -/* 136 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ -/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x00,\ -/* 152 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 120 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 128 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x04, 0x04, 0x00,\ +/* 136 */ 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x10, 0x10,\ +/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,\ +/* 152 */ 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00,\ /* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 168 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 176 */ 0x00,} +/* 168 */ 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00,\ +/* 176 */ 0x00, 0x00, 0x00,} /* The sqlite3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum @@ -15902,7 +15970,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); @@ -16874,6 +16942,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. @@ -16894,7 +16967,7 @@ struct sqlite3 { int errCode; /* Most recent error code (SQLITE_*) */ 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 */ @@ -16921,7 +16994,10 @@ 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 */ + unsigned bDropColumn : 1; /* Doing schema check after DROP COLUMN */ char **azInit; /* "type", "name", and "tbl_name" columns */ + /* or if bDropColumn, then azInit[0] is the */ + /* name of the column being dropped */ } init; int nVdbeActive; /* Number of VDBEs currently running */ int nVdbeRead; /* Number of active VDBEs that read or write */ @@ -17101,24 +17177,26 @@ 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_ExistsToIN 0x00020000 /* The EXISTS-to-IN optimization */ +#define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. @@ -17274,6 +17352,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 @@ -17309,6 +17390,9 @@ struct FuncDestructor { #define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } +#define MFUNCTION(zName, nArg, xPtr, xFunc) \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ + xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } @@ -17403,7 +17487,12 @@ struct Column { u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */ }; -/* Allowed values for Column.colFlags: +/* 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 */ @@ -17579,7 +17668,6 @@ struct Table { #endif Trigger *pTrigger; /* List of triggers stored in pSchema */ Schema *pSchema; /* Schema that contains this table */ - Table *pNextZombie; /* Next on the Parse.pZombieTab list */ }; /* @@ -17593,11 +17681,12 @@ struct Table { ** ** Constraints: ** -** TF_HasVirtual == COLFLAG_Virtual -** TF_HasStored == COLFLAG_Stored +** TF_HasVirtual == COLFLAG_VIRTUAL +** TF_HasStored == COLFLAG_STORED +** TF_HasHidden == COLFLAG_HIDDEN */ #define TF_Readonly 0x0001 /* Read-only system table */ -#define TF_Ephemeral 0x0002 /* An ephemeral table */ +#define TF_HasHidden 0x0002 /* Has one or more hidden columns */ #define TF_HasPrimaryKey 0x0004 /* Table has a primary key */ #define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */ #define TF_HasStat1 0x0010 /* nRowLogEst set from sqlite_stat1 */ @@ -17612,6 +17701,7 @@ struct Table { #define TF_HasNotNull 0x0800 /* Contains NOT NULL constraints */ #define TF_Shadow 0x1000 /* True for a shadow table */ #define TF_HasStat4 0x2000 /* STAT4 info available for this table */ +#define TF_Ephemeral 0x4000 /* An ephemeral table */ /* ** Test to see whether or not a table is a virtual table. This is @@ -17708,16 +17798,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 */ @@ -17974,7 +18070,6 @@ struct AggInfo { } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ - AggInfo *pNext; /* Next in list of them all */ }; /* @@ -18103,7 +18198,7 @@ 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 */ + int iRightJoinTable; /* If EP_FromJoin, the right table of the join */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ union { Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL @@ -18145,7 +18240,7 @@ struct Expr { #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 */ @@ -18294,6 +18389,45 @@ struct IdList { }; /* +** The SrcItem object represents a single term in the FROM clause of a query. +** The SrcList object is mostly an array of SrcItems. +*/ +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 */ + } 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<<N) set if column N of pTab is used */ + union { + char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" 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 ** the SrcList.a[] array. @@ -18315,36 +18449,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<<N) set if column N of pTab is used */ - union { - char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" 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 */ }; /* @@ -18420,6 +18525,7 @@ 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 */ @@ -18448,6 +18554,7 @@ struct NameContext { #define NC_UEList 0x00080 /* True if uNC.pEList is used */ #define NC_UAggInfo 0x00100 /* True if uNC.pAggInfo is used */ #define NC_UUpsert 0x00200 /* True if uNC.pUpsert is used */ +#define NC_UBaseReg 0x00400 /* True if uNC.iBaseReg is used */ #define NC_MinMaxAgg 0x01000 /* min/max aggregates seen. See note above */ #define NC_Complex 0x02000 /* True if a function or subquery seen */ #define NC_AllowWin 0x04000 /* Window functions are allowed here */ @@ -18471,15 +18578,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 */ @@ -18559,6 +18672,8 @@ struct Select { #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_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ +#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ /* ** The results of a SELECT can be distributed in several ways, as defined @@ -18730,6 +18845,17 @@ struct TriggerPrg { #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 ** carry around information that is global to the entire parse. @@ -18760,6 +18886,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 */ @@ -18787,12 +18916,15 @@ struct Parse { 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 */ + 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 */ @@ -18838,10 +18970,9 @@ 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 */ + ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */ #ifndef SQLITE_OMIT_ALTERTABLE RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */ #endif @@ -18921,6 +19052,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 @@ -18942,6 +19074,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 <column-list> trigger, the <column-list> is stored here */ @@ -19000,14 +19133,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 */ @@ -19016,18 +19150,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 */ }; /* @@ -19067,7 +19199,8 @@ typedef struct { /* ** Allowed values for mInitFlags */ -#define INITFLAG_AlterTable 0x0001 /* This is a reparse after ALTER TABLE */ +#define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */ +#define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */ /* ** Structure containing global configuration data for the SQLite library. @@ -19179,10 +19312,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*); @@ -19208,20 +19357,55 @@ 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 */ + 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 @@ -19567,6 +19751,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,Expr*,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*); @@ -19615,6 +19800,7 @@ 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 sqlite3AddReturning(Parse*,ExprList*); SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); #define sqlite3CodecQueryParameters(A,B,C) 0 @@ -19680,7 +19866,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*); @@ -19708,6 +19894,7 @@ 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*); @@ -19741,7 +19928,7 @@ 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 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*); @@ -19869,6 +20056,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); @@ -19891,7 +20079,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*); @@ -19954,6 +20141,7 @@ 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); @@ -20017,7 +20205,6 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; 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 @@ -20036,7 +20223,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*, struct SrcList_item*); +SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, SrcItem*); SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); SQLITE_PRIVATE int sqlite3MatchEName( const struct ExprList_item*, @@ -20054,6 +20241,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); +SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse*, SrcList*, Token*); SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse*, void*, Token*); SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*); @@ -20077,6 +20265,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 @@ -20207,6 +20396,7 @@ 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 *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*); #ifdef SQLITE_ENABLE_NORMALIZE SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*); #endif @@ -20221,23 +20411,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); #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) #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 @@ -20733,9 +20932,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" */ /* @@ -20859,6 +21059,7 @@ 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 hasBeenDuped:1; /* This cursor was source or target of OP_OpenDup */ u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ Btree *pBtx; /* Separate file holding temporary table */ i64 seqCount; /* Sequence counter */ @@ -21154,7 +21355,7 @@ 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 */ @@ -22659,6 +22860,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 @@ -23159,6 +23361,8 @@ SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ #ifdef SQLITE_TEST if( op!=SQLITE_FCNTL_COMMIT_PHASETWO && op!=SQLITE_FCNTL_LOCK_TIMEOUT + && op!=SQLITE_FCNTL_CKPT_DONE + && op!=SQLITE_FCNTL_CKPT_START ){ /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite ** is using a regular VFS, it is called after the corresponding @@ -23169,7 +23373,12 @@ SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ ** The core must call OsFileControl() though, not OsFileControlHint(), ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably ** means the commit really has failed and an error should be returned - ** to the user. */ + ** to the user. + ** + ** The CKPT_DONE and CKPT_START file-controls are write-only signals + ** to the cksumvfs. Their return code is meaningless and is ignored + ** by the SQLite core, so there is no point in simulating OOMs for them. + */ DO_OS_MALLOC_TEST(id); } #endif @@ -29068,7 +29277,7 @@ SQLITE_API void sqlite3_str_vappendf( case etSRCLIST: { SrcList *pSrc; int k; - struct SrcList_item *pItem; + SrcItem *pItem; if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; pSrc = va_arg(ap, SrcList*); k = va_arg(ap, int); @@ -29133,7 +29342,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ }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 */ @@ -29636,7 +29845,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, i<pWith->nCte-1); sqlite3TreeViewSelect(pView, pCte->pSelect, 0); @@ -29652,7 +29864,7 @@ 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; i<pSrc->nSrc; 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); @@ -29675,6 +29887,9 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) 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, i<pSrc->nSrc-1); if( pItem->pSelect ){ @@ -31372,6 +31587,16 @@ SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ } /* +** 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; + if( db->pErr ) sqlite3ValueSetNull(db->pErr); +} + +/* ** Load the sqlite3.iSysErrno field if that is an appropriate thing ** to do based on the SQLite error code in rc. */ @@ -33317,103 +33542,105 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 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 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), - /* 92 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), - /* 93 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), - /* 94 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), - /* 95 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), - /* 96 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), - /* 97 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), - /* 98 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), - /* 99 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), - /* 100 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), - /* 101 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), - /* 102 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), - /* 103 */ "Count" OpHelp("r[P2]=count()"), - /* 104 */ "ReadCookie" OpHelp(""), - /* 105 */ "String8" OpHelp("r[P2]='P4'"), - /* 106 */ "SetCookie" OpHelp(""), - /* 107 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), - /* 108 */ "OpenRead" OpHelp("root=P2 iDb=P3"), - /* 109 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), - /* 110 */ "OpenDup" OpHelp(""), - /* 111 */ "OpenAutoindex" OpHelp("nColumn=P2"), - /* 112 */ "OpenEphemeral" OpHelp("nColumn=P2"), - /* 113 */ "SorterOpen" OpHelp(""), - /* 114 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), - /* 115 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), - /* 116 */ "Close" OpHelp(""), - /* 117 */ "ColumnsUsed" OpHelp(""), - /* 118 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), - /* 119 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), - /* 120 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), - /* 121 */ "NewRowid" OpHelp("r[P2]=rowid"), - /* 122 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), - /* 123 */ "Delete" OpHelp(""), - /* 124 */ "ResetCount" OpHelp(""), - /* 125 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), - /* 126 */ "SorterData" OpHelp("r[P2]=data"), - /* 127 */ "RowData" OpHelp("r[P2]=data"), - /* 128 */ "Rowid" OpHelp("r[P2]=rowid"), - /* 129 */ "NullRow" OpHelp(""), - /* 130 */ "SeekEnd" OpHelp(""), - /* 131 */ "IdxInsert" OpHelp("key=r[P2]"), - /* 132 */ "SorterInsert" OpHelp("key=r[P2]"), - /* 133 */ "IdxDelete" OpHelp("key=r[P2@P3]"), - /* 134 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), - /* 135 */ "IdxRowid" OpHelp("r[P2]=rowid"), - /* 136 */ "FinishSeek" OpHelp(""), - /* 137 */ "Destroy" OpHelp(""), - /* 138 */ "Clear" OpHelp(""), - /* 139 */ "ResetSorter" OpHelp(""), - /* 140 */ "Real" OpHelp("r[P2]=P4"), - /* 141 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), - /* 142 */ "SqlExec" OpHelp(""), - /* 143 */ "ParseSchema" OpHelp(""), - /* 144 */ "LoadAnalysis" OpHelp(""), - /* 145 */ "DropTable" OpHelp(""), - /* 146 */ "DropIndex" OpHelp(""), - /* 147 */ "DropTrigger" OpHelp(""), - /* 148 */ "IntegrityCk" OpHelp(""), - /* 149 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), - /* 150 */ "Param" OpHelp(""), - /* 151 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), - /* 152 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), - /* 153 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), - /* 154 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), - /* 155 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 156 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 157 */ "AggValue" OpHelp("r[P3]=value N=P2"), - /* 158 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 159 */ "Expire" OpHelp(""), - /* 160 */ "CursorLock" OpHelp(""), - /* 161 */ "CursorUnlock" OpHelp(""), - /* 162 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), - /* 163 */ "VBegin" OpHelp(""), - /* 164 */ "VCreate" OpHelp(""), - /* 165 */ "VDestroy" OpHelp(""), - /* 166 */ "VOpen" OpHelp(""), - /* 167 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 168 */ "VRename" OpHelp(""), - /* 169 */ "Pagecount" OpHelp(""), - /* 170 */ "MaxPgcnt" OpHelp(""), - /* 171 */ "Trace" OpHelp(""), - /* 172 */ "CursorHint" OpHelp(""), - /* 173 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), - /* 174 */ "Noop" OpHelp(""), - /* 175 */ "Explain" OpHelp(""), - /* 176 */ "Abortable" OpHelp(""), + /* 80 */ "ChngCntRow" OpHelp("output=r[P1]"), + /* 81 */ "ResultRow" OpHelp("output=r[P1@P2]"), + /* 82 */ "CollSeq" OpHelp(""), + /* 83 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), + /* 84 */ "RealAffinity" OpHelp(""), + /* 85 */ "Cast" OpHelp("affinity(r[P1])"), + /* 86 */ "Permutation" OpHelp(""), + /* 87 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), + /* 88 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), + /* 89 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), + /* 90 */ "Column" OpHelp("r[P3]=PX"), + /* 91 */ "Affinity" OpHelp("affinity(r[P1@P2])"), + /* 92 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), + /* 93 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), + /* 94 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"), + /* 95 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"), + /* 96 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), + /* 97 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), + /* 98 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), + /* 99 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), + /* 100 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), + /* 101 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), + /* 102 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), + /* 103 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), + /* 104 */ "Count" OpHelp("r[P2]=count()"), + /* 105 */ "ReadCookie" OpHelp(""), + /* 106 */ "String8" OpHelp("r[P2]='P4'"), + /* 107 */ "SetCookie" OpHelp(""), + /* 108 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), + /* 109 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 110 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 111 */ "OpenDup" OpHelp(""), + /* 112 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 113 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 114 */ "SorterOpen" OpHelp(""), + /* 115 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), + /* 116 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), + /* 117 */ "Close" OpHelp(""), + /* 118 */ "ColumnsUsed" OpHelp(""), + /* 119 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), + /* 120 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), + /* 121 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), + /* 122 */ "NewRowid" OpHelp("r[P2]=rowid"), + /* 123 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), + /* 124 */ "RowCell" OpHelp(""), + /* 125 */ "Delete" OpHelp(""), + /* 126 */ "ResetCount" OpHelp(""), + /* 127 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), + /* 128 */ "SorterData" OpHelp("r[P2]=data"), + /* 129 */ "RowData" OpHelp("r[P2]=data"), + /* 130 */ "Rowid" OpHelp("r[P2]=rowid"), + /* 131 */ "NullRow" OpHelp(""), + /* 132 */ "SeekEnd" OpHelp(""), + /* 133 */ "IdxInsert" OpHelp("key=r[P2]"), + /* 134 */ "SorterInsert" OpHelp("key=r[P2]"), + /* 135 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 136 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), + /* 137 */ "IdxRowid" OpHelp("r[P2]=rowid"), + /* 138 */ "FinishSeek" OpHelp(""), + /* 139 */ "Destroy" OpHelp(""), + /* 140 */ "Clear" OpHelp(""), + /* 141 */ "ResetSorter" OpHelp(""), + /* 142 */ "Real" OpHelp("r[P2]=P4"), + /* 143 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), + /* 144 */ "SqlExec" OpHelp(""), + /* 145 */ "ParseSchema" OpHelp(""), + /* 146 */ "LoadAnalysis" OpHelp(""), + /* 147 */ "DropTable" OpHelp(""), + /* 148 */ "DropIndex" OpHelp(""), + /* 149 */ "DropTrigger" OpHelp(""), + /* 150 */ "IntegrityCk" OpHelp(""), + /* 151 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), + /* 152 */ "Param" OpHelp(""), + /* 153 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 154 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), + /* 155 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), + /* 156 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), + /* 157 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 158 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 159 */ "AggValue" OpHelp("r[P3]=value N=P2"), + /* 160 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 161 */ "Expire" OpHelp(""), + /* 162 */ "CursorLock" OpHelp(""), + /* 163 */ "CursorUnlock" OpHelp(""), + /* 164 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 165 */ "VBegin" OpHelp(""), + /* 166 */ "VCreate" OpHelp(""), + /* 167 */ "VDestroy" OpHelp(""), + /* 168 */ "VOpen" OpHelp(""), + /* 169 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 170 */ "VRename" OpHelp(""), + /* 171 */ "Pagecount" OpHelp(""), + /* 172 */ "MaxPgcnt" OpHelp(""), + /* 173 */ "Trace" OpHelp(""), + /* 174 */ "CursorHint" OpHelp(""), + /* 175 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), + /* 176 */ "Noop" OpHelp(""), + /* 177 */ "Explain" OpHelp(""), + /* 178 */ "Abortable" OpHelp(""), }; return azName[i]; } @@ -39982,7 +40209,8 @@ static int unixBackupDir(const char *z, int *pJ){ int j = *pJ; int i; if( j<=0 ) return 0; - for(i=j-1; ALWAYS(i>0) && z[i-1]!='/'; i--){} + 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; @@ -52341,6 +52569,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 @@ -52976,6 +53205,9 @@ static int subjRequiresPage(PgHdr *pPg){ for(i=0; i<pPager->nSavepoint; i++){ p = &pPager->aSavepoint[i]; if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){ + for(i=i+1; i<pPager->nSavepoint; i++){ + pPager->aSavepoint[i].bTruncateOnRelease = 0; + } return 1; } } @@ -58754,6 +58986,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; } @@ -58835,13 +59068,15 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ /* If this is a release of the outermost savepoint, truncate ** the sub-journal to zero bytes in size. */ 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)*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. @@ -64032,7 +64267,7 @@ 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 @@ -64137,6 +64372,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() */ }; /* @@ -65851,6 +66087,24 @@ static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow( } /* +** 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. ** @@ -67426,19 +67680,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 @@ -67590,6 +67848,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); } @@ -68819,7 +69078,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); } @@ -69229,7 +69488,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; @@ -72663,6 +72929,9 @@ static int balance_nonroot( apOld[i] = 0; rc = sqlite3PagerWrite(pNew->pDbPage); nNew++; + if( sqlite3PagerPageRefcount(pNew->pDbPage)!=1+(i==(iParentIdx-nxDiv)) ){ + rc = SQLITE_CORRUPT_BKPT; + } if( rc ) goto balance_cleanup; }else{ assert( i>0 ); @@ -72699,7 +72968,7 @@ static int balance_nonroot( aPgOrder[i] = aPgno[i] = apNew[i]->pgno; aPgFlags[i] = apNew[i]->pDbPage->flags; for(j=0; j<i; j++){ - if( aPgno[j]==aPgno[i] ){ + if( NEVER(aPgno[j]==aPgno[i]) ){ /* This branch is taken if the set of sibling pages somehow contains ** duplicate entries. This can happen if the database is corrupt. ** It would be simpler to detect this as part of the loop below, but @@ -73367,7 +73636,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 ); @@ -73385,7 +73655,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. ** @@ -73495,7 +73765,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( || 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 ){ @@ -73512,7 +73782,21 @@ 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) ); @@ -73620,6 +73904,114 @@ end_insert: } /* +** 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 && nIn<pDest->pPage->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( nOut<pSrc->info.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 ){ + 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. ** ** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then @@ -74216,7 +74608,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]); } @@ -78007,7 +78399,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 ); @@ -78208,7 +78600,7 @@ 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); @@ -78443,9 +78835,10 @@ 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; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j); sqlite3MayAbort(p->pParse); } @@ -78537,7 +78930,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 @@ -78862,7 +79255,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; } @@ -78947,7 +79340,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; } @@ -79271,7 +79664,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); @@ -79400,7 +79793,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; } @@ -80085,7 +80478,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 @@ -80265,14 +80658,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; i<p->nMem; i++){ @@ -80328,8 +80721,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; @@ -80414,8 +80809,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( } } - p->pVList = pParse->pVList; - pParse->pVList = 0; if( db->mallocFailed ){ p->nVar = 0; p->nCursor = 0; @@ -80443,20 +80836,15 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ return; } assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE ); + assert( pCx->pBtx==0 || pCx->isEphemeral ); switch( pCx->eCurType ){ case CURTYPE_SORTER: { sqlite3VdbeSorterClose(p->db, pCx); 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 @@ -81013,7 +81401,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 ){ @@ -81171,7 +81559,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; @@ -81344,7 +81732,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ } } #endif - p->magic = VDBE_MAGIC_RESET; + p->iVdbeMagic = VDBE_MAGIC_RESET; return p->rc & db->errMask; } @@ -81354,7 +81742,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 ); } @@ -81415,7 +81803,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); @@ -81463,7 +81851,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); } @@ -81540,6 +81928,7 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){ assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); if( p->deferredMoveto ){ u32 iMap; + assert( !p->isEphemeral ); if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 && !p->nullRow ){ *pp = p->pAltCursor; *piCol = iMap - 1; @@ -83842,7 +84231,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 @@ -84558,7 +84947,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, @@ -84912,7 +85301,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; } /* @@ -85404,7 +85793,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 ){ @@ -85748,11 +86137,6 @@ static VdbeCursor *allocateCursor( assert( iCur>=0 && iCur<p->nCursor ); 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; } @@ -86250,7 +86634,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 ){ @@ -87010,6 +87394,26 @@ case OP_IntCopy: { /* out2 */ break; } +/* Opcode: ChngCntRow P1 P2 * * * +** Synopsis: output=r[P1] +** +** Output value in register P1 as the chance count for a DML statement, +** due to the "PRAGMA count_changes=ON" setting. Or, if there was a +** foreign key error in the statement, trigger the error now. +** +** This opcode is a variant of OP_ResultRow that checks the foreign key +** immediate constraint count and throws an error if the count is +** non-zero. The P2 opcode must be 1. +*/ +case OP_ChngCntRow: { + assert( pOp->p2==1 ); + if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){ + goto abort_due_to_error; + } + /* Fall through to the next case, OP_ResultRow */ + /* no break */ deliberate_fall_through +} + /* Opcode: ResultRow P1 P2 * * * ** Synopsis: output=r[P1@P2] ** @@ -87026,34 +87430,6 @@ case OP_ResultRow: { assert( pOp->p1>0 ); 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; @@ -89446,7 +89822,7 @@ 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); if( pCx==0 ) goto no_mem; @@ -89456,7 +89832,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->pBtx = pOrig->pBtx; + pCx->hasBeenDuped = 1; + pOrig->hasBeenDuped = 1; + rc = sqlite3BtreeCursor(pCx->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 @@ -89522,9 +89901,10 @@ case OP_OpenEphemeral: { 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 ){ + /* 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; @@ -89538,33 +89918,36 @@ case OP_OpenEphemeral: { 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); + 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); + } + pCx->isTable = 0; + }else{ + pCx->pgnoRoot = SCHEMA_ROOT; + rc = sqlite3BtreeCursor(pCx->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->pBtx); } } - pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); } if( rc ) goto abort_due_to_error; pCx->nullRow = 1; @@ -89998,13 +90381,13 @@ seek_not_found: ** ** There are three possible outcomes from this opcode:<ol> ** -** <li> If after This.P1 steps, the cursor is still point to a place that -** is earlier in the btree than the target row, -** then fall through into the subsquence OP_SeekGE opcode. +** <li> 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. ** ** <li> 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 opcode that follows the OP_SeekGE. +** past the OP_IdxGT or OP_IdxGE opcode that follows the OP_SeekGE. ** ** <li> 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. @@ -90021,7 +90404,8 @@ case OP_SeekScan: { /* 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 ); + 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 ); @@ -90474,8 +90858,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; @@ -90691,7 +91077,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; @@ -90708,6 +91095,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. @@ -91363,7 +91777,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 ); @@ -91374,7 +91788,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 ); @@ -91447,7 +91861,7 @@ case OP_IdxDelete: { rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); if( rc ) goto abort_due_to_error; }else if( pOp->p5 ){ - rc = SQLITE_CORRUPT_INDEX; + rc = sqlite3ReportError(SQLITE_CORRUPT_INDEX, __LINE__, "index corruption"); goto abort_due_to_error; } assert( pC->deferredMoveto==0 ); @@ -91526,6 +91940,8 @@ case OP_IdxRowid: { /* out2 */ pTabCur->deferredMoveto = 1; assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); pTabCur->aAltMap = pOp->p4.ai; + assert( !pC->isEphemeral ); + assert( !pTabCur->isEphemeral ); pTabCur->pAltCursor = pC; }else{ pOut = out2Prerelease(p, pOp); @@ -91873,7 +92289,7 @@ case OP_ParseSchema: { 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 @@ -97581,7 +97997,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() */ @@ -97642,14 +98057,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; } /* @@ -97676,7 +98090,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 ){ @@ -97759,7 +98173,6 @@ static int memjrnlWrite( nWrite -= iSpace; p->endpoint.iOffset += iSpace; } - p->nSize = iAmt + iOfst; } } @@ -97767,22 +98180,30 @@ 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; - p->readpoint.pChunk = 0; - p->readpoint.iOffset = 0; + FileChunk *pIter = 0; + + if( size==0 ){ + memjrnlFreeChunks(p->pFirst); + p->pFirst = 0; + }else{ + i64 iOff = p->nChunkSize; + for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){ + 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; return SQLITE_OK; } @@ -97791,7 +98212,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; } @@ -97965,7 +98386,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; @@ -97984,6 +98405,7 @@ static int walkWindowList(Walker *pWalker, Window *pList){ if( NEVER(rc) ) return WRC_Abort; rc = sqlite3WalkExpr(pWalker, pWin->pEnd); if( NEVER(rc) ) return WRC_Abort; + if( bOneOnly ) break; } return WRC_Continue; } @@ -98031,7 +98453,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 } @@ -98078,7 +98500,7 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ if( pParse && IN_RENAME_OBJECT ){ /* 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; } } @@ -98096,7 +98518,7 @@ 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 ){ @@ -98262,7 +98684,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 */ @@ -98275,7 +98696,7 @@ static void resolveAlias( db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); if( pDup!=0 ){ - if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); + incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } @@ -98304,7 +98725,6 @@ static void resolveAlias( } sqlite3DbFree(db, pDup); } - ExprSetProperty(pExpr, EP_Alias); } @@ -98439,8 +98859,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 */ @@ -98561,25 +98981,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; @@ -98607,6 +99035,7 @@ static int lookupName( } if( iCol<pTab->nCol ){ cnt++; + pMatch = 0; #ifndef SQLITE_OMIT_UPSERT if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){ testcase( iCol==(-1) ); @@ -98618,27 +99047,32 @@ 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)<<iCol)); - }else{ - testcase( iCol==31 ); - testcase( iCol==32 ); - pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); - } pExpr->y.pTab = pTab; - pExpr->iColumn = (i16)iCol; - eNewExprOp = TK_TRIGGER; + if( pParse->bReturning ){ + eNewExprOp = TK_REGISTER; + 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)<<iCol)); + }else{ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); + } #endif /* SQLITE_OMIT_TRIGGER */ + } } } } @@ -98708,7 +99142,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 ); @@ -98743,6 +99177,7 @@ static int lookupName( assert( pExpr->op==TK_ID ); if( ExprHasProperty(pExpr,EP_DblQuoted) && areDoubleQuotedStringsEnabled(db, pTopNC) + && (db->init.bDropColumn==0 || sqlite3StrICmp(zCol, db->init.azInit[0])!=0) ){ /* If a double-quoted identifier does not match any known column name, ** then treat it as a string. @@ -98757,6 +99192,11 @@ static int lookupName( ** Someday, I hope to get rid of this hack. Unfortunately there is ** a huge amount of legacy SQL that uses it. So for now, we just ** issue a warning. + ** + ** 2021-03-15: ticket 1c24a659e6d7f3a1 + ** Do not do the ID-to-STRING conversion when doing the schema + ** sanity check following a DROP COLUMN if the identifer name matches + ** the name of the column being dropped. */ sqlite3_log(SQLITE_WARNING, "double-quoted string literal: \"%w\"", zCol); @@ -98810,18 +99250,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(;;){ @@ -98843,7 +99289,7 @@ lookupname_end: 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]; + SrcItem *pItem = &pSrc->a[iSrc]; Table *pTab = p->y.pTab = pItem->pTab; p->iTable = pItem->iCursor; if( p->y.pTab->iPKey==iCol ){ @@ -98955,7 +99401,7 @@ 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; @@ -98966,6 +99412,47 @@ 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 && i<ArraySize(anRef); p=p->pNext, i++){ + anRef[i] = p->nRef; + } + sqlite3WalkExpr(pWalker, pExpr->pLeft); + if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){ + 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 && i<ArraySize(anRef); p=p->pNext, 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 @@ -99193,6 +99680,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( 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); @@ -99267,7 +99755,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 || pRight->op==TK_TRUEFALSE) ){ + 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 ){ @@ -99583,8 +100071,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy( resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); 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; @@ -99769,27 +100256,26 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Recursively resolve names in all subqueries */ for(i=0; i<p->pSrc->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; - 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); + } } } @@ -99831,7 +100317,7 @@ 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; @@ -99839,7 +100325,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Resolve names in table-valued-function arguments */ for(i=0; i<p->pSrc->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) ){ @@ -100248,7 +100734,18 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken( const Token *pCollName, /* Name of collating sequence */ int dequote /* True to dequote pCollName */ ){ - if( pCollName->n>0 ){ + assert( pExpr!=0 || pParse->db->mallocFailed ); + if( pExpr==0 ) return 0; + if( pExpr->op==TK_VECTOR ){ + ExprList *pList = pExpr->x.pList; + if( ALWAYS(pList!=0) ){ + int i; + for(i=0; i<pList->nExpr; i++){ + pList->a[i].pExpr = sqlite3ExprAddCollateToken(pParse,pList->a[i].pExpr, + pCollName, dequote); + } + } + }else if( pCollName->n>0 ){ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); if( pNew ){ pNew->pLeft = pExpr; @@ -101100,8 +101597,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); @@ -101298,6 +101795,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. */ @@ -101672,8 +102185,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; i<p->nSrc; i++){ - struct SrcList_item *pNewItem = &pNew->a[i]; - struct SrcList_item *pOldItem = &p->a[i]; + SrcItem *pNewItem = &pNew->a[i]; + SrcItem *pOldItem = &p->a[i]; Table *pTab; pNewItem->pSchema = pOldItem->pSchema; pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); @@ -101686,7 +102199,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); @@ -102724,7 +103240,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( /* Code an OP_Transaction and OP_TableLock for <table>. */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iDb>=0 && iDb<SQLITE_MAX_ATTACHED ); + assert( iDb>=0 && iDb<SQLITE_MAX_DB ); sqlite3CodeVerifySchema(pParse, iDb); sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); @@ -105920,8 +106436,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{ @@ -105930,8 +106445,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); } } } @@ -106003,7 +106517,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; i<pSrcList->nSrc; i++, pItem++){ struct AggInfo_col *pCol; assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); @@ -106292,15 +106806,22 @@ 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 */ + const char *zDropColumn /* Name of column being dropped */ +){ + pParse->colNamesSet = 1; sqlite3NestedParse(pParse, "SELECT 1 " "FROM \"%w\"." DFLT_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, %Q)=NULL ", zDb, - zDb, bTemp + zDb, bTemp, zWhen, zDropColumn ); if( bTemp==0 ){ @@ -106309,8 +106830,8 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ "FROM temp." DFLT_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, %Q)=NULL ", + zDb, zWhen, zDropColumn ); } } @@ -106319,12 +106840,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); } } @@ -106473,7 +106994,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); @@ -106492,8 +107013,8 @@ 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); @@ -106624,11 +107145,14 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ *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: */ sqlite3NestedParse(pParse, "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " - "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " + "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->addColOffset, zCol, pNew->addColOffset, zTab ); sqlite3DbFree(db, zCol); @@ -106652,7 +107176,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ } /* Reload the table definition */ - renameReloadSchema(pParse, iDb); + renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); } /* @@ -106752,7 +107276,7 @@ exit_begin_add_column: ** 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 ){ @@ -106765,15 +107289,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 /* @@ -106802,7 +107327,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); @@ -106856,8 +107381,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( ); /* 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", 0); exit_rename_column: sqlite3SrcListDelete(db, pSrc); @@ -107109,23 +107634,33 @@ 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, + void *pPtr +){ RenameToken **pp; assert( pPtr!=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; } /* @@ -107196,7 +107731,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 @@ -107205,8 +107740,8 @@ 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 = sqlite3_mprintf("error in %s %s%s%s: %s", + zT, zN, (zWhen[0] ? " " : ""), zWhen, pParse->zErrMsg ); sqlite3_result_error(pCtx, zErr, -1); @@ -107271,12 +107806,17 @@ static int renameParseSql( const char *zDb, /* Name of schema SQL belongs to */ sqlite3 *db, /* Database handle */ const char *zSql, /* SQL to parse */ - int bTemp /* True if SQL is from temp schema */ + int bTemp, /* True if SQL is from temp schema */ + const char *zDropColumn /* Name of column being dropped */ ){ int rc; char *zErr = 0; db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); + if( zDropColumn ){ + db->init.bDropColumn = 1; + db->init.azInit = (char**)&zDropColumn; + } /* 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 @@ -107285,7 +107825,7 @@ static int renameParseSql( p->eParseMode = PARSE_MODE_RENAME; p->db = db; p->nQueryLoop = 1; - rc = sqlite3RunParser(p, zSql, &zErr); + rc = zSql ? sqlite3RunParser(p, zSql, &zErr) : SQLITE_NOMEM; assert( p->zErrMsg==0 ); assert( rc!=SQLITE_OK || zErr==0 ); p->zErrMsg = zErr; @@ -107309,6 +107849,7 @@ static int renameParseSql( #endif db->init.iDb = 0; + db->init.bDropColumn = 0; return rc; } @@ -107438,7 +107979,7 @@ static int renameResolveTrigger(Parse *pParse){ if( pSrc ){ int i; for(i=0; i<pSrc->nSrc && rc==SQLITE_OK; i++){ - struct SrcList_item *p = &pSrc->a[i]; + SrcItem *p = &pSrc->a[i]; p->iCursor = pParse->nTab++; if( p->pSelect ){ sqlite3SelectPrep(pParse, p->pSelect, 0); @@ -107464,9 +108005,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; @@ -107611,7 +108151,7 @@ static void renameColumnFunc( #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = 0; #endif - rc = renameParseSql(&sParse, zDb, db, zSql, bTemp); + rc = renameParseSql(&sParse, zDb, db, zSql, bTemp, 0); /* Find tokens that need to be replaced. */ memset(&sWalker, 0, sizeof(Walker)); @@ -107653,12 +108193,12 @@ static void renameColumnFunc( for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){ sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } - } #ifndef SQLITE_OMIT_GENERATED_COLUMNS - for(i=0; i<sParse.pNewTable->nCol; i++){ - sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); - } + for(i=0; i<sParse.pNewTable->nCol; i++){ + sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); + } #endif + } for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ for(i=0; i<pFKey->nCol; i++){ @@ -107712,7 +108252,7 @@ static void renameColumnFunc( renameColumnFunc_done: if( rc!=SQLITE_OK ){ if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); } @@ -107750,7 +108290,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ return WRC_Abort; } for(i=0; i<pSrc->nSrc; i++){ - struct SrcList_item *pItem = &pSrc->a[i]; + SrcItem *pItem = &pSrc->a[i]; if( pItem->pTab==p->pTab ){ renameTokenFind(pWalker->pParse, p, pItem->zName); } @@ -107815,7 +108355,7 @@ static void renameTableFunc( sWalker.xSelectCallback = renameTableSelectCb; sWalker.u.pRename = &sCtx; - rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp, 0); if( rc==SQLITE_OK ){ int isLegacy = (db->flags & SQLITE_LegacyAlter); @@ -107901,7 +108441,7 @@ static void renameTableFunc( } if( rc!=SQLITE_OK ){ if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); } @@ -107930,6 +108470,8 @@ 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: Name of column being dropped, or NULL. ** ** Unless it finds an error, this function normally returns NULL. However, it ** returns integer value 1 if: @@ -107947,6 +108489,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]); + char const *zDropColumn = (const char*)sqlite3_value_text(argv[6]); #ifndef SQLITE_OMIT_AUTHORIZATION sqlite3_xauth xAuth = db->xAuth; @@ -107957,7 +108501,7 @@ static void renameTableTest( if( zDb && zInput ){ int rc; Parse sParse; - rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp, zDropColumn); if( rc==SQLITE_OK ){ if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){ NameContext sNC; @@ -107979,8 +108523,8 @@ static void renameTableTest( } } - if( rc!=SQLITE_OK ){ - renameColumnParseError(context, 1, argv[2], argv[3], &sParse); + if( rc!=SQLITE_OK && zWhen ){ + renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse); } renameParseCleanup(&sParse); } @@ -107991,13 +108535,216 @@ static void renameTableTest( } /* +** 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, 0); + 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].zName); + if( iCol<pTab->nCol-1 ){ + RenameToken *pEnd; + pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zName); + zEnd = (const char*)pEnd->t.z; + }else{ + zEnd = (const char*)&zSql[pTab->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, 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: \"%s\"", zCol); + 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; + renameTestSchema(pParse, zDb, iDb==1, "", 0); + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." DFLT_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", zCol); + + /* 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; i<pPk->nKeyCol; i++){ + sqlite3VdbeAddOp3(v, OP_Column, iCur, i, reg+i+1); + } + nField = pPk->nKeyCol; + } + regRec = ++pParse->nMem; + for(i=0; i<pTab->nCol; 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( iPos<pPk->nKeyCol ) 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++; + } + } + 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), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); } @@ -110387,6 +111134,62 @@ 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; i<pList->nSrc; 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 WRC_Abort; + } + 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( sqlite3WalkExpr(&pFix->w, pList->a[i].pOn) ) return WRC_Abort; +#endif + } + if( pSelect->pWith ){ + for(i=0; i<pSelect->pWith->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. */ @@ -110397,9 +111200,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; @@ -110407,6 +111208,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 = 0; + pFix->w.walkerDepth = 0; + pFix->w.eCode = 0; + pFix->w.u.pFix = pFix; } /* @@ -110427,115 +111235,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; i<pList->nSrc; 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; i<pSelect->pWith->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; i<pList->nExpr; i++, pItem++){ - if( sqlite3FixExpr(pFix, pItem->pExpr) ){ - return 1; - } - } - return 0; + return sqlite3WalkExpr(&pFix->w, pExpr); } #endif @@ -110545,25 +111265,20 @@ 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) + if( sqlite3WalkExprList(&pFix->w, pUp->pUpsertTarget) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertTargetWhere) + || sqlite3WalkExprList(&pFix->w, pUp->pUpsertSet) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertWhere) ){ return 1; } @@ -110571,6 +111286,7 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep( #endif pStep = pStep->pNext; } + return 0; } #endif @@ -110722,7 +111438,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 */ @@ -110730,8 +111445,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 @@ -110743,7 +111458,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( pTab = pParse->pTriggerTab; }else{ assert( pTabList ); - for(iSrc=0; ALWAYS(iSrc<pTabList->nSrc); iSrc++){ + for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ pTab = pTabList->a[iSrc].pTab; break; @@ -110751,7 +111466,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( } } iCol = pExpr->iColumn; - if( NEVER(pTab==0) ) return; + if( pTab==0 ) return; if( iCol>=0 ){ assert( iCol<pTab->nCol ); @@ -110762,7 +111477,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( }else{ zCol = "ROWID"; } - assert( iDb>=0 && iDb<db->nDb ); + assert( iDb>=0 && iDb<pParse->db->nDb ); if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ pExpr->op = TK_NULL; } @@ -110788,11 +111503,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; } @@ -110998,10 +111709,36 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ /* 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; + + addrRewind = + sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); + VdbeCoverage(v); + reg = pReturning->iRetReg; + for(i=0; i<pReturning->nRetCol; 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 @@ -111079,12 +111816,16 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ } } + if( pParse->bReturning ){ + Returning *pRet = pParse->u1.pReturning; + 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 ){ @@ -111303,7 +112044,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 ); @@ -112061,7 +112802,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); @@ -112088,12 +112830,85 @@ begin_table_error: SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ if( sqlite3_strnicmp(pCol->zName, "__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.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. @@ -112110,6 +112925,8 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ char *zType; Column *pCol; sqlite3 *db = pParse->db; + u8 hName; + if( (p = pParse->pNewTable)==0 ) return; if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); @@ -112121,8 +112938,9 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ memcpy(z, pName->z, pName->n); z[pName->n] = 0; sqlite3Dequote(z); + hName = sqlite3StrIHash(z); for(i=0; i<p->nCol; i++){ - if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){ + if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zName)==0 ){ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); sqlite3DbFree(db, z); return; @@ -112140,7 +112958,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); pCol->zName = z; - pCol->hName = sqlite3StrIHash(z); + pCol->hName = hName; sqlite3ColumnPropertiesFromName(p, pCol); if( pType->n==0 ){ @@ -112923,9 +113741,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 @@ -113389,7 +114208,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. @@ -113406,20 +114225,17 @@ 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( !pSelect && !p->pSelect ){ + assert( pCons && pEnd ); + if( pCons->z==0 ){ + pCons = pEnd; } -#endif + p->addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z); } +#endif } #ifndef SQLITE_OMIT_VIEW @@ -113610,6 +114426,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) ); @@ -114877,7 +115694,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); } @@ -114898,7 +115715,11 @@ 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 */ + 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 = &pTab->pIndex; Index *pThis; for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){ @@ -114912,6 +115733,16 @@ exit_create_index: } 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); @@ -115270,7 +116101,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 ); @@ -115311,7 +116142,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( */ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; - struct SrcList_item *pItem; + SrcItem *pItem; assert(pList || pParse->db->mallocFailed ); if( pList ){ for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ @@ -115329,7 +116160,7 @@ 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; i<pList->nSrc; i++, pItem++){ if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase); @@ -115371,7 +116202,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", @@ -115415,7 +116246,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 ); @@ -115445,7 +116276,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); } } @@ -115458,7 +116289,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 ); @@ -115613,7 +116444,7 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ static void sqlite3CodeVerifySchemaAtToplevel(Parse *pToplevel, int iDb){ assert( iDb>=0 && iDb<pToplevel->db->nDb ); assert( pToplevel->db->aDb[iDb].pBt!=0 || iDb==1 ); - assert( iDb<SQLITE_MAX_ATTACHED+2 ); + assert( iDb<SQLITE_MAX_DB ); assert( sqlite3SchemaMutexHeld(pToplevel->db, iDb, 0) ); if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ DbMaskSet(pToplevel->cookieMask, iDb); @@ -115956,23 +116787,75 @@ 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; i<pWith->nCte; i++){ @@ -115991,16 +116874,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; @@ -116013,10 +116891,7 @@ SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ if( pWith ){ int i; for(i=0; i<pWith->nCte; 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); } @@ -116595,7 +117470,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); @@ -116603,9 +117478,9 @@ 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; } @@ -116773,9 +117648,15 @@ 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 ){ + 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, @@ -116953,6 +117834,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); @@ -117174,7 +118056,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( ** invoke the callback function. */ if( memCnt ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, memCnt, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); } @@ -118222,7 +119104,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; } @@ -119393,7 +120276,9 @@ 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 ); + if( !pExpr->x.pList ){ return 0; } assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); @@ -119432,6 +120317,203 @@ 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 2-argument SQL math functions: +** +** power(X,Y) - Compute X to the Y-th power +*/ +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 @@ -119550,6 +120632,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 ), }; @@ -120605,7 +121724,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++; @@ -120693,7 +121812,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). ** @@ -120705,13 +121826,14 @@ SQLITE_PRIVATE int sqlite3FkRequired( int *aChange, /* Non-NULL for UPDATE operations */ int chngRowid /* True for UPDATE that affects rowid */ ){ - int eRet = 0; + int eRet = 1; /* Value to return if bHaveFK is true */ + int bHaveFK = 0; /* If FK processing is required */ if( pParse->db->flags&SQLITE_ForeignKeys ){ if( !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->pFKey); }else{ /* This is an UPDATE. Foreign key processing is only required if the ** operation modifies one or more child or parent key columns. */ @@ -120719,9 +121841,9 @@ SQLITE_PRIVATE int sqlite3FkRequired( /* 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; if( fkChildIsModified(pTab, p, aChange, chngRowid) ){ - eRet = 1; + if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) eRet = 2; + bHaveFK = 1; } } @@ -120729,12 +121851,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; } /* @@ -121403,7 +122525,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; @@ -121961,19 +123085,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; i<pTab->nCol; 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; i<pTab->nCol; 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, 0, pTab->nCol-nHidden, nColumn); + goto insert_cleanup; + } } if( pColumn!=0 && nColumn!=pColumn->nId ){ sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); @@ -121985,6 +123114,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); @@ -122008,6 +123138,7 @@ 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); @@ -122021,13 +123152,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 @@ -122168,11 +123305,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); @@ -122327,7 +123459,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. @@ -122342,7 +123476,7 @@ insert_end: ** invoke the callback function. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); } @@ -122433,6 +123567,70 @@ SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn( } /* +** 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. ** @@ -122540,7 +123738,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 */ @@ -122548,11 +123746,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 @@ -122562,6 +123760,7 @@ 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; @@ -122759,19 +123958,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 ); } } @@ -122834,11 +124077,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); } } @@ -122848,7 +124100,7 @@ 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 */ ){ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; @@ -122945,7 +124197,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); } @@ -122958,7 +124212,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 */ @@ -122966,15 +124223,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; } @@ -123045,8 +124301,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 */ @@ -123084,7 +124340,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); @@ -123236,13 +124492,16 @@ 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 */ @@ -123309,6 +124568,32 @@ SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ #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. ** A consecutive range of registers starting at regNewData contains the @@ -123356,17 +124641,9 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( 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, @@ -123564,7 +124841,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 */ @@ -123781,6 +125058,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 ); @@ -123816,11 +125094,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); @@ -123828,16 +125108,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); @@ -123879,13 +125171,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); @@ -128201,7 +129502,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 ){ @@ -128849,7 +130150,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; @@ -128857,14 +130158,18 @@ 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_AlterRename|INITFLAG_AlterDrop) ){ + *pData->pzErrMsg = sqlite3MPrintf(db, + "error in %s %s after %s: %s", azObj[0], azObj[1], + (pData->mInitFlags & INITFLAG_AlterRename) ? "rename" : "drop column", + 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; @@ -128922,19 +130227,26 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char db->mDbFlags |= DBFLAG_EncodingFixed; pData->nInitRow++; if( db->mallocFailed ){ - corruptSchema(pData, argv[1], 0); + corruptSchema(pData, argv, 0); return 1; } assert( iDb>=0 && iDb<db->nDb ); 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; @@ -128947,7 +130259,7 @@ 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; @@ -128966,13 +130278,13 @@ 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)); } } } 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 @@ -128983,7 +130295,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 @@ -128991,7 +130303,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"); } } } @@ -129372,27 +130684,20 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ } /* -** 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){ sqlite3 *db = pParse->db; - AggInfo *pThis = pParse->pAggList; - while( pThis ){ - AggInfo *pNext = pThis->pNext; - agginfoFree(db, pThis); - pThis = pNext; + 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( pParse->pConstExpr ){ + sqlite3ExprListDelete(db, pParse->pConstExpr); + } if( db ){ assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; @@ -129402,6 +130707,55 @@ SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ } /* +** 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 +** sqlite3ParserReset(), 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; +} + +/* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ static int sqlite3Prepare( @@ -129499,12 +130853,6 @@ static int sqlite3Prepare( } assert( 0==sParse.nQueryLoop ); - if( sParse.rc==SQLITE_DONE ){ - sParse.rc = SQLITE_OK; - } - if( sParse.checkSchema ){ - schemaIsValid(&sParse); - } if( pzTail ){ *pzTail = sParse.zTail; } @@ -129515,20 +130863,28 @@ static int sqlite3Prepare( if( db->mallocFailed ){ sParse.rc = SQLITE_NOMEM_BKPT; } - 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 ){ + schemaIsValid(&sParse); + } + if( sParse.pVdbe ){ + sqlite3VdbeFinalize(sParse.pVdbe); + } + assert( 0==(*ppStmt) ); + rc = sParse.rc; + if( zErrMsg ){ + sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); + sqlite3DbFree(db, zErrMsg); + }else{ + sqlite3Error(db, rc); + } }else{ + assert( 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 ){ @@ -129874,12 +131230,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; @@ -130051,7 +131411,7 @@ 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; @@ -130083,7 +131443,7 @@ static int tableAndColumnIndex( assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=0; i<N; i++){ - iCol = columnIndex(pSrc->a[i].pTab, zCol); + iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol); if( iCol>=0 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) ){ @@ -130136,7 +131496,7 @@ static void addWhereTerm( ExprSetProperty(pEq, EP_FromJoin); assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(pEq, EP_NoReduce); - pEq->iRightJoinTable = (i16)pE2->iTable; + pEq->iRightJoinTable = pE2->iTable; } *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq); } @@ -130172,7 +131532,7 @@ 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; + p->iRightJoinTable = iTable; if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; i<p->x.pList->nExpr; i++){ @@ -130196,6 +131556,9 @@ static void unsetJoinExpr(Expr *p, int iTable){ && (iTable<0 || p->iRightJoinTable==iTable) ){ ExprClearProperty(p, EP_FromJoin); } + if( p->op==TK_COLUMN && p->iTable==iTable ){ + ExprClearProperty(p, EP_CanBeNull); + } if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; i<p->x.pList->nExpr; i++){ @@ -130224,8 +131587,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]; @@ -130293,7 +131656,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) ){ @@ -131172,7 +132535,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; @@ -131768,7 +133131,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( 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; @@ -131875,6 +133238,7 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation( for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ const char *zType; int 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 */ @@ -132390,12 +133754,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 */ @@ -132452,7 +133812,7 @@ static int multiSelect( pPrior->iOffset = p->iOffset; pPrior->pLimit = p->pLimit; rc = sqlite3Select(pParse, pPrior, &dest); - p->pLimit = 0; + pPrior->pLimit = 0; if( rc ){ goto multi_select_end; } @@ -132473,8 +133833,8 @@ static int multiSelect( 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); @@ -132538,7 +133898,7 @@ static int multiSelect( p->pLimit = 0; uniondest.eDest = op; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", - selectOpName(p->op))); + sqlite3SelectOpName(p->op))); rc = sqlite3Select(pParse, p, &uniondest); testcase( rc!=SQLITE_OK ); assert( p->pOrderBy==0 ); @@ -132614,7 +133974,7 @@ static int multiSelect( p->pLimit = 0; intersectdest.iSDParm = tab2; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", - selectOpName(p->op))); + sqlite3SelectOpName(p->op))); rc = sqlite3Select(pParse, p, &intersectdest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; @@ -132723,7 +134083,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)); } } @@ -132820,10 +134181,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; } @@ -133115,7 +134474,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. @@ -133385,7 +134744,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{ @@ -133415,7 +134774,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; @@ -133425,7 +134784,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; @@ -133440,6 +134799,89 @@ static void recomputeColumnsUsed( #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] = iNew; +** +** The array is guaranteed by the caller to be large enough for all +** existing cursor numbers in pSrc. +** +** 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; i<pSrc->nSrc; i++, pItem++){ + if( i!=iExcept ){ + Select *p; + pItem->iCursor = aCsrMap[pItem->iCursor] = pParse->nTab++; + for(p=pItem->pSelect; p; p=p->pPrior){ + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); + } + } + } +} + +/* +** Expression walker callback used by renumberCursors() to update +** Expr objects to match newly assigned cursor numbers. +*/ +static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ + int *aCsrMap = pWalker->u.aiCol; + int op = pExpr->op; + if( (op==TK_COLUMN || op==TK_IF_NULL_ROW) && aCsrMap[pExpr->iTable] ){ + pExpr->iTable = aCsrMap[pExpr->iTable]; + } + if( ExprHasProperty(pExpr, EP_FromJoin) && aCsrMap[pExpr->iRightJoinTable] ){ + pExpr->iRightJoinTable = aCsrMap[pExpr->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. ** This routine returns 1 if it makes changes and 0 if no flattening occurs. ** @@ -133532,9 +134974,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, @@ -133550,8 +134992,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. @@ -133567,9 +135009,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(). ** @@ -133611,9 +135052,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. */ @@ -133709,13 +135151,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) */ @@ -133736,15 +135179,15 @@ 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, pParse->nTab*sizeof(int)); + } + } /***** If we reach this point, flattening is permitted. *****/ SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n", @@ -133756,6 +135199,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: @@ -133794,18 +135248,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 && db->mallocFailed==0 ){ + renumberCursors(pParse, pNew, iFrom, aCsrMap); + } pNew->pPrior = pPrior; if( pPrior ) pPrior->pNext = pNew; pNew->pNext = p; @@ -133813,24 +135272,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 @@ -133843,8 +135291,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--; } @@ -133864,6 +135314,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; @@ -133872,14 +135323,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 @@ -133999,7 +135444,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); } @@ -134194,6 +135639,35 @@ static int propagateConstants( } #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 ** the WHERE clause of subquery. Example: @@ -134240,9 +135714,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. @@ -134256,13 +135745,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 @@ -134298,6 +135791,7 @@ static int pushDownWhereTerms( } if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ nChng++; + pSubq->selFlags |= SF_PushDown; while( pSubq ){ SubstContext x; pNew = sqlite3ExprDup(pParse->db, pWhere, 0); @@ -134308,6 +135802,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{ @@ -134346,7 +135848,11 @@ 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) ){ + if( pEList==0 + || pEList->nExpr!=1 + || ExprHasProperty(pFunc, EP_WinFunc) + || OptimizationDisabled(db, SQLITE_MinMaxOpt) + ){ return eRet; } zFunc = pFunc->u.zToken; @@ -134409,24 +135915,26 @@ 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; } + pFrom->u2.pIBIndex = pIdx; return SQLITE_OK; } + /* ** Detect compound SELECT statements that use an ORDER BY clause with ** an alternative collating sequence. @@ -134513,7 +136021,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; @@ -134534,19 +136042,19 @@ 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; i<p->nCte; 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; i<p->nCte; i++){ + if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ + *ppContext = p; + return &p->a[i]; } } } @@ -134564,46 +136072,54 @@ static struct Cte *searchWith( ** statement with which it is associated. */ SQLITE_PRIVATE void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ - assert( bFree==0 || (pParse->pWith==0 && pParse->pWithToFree==0) ); if( pWith ){ assert( pParse->pWith!=pWith ); pWith->pOuter = pParse->pWith; pParse->pWith = pWith; - if( bFree ) pParse->pWithToFree = pWith; + if( bFree ){ + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3WithDelete, + pWith); + testcase( pParse->earlyCleanup ); + } } } /* ** 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->nErr ){ - return SQLITE_ERROR; + if( pParse->pWith==0 ){ + /* There are no WITH clauses in the stack. No match is possible */ + 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; } - pCte = searchWith(pParse->pWith, pFrom, &pWith); if( pCte ){ + sqlite3 *db = pParse->db; Table *pTab; ExprList *pEList; Select *pSel; @@ -134612,6 +136128,7 @@ static int withExpand( 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 @@ -134619,21 +136136,39 @@ 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; assert( pFrom->pSelect ); + 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. */ pRecTerm = pSel = pFrom->pSelect; @@ -134643,7 +136178,7 @@ static int withExpand( SrcList *pSrc = pRecTerm->pSrc; assert( pRecTerm->pPrior!=0 ); for(i=0; i<pSrc->nSrc; 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) @@ -134655,7 +136190,7 @@ static int withExpand( sqlite3ErrorMsg(pParse, "multiple references to recursive table: %s", pCte->zName ); - return SQLITE_ERROR; + return 2; } pRecTerm->selFlags |= SF_Recursive; if( iRecTab<0 ) iRecTab = pParse->nTab++; @@ -134670,16 +136205,24 @@ static int withExpand( pSavedWith = pParse->pWith; pParse->pWith = pWith; 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; - sqlite3WalkSelect(pWalker, pRecTerm); + 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; @@ -134691,7 +136234,7 @@ static int withExpand( pCte->zName, pEList->nExpr, pCte->pCols->nExpr ); pParse->pWith = pSavedWith; - return SQLITE_ERROR; + return 2; } pEList = pCte->pCols; } @@ -134707,9 +136250,9 @@ static int withExpand( } pCte->zCteErr = 0; pParse->pWith = pSavedWith; + return 1; /* Success */ } - - return SQLITE_OK; + return 0; /* No match */ } #endif @@ -134743,7 +136286,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; @@ -134791,10 +136334,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; @@ -134830,10 +136373,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; @@ -134843,6 +136382,12 @@ static int selectExpander(Walker *pWalker, Select *p){ 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 */ assert( pFrom->pTab==0 ); @@ -134864,7 +136409,10 @@ static int selectExpander(Walker *pWalker, Select *p){ u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); - if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){ + if( pTab->pSelect + && (db->flags & SQLITE_EnableView)==0 + && pTab->pSchema!=db->aDb[1].pSchema + ){ sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", pTab->zName); } @@ -134890,7 +136438,7 @@ 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; } } @@ -135133,7 +136681,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; @@ -135445,7 +136993,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); } @@ -135457,11 +137005,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; pItem<pThis; pItem++){ Select *pS1; if( pItem->pSelect==0 ) continue; @@ -135477,9 +137027,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; @@ -135489,6 +137037,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 @@ -135567,7 +137124,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); } @@ -135620,7 +137177,7 @@ SQLITE_PRIVATE int sqlite3Select( 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 @@ -135634,8 +137191,19 @@ SQLITE_PRIVATE int sqlite3Select( 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 */ - sqlite3ExprListDelete(db, p->pOrderBy); - p->pOrderBy = 0; + 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; } @@ -135645,7 +137213,7 @@ SQLITE_PRIVATE int sqlite3Select( } 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); } @@ -135656,9 +137224,9 @@ SQLITE_PRIVATE int sqlite3Select( ** 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]; + SrcItem *p0 = &p->pSrc->a[0]; for(i=1; i<p->pSrc->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", @@ -135680,7 +137248,7 @@ SQLITE_PRIVATE int sqlite3Select( 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); } @@ -135696,7 +137264,7 @@ SQLITE_PRIVATE int sqlite3Select( */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ - struct SrcList_item *pItem = &pTabList->a[i]; + SrcItem *pItem = &pTabList->a[i]; Select *pSub = pItem->pSelect; Table *pTab = pItem->pTab; @@ -135787,7 +137355,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 @@ -135806,7 +137374,7 @@ SQLITE_PRIVATE int sqlite3Select( && 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); } @@ -135830,7 +137398,8 @@ SQLITE_PRIVATE int sqlite3Select( ** (2) Generate code for all sub-queries */ for(i=0; i<pTabList->nSrc; 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) @@ -135890,16 +137459,18 @@ SQLITE_PRIVATE int sqlite3Select( ** inside the subquery. This can help the subquery to run more efficiently. */ if( OptimizationEnabled(db, SQLITE_PushDown) + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, (pItem->fg.jointype & JT_OUTER)!=0) ){ #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")); } @@ -135909,16 +137480,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. @@ -135938,16 +137511,32 @@ 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); + } + 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{ + /* Materalize 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; @@ -135962,22 +137551,22 @@ SQLITE_PRIVATE int sqlite3Select( }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; - }else{ - sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); - ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); - sqlite3Select(pParse, pSub, &dest); - } + sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); + ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); + 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)); 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); @@ -135994,7 +137583,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); } @@ -136030,7 +137619,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); } @@ -136122,6 +137711,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 @@ -136160,6 +137750,7 @@ SQLITE_PRIVATE int sqlite3Select( /* End the database scan loop. */ + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); } }else{ @@ -136230,11 +137821,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; @@ -136278,10 +137872,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; ii<pAggInfo->nColumn; ii++){ sqlite3DebugPrintf("agg-column[%d] iMem=%d\n", ii, pAggInfo->aCol[ii].iMem); @@ -136349,6 +137947,7 @@ SQLITE_PRIVATE int sqlite3Select( WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 ); if( pWInfo==0 ) goto select_end; + 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 @@ -136397,6 +137996,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); @@ -136471,9 +138071,10 @@ SQLITE_PRIVATE int sqlite3Select( /* 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); } @@ -136583,7 +138184,6 @@ SQLITE_PRIVATE int sqlite3Select( explainSimpleCount(pParse, pTab, pBest); }else{ int regAcc = 0; /* "populate accumulators" flag */ - int addrSkip; /* If there are accumulator registers but no min() or max() functions ** without FILTER clauses, allocate register regAcc. Register regAcc @@ -136630,12 +138230,13 @@ SQLITE_PRIVATE int sqlite3Select( if( pWInfo==0 ){ goto select_end; } + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); updateAccumulator(pParse, regAcc, pAggInfo); 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); } @@ -136680,15 +138281,13 @@ select_end: if( pAggInfo && !db->mallocFailed ){ for(i=0; i<pAggInfo->nColumn; 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; i<pAggInfo->nFunc; 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 ); } @@ -136697,7 +138296,7 @@ select_end: #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 @@ -136958,28 +138557,39 @@ 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; } - + pTmpSchema = pParse->db->aDb[1].pSchema; + p = sqliteHashFirst(&pTmpSchema->trigHash); + if( p==0 ){ + return pTab->pTrigger; + } + pList = pTab->pTrigger; if( pTmpSchema!=pTab->pSchema ){ - HashElem *p; - assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) ); - for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){ + while( p ){ Trigger *pTrig = (Trigger *)sqliteHashData(p); if( pTrig->pTabSchema==pTab->pSchema && 0==sqlite3StrICmp(pTrig->table, pTab->zName) ){ - pTrig->pNext = (pList ? pList : pTab->pTrigger); + pTrig->pNext = pList; + pList = pTrig; + }else if( pTrig->op==TK_RETURNING ){ + 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); + return pList; } /* @@ -137255,7 +138865,7 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( 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 ){ @@ -137468,7 +139078,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); @@ -137633,15 +139243,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; } @@ -137685,6 +139333,131 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc( } /* +** 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; i<pList->nExpr; i++){ + Expr *pOldExpr = pList->a[i].pExpr; + if( NEVER(pOldExpr==0) ) continue; + if( isAsteriskTerm(pParse, pOldExpr) ){ + int jj; + for(jj=0; jj<pTab->nCol; jj++){ + Expr *pNewExpr; + if( IsHiddenColumn(pTab->aCol+jj) ) continue; + pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zName); + pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); + if( !db->mallocFailed ){ + struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; + pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zName); + pItem->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; + } + } + } + if( !db->mallocFailed ){ + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + sqlite3VdbeSetNumCols(v, pNew->nExpr); + for(i=0; i<pNew->nExpr; i++){ + sqlite3VdbeSetColName(v, i, COLNAME_NAME, pNew->a[i].zEName, + SQLITE_TRANSIENT); + } + } + 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; + ExprList *pNew; + Returning *pReturning; + + assert( v!=0 ); + assert( pParse->bReturning ); + pReturning = pParse->u1.pReturning; + assert( pTrigger == &(pReturning->retTrig) ); + pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); + if( pNew ){ + 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 ){ + int i; + int nCol = pNew->nExpr; + int reg = pParse->nMem+1; + pParse->nMem += nCol+2; + pReturning->iRetReg = reg; + for(i=0; i<nCol; i++){ + sqlite3ExprCodeFactorable(pParse, pNew->a[i].pExpr, 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(pParse->db, pNew); + pParse->eTriggerOp = 0; + pParse->pTriggerTab = 0; + } +} + + + +/* ** Generate VDBE code for the statements inside the body of a single ** trigger. */ @@ -137733,6 +139506,7 @@ static int codeTriggerProgram( sqlite3ExprDup(db, pStep->pWhere, 0), pParse->eOrconf, 0, 0, 0 ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } case TK_INSERT: { @@ -137743,6 +139517,7 @@ static int codeTriggerProgram( pParse->eOrconf, sqlite3UpsertDup(db, pStep->pUpsert) ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } case TK_DELETE: { @@ -137750,6 +139525,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 ); { @@ -137761,9 +139537,6 @@ static int codeTriggerProgram( break; } } - if( pStep->op!=TK_SELECT ){ - sqlite3VdbeAddOp0(v, OP_ResetCount); - } } return 0; @@ -137910,7 +139683,6 @@ static TriggerPrg *codeRowTrigger( sqlite3VdbeDelete(v); } - assert( !pSubParse->pAinc && !pSubParse->pZombieTab ); assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); sqlite3ParserReset(pSubParse); sqlite3StackFree(db, pSubParse); @@ -138012,7 +139784,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 ** @@ -138057,12 +139829,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); + } } } } @@ -138107,13 +139887,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]; + } } } } @@ -138770,6 +140555,7 @@ SQLITE_PRIVATE void sqlite3Update( if( (db->flags&SQLITE_CountRows)!=0 && !pParse->pTriggerTab && !pParse->nested + && !pParse->bReturning && pUpsert==0 ){ regRowCount = ++pParse->nMem; @@ -139233,7 +141019,7 @@ SQLITE_PRIVATE void sqlite3Update( ** that information. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); } @@ -139468,16 +141254,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. */ @@ -139487,7 +141280,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) ); } @@ -139499,22 +141293,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; } @@ -139539,6 +141336,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 ); @@ -139552,87 +141350,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; ii<nn; ii++){ - Expr *pExpr; - sCol[0].u.zToken = (char*)pIdx->azColl[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; ii<nn; ii++){ + Expr *pExpr; + sCol[0].u.zToken = (char*)pIdx->azColl[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; jj<nn; jj++){ - if( sqlite3ExprCompare(pParse, pTarget->a[jj].pExpr, pExpr,iCursor)<2 ){ - break; /* Column ii of the index matches column jj of target */ + for(jj=0; jj<nn; jj++){ + if( sqlite3ExprCompare(pParse,pTarget->a[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( ii<nn ){ + /* Column ii of the index did not match any term of the conflict target. + ** Continue the search with the next index. */ + continue; } + pUpsert->pUpsertIdx = pIdx; + break; } - if( ii<nn ){ - /* Column ii of the index did not match any term of the conflict target. - ** Continue the search with the next index. */ - continue; + if( pUpsert->pUpsertIdx==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; } /* @@ -139656,11 +141498,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); @@ -139690,19 +141534,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; i<pTab->nCol; 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")); } @@ -140608,7 +142450,7 @@ 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; @@ -140779,6 +142621,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; @@ -140947,7 +142790,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ Table *pNew = sParse.pNewTable; Index *pIdx; pTab->aCol = pNew->aCol; - pTab->nCol = pNew->nCol; + pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); pNew->nCol = 0; pNew->aCol = 0; @@ -141479,19 +143322,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 */ @@ -141745,11 +143575,7 @@ struct WhereTerm { #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_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 */ @@ -142019,7 +143845,7 @@ 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*); @@ -142197,7 +144023,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. */ @@ -142990,7 +144816,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 */ @@ -143365,7 +145191,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 */ @@ -143811,6 +145637,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( 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. @@ -144147,7 +145979,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])); @@ -145070,6 +146902,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 @@ -145567,6 +147400,277 @@ static int exprMightBeIndexed( } /* +** Expression callback for exprUsesSrclist(). +*/ +static int exprUsesSrclistCb(Walker *p, Expr *pExpr){ + if( pExpr->op==TK_COLUMN ){ + SrcList *pSrc = p->u.pSrcList; + int iCsr = pExpr->iTable; + int ii; + for(ii=0; ii<pSrc->nSrc; ii++){ + if( pSrc->a[ii].iCursor==iCsr ){ + return p->eCode ? WRC_Abort : WRC_Continue; + } + } + return p->eCode ? WRC_Continue : WRC_Abort; + } + return WRC_Continue; +} + +/* +** Select callback for exprUsesSrclist(). +*/ +static int exprUsesSrclistSelectCb(Walker *NotUsed1, Select *NotUsed2){ + UNUSED_PARAMETER(NotUsed1); + UNUSED_PARAMETER(NotUsed2); + return WRC_Abort; +} + +/* +** This function always returns true if expression pExpr contains +** a sub-select. +** +** If there is no sub-select in pExpr, then return true if pExpr +** contains a TK_COLUMN node for a table that is (bUses==1) +** or is not (bUses==0) in pSrc. +** +** Said another way: +** +** bUses Return Meaning +** -------- ------ ------------------------------------------------ +** +** bUses==1 true pExpr contains either a sub-select or a +** TK_COLUMN referencing pSrc. +** +** bUses==1 false pExpr contains no sub-selects and all TK_COLUMN +** nodes reference tables not found in pSrc +** +** bUses==0 true pExpr contains either a sub-select or a TK_COLUMN +** that references a table not in pSrc. +** +** bUses==0 false pExpr contains no sub-selects and all TK_COLUMN +** nodes reference pSrc +*/ +static int exprUsesSrclist(SrcList *pSrc, Expr *pExpr, int bUses){ + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.eCode = bUses; + sWalker.u.pSrcList = pSrc; + sWalker.xExprCallback = exprUsesSrclistCb; + sWalker.xSelectCallback = exprUsesSrclistSelectCb; + return (sqlite3WalkExpr(&sWalker, pExpr)==WRC_Abort); +} + +/* +** Context object used by exprExistsToInIter() as it iterates through an +** expression tree. +*/ +struct ExistsToInCtx { + SrcList *pSrc; /* The tables in an EXISTS(SELECT ... FROM <here> ...) */ + Expr *pInLhs; /* OUT: Use this as the LHS of the IN operator */ + Expr *pEq; /* OUT: The == term that include pInLhs */ + Expr **ppAnd; /* OUT: The AND operator that includes pEq as a child */ + Expr **ppParent; /* The AND operator currently being examined */ +}; + +/* +** Iterate through all AND connected nodes in the expression tree +** headed by (*ppExpr), populating the structure passed as the first +** argument with the values required by exprAnalyzeExistsFindEq(). +** +** This function returns non-zero if the expression tree does not meet +** the two conditions described by the header comment for +** exprAnalyzeExistsFindEq(), or zero if it does. +*/ +static int exprExistsToInIter(struct ExistsToInCtx *p, Expr **ppExpr){ + Expr *pExpr = *ppExpr; + switch( pExpr->op ){ + case TK_AND: + p->ppParent = ppExpr; + if( exprExistsToInIter(p, &pExpr->pLeft) ) return 1; + p->ppParent = ppExpr; + if( exprExistsToInIter(p, &pExpr->pRight) ) return 1; + break; + case TK_EQ: { + int bLeft = exprUsesSrclist(p->pSrc, pExpr->pLeft, 0); + int bRight = exprUsesSrclist(p->pSrc, pExpr->pRight, 0); + if( bLeft || bRight ){ + if( (bLeft && bRight) || p->pInLhs ) return 1; + p->pInLhs = bLeft ? pExpr->pLeft : pExpr->pRight; + if( exprUsesSrclist(p->pSrc, p->pInLhs, 1) ) return 1; + p->pEq = pExpr; + p->ppAnd = p->ppParent; + } + break; + } + default: + if( exprUsesSrclist(p->pSrc, pExpr, 0) ){ + return 1; + } + break; + } + + return 0; +} + +/* +** This function is used by exprAnalyzeExists() when creating virtual IN(...) +** terms equivalent to user-supplied EXIST(...) clauses. It splits the WHERE +** clause of the Select object passed as the first argument into one or more +** expressions joined by AND operators, and then tests if the following are +** true: +** +** 1. Exactly one of the AND separated terms refers to the outer +** query, and it is an == (TK_EQ) expression. +** +** 2. Only one side of the == expression refers to the outer query, and +** it does not refer to any columns from the inner query. +** +** If both these conditions are true, then a pointer to the side of the == +** expression that refers to the outer query is returned. The caller will +** use this expression as the LHS of the IN(...) virtual term. Or, if one +** or both of the above conditions are not true, NULL is returned. +** +** If non-NULL is returned and ppEq is non-NULL, *ppEq is set to point +** to the == expression node before returning. If pppAnd is non-NULL and +** the == node is not the root of the WHERE clause, then *pppAnd is set +** to point to the pointer to the AND node that is the parent of the == +** node within the WHERE expression tree. +*/ +static Expr *exprAnalyzeExistsFindEq( + Select *pSel, /* The SELECT of the EXISTS */ + Expr **ppEq, /* OUT: == node from WHERE clause */ + Expr ***pppAnd /* OUT: Pointer to parent of ==, if any */ +){ + struct ExistsToInCtx ctx; + memset(&ctx, 0, sizeof(ctx)); + ctx.pSrc = pSel->pSrc; + if( exprExistsToInIter(&ctx, &pSel->pWhere) ){ + return 0; + } + if( ppEq ) *ppEq = ctx.pEq; + if( pppAnd ) *pppAnd = ctx.ppAnd; + return ctx.pInLhs; +} + +/* +** Term idxTerm of the WHERE clause passed as the second argument is an +** EXISTS expression with a correlated SELECT statement on the RHS. +** This function analyzes the SELECT statement, and if possible adds an +** equivalent "? IN(SELECT...)" virtual term to the WHERE clause. +** +** For an EXISTS term such as the following: +** +** EXISTS (SELECT ... FROM <srclist> WHERE <e1> = <e2> AND <e3>) +** +** The virtual IN() term added is: +** +** <e1> IN (SELECT <e2> FROM <srclist> WHERE <e3>) +** +** The virtual term is only added if the following conditions are met: +** +** 1. The sub-select must not be an aggregate or use window functions, +** +** 2. The sub-select must not be a compound SELECT, +** +** 3. Expression <e1> must refer to at least one column from the outer +** query, and must not refer to any column from the inner query +** (i.e. from <srclist>). +** +** 4. <e2> and <e3> must not refer to any values from the outer query. +** In other words, once <e1> has been removed, the inner query +** must not be correlated. +** +*/ +static void exprAnalyzeExists( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* the WHERE clause */ + int idxTerm /* Index of the term to be analyzed */ +){ + Parse *pParse = pWC->pWInfo->pParse; + WhereTerm *pTerm = &pWC->a[idxTerm]; + Expr *pExpr = pTerm->pExpr; + Select *pSel = pExpr->x.pSelect; + Expr *pDup = 0; + Expr *pEq = 0; + Expr *pRet = 0; + Expr *pInLhs = 0; + Expr **ppAnd = 0; + int idxNew; + sqlite3 *db = pParse->db; + + assert( pExpr->op==TK_EXISTS ); + assert( (pExpr->flags & EP_VarSelect) && (pExpr->flags & EP_xIsSelect) ); + + if( pSel->selFlags & SF_Aggregate ) return; +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSel->pWin ) return; +#endif + if( pSel->pPrior ) return; + if( pSel->pWhere==0 ) return; + if( pSel->pLimit ) return; + if( 0==exprAnalyzeExistsFindEq(pSel, 0, 0) ) return; + + pDup = sqlite3ExprDup(db, pExpr, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + return; + } + pSel = pDup->x.pSelect; + sqlite3ExprListDelete(db, pSel->pEList); + pSel->pEList = 0; + + pInLhs = exprAnalyzeExistsFindEq(pSel, &pEq, &ppAnd); + assert( pInLhs && pEq ); + assert( pEq==pSel->pWhere || ppAnd ); + if( pInLhs==pEq->pLeft ){ + pRet = pEq->pRight; + }else{ + CollSeq *p = sqlite3ExprCompareCollSeq(pParse, pEq); + pInLhs = sqlite3ExprAddCollateString(pParse, pInLhs, p?p->zName:"BINARY"); + pRet = pEq->pLeft; + } + + assert( pDup->pLeft==0 ); + pDup->op = TK_IN; + pDup->pLeft = pInLhs; + pDup->flags &= ~EP_VarSelect; + if( pRet->op==TK_VECTOR ){ + pSel->pEList = pRet->x.pList; + pRet->x.pList = 0; + sqlite3ExprDelete(db, pRet); + }else{ + pSel->pEList = sqlite3ExprListAppend(pParse, 0, pRet); + } + pEq->pLeft = 0; + pEq->pRight = 0; + if( ppAnd ){ + Expr *pAnd = *ppAnd; + Expr *pOther = (pAnd->pLeft==pEq) ? pAnd->pRight : pAnd->pLeft; + pAnd->pLeft = pAnd->pRight = 0; + sqlite3ExprDelete(db, pAnd); + *ppAnd = pOther; + }else{ + assert( pSel->pWhere==pEq ); + pSel->pWhere = 0; + } + sqlite3ExprDelete(db, pEq); + +#ifdef WHERETRACE_ENABLED /* 0x20 */ + if( sqlite3WhereTrace & 0x20 ){ + sqlite3DebugPrintf("Convert EXISTS:\n"); + sqlite3TreeViewExpr(0, pExpr, 0); + sqlite3DebugPrintf("into IN:\n"); + sqlite3TreeViewExpr(0, pDup, 0); + } +#endif + idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pWC, idxNew); + markTermAsChild(pWC, idxNew, idxTerm); + pWC->a[idxTerm].wtFlags |= TERM_COPIED; +} + +/* ** 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 ** subexpression and populate all the other fields of the WhereTerm @@ -145699,6 +147803,12 @@ static void exprAnalyze( pNew->prereqRight = prereqLeft | extraRight; pNew->prereqAll = prereqAll; pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; + }else if( op==TK_ISNULL && 0==sqlite3ExprCanBeNull(pLeft) ){ + pExpr->op = TK_TRUEFALSE; + pExpr->u.zToken = "false"; + ExprSetProperty(pExpr, EP_IsFalse); + pTerm->prereqAll = 0; + pTerm->eOperator = 0; } } @@ -145751,6 +147861,52 @@ static void exprAnalyze( } #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ + else if( pExpr->op==TK_EXISTS ){ + /* Perhaps treat an EXISTS operator as an IN operator */ + if( (pExpr->flags & EP_VarSelect)!=0 + && OptimizationEnabled(db, SQLITE_ExistsToIN) + ){ + exprAnalyzeExists(pSrc, pWC, idxTerm); + } + } + + /* 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 ** operator. @@ -145765,7 +147921,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 */ @@ -145835,52 +147992,6 @@ 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.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_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 @@ -145888,12 +147999,12 @@ static void exprAnalyze( ** ** 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) + 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; i<nLeft; i++){ @@ -145921,12 +148032,14 @@ static void exprAnalyze( ** 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->u.x.iField==0 + else if( pExpr->op==TK_IN + && pTerm->u.x.iField==0 && pExpr->pLeft->op==TK_VECTOR && pExpr->x.pSelect->pPrior==0 #ifndef SQLITE_OMIT_WINDOWFUNC && pExpr->x.pSelect->pWin==0 #endif + && pWC->op==TK_AND ){ int i; for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){ @@ -145938,44 +148051,51 @@ static void exprAnalyze( } } -#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.x.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->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.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. @@ -146135,7 +148255,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; @@ -146212,12 +148332,6 @@ struct HiddenIndexInfo { /* 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 */ @@ -146281,6 +148395,32 @@ SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ } /* +** 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. */ @@ -146849,7 +148989,7 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ */ static int termCanDriveIndex( WhereTerm *pTerm, /* WHERE clause term to check */ - struct SrcList_item *pSrc, /* Table we are trying to access */ + SrcItem *pSrc, /* Table we are trying to access */ Bitmask notReady /* Tables in outer loops of the join */ ){ char aff; @@ -146883,7 +149023,7 @@ static int termCanDriveIndex( static 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 */ + SrcItem *pSrc, /* The FROM clause term to get the next index */ Bitmask notReady, /* Mask of cursors that are not available */ WhereLevel *pLevel /* Write new index here */ ){ @@ -146907,7 +149047,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 */ @@ -147091,7 +149231,7 @@ static sqlite3_index_info *allocateIndexInfo( Parse *pParse, /* The parsing context */ 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 */ + SrcItem *pSrc, /* The FROM clause term that is the vtab */ ExprList *pOrderBy, /* The ORDER BY clause */ u16 *pmNoOmit /* Mask of terms not to omit */ ){ @@ -147989,7 +150129,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, @@ -148600,7 +150740,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) */ ){ @@ -148786,7 +150926,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))<pTerm->pWC->nTerm ); @@ -149091,7 +151231,7 @@ 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 */ @@ -149109,9 +151249,9 @@ static int whereLoopAddBtree( pWC = pBuilder->pWC; assert( !IsVirtual(pSrc->pTab) ); - if( pSrc->pIBIndex ){ + if( pSrc->fg.isIndexedBy ){ /* 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{ @@ -149147,7 +151287,7 @@ static int whereLoopAddBtree( 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 */ @@ -149197,7 +151337,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 @@ -149372,7 +151512,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 ); @@ -149564,7 +151704,7 @@ 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 */ @@ -149692,7 +151832,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; @@ -149808,8 +151948,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; @@ -149832,7 +151972,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ - struct SrcList_item *p; + SrcItem *p; for(p=&pItem[1]; p<pEnd; p++){ if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){ mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); @@ -150687,7 +152827,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; @@ -151146,7 +153286,7 @@ 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 || db->mallocFailed ){ goto whereBeginError; } #ifdef WHERETRACE_ENABLED @@ -151217,7 +153357,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( } for(i=pWInfo->nLevel-1; i>=1; i--){ WhereTerm *pTerm, *pEnd; - struct SrcList_item *pItem; + SrcItem *pItem; pLoop = pWInfo->a[i].pWLoop; pItem = &pWInfo->pTabList->a[pLoop->iTab]; if( (pItem->fg.jointype & JT_LEFT)==0 ) continue; @@ -151307,7 +153447,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){ Table *pTab; /* Table to open */ int iDb; /* Index of database containing table/index */ - struct SrcList_item *pTabItem; + SrcItem *pTabItem; pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; @@ -151644,7 +153784,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ int k, last; 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; @@ -151720,7 +153860,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ #endif pOp = sqlite3VdbeGetOp(v, k); pLastOp = pOp + (last - k); - assert( pOp<pLastOp ); + assert( pOp<pLastOp || (pParse->nErr>0 && pOp==pLastOp) ); do{ if( pOp->p1!=pLevel->iTabCur ){ /* no-op */ @@ -153088,15 +155228,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; } } @@ -153249,6 +155393,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); @@ -153845,6 +155990,7 @@ static void windowCodeRangeTest( int regString = ++pParse->nMem; /* Reg. for constant value '' */ int arith = OP_Add; /* OP_Add or OP_Subtract */ int addrGe; /* Jump destination */ + CollSeq *pColl; assert( op==OP_Ge || op==OP_Gt || op==OP_Le ); assert( pOrderBy && pOrderBy->nExpr==1 ); @@ -153935,6 +156081,8 @@ static void windowCodeRangeTest( ** 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); assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le ); @@ -154941,11 +157089,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 && @@ -154956,6 +157114,19 @@ static void updateDeleteLimitError( } } + /* 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 identifier. Use the ** new Expr to populate pOut. Set the span of pOut to be the identifier @@ -155121,87 +157292,89 @@ static void updateDeleteLimitError( #define TK_LAST 84 #define TK_GENERATED 85 #define TK_ALWAYS 86 -#define TK_REINDEX 87 -#define TK_RENAME 88 -#define TK_CTIME_KW 89 -#define TK_ANY 90 -#define TK_BITAND 91 -#define TK_BITOR 92 -#define TK_LSHIFT 93 -#define TK_RSHIFT 94 -#define TK_PLUS 95 -#define TK_MINUS 96 -#define TK_STAR 97 -#define TK_SLASH 98 -#define TK_REM 99 -#define TK_CONCAT 100 -#define TK_COLLATE 101 -#define TK_BITNOT 102 -#define TK_ON 103 -#define TK_INDEXED 104 -#define TK_STRING 105 -#define TK_JOIN_KW 106 -#define TK_CONSTRAINT 107 -#define TK_DEFAULT 108 -#define TK_NULL 109 -#define TK_PRIMARY 110 -#define TK_UNIQUE 111 -#define TK_CHECK 112 -#define TK_REFERENCES 113 -#define TK_AUTOINCR 114 -#define TK_INSERT 115 -#define TK_DELETE 116 -#define TK_UPDATE 117 -#define TK_SET 118 -#define TK_DEFERRABLE 119 -#define TK_FOREIGN 120 -#define TK_DROP 121 -#define TK_UNION 122 -#define TK_ALL 123 -#define TK_EXCEPT 124 -#define TK_INTERSECT 125 -#define TK_SELECT 126 -#define TK_VALUES 127 -#define TK_DISTINCT 128 -#define TK_DOT 129 -#define TK_FROM 130 -#define TK_JOIN 131 -#define TK_USING 132 -#define TK_ORDER 133 -#define TK_GROUP 134 -#define TK_HAVING 135 -#define TK_LIMIT 136 -#define TK_WHERE 137 -#define TK_INTO 138 -#define TK_NOTHING 139 -#define TK_FLOAT 140 -#define TK_BLOB 141 -#define TK_INTEGER 142 -#define TK_VARIABLE 143 -#define TK_CASE 144 -#define TK_WHEN 145 -#define TK_THEN 146 -#define TK_ELSE 147 -#define TK_INDEX 148 -#define TK_ALTER 149 -#define TK_ADD 150 -#define TK_COLUMN 151 -#define TK_AGG_FUNCTION 152 -#define TK_AGG_COLUMN 153 -#define TK_TRUEFALSE 154 -#define TK_ISNOT 155 -#define TK_FUNCTION 156 -#define TK_UMINUS 157 -#define TK_UPLUS 158 -#define TK_TRUTH 159 -#define TK_REGISTER 160 -#define TK_VECTOR 161 -#define TK_SELECT_COLUMN 162 -#define TK_IF_NULL_ROW 163 -#define TK_ASTERISK 164 -#define TK_SPAN 165 -#define TK_SPACE 166 -#define TK_ILLEGAL 167 +#define TK_MATERIALIZED 87 +#define TK_REINDEX 88 +#define TK_RENAME 89 +#define TK_CTIME_KW 90 +#define TK_ANY 91 +#define TK_BITAND 92 +#define TK_BITOR 93 +#define TK_LSHIFT 94 +#define TK_RSHIFT 95 +#define TK_PLUS 96 +#define TK_MINUS 97 +#define TK_STAR 98 +#define TK_SLASH 99 +#define TK_REM 100 +#define TK_CONCAT 101 +#define TK_COLLATE 102 +#define TK_BITNOT 103 +#define TK_ON 104 +#define TK_INDEXED 105 +#define TK_STRING 106 +#define TK_JOIN_KW 107 +#define TK_CONSTRAINT 108 +#define TK_DEFAULT 109 +#define TK_NULL 110 +#define TK_PRIMARY 111 +#define TK_UNIQUE 112 +#define TK_CHECK 113 +#define TK_REFERENCES 114 +#define TK_AUTOINCR 115 +#define TK_INSERT 116 +#define TK_DELETE 117 +#define TK_UPDATE 118 +#define TK_SET 119 +#define TK_DEFERRABLE 120 +#define TK_FOREIGN 121 +#define TK_DROP 122 +#define TK_UNION 123 +#define TK_ALL 124 +#define TK_EXCEPT 125 +#define TK_INTERSECT 126 +#define TK_SELECT 127 +#define TK_VALUES 128 +#define TK_DISTINCT 129 +#define TK_DOT 130 +#define TK_FROM 131 +#define TK_JOIN 132 +#define TK_USING 133 +#define TK_ORDER 134 +#define TK_GROUP 135 +#define TK_HAVING 136 +#define TK_LIMIT 137 +#define TK_WHERE 138 +#define TK_RETURNING 139 +#define TK_INTO 140 +#define TK_NOTHING 141 +#define TK_FLOAT 142 +#define TK_BLOB 143 +#define TK_INTEGER 144 +#define TK_VARIABLE 145 +#define TK_CASE 146 +#define TK_WHEN 147 +#define TK_THEN 148 +#define TK_ELSE 149 +#define TK_INDEX 150 +#define TK_ALTER 151 +#define TK_ADD 152 +#define TK_COLUMN 153 +#define TK_AGG_FUNCTION 154 +#define TK_AGG_COLUMN 155 +#define TK_TRUEFALSE 156 +#define TK_ISNOT 157 +#define TK_FUNCTION 158 +#define TK_UMINUS 159 +#define TK_UPLUS 160 +#define TK_TRUTH 161 +#define TK_REGISTER 162 +#define TK_VECTOR 163 +#define TK_SELECT_COLUMN 164 +#define TK_IF_NULL_ROW 165 +#define TK_ASTERISK 166 +#define TK_SPAN 167 +#define TK_SPACE 168 +#define TK_ILLEGAL 169 #endif /**************** End token definitions ***************************************/ @@ -155261,25 +157434,27 @@ static void updateDeleteLimitError( #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 281 +#define YYNOCODE 287 #define YYACTIONTYPE unsigned short int -#define YYWILDCARD 90 +#define YYWILDCARD 91 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; - IdList* yy14; - TriggerStep* yy39; - Upsert* yy90; - struct TrigEvent yy168; - int yy222; - Expr* yy244; - ExprList* yy328; - Select* yy341; - const char* yy386; - SrcList* yy475; - struct {int value; int mask;} yy501; - With* yy523; + Expr* yy62; + IdList* yy76; + int yy116; + const char* yy224; + SrcList* yy315; + ExprList* yy336; + Upsert* yy402; + Cte* yy403; + struct TrigEvent yy440; + TriggerStep* yy441; + Select* yy457; + u8 yy518; + struct {int value; int mask;} yy523; + With* yy535; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -155295,18 +157470,18 @@ typedef union { #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 -#define YYNSTATE 498 -#define YYNRULE 344 -#define YYNRULE_WITH_ACTION 285 -#define YYNTOKEN 168 -#define YY_MAX_SHIFT 497 -#define YY_MIN_SHIFTREDUCE 716 -#define YY_MAX_SHIFTREDUCE 1059 -#define YY_ERROR_ACTION 1060 -#define YY_ACCEPT_ACTION 1061 -#define YY_NO_ACTION 1062 -#define YY_MIN_REDUCE 1063 -#define YY_MAX_REDUCE 1406 +#define YYNSTATE 515 +#define YYNRULE 357 +#define YYNRULE_WITH_ACTION 297 +#define YYNTOKEN 170 +#define YY_MAX_SHIFT 514 +#define YY_MIN_SHIFTREDUCE 738 +#define YY_MAX_SHIFTREDUCE 1094 +#define YY_ERROR_ACTION 1095 +#define YY_ACCEPT_ACTION 1096 +#define YY_NO_ACTION 1097 +#define YY_MIN_REDUCE 1098 +#define YY_MAX_REDUCE 1454 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -155373,511 +157548,527 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (1678) +#define YY_ACTTAB_COUNT (1728) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 101, 98, 187, 101, 98, 187, 1368, 1130, 492, 1109, - /* 10 */ 172, 172, 462, 1092, 1102, 492, 357, 1130, 336, 1402, - /* 20 */ 343, 1329, 350, 345, 325, 234, 1373, 326, 847, 778, - /* 30 */ 58, 58, 416, 357, 12, 12, 848, 43, 43, 463, - /* 40 */ 85, 108, 109, 99, 1037, 1037, 914, 917, 907, 907, - /* 50 */ 106, 106, 107, 107, 107, 107, 342, 1057, 108, 109, - /* 60 */ 99, 1037, 1037, 914, 917, 907, 907, 106, 106, 107, - /* 70 */ 107, 107, 107, 239, 239, 101, 98, 187, 101, 98, - /* 80 */ 187, 957, 101, 98, 187, 489, 110, 162, 329, 215, - /* 90 */ 184, 105, 105, 105, 105, 104, 104, 103, 103, 103, - /* 100 */ 102, 389, 389, 357, 107, 107, 107, 107, 105, 105, - /* 110 */ 105, 105, 104, 104, 103, 103, 103, 102, 389, 107, - /* 120 */ 107, 107, 107, 100, 147, 1014, 366, 1058, 108, 109, - /* 130 */ 99, 1037, 1037, 914, 917, 907, 907, 106, 106, 107, - /* 140 */ 107, 107, 107, 105, 105, 105, 105, 104, 104, 103, - /* 150 */ 103, 103, 102, 389, 68, 486, 486, 486, 105, 105, - /* 160 */ 105, 105, 104, 104, 103, 103, 103, 102, 389, 261, - /* 170 */ 483, 357, 1014, 1015, 1016, 91, 69, 89, 105, 105, - /* 180 */ 105, 105, 104, 104, 103, 103, 103, 102, 389, 407, - /* 190 */ 285, 996, 1400, 357, 269, 1400, 108, 109, 99, 1037, - /* 200 */ 1037, 914, 917, 907, 907, 106, 106, 107, 107, 107, - /* 210 */ 107, 104, 104, 103, 103, 103, 102, 389, 108, 109, - /* 220 */ 99, 1037, 1037, 914, 917, 907, 907, 106, 106, 107, - /* 230 */ 107, 107, 107, 105, 105, 105, 105, 104, 104, 103, - /* 240 */ 103, 103, 102, 389, 407, 285, 105, 105, 105, 105, - /* 250 */ 104, 104, 103, 103, 103, 102, 389, 103, 103, 103, - /* 260 */ 102, 389, 994, 357, 397, 102, 389, 299, 105, 105, - /* 270 */ 105, 105, 104, 104, 103, 103, 103, 102, 389, 876, - /* 280 */ 357, 397, 396, 490, 445, 803, 803, 147, 108, 109, - /* 290 */ 99, 1037, 1037, 914, 917, 907, 907, 106, 106, 107, - /* 300 */ 107, 107, 107, 342, 995, 108, 109, 99, 1037, 1037, - /* 310 */ 914, 917, 907, 907, 106, 106, 107, 107, 107, 107, - /* 320 */ 310, 283, 207, 87, 297, 444, 441, 440, 312, 492, - /* 330 */ 309, 1014, 261, 483, 1095, 439, 112, 172, 105, 105, - /* 340 */ 105, 105, 104, 104, 103, 103, 103, 102, 389, 356, - /* 350 */ 397, 59, 59, 163, 1094, 105, 105, 105, 105, 104, - /* 360 */ 104, 103, 103, 103, 102, 389, 366, 904, 904, 915, - /* 370 */ 918, 253, 357, 253, 1058, 129, 753, 366, 1014, 1015, - /* 380 */ 1016, 207, 1135, 1135, 444, 441, 440, 474, 292, 357, - /* 390 */ 295, 1014, 267, 746, 439, 1374, 464, 108, 109, 99, - /* 400 */ 1037, 1037, 914, 917, 907, 907, 106, 106, 107, 107, - /* 410 */ 107, 107, 354, 353, 108, 109, 99, 1037, 1037, 914, - /* 420 */ 917, 907, 907, 106, 106, 107, 107, 107, 107, 414, - /* 430 */ 399, 978, 908, 147, 246, 436, 1133, 1133, 1014, 1015, - /* 440 */ 1016, 347, 431, 1014, 431, 247, 979, 105, 105, 105, - /* 450 */ 105, 104, 104, 103, 103, 103, 102, 389, 154, 731, - /* 460 */ 398, 1165, 980, 211, 105, 105, 105, 105, 104, 104, - /* 470 */ 103, 103, 103, 102, 389, 239, 239, 1293, 261, 483, - /* 480 */ 8, 357, 492, 789, 260, 895, 1328, 489, 1292, 214, - /* 490 */ 1014, 1015, 1016, 355, 312, 790, 1014, 181, 357, 1014, - /* 500 */ 491, 245, 881, 412, 59, 59, 108, 109, 99, 1037, - /* 510 */ 1037, 914, 917, 907, 907, 106, 106, 107, 107, 107, - /* 520 */ 107, 405, 362, 108, 109, 99, 1037, 1037, 914, 917, - /* 530 */ 907, 907, 106, 106, 107, 107, 107, 107, 302, 813, - /* 540 */ 474, 131, 276, 1014, 1015, 1016, 1014, 1015, 1016, 473, - /* 550 */ 268, 959, 937, 1014, 421, 959, 105, 105, 105, 105, - /* 560 */ 104, 104, 103, 103, 103, 102, 389, 4, 168, 1298, - /* 570 */ 834, 324, 492, 105, 105, 105, 105, 104, 104, 103, - /* 580 */ 103, 103, 102, 389, 239, 239, 1298, 1300, 426, 1285, - /* 590 */ 357, 492, 261, 483, 9, 9, 489, 387, 387, 387, - /* 600 */ 1014, 1015, 1016, 386, 385, 1014, 273, 357, 275, 368, - /* 610 */ 312, 82, 173, 59, 59, 108, 109, 99, 1037, 1037, - /* 620 */ 914, 917, 907, 907, 106, 106, 107, 107, 107, 107, - /* 630 */ 361, 832, 108, 109, 99, 1037, 1037, 914, 917, 907, - /* 640 */ 907, 106, 106, 107, 107, 107, 107, 468, 1044, 474, - /* 650 */ 1044, 211, 1014, 1015, 1016, 1298, 1018, 128, 453, 281, - /* 660 */ 185, 1141, 431, 1081, 328, 105, 105, 105, 105, 104, - /* 670 */ 104, 103, 103, 103, 102, 389, 808, 274, 492, 420, - /* 680 */ 492, 807, 105, 105, 105, 105, 104, 104, 103, 103, - /* 690 */ 103, 102, 389, 239, 239, 239, 239, 239, 239, 357, - /* 700 */ 9, 9, 9, 9, 1018, 489, 1142, 489, 425, 489, - /* 710 */ 362, 1014, 422, 420, 186, 373, 357, 375, 414, 876, - /* 720 */ 90, 431, 456, 1014, 108, 109, 99, 1037, 1037, 914, - /* 730 */ 917, 907, 907, 106, 106, 107, 107, 107, 107, 832, - /* 740 */ 1336, 108, 97, 99, 1037, 1037, 914, 917, 907, 907, - /* 750 */ 106, 106, 107, 107, 107, 107, 239, 239, 1014, 1015, - /* 760 */ 1016, 283, 402, 271, 2, 394, 1113, 1014, 489, 431, - /* 770 */ 1014, 1015, 1016, 248, 105, 105, 105, 105, 104, 104, - /* 780 */ 103, 103, 103, 102, 389, 833, 769, 459, 420, 492, - /* 790 */ 249, 105, 105, 105, 105, 104, 104, 103, 103, 103, - /* 800 */ 102, 389, 1014, 414, 71, 233, 233, 282, 357, 492, - /* 810 */ 1227, 9, 9, 1138, 1014, 1015, 1016, 489, 448, 392, - /* 820 */ 991, 239, 239, 344, 431, 357, 252, 192, 770, 1084, - /* 830 */ 363, 59, 59, 489, 109, 99, 1037, 1037, 914, 917, - /* 840 */ 907, 907, 106, 106, 107, 107, 107, 107, 492, 1014, - /* 850 */ 1015, 1016, 99, 1037, 1037, 914, 917, 907, 907, 106, - /* 860 */ 106, 107, 107, 107, 107, 996, 1401, 469, 290, 1401, - /* 870 */ 44, 44, 377, 492, 465, 250, 492, 94, 484, 370, - /* 880 */ 3, 313, 251, 105, 105, 105, 105, 104, 104, 103, - /* 890 */ 103, 103, 102, 389, 487, 11, 11, 1112, 9, 9, - /* 900 */ 105, 105, 105, 105, 104, 104, 103, 103, 103, 102, - /* 910 */ 389, 492, 477, 471, 312, 181, 8, 492, 390, 374, - /* 920 */ 1061, 1, 1, 497, 1063, 894, 492, 94, 484, 262, - /* 930 */ 3, 123, 481, 59, 59, 194, 994, 492, 1143, 59, - /* 940 */ 59, 887, 147, 126, 487, 886, 239, 239, 33, 33, - /* 950 */ 894, 236, 393, 5, 832, 218, 92, 92, 489, 45, - /* 960 */ 45, 130, 466, 93, 409, 390, 494, 493, 390, 384, - /* 970 */ 886, 492, 239, 239, 492, 388, 886, 886, 888, 1227, - /* 980 */ 978, 741, 481, 452, 489, 171, 873, 261, 483, 1227, - /* 990 */ 406, 1035, 756, 46, 46, 979, 47, 47, 195, 1147, - /* 1000 */ 894, 886, 886, 888, 889, 19, 92, 92, 812, 808, - /* 1010 */ 489, 980, 313, 93, 807, 390, 494, 493, 94, 484, - /* 1020 */ 886, 3, 176, 492, 962, 962, 428, 391, 847, 741, - /* 1030 */ 86, 484, 480, 3, 475, 487, 848, 186, 492, 1035, - /* 1040 */ 756, 492, 418, 492, 1227, 59, 59, 487, 371, 454, - /* 1050 */ 381, 886, 886, 888, 889, 19, 492, 1333, 372, 390, - /* 1060 */ 39, 39, 832, 48, 48, 49, 49, 944, 239, 239, - /* 1070 */ 492, 390, 13, 481, 240, 240, 190, 492, 50, 50, - /* 1080 */ 489, 474, 266, 239, 239, 481, 489, 210, 209, 208, - /* 1090 */ 476, 894, 34, 34, 241, 489, 455, 92, 92, 35, - /* 1100 */ 35, 485, 363, 894, 93, 492, 390, 494, 493, 92, - /* 1110 */ 92, 886, 408, 382, 492, 944, 93, 492, 390, 494, - /* 1120 */ 493, 1227, 1052, 886, 1348, 1004, 243, 36, 36, 492, - /* 1130 */ 419, 340, 340, 339, 228, 337, 38, 38, 728, 51, - /* 1140 */ 51, 492, 886, 886, 888, 889, 19, 261, 483, 749, - /* 1150 */ 1178, 52, 52, 265, 886, 886, 888, 889, 19, 1004, - /* 1160 */ 243, 264, 1177, 53, 53, 340, 340, 339, 228, 337, - /* 1170 */ 492, 379, 728, 1349, 497, 1063, 303, 719, 720, 721, - /* 1180 */ 262, 894, 123, 401, 492, 238, 184, 265, 22, 1143, - /* 1190 */ 427, 492, 10, 10, 191, 264, 749, 887, 84, 492, - /* 1200 */ 1339, 886, 140, 492, 1361, 142, 54, 54, 492, 364, - /* 1210 */ 148, 768, 767, 114, 114, 492, 127, 277, 28, 492, - /* 1220 */ 23, 55, 55, 239, 239, 40, 40, 956, 191, 956, - /* 1230 */ 56, 56, 886, 886, 888, 489, 140, 57, 57, 142, - /* 1240 */ 447, 41, 41, 280, 1317, 358, 84, 492, 1034, 195, - /* 1250 */ 261, 483, 1014, 492, 878, 413, 376, 217, 217, 492, - /* 1260 */ 775, 776, 225, 242, 311, 450, 306, 449, 212, 135, - /* 1270 */ 135, 492, 1316, 395, 302, 136, 136, 415, 391, 358, - /* 1280 */ 217, 64, 64, 492, 261, 483, 492, 218, 423, 760, - /* 1290 */ 386, 385, 492, 42, 42, 492, 850, 851, 1041, 1014, - /* 1300 */ 1015, 1016, 492, 1043, 492, 60, 60, 395, 115, 115, - /* 1310 */ 492, 1042, 890, 287, 61, 61, 492, 116, 116, 492, - /* 1320 */ 955, 492, 955, 1035, 117, 117, 113, 113, 492, 1174, - /* 1330 */ 1111, 492, 134, 134, 492, 1044, 492, 1044, 133, 133, - /* 1340 */ 492, 121, 121, 120, 120, 492, 286, 492, 479, 84, - /* 1350 */ 118, 118, 291, 119, 119, 176, 63, 63, 65, 65, - /* 1360 */ 890, 437, 62, 62, 213, 294, 296, 32, 32, 37, - /* 1370 */ 37, 1035, 300, 298, 940, 84, 841, 213, 805, 217, - /* 1380 */ 739, 96, 806, 125, 1126, 96, 1110, 305, 7, 314, - /* 1390 */ 315, 1186, 1226, 1161, 1172, 258, 478, 1232, 432, 1091, - /* 1400 */ 231, 1083, 1072, 1071, 1073, 1355, 174, 270, 189, 1158, - /* 1410 */ 341, 317, 279, 319, 321, 178, 1219, 417, 284, 482, - /* 1420 */ 182, 400, 334, 272, 323, 177, 1358, 1052, 1049, 220, - /* 1430 */ 71, 150, 442, 308, 67, 365, 1289, 70, 1109, 1288, - /* 1440 */ 411, 160, 82, 1216, 145, 403, 1294, 404, 25, 435, - /* 1450 */ 197, 201, 348, 26, 424, 152, 76, 430, 232, 203, - /* 1460 */ 155, 156, 157, 158, 1222, 1211, 164, 1305, 1208, 289, - /* 1470 */ 169, 293, 204, 346, 410, 433, 1074, 349, 205, 1283, - /* 1480 */ 451, 351, 1129, 1128, 1127, 378, 78, 1372, 1120, 352, - /* 1490 */ 760, 1371, 1099, 380, 81, 307, 1098, 1097, 1119, 467, - /* 1500 */ 1370, 458, 1169, 316, 461, 1170, 219, 318, 383, 1168, - /* 1510 */ 6, 320, 327, 256, 1269, 1167, 88, 257, 259, 111, - /* 1520 */ 1193, 322, 1192, 472, 83, 226, 1009, 1080, 470, 24, - /* 1530 */ 495, 227, 230, 331, 1151, 332, 330, 333, 496, 229, - /* 1540 */ 1069, 137, 1064, 1321, 1322, 1320, 124, 138, 254, 175, - /* 1550 */ 263, 1319, 188, 244, 122, 954, 179, 952, 870, 151, - /* 1560 */ 180, 139, 141, 193, 66, 153, 792, 278, 359, 196, - /* 1570 */ 968, 159, 874, 143, 367, 72, 161, 369, 73, 74, - /* 1580 */ 144, 971, 75, 198, 967, 199, 149, 132, 360, 14, - /* 1590 */ 200, 288, 1046, 960, 217, 429, 166, 202, 27, 730, - /* 1600 */ 165, 309, 434, 206, 301, 438, 167, 77, 15, 16, - /* 1610 */ 758, 443, 304, 79, 255, 146, 893, 771, 892, 446, - /* 1620 */ 920, 999, 80, 29, 457, 1000, 30, 460, 183, 235, - /* 1630 */ 237, 170, 835, 216, 96, 935, 84, 921, 840, 17, - /* 1640 */ 919, 923, 977, 924, 976, 18, 221, 222, 20, 31, - /* 1650 */ 488, 891, 740, 95, 338, 21, 1005, 335, 1062, 802, - /* 1660 */ 1062, 1062, 1062, 1062, 1062, 1062, 1062, 1062, 223, 1062, - /* 1670 */ 1062, 1062, 1062, 1062, 224, 1363, 1062, 1362, + /* 0 */ 102, 99, 194, 102, 99, 194, 1127, 479, 1165, 509, + /* 10 */ 1144, 503, 503, 503, 240, 240, 371, 413, 1165, 1415, + /* 20 */ 1340, 1371, 339, 241, 1130, 340, 506, 1137, 869, 12, + /* 30 */ 12, 58, 58, 371, 413, 412, 870, 1340, 1342, 480, + /* 40 */ 86, 109, 110, 100, 1072, 1072, 943, 946, 936, 936, + /* 50 */ 107, 107, 108, 108, 108, 108, 1170, 1170, 109, 110, + /* 60 */ 100, 1072, 1072, 943, 946, 936, 936, 107, 107, 108, + /* 70 */ 108, 108, 108, 246, 246, 102, 99, 194, 102, 99, + /* 80 */ 194, 113, 102, 99, 194, 506, 111, 1168, 1168, 222, + /* 90 */ 191, 343, 106, 106, 106, 106, 105, 105, 104, 104, + /* 100 */ 104, 103, 406, 371, 434, 413, 406, 1048, 1340, 106, + /* 110 */ 106, 106, 106, 105, 105, 104, 104, 104, 103, 406, + /* 120 */ 108, 108, 108, 108, 101, 425, 299, 124, 109, 110, + /* 130 */ 100, 1072, 1072, 943, 946, 936, 936, 107, 107, 108, + /* 140 */ 108, 108, 108, 106, 106, 106, 106, 105, 105, 104, + /* 150 */ 104, 104, 103, 406, 68, 1048, 1049, 1050, 368, 367, + /* 160 */ 106, 106, 106, 106, 105, 105, 104, 104, 104, 103, + /* 170 */ 406, 371, 243, 275, 500, 854, 69, 254, 375, 106, + /* 180 */ 106, 106, 106, 105, 105, 104, 104, 104, 103, 406, + /* 190 */ 71, 1048, 434, 371, 1048, 436, 109, 110, 100, 1072, + /* 200 */ 1072, 943, 946, 936, 936, 107, 107, 108, 108, 108, + /* 210 */ 108, 105, 105, 104, 104, 104, 103, 406, 109, 110, + /* 220 */ 100, 1072, 1072, 943, 946, 936, 936, 107, 107, 108, + /* 230 */ 108, 108, 108, 104, 104, 104, 103, 406, 509, 1048, + /* 240 */ 1049, 1050, 1048, 1049, 1050, 753, 1129, 106, 106, 106, + /* 250 */ 106, 105, 105, 104, 104, 104, 103, 406, 445, 193, + /* 260 */ 43, 43, 442, 1048, 371, 259, 856, 282, 313, 106, + /* 270 */ 106, 106, 106, 105, 105, 104, 104, 104, 103, 406, + /* 280 */ 108, 108, 108, 108, 854, 933, 933, 944, 947, 109, + /* 290 */ 110, 100, 1072, 1072, 943, 946, 936, 936, 107, 107, + /* 300 */ 108, 108, 108, 108, 835, 215, 124, 423, 464, 461, + /* 310 */ 460, 1048, 1049, 1050, 356, 1092, 180, 434, 459, 165, + /* 320 */ 106, 106, 106, 106, 105, 105, 104, 104, 104, 103, + /* 330 */ 406, 103, 406, 371, 414, 1048, 440, 465, 430, 966, + /* 340 */ 106, 106, 106, 106, 105, 105, 104, 104, 104, 103, + /* 350 */ 406, 937, 275, 500, 1335, 771, 1269, 1048, 109, 110, + /* 360 */ 100, 1072, 1072, 943, 946, 936, 936, 107, 107, 108, + /* 370 */ 108, 108, 108, 182, 403, 402, 509, 1327, 509, 404, + /* 380 */ 404, 404, 1076, 1048, 1049, 1050, 1093, 1078, 923, 492, + /* 390 */ 262, 329, 172, 252, 905, 1077, 1450, 357, 59, 59, + /* 400 */ 59, 59, 124, 771, 916, 1048, 1049, 1050, 915, 106, + /* 410 */ 106, 106, 106, 105, 105, 104, 104, 104, 103, 406, + /* 420 */ 1079, 175, 1079, 246, 246, 386, 371, 246, 246, 350, + /* 430 */ 775, 1421, 258, 364, 486, 506, 491, 297, 134, 506, + /* 440 */ 915, 915, 917, 371, 509, 493, 451, 768, 275, 500, + /* 450 */ 508, 109, 110, 100, 1072, 1072, 943, 946, 936, 936, + /* 460 */ 107, 107, 108, 108, 108, 108, 44, 44, 109, 110, + /* 470 */ 100, 1072, 1072, 943, 946, 936, 936, 107, 107, 108, + /* 480 */ 108, 108, 108, 1007, 1182, 403, 402, 986, 175, 456, + /* 490 */ 379, 991, 991, 448, 1048, 506, 275, 500, 1008, 1393, + /* 500 */ 359, 13, 106, 106, 106, 106, 105, 105, 104, 104, + /* 510 */ 104, 103, 406, 507, 1009, 825, 825, 219, 175, 106, + /* 520 */ 106, 106, 106, 105, 105, 104, 104, 104, 103, 406, + /* 530 */ 370, 1079, 381, 1079, 1269, 811, 371, 509, 188, 381, + /* 540 */ 924, 382, 1048, 1049, 1050, 215, 409, 812, 464, 461, + /* 550 */ 460, 338, 267, 371, 267, 440, 327, 910, 459, 59, + /* 560 */ 59, 109, 110, 100, 1072, 1072, 943, 946, 936, 936, + /* 570 */ 107, 107, 108, 108, 108, 108, 434, 376, 109, 110, + /* 580 */ 100, 1072, 1072, 943, 946, 936, 936, 107, 107, 108, + /* 590 */ 108, 108, 108, 316, 390, 491, 425, 299, 1026, 1448, + /* 600 */ 284, 509, 1448, 387, 481, 509, 361, 255, 263, 741, + /* 610 */ 742, 743, 106, 106, 106, 106, 105, 105, 104, 104, + /* 620 */ 104, 103, 406, 59, 59, 509, 166, 11, 11, 106, + /* 630 */ 106, 106, 106, 105, 105, 104, 104, 104, 103, 406, + /* 640 */ 246, 246, 246, 246, 509, 8, 371, 9, 9, 264, + /* 650 */ 1148, 296, 506, 83, 506, 329, 1119, 377, 440, 491, + /* 660 */ 329, 485, 384, 371, 1048, 381, 32, 32, 490, 432, + /* 670 */ 1024, 109, 110, 100, 1072, 1072, 943, 946, 936, 936, + /* 680 */ 107, 107, 108, 108, 108, 108, 509, 192, 109, 110, + /* 690 */ 100, 1072, 1072, 943, 946, 936, 936, 107, 107, 108, + /* 700 */ 108, 108, 108, 1007, 342, 395, 311, 136, 45, 45, + /* 710 */ 317, 1377, 1048, 1049, 1050, 509, 174, 1048, 1008, 502, + /* 720 */ 377, 424, 106, 106, 106, 106, 105, 105, 104, 104, + /* 730 */ 104, 103, 406, 257, 1009, 356, 1025, 59, 59, 106, + /* 740 */ 106, 106, 106, 105, 105, 104, 104, 104, 103, 406, + /* 750 */ 1395, 1038, 250, 509, 265, 497, 1048, 354, 354, 353, + /* 760 */ 235, 351, 1379, 1394, 750, 1048, 1049, 1050, 1393, 923, + /* 770 */ 306, 126, 309, 491, 467, 9, 9, 410, 88, 280, + /* 780 */ 1026, 1449, 473, 1375, 1449, 916, 5, 279, 225, 915, + /* 790 */ 389, 392, 855, 509, 4, 91, 509, 232, 249, 325, + /* 800 */ 470, 320, 469, 220, 1048, 1049, 1050, 1093, 1420, 316, + /* 810 */ 8, 800, 371, 509, 219, 9, 9, 176, 9, 9, + /* 820 */ 199, 915, 915, 917, 1069, 218, 217, 216, 145, 371, + /* 830 */ 391, 122, 1048, 266, 281, 59, 59, 109, 110, 100, + /* 840 */ 1072, 1072, 943, 946, 936, 936, 107, 107, 108, 108, + /* 850 */ 108, 108, 1024, 509, 109, 110, 100, 1072, 1072, 943, + /* 860 */ 946, 936, 936, 107, 107, 108, 108, 108, 108, 275, + /* 870 */ 500, 401, 372, 1069, 376, 33, 33, 275, 500, 451, + /* 880 */ 1048, 1049, 1050, 1176, 451, 1116, 441, 1048, 106, 106, + /* 890 */ 106, 106, 105, 105, 104, 104, 104, 103, 406, 476, + /* 900 */ 2, 411, 129, 509, 327, 106, 106, 106, 106, 105, + /* 910 */ 105, 104, 104, 104, 103, 406, 1269, 246, 246, 246, + /* 920 */ 246, 509, 371, 1370, 869, 9, 9, 1147, 1334, 506, + /* 930 */ 22, 506, 870, 246, 246, 1048, 1049, 1050, 1048, 371, + /* 940 */ 488, 1213, 398, 59, 59, 506, 494, 109, 98, 100, + /* 950 */ 1072, 1072, 943, 946, 936, 936, 107, 107, 108, 108, + /* 960 */ 108, 108, 23, 854, 472, 110, 100, 1072, 1072, 943, + /* 970 */ 946, 936, 936, 107, 107, 108, 108, 108, 108, 405, + /* 980 */ 246, 246, 329, 905, 289, 388, 1048, 1049, 1050, 1212, + /* 990 */ 830, 509, 506, 329, 451, 829, 419, 451, 106, 106, + /* 1000 */ 106, 106, 105, 105, 104, 104, 104, 103, 406, 1382, + /* 1010 */ 791, 509, 188, 46, 46, 106, 106, 106, 106, 105, + /* 1020 */ 105, 104, 104, 104, 103, 406, 297, 420, 285, 133, + /* 1030 */ 415, 509, 371, 47, 47, 509, 1269, 417, 1177, 225, + /* 1040 */ 135, 1173, 468, 247, 247, 988, 369, 193, 286, 988, + /* 1050 */ 288, 509, 792, 48, 48, 506, 451, 49, 49, 100, + /* 1060 */ 1072, 1072, 943, 946, 936, 936, 107, 107, 108, 108, + /* 1070 */ 108, 108, 854, 50, 50, 1069, 509, 1021, 95, 501, + /* 1080 */ 358, 3, 446, 1200, 509, 1096, 1, 1, 514, 1098, + /* 1090 */ 1393, 1269, 1052, 85, 276, 504, 127, 393, 34, 34, + /* 1100 */ 304, 1393, 290, 1178, 509, 447, 35, 35, 106, 106, + /* 1110 */ 106, 106, 105, 105, 104, 104, 104, 103, 406, 407, + /* 1120 */ 183, 287, 378, 152, 1069, 1068, 36, 36, 482, 95, + /* 1130 */ 501, 509, 3, 498, 509, 418, 438, 246, 246, 509, + /* 1140 */ 92, 1052, 90, 124, 369, 474, 504, 95, 501, 506, + /* 1150 */ 3, 509, 923, 38, 38, 1146, 39, 39, 93, 93, + /* 1160 */ 399, 51, 51, 203, 504, 94, 427, 407, 511, 510, + /* 1170 */ 407, 200, 915, 52, 52, 369, 509, 431, 509, 246, + /* 1180 */ 246, 245, 191, 778, 498, 782, 369, 274, 407, 275, + /* 1190 */ 500, 506, 475, 198, 408, 132, 369, 28, 53, 53, + /* 1200 */ 10, 10, 498, 923, 915, 915, 917, 918, 19, 93, + /* 1210 */ 93, 834, 72, 179, 790, 789, 94, 483, 407, 511, + /* 1220 */ 510, 923, 985, 915, 985, 439, 509, 93, 93, 509, + /* 1230 */ 830, 509, 778, 183, 94, 829, 407, 511, 510, 1087, + /* 1240 */ 509, 915, 509, 426, 87, 501, 509, 3, 54, 54, + /* 1250 */ 251, 115, 115, 55, 55, 915, 915, 917, 918, 19, + /* 1260 */ 131, 504, 40, 40, 56, 56, 294, 509, 57, 57, + /* 1270 */ 797, 798, 973, 915, 915, 917, 918, 19, 428, 295, + /* 1280 */ 202, 509, 85, 278, 509, 407, 509, 1038, 250, 41, + /* 1290 */ 41, 509, 324, 354, 354, 353, 235, 351, 763, 498, + /* 1300 */ 750, 260, 323, 140, 140, 509, 141, 141, 64, 64, + /* 1310 */ 478, 1359, 919, 42, 42, 280, 907, 509, 923, 224, + /* 1320 */ 984, 973, 984, 279, 93, 93, 1358, 60, 60, 509, + /* 1330 */ 248, 94, 509, 407, 511, 510, 509, 272, 915, 116, + /* 1340 */ 116, 1396, 514, 1098, 872, 873, 433, 763, 276, 224, + /* 1350 */ 127, 61, 61, 452, 117, 117, 199, 1178, 118, 118, + /* 1360 */ 435, 919, 509, 224, 145, 827, 509, 122, 97, 443, + /* 1370 */ 915, 915, 917, 918, 19, 301, 509, 300, 509, 1209, + /* 1380 */ 85, 1030, 509, 457, 114, 114, 221, 509, 139, 139, + /* 1390 */ 305, 246, 246, 308, 314, 310, 509, 85, 138, 138, + /* 1400 */ 123, 123, 312, 506, 121, 121, 509, 1161, 372, 119, + /* 1410 */ 119, 1145, 509, 275, 500, 319, 509, 203, 120, 120, + /* 1420 */ 509, 969, 509, 328, 221, 1221, 1268, 863, 63, 63, + /* 1430 */ 224, 1196, 238, 761, 65, 65, 130, 411, 62, 62, + /* 1440 */ 1207, 1408, 31, 31, 37, 37, 495, 1274, 408, 828, + /* 1450 */ 496, 1126, 97, 1118, 1107, 1106, 1108, 1402, 177, 1193, + /* 1460 */ 331, 333, 7, 335, 185, 355, 197, 1255, 253, 1250, + /* 1470 */ 1243, 292, 189, 416, 437, 462, 293, 1405, 256, 261, + /* 1480 */ 1260, 298, 184, 1144, 322, 1331, 1330, 154, 1087, 195, + /* 1490 */ 348, 1084, 337, 380, 227, 1259, 71, 362, 181, 163, + /* 1500 */ 150, 421, 156, 422, 455, 205, 83, 158, 159, 160, + /* 1510 */ 360, 161, 1264, 499, 444, 167, 209, 77, 450, 1256, + /* 1520 */ 25, 429, 239, 171, 211, 1262, 307, 1261, 1336, 363, + /* 1530 */ 1325, 453, 67, 70, 212, 365, 1109, 213, 471, 394, + /* 1540 */ 1164, 79, 1155, 1419, 1163, 26, 782, 1162, 1134, 396, + /* 1550 */ 321, 1418, 366, 1133, 397, 484, 1132, 1204, 82, 1417, + /* 1560 */ 330, 226, 332, 1154, 326, 400, 1205, 270, 271, 6, + /* 1570 */ 1347, 1203, 303, 1311, 341, 89, 334, 273, 1202, 336, + /* 1580 */ 112, 489, 84, 487, 233, 1115, 24, 1043, 512, 477, + /* 1590 */ 234, 237, 236, 513, 1104, 1099, 373, 345, 1186, 344, + /* 1600 */ 374, 346, 347, 186, 1363, 153, 142, 1364, 1228, 1227, + /* 1610 */ 128, 1362, 178, 143, 268, 144, 1361, 277, 187, 196, + /* 1620 */ 66, 125, 983, 981, 283, 155, 146, 1068, 157, 814, + /* 1630 */ 201, 204, 291, 997, 162, 147, 148, 383, 73, 385, + /* 1640 */ 164, 74, 75, 76, 149, 1000, 206, 996, 207, 137, + /* 1650 */ 14, 208, 302, 989, 168, 1081, 224, 210, 449, 169, + /* 1660 */ 27, 752, 323, 214, 454, 458, 463, 780, 170, 78, + /* 1670 */ 15, 151, 315, 16, 318, 466, 80, 29, 269, 922, + /* 1680 */ 793, 921, 949, 81, 1032, 242, 190, 1031, 244, 862, + /* 1690 */ 173, 857, 97, 85, 223, 964, 950, 17, 18, 948, + /* 1700 */ 952, 1006, 953, 1005, 229, 228, 20, 30, 352, 920, + /* 1710 */ 762, 96, 21, 230, 505, 349, 1039, 1097, 824, 1097, + /* 1720 */ 1097, 1097, 1097, 1097, 1097, 231, 1410, 1409, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 251, 252, 253, 251, 252, 253, 196, 204, 175, 206, - /* 10 */ 175, 175, 175, 197, 204, 175, 16, 214, 183, 278, - /* 20 */ 279, 272, 187, 187, 200, 194, 20, 200, 28, 23, - /* 30 */ 197, 198, 175, 16, 197, 198, 36, 197, 198, 186, + /* 0 */ 255, 256, 257, 255, 256, 257, 199, 177, 206, 177, + /* 10 */ 208, 193, 194, 195, 222, 223, 16, 177, 216, 198, + /* 20 */ 177, 276, 202, 196, 199, 202, 234, 206, 28, 199, + /* 30 */ 200, 199, 200, 16, 194, 195, 36, 194, 195, 188, /* 40 */ 23, 41, 42, 43, 44, 45, 46, 47, 48, 49, - /* 50 */ 50, 51, 52, 53, 54, 55, 19, 20, 41, 42, + /* 50 */ 50, 51, 52, 53, 54, 55, 218, 219, 41, 42, /* 60 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 70 */ 53, 54, 55, 220, 221, 251, 252, 253, 251, 252, - /* 80 */ 253, 8, 251, 252, 253, 232, 69, 19, 255, 236, - /* 90 */ 237, 91, 92, 93, 94, 95, 96, 97, 98, 99, - /* 100 */ 100, 101, 101, 16, 52, 53, 54, 55, 91, 92, - /* 110 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 52, - /* 120 */ 53, 54, 55, 56, 81, 57, 175, 90, 41, 42, + /* 70 */ 53, 54, 55, 222, 223, 255, 256, 257, 255, 256, + /* 80 */ 257, 19, 255, 256, 257, 234, 69, 218, 219, 238, + /* 90 */ 239, 259, 92, 93, 94, 95, 96, 97, 98, 99, + /* 100 */ 100, 101, 102, 16, 177, 265, 102, 57, 265, 92, + /* 110 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + /* 120 */ 52, 53, 54, 55, 56, 117, 118, 81, 41, 42, /* 130 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 140 */ 53, 54, 55, 91, 92, 93, 94, 95, 96, 97, - /* 150 */ 98, 99, 100, 101, 67, 191, 192, 193, 91, 92, - /* 160 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 126, - /* 170 */ 127, 16, 104, 105, 106, 145, 21, 147, 91, 92, - /* 180 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 116, - /* 190 */ 117, 19, 20, 16, 243, 23, 41, 42, 43, 44, + /* 140 */ 53, 54, 55, 92, 93, 94, 95, 96, 97, 98, + /* 150 */ 99, 100, 101, 102, 67, 105, 106, 107, 96, 97, + /* 160 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + /* 170 */ 102, 16, 20, 127, 128, 23, 21, 250, 182, 92, + /* 180 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + /* 190 */ 140, 57, 177, 16, 57, 177, 41, 42, 43, 44, /* 200 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 210 */ 55, 95, 96, 97, 98, 99, 100, 101, 41, 42, + /* 210 */ 55, 96, 97, 98, 99, 100, 101, 102, 41, 42, /* 220 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 230 */ 53, 54, 55, 91, 92, 93, 94, 95, 96, 97, - /* 240 */ 98, 99, 100, 101, 116, 117, 91, 92, 93, 94, - /* 250 */ 95, 96, 97, 98, 99, 100, 101, 97, 98, 99, - /* 260 */ 100, 101, 90, 16, 175, 100, 101, 20, 91, 92, - /* 270 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 73, - /* 280 */ 16, 192, 193, 122, 20, 124, 125, 81, 41, 42, - /* 290 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 300 */ 53, 54, 55, 19, 20, 41, 42, 43, 44, 45, - /* 310 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - /* 320 */ 109, 115, 107, 146, 13, 110, 111, 112, 175, 175, - /* 330 */ 119, 57, 126, 127, 197, 120, 19, 175, 91, 92, - /* 340 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 187, - /* 350 */ 261, 197, 198, 19, 197, 91, 92, 93, 94, 95, - /* 360 */ 96, 97, 98, 99, 100, 101, 175, 44, 45, 46, - /* 370 */ 47, 209, 16, 211, 90, 222, 20, 175, 104, 105, - /* 380 */ 106, 107, 216, 217, 110, 111, 112, 233, 77, 16, - /* 390 */ 79, 57, 175, 20, 120, 211, 242, 41, 42, 43, - /* 400 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 410 */ 54, 55, 95, 96, 41, 42, 43, 44, 45, 46, - /* 420 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 175, - /* 430 */ 248, 9, 109, 81, 243, 16, 216, 217, 104, 105, - /* 440 */ 106, 186, 175, 57, 175, 243, 24, 91, 92, 93, - /* 450 */ 94, 95, 96, 97, 98, 99, 100, 101, 72, 18, - /* 460 */ 108, 238, 40, 44, 91, 92, 93, 94, 95, 96, - /* 470 */ 97, 98, 99, 100, 101, 220, 221, 260, 126, 127, - /* 480 */ 194, 16, 175, 61, 225, 20, 219, 232, 219, 23, - /* 490 */ 104, 105, 106, 234, 175, 73, 57, 23, 16, 57, - /* 500 */ 175, 247, 20, 248, 197, 198, 41, 42, 43, 44, - /* 510 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 520 */ 55, 80, 103, 41, 42, 43, 44, 45, 46, 47, - /* 530 */ 48, 49, 50, 51, 52, 53, 54, 55, 119, 97, - /* 540 */ 233, 222, 13, 104, 105, 106, 104, 105, 106, 242, - /* 550 */ 186, 26, 111, 57, 268, 30, 91, 92, 93, 94, - /* 560 */ 95, 96, 97, 98, 99, 100, 101, 19, 72, 175, - /* 570 */ 131, 175, 175, 91, 92, 93, 94, 95, 96, 97, - /* 580 */ 98, 99, 100, 101, 220, 221, 192, 193, 63, 148, - /* 590 */ 16, 175, 126, 127, 197, 198, 232, 191, 192, 193, - /* 600 */ 104, 105, 106, 95, 96, 57, 77, 16, 79, 212, - /* 610 */ 175, 137, 21, 197, 198, 41, 42, 43, 44, 45, - /* 620 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - /* 630 */ 180, 23, 41, 42, 43, 44, 45, 46, 47, 48, - /* 640 */ 49, 50, 51, 52, 53, 54, 55, 175, 140, 233, - /* 650 */ 142, 44, 104, 105, 106, 261, 57, 222, 242, 186, - /* 660 */ 175, 186, 175, 186, 175, 91, 92, 93, 94, 95, - /* 670 */ 96, 97, 98, 99, 100, 101, 123, 148, 175, 175, - /* 680 */ 175, 128, 91, 92, 93, 94, 95, 96, 97, 98, - /* 690 */ 99, 100, 101, 220, 221, 220, 221, 220, 221, 16, - /* 700 */ 197, 198, 197, 198, 105, 232, 219, 232, 258, 232, - /* 710 */ 103, 57, 262, 175, 106, 212, 16, 212, 175, 73, - /* 720 */ 146, 175, 186, 57, 41, 42, 43, 44, 45, 46, - /* 730 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 131, - /* 740 */ 175, 41, 42, 43, 44, 45, 46, 47, 48, 49, - /* 750 */ 50, 51, 52, 53, 54, 55, 220, 221, 104, 105, - /* 760 */ 106, 115, 116, 117, 19, 219, 207, 57, 232, 175, - /* 770 */ 104, 105, 106, 269, 91, 92, 93, 94, 95, 96, - /* 780 */ 97, 98, 99, 100, 101, 131, 32, 186, 175, 175, - /* 790 */ 247, 91, 92, 93, 94, 95, 96, 97, 98, 99, - /* 800 */ 100, 101, 57, 175, 138, 220, 221, 269, 16, 175, - /* 810 */ 175, 197, 198, 219, 104, 105, 106, 232, 64, 273, - /* 820 */ 20, 220, 221, 23, 175, 16, 212, 21, 74, 189, - /* 830 */ 190, 197, 198, 232, 42, 43, 44, 45, 46, 47, - /* 840 */ 48, 49, 50, 51, 52, 53, 54, 55, 175, 104, - /* 850 */ 105, 106, 43, 44, 45, 46, 47, 48, 49, 50, - /* 860 */ 51, 52, 53, 54, 55, 19, 20, 233, 219, 23, - /* 870 */ 197, 198, 118, 175, 16, 247, 175, 16, 17, 244, - /* 880 */ 19, 175, 269, 91, 92, 93, 94, 95, 96, 97, - /* 890 */ 98, 99, 100, 101, 33, 197, 198, 207, 197, 198, - /* 900 */ 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - /* 910 */ 101, 175, 186, 212, 175, 23, 194, 175, 57, 213, - /* 920 */ 168, 169, 170, 171, 172, 89, 175, 16, 17, 177, - /* 930 */ 19, 179, 71, 197, 198, 129, 90, 175, 186, 197, - /* 940 */ 198, 105, 81, 19, 33, 109, 220, 221, 197, 198, - /* 950 */ 89, 20, 175, 19, 23, 21, 95, 96, 232, 197, - /* 960 */ 198, 222, 104, 102, 117, 104, 105, 106, 57, 233, - /* 970 */ 109, 175, 220, 221, 175, 233, 140, 141, 142, 175, - /* 980 */ 9, 57, 71, 97, 232, 263, 139, 126, 127, 175, - /* 990 */ 268, 57, 57, 197, 198, 24, 197, 198, 246, 221, - /* 1000 */ 89, 140, 141, 142, 143, 144, 95, 96, 97, 123, - /* 1010 */ 232, 40, 175, 102, 128, 104, 105, 106, 16, 17, - /* 1020 */ 109, 19, 130, 175, 115, 116, 117, 275, 28, 105, - /* 1030 */ 16, 17, 61, 19, 186, 33, 36, 106, 175, 105, - /* 1040 */ 105, 175, 16, 175, 175, 197, 198, 33, 244, 186, - /* 1050 */ 213, 140, 141, 142, 143, 144, 175, 175, 244, 57, - /* 1060 */ 197, 198, 131, 197, 198, 197, 198, 57, 220, 221, - /* 1070 */ 175, 57, 19, 71, 220, 221, 12, 175, 197, 198, - /* 1080 */ 232, 233, 175, 220, 221, 71, 232, 115, 116, 117, - /* 1090 */ 242, 89, 197, 198, 19, 232, 233, 95, 96, 197, - /* 1100 */ 198, 189, 190, 89, 102, 175, 104, 105, 106, 95, - /* 1110 */ 96, 109, 59, 244, 175, 105, 102, 175, 104, 105, - /* 1120 */ 106, 175, 58, 109, 0, 1, 2, 197, 198, 175, - /* 1130 */ 104, 7, 8, 9, 10, 11, 197, 198, 14, 197, - /* 1140 */ 198, 175, 140, 141, 142, 143, 144, 126, 127, 57, - /* 1150 */ 175, 197, 198, 29, 140, 141, 142, 143, 144, 1, - /* 1160 */ 2, 37, 175, 197, 198, 7, 8, 9, 10, 11, - /* 1170 */ 175, 16, 14, 170, 171, 172, 21, 4, 5, 6, - /* 1180 */ 177, 89, 179, 175, 175, 236, 237, 29, 19, 186, - /* 1190 */ 244, 175, 197, 198, 70, 37, 104, 105, 23, 175, - /* 1200 */ 175, 109, 78, 175, 129, 81, 197, 198, 175, 276, - /* 1210 */ 277, 108, 109, 197, 198, 175, 19, 175, 21, 175, - /* 1220 */ 51, 197, 198, 220, 221, 197, 198, 140, 70, 142, - /* 1230 */ 197, 198, 140, 141, 142, 232, 78, 197, 198, 81, - /* 1240 */ 85, 197, 198, 20, 175, 121, 23, 175, 23, 246, - /* 1250 */ 126, 127, 57, 175, 20, 20, 101, 23, 23, 175, - /* 1260 */ 4, 5, 107, 108, 109, 110, 111, 112, 113, 197, - /* 1270 */ 198, 175, 175, 149, 119, 197, 198, 20, 275, 121, - /* 1280 */ 23, 197, 198, 175, 126, 127, 175, 21, 175, 114, - /* 1290 */ 95, 96, 175, 197, 198, 175, 83, 84, 103, 104, - /* 1300 */ 105, 106, 175, 108, 175, 197, 198, 149, 197, 198, - /* 1310 */ 175, 116, 57, 175, 197, 198, 175, 197, 198, 175, - /* 1320 */ 140, 175, 142, 57, 197, 198, 197, 198, 175, 175, - /* 1330 */ 207, 175, 197, 198, 175, 140, 175, 142, 197, 198, - /* 1340 */ 175, 197, 198, 197, 198, 175, 20, 175, 217, 23, - /* 1350 */ 197, 198, 175, 197, 198, 130, 197, 198, 197, 198, - /* 1360 */ 105, 20, 197, 198, 23, 175, 175, 197, 198, 197, - /* 1370 */ 198, 105, 20, 175, 20, 23, 20, 23, 20, 23, - /* 1380 */ 20, 23, 20, 23, 175, 23, 175, 175, 224, 175, - /* 1390 */ 175, 175, 175, 175, 175, 235, 175, 175, 265, 175, - /* 1400 */ 264, 175, 175, 175, 175, 175, 223, 226, 274, 235, - /* 1410 */ 173, 235, 270, 235, 235, 195, 227, 270, 226, 257, - /* 1420 */ 210, 239, 226, 239, 239, 224, 178, 58, 35, 129, - /* 1430 */ 138, 274, 201, 200, 271, 182, 200, 271, 206, 200, - /* 1440 */ 103, 19, 137, 250, 41, 15, 260, 182, 249, 15, - /* 1450 */ 181, 181, 250, 249, 182, 215, 145, 60, 182, 181, - /* 1460 */ 218, 218, 218, 218, 215, 227, 215, 267, 227, 266, - /* 1470 */ 19, 182, 181, 227, 227, 202, 182, 227, 181, 227, - /* 1480 */ 103, 202, 199, 199, 199, 62, 19, 205, 208, 202, - /* 1490 */ 114, 205, 199, 101, 103, 199, 201, 199, 208, 132, - /* 1500 */ 199, 202, 241, 240, 202, 241, 182, 240, 82, 241, - /* 1510 */ 19, 240, 182, 259, 254, 241, 145, 259, 256, 136, - /* 1520 */ 245, 240, 245, 133, 135, 22, 10, 185, 134, 23, - /* 1530 */ 184, 176, 3, 229, 231, 228, 230, 227, 174, 176, - /* 1540 */ 174, 188, 174, 194, 194, 194, 203, 188, 203, 19, - /* 1550 */ 150, 194, 12, 88, 13, 20, 195, 20, 127, 138, - /* 1560 */ 195, 188, 118, 21, 194, 130, 17, 13, 280, 132, - /* 1570 */ 1, 130, 139, 118, 59, 51, 138, 34, 51, 51, - /* 1580 */ 118, 104, 51, 31, 1, 129, 277, 2, 280, 19, - /* 1590 */ 103, 148, 75, 68, 23, 38, 103, 129, 21, 17, - /* 1600 */ 68, 119, 16, 113, 20, 67, 19, 19, 19, 19, - /* 1610 */ 57, 67, 21, 19, 67, 34, 20, 25, 20, 86, - /* 1620 */ 20, 20, 23, 19, 21, 20, 19, 21, 129, 20, - /* 1630 */ 20, 19, 131, 31, 23, 20, 23, 20, 104, 31, - /* 1640 */ 20, 20, 20, 8, 20, 31, 23, 19, 19, 19, - /* 1650 */ 23, 20, 20, 19, 12, 19, 1, 20, 281, 123, - /* 1660 */ 281, 281, 281, 281, 281, 281, 281, 281, 129, 281, - /* 1670 */ 281, 281, 281, 281, 129, 129, 281, 129, 281, 281, - /* 1680 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1690 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1700 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1710 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1720 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1730 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1740 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1750 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1760 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1770 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1780 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1790 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1800 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1810 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1820 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1830 */ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, - /* 1840 */ 281, 281, 281, 281, 281, 281, + /* 230 */ 53, 54, 55, 98, 99, 100, 101, 102, 177, 105, + /* 240 */ 106, 107, 105, 106, 107, 18, 199, 92, 93, 94, + /* 250 */ 95, 96, 97, 98, 99, 100, 101, 102, 262, 107, + /* 260 */ 199, 200, 266, 57, 16, 250, 132, 177, 20, 92, + /* 270 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + /* 280 */ 52, 53, 54, 55, 132, 44, 45, 46, 47, 41, + /* 290 */ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + /* 300 */ 52, 53, 54, 55, 98, 108, 81, 80, 111, 112, + /* 310 */ 113, 105, 106, 107, 19, 20, 139, 177, 121, 19, + /* 320 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + /* 330 */ 102, 101, 102, 16, 109, 57, 177, 20, 104, 112, + /* 340 */ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + /* 350 */ 102, 110, 127, 128, 264, 57, 177, 57, 41, 42, + /* 360 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + /* 370 */ 53, 54, 55, 139, 96, 97, 177, 150, 177, 193, + /* 380 */ 194, 195, 104, 105, 106, 107, 91, 109, 90, 188, + /* 390 */ 250, 177, 23, 188, 73, 117, 282, 283, 199, 200, + /* 400 */ 199, 200, 81, 105, 106, 105, 106, 107, 110, 92, + /* 410 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + /* 420 */ 142, 177, 144, 222, 223, 246, 16, 222, 223, 185, + /* 430 */ 20, 213, 273, 189, 235, 234, 235, 116, 224, 234, + /* 440 */ 142, 143, 144, 16, 177, 244, 177, 20, 127, 128, + /* 450 */ 177, 41, 42, 43, 44, 45, 46, 47, 48, 49, + /* 460 */ 50, 51, 52, 53, 54, 55, 199, 200, 41, 42, + /* 470 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + /* 480 */ 53, 54, 55, 9, 223, 96, 97, 8, 177, 16, + /* 490 */ 221, 116, 117, 118, 57, 234, 127, 128, 24, 285, + /* 500 */ 189, 19, 92, 93, 94, 95, 96, 97, 98, 99, + /* 510 */ 100, 101, 102, 123, 40, 125, 126, 44, 177, 92, + /* 520 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + /* 530 */ 189, 142, 177, 144, 177, 61, 16, 177, 23, 177, + /* 540 */ 20, 59, 105, 106, 107, 108, 277, 73, 111, 112, + /* 550 */ 113, 177, 211, 16, 213, 177, 177, 20, 121, 199, + /* 560 */ 200, 41, 42, 43, 44, 45, 46, 47, 48, 49, + /* 570 */ 50, 51, 52, 53, 54, 55, 177, 104, 41, 42, + /* 580 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + /* 590 */ 53, 54, 55, 120, 215, 235, 117, 118, 19, 20, + /* 600 */ 245, 177, 23, 246, 244, 177, 188, 245, 188, 4, + /* 610 */ 5, 6, 92, 93, 94, 95, 96, 97, 98, 99, + /* 620 */ 100, 101, 102, 199, 200, 177, 19, 199, 200, 92, + /* 630 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + /* 640 */ 222, 223, 222, 223, 177, 196, 16, 199, 200, 250, + /* 650 */ 209, 273, 234, 138, 234, 177, 191, 192, 177, 235, + /* 660 */ 177, 177, 214, 16, 57, 177, 199, 200, 244, 251, + /* 670 */ 91, 41, 42, 43, 44, 45, 46, 47, 48, 49, + /* 680 */ 50, 51, 52, 53, 54, 55, 177, 177, 41, 42, + /* 690 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + /* 700 */ 53, 54, 55, 9, 177, 16, 13, 224, 199, 200, + /* 710 */ 21, 177, 105, 106, 107, 177, 267, 57, 24, 191, + /* 720 */ 192, 272, 92, 93, 94, 95, 96, 97, 98, 99, + /* 730 */ 100, 101, 102, 245, 40, 19, 20, 199, 200, 92, + /* 740 */ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + /* 750 */ 0, 1, 2, 177, 273, 61, 57, 7, 8, 9, + /* 760 */ 10, 11, 177, 285, 14, 105, 106, 107, 285, 90, + /* 770 */ 77, 72, 79, 235, 85, 199, 200, 177, 148, 29, + /* 780 */ 19, 20, 244, 177, 23, 106, 19, 37, 21, 110, + /* 790 */ 214, 102, 132, 177, 19, 148, 177, 108, 109, 110, + /* 800 */ 111, 112, 113, 114, 105, 106, 107, 91, 20, 120, + /* 810 */ 196, 23, 16, 177, 44, 199, 200, 21, 199, 200, + /* 820 */ 70, 142, 143, 144, 57, 116, 117, 118, 78, 16, + /* 830 */ 214, 81, 57, 214, 177, 199, 200, 41, 42, 43, + /* 840 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 850 */ 54, 55, 91, 177, 41, 42, 43, 44, 45, 46, + /* 860 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 127, + /* 870 */ 128, 235, 122, 106, 104, 199, 200, 127, 128, 177, + /* 880 */ 105, 106, 107, 188, 177, 188, 272, 57, 92, 93, + /* 890 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 188, + /* 900 */ 19, 151, 72, 177, 177, 92, 93, 94, 95, 96, + /* 910 */ 97, 98, 99, 100, 101, 102, 177, 222, 223, 222, + /* 920 */ 223, 177, 16, 221, 28, 199, 200, 209, 221, 234, + /* 930 */ 19, 234, 36, 222, 223, 105, 106, 107, 57, 16, + /* 940 */ 214, 177, 215, 199, 200, 234, 188, 41, 42, 43, + /* 950 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 960 */ 54, 55, 51, 23, 98, 42, 43, 44, 45, 46, + /* 970 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 235, + /* 980 */ 222, 223, 177, 73, 13, 246, 105, 106, 107, 177, + /* 990 */ 124, 177, 234, 177, 177, 129, 177, 177, 92, 93, + /* 1000 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 177, + /* 1010 */ 32, 177, 23, 199, 200, 92, 93, 94, 95, 96, + /* 1020 */ 97, 98, 99, 100, 101, 102, 116, 117, 118, 224, + /* 1030 */ 251, 177, 16, 199, 200, 177, 177, 227, 221, 21, + /* 1040 */ 224, 221, 64, 222, 223, 26, 236, 107, 77, 30, + /* 1050 */ 79, 177, 74, 199, 200, 234, 177, 199, 200, 43, + /* 1060 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 1070 */ 54, 55, 132, 199, 200, 57, 177, 20, 16, 17, + /* 1080 */ 23, 19, 63, 240, 177, 170, 171, 172, 173, 174, + /* 1090 */ 285, 177, 57, 23, 179, 33, 181, 119, 199, 200, + /* 1100 */ 221, 285, 177, 188, 177, 246, 199, 200, 92, 93, + /* 1110 */ 94, 95, 96, 97, 98, 99, 100, 101, 102, 57, + /* 1120 */ 131, 150, 280, 281, 106, 23, 199, 200, 16, 16, + /* 1130 */ 17, 177, 19, 71, 177, 227, 16, 222, 223, 177, + /* 1140 */ 147, 106, 149, 81, 236, 188, 33, 16, 17, 234, + /* 1150 */ 19, 177, 90, 199, 200, 209, 199, 200, 96, 97, + /* 1160 */ 246, 199, 200, 248, 33, 103, 227, 105, 106, 107, + /* 1170 */ 57, 21, 110, 199, 200, 236, 177, 227, 177, 222, + /* 1180 */ 223, 238, 239, 57, 71, 115, 236, 227, 57, 127, + /* 1190 */ 128, 234, 235, 12, 279, 19, 236, 21, 199, 200, + /* 1200 */ 199, 200, 71, 90, 142, 143, 144, 145, 146, 96, + /* 1210 */ 97, 98, 138, 139, 109, 110, 103, 105, 105, 106, + /* 1220 */ 107, 90, 142, 110, 144, 105, 177, 96, 97, 177, + /* 1230 */ 124, 177, 106, 131, 103, 129, 105, 106, 107, 58, + /* 1240 */ 177, 110, 177, 118, 16, 17, 177, 19, 199, 200, + /* 1250 */ 89, 199, 200, 199, 200, 142, 143, 144, 145, 146, + /* 1260 */ 19, 33, 199, 200, 199, 200, 141, 177, 199, 200, + /* 1270 */ 4, 5, 57, 142, 143, 144, 145, 146, 118, 20, + /* 1280 */ 130, 177, 23, 122, 177, 57, 177, 1, 2, 199, + /* 1290 */ 200, 177, 110, 7, 8, 9, 10, 11, 57, 71, + /* 1300 */ 14, 141, 120, 199, 200, 177, 199, 200, 199, 200, + /* 1310 */ 16, 177, 57, 199, 200, 29, 20, 177, 90, 23, + /* 1320 */ 142, 106, 144, 37, 96, 97, 177, 199, 200, 177, + /* 1330 */ 19, 103, 177, 105, 106, 107, 177, 237, 110, 199, + /* 1340 */ 200, 172, 173, 174, 83, 84, 20, 106, 179, 23, + /* 1350 */ 181, 199, 200, 269, 199, 200, 70, 188, 199, 200, + /* 1360 */ 20, 106, 177, 23, 78, 20, 177, 81, 23, 177, + /* 1370 */ 142, 143, 144, 145, 146, 177, 177, 20, 177, 177, + /* 1380 */ 23, 87, 177, 20, 199, 200, 23, 177, 199, 200, + /* 1390 */ 177, 222, 223, 177, 20, 177, 177, 23, 199, 200, + /* 1400 */ 199, 200, 177, 234, 199, 200, 177, 177, 122, 199, + /* 1410 */ 200, 177, 177, 127, 128, 177, 177, 248, 199, 200, + /* 1420 */ 177, 20, 177, 177, 23, 177, 177, 20, 199, 200, + /* 1430 */ 23, 177, 268, 20, 199, 200, 23, 151, 199, 200, + /* 1440 */ 177, 130, 199, 200, 199, 200, 177, 177, 279, 20, + /* 1450 */ 219, 177, 23, 177, 177, 177, 177, 177, 225, 237, + /* 1460 */ 237, 237, 226, 237, 197, 175, 278, 253, 228, 249, + /* 1470 */ 249, 274, 212, 241, 274, 203, 229, 180, 241, 229, + /* 1480 */ 253, 228, 226, 208, 202, 202, 202, 278, 58, 278, + /* 1490 */ 228, 35, 241, 184, 130, 253, 140, 253, 139, 19, + /* 1500 */ 41, 15, 217, 184, 15, 183, 138, 220, 220, 220, + /* 1510 */ 229, 220, 217, 261, 184, 217, 183, 147, 60, 254, + /* 1520 */ 252, 229, 184, 19, 183, 254, 184, 254, 264, 229, + /* 1530 */ 229, 204, 275, 275, 183, 204, 184, 183, 104, 62, + /* 1540 */ 201, 19, 210, 207, 201, 252, 115, 201, 201, 21, + /* 1550 */ 201, 207, 204, 203, 102, 133, 201, 243, 104, 201, + /* 1560 */ 242, 184, 242, 210, 204, 82, 243, 263, 263, 19, + /* 1570 */ 271, 243, 270, 258, 184, 147, 242, 260, 243, 242, + /* 1580 */ 137, 134, 136, 135, 22, 187, 23, 10, 186, 286, + /* 1590 */ 178, 3, 178, 176, 176, 176, 284, 231, 233, 232, + /* 1600 */ 284, 230, 229, 197, 196, 281, 190, 196, 247, 247, + /* 1610 */ 205, 196, 19, 190, 205, 190, 196, 152, 197, 12, + /* 1620 */ 196, 13, 20, 20, 128, 140, 119, 23, 131, 17, + /* 1630 */ 21, 133, 13, 1, 131, 119, 119, 59, 51, 34, + /* 1640 */ 140, 51, 51, 51, 119, 105, 31, 1, 130, 2, + /* 1650 */ 19, 104, 150, 68, 68, 75, 23, 130, 38, 104, + /* 1660 */ 21, 17, 120, 114, 16, 67, 67, 57, 19, 19, + /* 1670 */ 19, 34, 20, 19, 21, 86, 19, 19, 67, 20, + /* 1680 */ 25, 20, 20, 23, 20, 20, 130, 87, 20, 105, + /* 1690 */ 19, 132, 23, 23, 31, 20, 20, 31, 31, 20, + /* 1700 */ 20, 20, 8, 20, 19, 23, 19, 19, 12, 20, + /* 1710 */ 20, 19, 19, 130, 23, 20, 1, 287, 124, 287, + /* 1720 */ 287, 287, 287, 287, 287, 130, 130, 130, 287, 287, + /* 1730 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1740 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1750 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1760 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1770 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1780 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1790 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1800 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1810 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1820 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1830 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1840 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1850 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1860 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1870 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1880 */ 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, + /* 1890 */ 287, 287, 287, 287, 287, 287, 287, 287, }; -#define YY_SHIFT_COUNT (497) +#define YY_SHIFT_COUNT (514) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (1655) +#define YY_SHIFT_MAX (1715) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 1158, 1124, 861, 861, 43, 1002, 1002, 1002, 206, 0, - /* 10 */ 0, 87, 683, 1002, 1002, 1002, 1002, 1002, 1002, 1002, - /* 20 */ 1002, 1002, 1195, 1195, 274, 352, 43, 43, 43, 43, - /* 30 */ 43, 43, 17, 155, 247, 264, 356, 373, 465, 482, - /* 40 */ 177, 574, 591, 683, 683, 683, 683, 683, 683, 683, - /* 50 */ 683, 683, 683, 683, 683, 683, 683, 683, 683, 683, - /* 60 */ 683, 700, 683, 792, 809, 809, 911, 1002, 1002, 1002, - /* 70 */ 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, - /* 80 */ 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, - /* 90 */ 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1014, - /* 100 */ 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002, - /* 110 */ 1002, 1002, 1002, 67, 52, 52, 52, 52, 52, 142, - /* 120 */ 116, 160, 710, 441, 419, 508, 508, 710, 466, 466, - /* 130 */ 466, 466, 128, 165, 1, 1678, 1678, 1155, 1155, 1155, - /* 140 */ 666, 68, 386, 68, 68, 422, 422, 496, 172, 846, - /* 150 */ 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, - /* 160 */ 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, - /* 170 */ 710, 73, 599, 599, 1021, 1678, 1678, 1678, 1092, 836, - /* 180 */ 836, 334, 215, 442, 548, 439, 654, 745, 710, 710, - /* 190 */ 710, 710, 710, 710, 710, 646, 710, 710, 710, 710, - /* 200 */ 710, 710, 710, 710, 710, 710, 710, 710, 754, 754, - /* 210 */ 754, 710, 710, 710, 710, 931, 710, 710, 710, 934, - /* 220 */ 710, 710, 971, 710, 710, 710, 710, 710, 710, 710, - /* 230 */ 710, 909, 525, 161, 1266, 1266, 1266, 1266, 608, 161, - /* 240 */ 161, 886, 317, 1173, 1064, 892, 858, 858, 1026, 474, - /* 250 */ 892, 1026, 1175, 6, 607, 1000, 1000, 1000, 858, 30, - /* 260 */ 1225, 553, 1197, 1369, 1393, 1393, 1300, 1292, 1337, 1422, - /* 270 */ 1305, 1403, 1305, 1430, 1430, 1430, 1430, 1300, 1434, 1305, - /* 280 */ 1305, 1337, 1422, 1403, 1305, 1403, 1305, 1300, 1434, 1311, - /* 290 */ 1397, 1300, 1434, 1451, 1300, 1434, 1300, 1434, 1451, 1377, - /* 300 */ 1377, 1377, 1423, 1467, 1467, 1451, 1377, 1376, 1377, 1423, - /* 310 */ 1377, 1377, 1451, 1392, 1392, 1451, 1367, 1391, 1367, 1391, - /* 320 */ 1367, 1391, 1367, 1391, 1300, 1426, 1426, 1491, 1300, 1371, - /* 330 */ 1383, 1390, 1389, 1394, 1305, 1503, 1506, 1516, 1516, 1529, - /* 340 */ 1529, 1529, 1678, 1678, 1678, 1678, 1678, 1678, 1678, 1678, - /* 350 */ 1678, 1678, 1678, 1678, 1678, 1678, 1678, 323, 529, 37, - /* 360 */ 284, 311, 972, 924, 800, 1169, 806, 847, 1223, 1053, - /* 370 */ 1234, 1235, 1257, 1326, 1341, 1352, 935, 1103, 1256, 211, - /* 380 */ 1010, 1354, 1356, 1213, 1358, 1087, 1180, 1360, 1362, 1255, - /* 390 */ 1075, 1530, 1400, 1540, 1465, 1541, 1535, 1537, 1431, 1421, - /* 400 */ 1444, 1542, 1435, 1549, 1437, 1554, 1569, 1441, 1433, 1455, - /* 410 */ 1515, 1543, 1438, 1524, 1527, 1528, 1531, 1462, 1477, 1552, - /* 420 */ 1456, 1583, 1585, 1570, 1487, 1443, 1525, 1571, 1532, 1517, - /* 430 */ 1557, 1468, 1493, 1577, 1582, 1586, 1482, 1490, 1587, 1538, - /* 440 */ 1588, 1589, 1584, 1590, 1544, 1553, 1591, 1533, 1592, 1594, - /* 450 */ 1547, 1581, 1596, 1598, 1600, 1599, 1601, 1604, 1603, 1605, - /* 460 */ 1607, 1606, 1499, 1609, 1610, 1534, 1602, 1612, 1501, 1611, - /* 470 */ 1608, 1613, 1614, 1615, 1611, 1617, 1620, 1621, 1622, 1623, - /* 480 */ 1624, 1628, 1635, 1629, 1630, 1631, 1632, 1634, 1636, 1627, - /* 490 */ 1536, 1539, 1545, 1546, 1548, 1637, 1642, 1655, + /* 0 */ 1286, 750, 1062, 1062, 46, 1131, 1131, 1131, 321, 0, + /* 10 */ 0, 87, 813, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + /* 20 */ 1131, 1131, 278, 278, 437, 225, 46, 46, 46, 46, + /* 30 */ 46, 17, 155, 177, 248, 317, 410, 427, 520, 537, + /* 40 */ 630, 647, 796, 813, 813, 813, 813, 813, 813, 813, + /* 50 */ 813, 813, 813, 813, 813, 813, 813, 813, 813, 813, + /* 60 */ 813, 906, 813, 923, 1016, 1016, 1113, 1131, 1131, 1131, + /* 70 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + /* 80 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + /* 90 */ 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + /* 100 */ 1228, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, + /* 110 */ 1131, 1131, 1131, 1131, 68, 228, 228, 228, 228, 228, + /* 120 */ 51, 115, 699, 135, 830, 137, 137, 227, 473, 137, + /* 130 */ 389, 389, 137, 369, 369, 369, 369, 8, 230, 4, + /* 140 */ 1728, 1728, 689, 689, 689, 50, 300, 300, 300, 300, + /* 150 */ 474, 474, 579, 761, 137, 137, 137, 137, 137, 137, + /* 160 */ 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + /* 170 */ 137, 137, 137, 137, 479, 1035, 1035, 742, 1728, 1728, + /* 180 */ 1728, 1728, 1728, 1728, 1728, 298, 679, 679, 607, 197, + /* 190 */ 206, 775, 134, 660, 881, 137, 137, 137, 137, 137, + /* 200 */ 137, 137, 137, 910, 137, 137, 137, 137, 137, 137, + /* 210 */ 137, 137, 137, 137, 137, 137, 978, 978, 978, 137, + /* 220 */ 137, 137, 152, 137, 137, 137, 767, 137, 137, 694, + /* 230 */ 137, 137, 137, 137, 137, 137, 137, 137, 375, 1019, + /* 240 */ 390, 1018, 1018, 1018, 1018, 940, 390, 390, 866, 62, + /* 250 */ 605, 1181, 234, 1074, 989, 1112, 1074, 1112, 1120, 515, + /* 260 */ 234, 234, 515, 234, 989, 1120, 1070, 788, 770, 896, + /* 270 */ 896, 896, 1112, 993, 1102, 1106, 1176, 1430, 1430, 1456, + /* 280 */ 1456, 1364, 1356, 1359, 1480, 1459, 1486, 1486, 1486, 1486, + /* 290 */ 1364, 1489, 1368, 1359, 1359, 1368, 1480, 1459, 1368, 1459, + /* 300 */ 1368, 1364, 1489, 1370, 1458, 1364, 1489, 1504, 1364, 1489, + /* 310 */ 1364, 1489, 1504, 1434, 1434, 1434, 1477, 1522, 1522, 1504, + /* 320 */ 1434, 1431, 1434, 1477, 1434, 1434, 1528, 1452, 1452, 1504, + /* 330 */ 1422, 1454, 1422, 1454, 1422, 1454, 1422, 1454, 1364, 1483, + /* 340 */ 1483, 1550, 1364, 1428, 1443, 1447, 1446, 1448, 1368, 1562, + /* 350 */ 1563, 1577, 1577, 1588, 1588, 1588, 1728, 1728, 1728, 1728, + /* 360 */ 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, + /* 370 */ 1728, 241, 971, 295, 716, 693, 709, 1241, 1057, 1161, + /* 380 */ 911, 1150, 1125, 1160, 1259, 482, 1296, 1326, 1340, 1357, + /* 390 */ 1363, 1374, 1126, 1105, 1266, 1182, 1294, 1215, 1401, 1407, + /* 400 */ 1261, 1345, 1080, 1178, 1413, 1429, 1255, 1311, 1593, 1465, + /* 410 */ 1607, 1608, 1602, 1603, 1496, 1485, 1507, 1604, 1604, 1609, + /* 420 */ 1497, 1612, 1498, 1619, 1632, 1503, 1516, 1604, 1517, 1578, + /* 430 */ 1605, 1604, 1500, 1587, 1590, 1591, 1592, 1525, 1540, 1615, + /* 440 */ 1518, 1646, 1647, 1631, 1547, 1502, 1585, 1633, 1586, 1580, + /* 450 */ 1620, 1527, 1555, 1639, 1644, 1648, 1542, 1549, 1649, 1598, + /* 460 */ 1650, 1651, 1652, 1654, 1599, 1610, 1653, 1589, 1655, 1657, + /* 470 */ 1611, 1637, 1659, 1661, 1662, 1660, 1664, 1658, 1600, 1556, + /* 480 */ 1665, 1668, 1584, 1663, 1671, 1559, 1669, 1666, 1670, 1667, + /* 490 */ 1675, 1669, 1676, 1679, 1680, 1681, 1682, 1683, 1685, 1694, + /* 500 */ 1687, 1688, 1689, 1690, 1692, 1693, 1691, 1594, 1583, 1595, + /* 510 */ 1596, 1597, 1695, 1696, 1715, }; -#define YY_REDUCE_COUNT (356) -#define YY_REDUCE_MIN (-259) -#define YY_REDUCE_MAX (1373) +#define YY_REDUCE_COUNT (370) +#define YY_REDUCE_MIN (-255) +#define YY_REDUCE_MAX (1425) static const short yy_reduce_ofst[] = { - /* 0 */ 752, 1003, 848, 863, -147, 154, 307, 416, 255, -176, - /* 10 */ -173, -251, -169, 397, 503, 505, 614, 634, 701, -167, - /* 20 */ 736, 742, 89, 394, 162, 364, 473, 475, 477, 536, - /* 30 */ 601, 726, -248, -248, -248, -248, -248, -248, -248, -248, - /* 40 */ -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, - /* 50 */ -248, -248, -248, -248, -248, -248, -248, -248, -248, -248, - /* 60 */ -248, -248, -248, -248, -248, -248, -163, -160, 673, 698, - /* 70 */ 751, 762, 796, 799, 866, 868, 881, 895, 902, 930, - /* 80 */ 939, 942, 954, 966, 995, 1009, 1016, 1024, 1028, 1033, - /* 90 */ 1040, 1044, 1072, 1078, 1084, 1096, 1108, 1111, 1117, 1120, - /* 100 */ 1127, 1129, 1135, 1141, 1144, 1146, 1153, 1156, 1159, 1161, - /* 110 */ 1165, 1170, 1172, -248, -248, -248, -248, -248, -248, -248, - /* 120 */ -248, -248, 546, 450, -197, -36, 406, -165, 585, 854, - /* 130 */ 585, 854, 722, -248, -248, -248, -248, -190, -190, -190, - /* 140 */ 217, 254, 153, 543, 628, 166, 220, 319, -259, -259, - /* 150 */ -164, -49, 191, 202, 435, 267, 269, 487, 594, 504, - /* 160 */ 635, 538, 804, 814, 613, 946, 649, 706, 739, 837, - /* 170 */ 869, 286, 640, 912, 778, 933, 949, 259, -184, 137, - /* 180 */ 157, -143, 184, 325, 396, 472, 485, 489, 565, 777, - /* 190 */ 882, 907, 975, 987, 1008, 182, 1025, 1042, 1069, 1097, - /* 200 */ 1113, 1138, 1154, 1177, 1190, 1191, 1198, 1209, 559, 690, - /* 210 */ 1123, 1211, 1212, 1214, 1215, 223, 1216, 1217, 1218, 1160, - /* 220 */ 1219, 1221, 1131, 1222, 325, 1224, 1226, 1227, 1228, 1229, - /* 230 */ 1230, 1133, 1136, 1183, 1174, 1176, 1178, 1179, 223, 1183, - /* 240 */ 1183, 1164, 1220, 1237, 1134, 1181, 1182, 1184, 1142, 1189, - /* 250 */ 1192, 1147, 1231, 1210, 1232, 1233, 1236, 1239, 1185, 1162, - /* 260 */ 1196, 1201, 1248, 1157, 1163, 1166, 1253, 1186, 1193, 1199, - /* 270 */ 1238, 1240, 1241, 1242, 1243, 1244, 1245, 1265, 1269, 1246, - /* 280 */ 1247, 1202, 1204, 1249, 1250, 1251, 1252, 1272, 1270, 1200, - /* 290 */ 1203, 1276, 1278, 1273, 1289, 1291, 1294, 1297, 1279, 1283, - /* 300 */ 1284, 1285, 1280, 1282, 1286, 1287, 1293, 1295, 1296, 1290, - /* 310 */ 1298, 1301, 1299, 1254, 1258, 1302, 1261, 1263, 1264, 1267, - /* 320 */ 1268, 1271, 1274, 1281, 1324, 1275, 1277, 1260, 1330, 1262, - /* 330 */ 1303, 1306, 1304, 1307, 1310, 1342, 1346, 1355, 1363, 1364, - /* 340 */ 1366, 1368, 1288, 1308, 1309, 1353, 1349, 1350, 1351, 1357, - /* 350 */ 1359, 1343, 1345, 1361, 1365, 1370, 1373, + /* 0 */ 915, 1169, 201, 957, -149, 360, 424, 538, 418, -180, + /* 10 */ -177, -255, -173, 448, 576, 616, 619, 199, 726, -168, + /* 20 */ 636, 744, -160, -157, 341, 205, 420, 695, 697, 711, + /* 30 */ 758, -252, -252, -252, -252, -252, -252, -252, -252, -252, + /* 40 */ -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, + /* 50 */ -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, + /* 60 */ -252, -252, -252, -252, -252, -252, -170, 61, 267, 428, + /* 70 */ 467, 509, 676, 814, 834, 854, 858, 874, 899, 907, + /* 80 */ 927, 954, 962, 974, 999, 1001, 1049, 1052, 1054, 1063, + /* 90 */ 1065, 1069, 1090, 1104, 1107, 1109, 1114, 1128, 1140, 1152, + /* 100 */ 1155, 1159, 1185, 1189, 1199, 1201, 1205, 1210, 1219, 1229, + /* 110 */ 1235, 1239, 1243, 1245, -252, -252, -252, -252, -252, -252, + /* 120 */ -252, -252, 214, -252, 483, 269, 805, -4, -198, 816, + /* 130 */ -182, 186, 244, -208, 821, -208, 821, 449, -252, -252, + /* 140 */ -252, -252, -179, -179, -179, 90, -73, 15, 140, 399, + /* 150 */ -162, -131, 114, 114, 311, 355, 362, 488, 702, 707, + /* 160 */ 817, 820, 159, 179, 378, 357, 739, 481, 859, 879, + /* 170 */ 379, 727, 478, 914, 614, 465, 528, 261, 842, 810, + /* 180 */ 908, 939, 950, 943, 960, -193, -175, 47, 18, 218, + /* 190 */ 273, 374, 484, 510, 527, 534, 585, 600, 606, 657, + /* 200 */ 764, 812, 819, 779, 832, 925, 1134, 1149, 1192, 1198, + /* 210 */ 1202, 1213, 1216, 1218, 1225, 1230, 441, 718, 946, 1234, + /* 220 */ 1238, 1246, 843, 1248, 1249, 1254, 1100, 1263, 1269, 1231, + /* 230 */ 1270, 273, 1274, 1276, 1277, 1278, 1279, 1280, 1084, 1164, + /* 240 */ 1233, 1222, 1223, 1224, 1226, 843, 1233, 1233, 1236, 1267, + /* 250 */ 1290, 1188, 1214, 1220, 1240, 1232, 1221, 1237, 1197, 1247, + /* 260 */ 1227, 1242, 1250, 1244, 1253, 1200, 1272, 1260, 1275, 1282, + /* 270 */ 1283, 1284, 1251, 1252, 1262, 1256, 1297, 1209, 1211, 1257, + /* 280 */ 1258, 1309, 1264, 1265, 1268, 1285, 1287, 1288, 1289, 1291, + /* 290 */ 1319, 1322, 1281, 1271, 1273, 1292, 1293, 1295, 1300, 1298, + /* 300 */ 1301, 1330, 1333, 1299, 1302, 1338, 1341, 1327, 1342, 1351, + /* 310 */ 1352, 1354, 1331, 1339, 1343, 1346, 1332, 1336, 1344, 1348, + /* 320 */ 1347, 1350, 1349, 1353, 1355, 1358, 1303, 1304, 1305, 1360, + /* 330 */ 1314, 1318, 1323, 1320, 1328, 1334, 1335, 1337, 1377, 1361, + /* 340 */ 1362, 1315, 1390, 1317, 1365, 1367, 1366, 1371, 1373, 1398, + /* 350 */ 1402, 1412, 1414, 1417, 1418, 1419, 1312, 1316, 1324, 1416, + /* 360 */ 1408, 1411, 1415, 1420, 1423, 1405, 1409, 1406, 1421, 1424, + /* 370 */ 1425, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1406, 1406, 1278, 1060, 1166, 1278, 1278, 1278, 1060, 1196, - /* 10 */ 1196, 1331, 1089, 1060, 1060, 1060, 1060, 1060, 1060, 1277, - /* 20 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 30 */ 1060, 1060, 1205, 1060, 1060, 1060, 1060, 1060, 1279, 1280, - /* 40 */ 1060, 1060, 1060, 1330, 1332, 1295, 1215, 1214, 1213, 1212, - /* 50 */ 1313, 1183, 1210, 1203, 1207, 1273, 1274, 1272, 1276, 1280, - /* 60 */ 1279, 1060, 1206, 1244, 1258, 1243, 1060, 1060, 1060, 1060, - /* 70 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 80 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 90 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 100 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 110 */ 1060, 1060, 1060, 1252, 1257, 1263, 1256, 1253, 1246, 1245, - /* 120 */ 1247, 1248, 1060, 1079, 1131, 1060, 1060, 1060, 1345, 1344, - /* 130 */ 1060, 1060, 1089, 1249, 1250, 1260, 1259, 1334, 1360, 1359, - /* 140 */ 1296, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 150 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 160 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 170 */ 1060, 1089, 1085, 1085, 1060, 1340, 1166, 1157, 1060, 1060, - /* 180 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 190 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 200 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 210 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1162, - /* 220 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 230 */ 1354, 1060, 1308, 1145, 1162, 1162, 1162, 1162, 1164, 1146, - /* 240 */ 1144, 1156, 1090, 1065, 1398, 1163, 1185, 1185, 1395, 1209, - /* 250 */ 1163, 1395, 1106, 1376, 1101, 1196, 1196, 1196, 1185, 1275, - /* 260 */ 1163, 1156, 1060, 1398, 1397, 1397, 1171, 1296, 1218, 1224, - /* 270 */ 1209, 1134, 1209, 1140, 1140, 1140, 1140, 1171, 1076, 1209, - /* 280 */ 1209, 1218, 1224, 1134, 1209, 1134, 1209, 1171, 1076, 1312, - /* 290 */ 1392, 1171, 1076, 1286, 1171, 1076, 1171, 1076, 1286, 1132, - /* 300 */ 1132, 1132, 1121, 1060, 1060, 1286, 1132, 1106, 1132, 1121, - /* 310 */ 1132, 1132, 1286, 1290, 1290, 1286, 1189, 1184, 1189, 1184, - /* 320 */ 1189, 1184, 1189, 1184, 1171, 1199, 1199, 1281, 1171, 1060, - /* 330 */ 1204, 1190, 1202, 1200, 1209, 1082, 1124, 1357, 1357, 1353, - /* 340 */ 1353, 1353, 1403, 1403, 1340, 1369, 1089, 1089, 1089, 1089, - /* 350 */ 1369, 1108, 1108, 1090, 1090, 1089, 1369, 1060, 1060, 1060, - /* 360 */ 1060, 1060, 1060, 1364, 1060, 1297, 1175, 1060, 1060, 1060, - /* 370 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 380 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 390 */ 1229, 1337, 1060, 1060, 1335, 1060, 1060, 1060, 1060, 1060, - /* 400 */ 1060, 1176, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 410 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 420 */ 1394, 1060, 1060, 1060, 1060, 1060, 1060, 1311, 1310, 1060, - /* 430 */ 1060, 1173, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 440 */ 1060, 1060, 1060, 1060, 1060, 1104, 1060, 1060, 1060, 1060, - /* 450 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, - /* 460 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1201, - /* 470 */ 1060, 1191, 1060, 1060, 1385, 1060, 1060, 1060, 1060, 1060, - /* 480 */ 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1060, 1380, - /* 490 */ 1148, 1231, 1060, 1230, 1234, 1060, 1070, 1060, + /* 0 */ 1454, 1454, 1320, 1095, 1201, 1320, 1320, 1320, 1095, 1231, + /* 10 */ 1231, 1373, 1124, 1095, 1095, 1095, 1095, 1095, 1095, 1319, + /* 20 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 30 */ 1095, 1240, 1095, 1247, 1095, 1095, 1095, 1095, 1321, 1322, + /* 40 */ 1095, 1095, 1095, 1372, 1374, 1337, 1254, 1253, 1252, 1251, + /* 50 */ 1355, 1218, 1245, 1238, 1242, 1315, 1316, 1314, 1318, 1322, + /* 60 */ 1321, 1095, 1241, 1286, 1300, 1285, 1095, 1095, 1095, 1095, + /* 70 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 80 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 90 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 100 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 110 */ 1095, 1095, 1095, 1095, 1294, 1299, 1305, 1298, 1295, 1288, + /* 120 */ 1287, 1289, 1095, 1290, 1095, 1095, 1095, 1114, 1166, 1095, + /* 130 */ 1095, 1095, 1095, 1388, 1387, 1095, 1095, 1124, 1291, 1292, + /* 140 */ 1302, 1301, 1376, 1407, 1406, 1338, 1095, 1095, 1095, 1095, + /* 150 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 160 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 170 */ 1095, 1095, 1095, 1095, 1124, 1120, 1120, 1095, 1383, 1192, + /* 180 */ 1192, 1192, 1192, 1201, 1192, 1095, 1095, 1095, 1095, 1095, + /* 190 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 200 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 210 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 220 */ 1095, 1095, 1095, 1095, 1095, 1095, 1197, 1095, 1095, 1095, + /* 230 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1401, 1095, 1350, + /* 240 */ 1180, 1197, 1197, 1197, 1197, 1199, 1181, 1179, 1191, 1125, + /* 250 */ 1100, 1446, 1257, 1246, 1198, 1220, 1246, 1220, 1443, 1244, + /* 260 */ 1257, 1257, 1244, 1257, 1198, 1443, 1141, 1423, 1136, 1231, + /* 270 */ 1231, 1231, 1220, 1317, 1198, 1191, 1095, 1446, 1446, 1445, + /* 280 */ 1445, 1206, 1338, 1430, 1266, 1169, 1175, 1175, 1175, 1175, + /* 290 */ 1206, 1111, 1244, 1430, 1430, 1244, 1266, 1169, 1244, 1169, + /* 300 */ 1244, 1206, 1111, 1354, 1440, 1206, 1111, 1328, 1206, 1111, + /* 310 */ 1206, 1111, 1328, 1167, 1167, 1167, 1156, 1095, 1095, 1328, + /* 320 */ 1167, 1141, 1167, 1156, 1167, 1167, 1095, 1332, 1332, 1328, + /* 330 */ 1224, 1219, 1224, 1219, 1224, 1219, 1224, 1219, 1206, 1234, + /* 340 */ 1234, 1323, 1206, 1095, 1239, 1225, 1237, 1235, 1244, 1117, + /* 350 */ 1159, 1404, 1404, 1400, 1400, 1400, 1451, 1451, 1383, 1416, + /* 360 */ 1124, 1124, 1124, 1124, 1416, 1143, 1143, 1125, 1125, 1124, + /* 370 */ 1416, 1095, 1095, 1095, 1095, 1095, 1095, 1411, 1095, 1378, + /* 380 */ 1339, 1210, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 390 */ 1095, 1095, 1095, 1095, 1095, 1095, 1389, 1095, 1095, 1095, + /* 400 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1271, 1380, 1095, + /* 410 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1248, 1249, 1211, + /* 420 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1263, 1095, 1095, + /* 430 */ 1095, 1258, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 440 */ 1442, 1095, 1095, 1095, 1095, 1095, 1095, 1353, 1352, 1095, + /* 450 */ 1095, 1208, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 460 */ 1095, 1095, 1095, 1095, 1095, 1139, 1095, 1095, 1095, 1095, + /* 470 */ 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 480 */ 1095, 1095, 1095, 1095, 1095, 1095, 1236, 1095, 1226, 1095, + /* 490 */ 1095, 1433, 1095, 1095, 1095, 1095, 1095, 1095, 1095, 1095, + /* 500 */ 1095, 1095, 1095, 1095, 1095, 1095, 1427, 1183, 1273, 1095, + /* 510 */ 1272, 1276, 1095, 1105, 1095, }; /********** End of lemon-generated parsing tables *****************************/ @@ -155984,6 +158175,7 @@ static const YYCODETYPE yyFallback[] = { 57, /* LAST => ID */ 57, /* GENERATED => ID */ 57, /* ALWAYS => ID */ + 57, /* MATERIALIZED => ID */ 57, /* REINDEX => ID */ 57, /* RENAME => ID */ 57, /* CTIME_KW => ID */ @@ -156035,6 +158227,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 */ @@ -156240,200 +158433,206 @@ static const char *const yyTokenName[] = { /* 84 */ "LAST", /* 85 */ "GENERATED", /* 86 */ "ALWAYS", - /* 87 */ "REINDEX", - /* 88 */ "RENAME", - /* 89 */ "CTIME_KW", - /* 90 */ "ANY", - /* 91 */ "BITAND", - /* 92 */ "BITOR", - /* 93 */ "LSHIFT", - /* 94 */ "RSHIFT", - /* 95 */ "PLUS", - /* 96 */ "MINUS", - /* 97 */ "STAR", - /* 98 */ "SLASH", - /* 99 */ "REM", - /* 100 */ "CONCAT", - /* 101 */ "COLLATE", - /* 102 */ "BITNOT", - /* 103 */ "ON", - /* 104 */ "INDEXED", - /* 105 */ "STRING", - /* 106 */ "JOIN_KW", - /* 107 */ "CONSTRAINT", - /* 108 */ "DEFAULT", - /* 109 */ "NULL", - /* 110 */ "PRIMARY", - /* 111 */ "UNIQUE", - /* 112 */ "CHECK", - /* 113 */ "REFERENCES", - /* 114 */ "AUTOINCR", - /* 115 */ "INSERT", - /* 116 */ "DELETE", - /* 117 */ "UPDATE", - /* 118 */ "SET", - /* 119 */ "DEFERRABLE", - /* 120 */ "FOREIGN", - /* 121 */ "DROP", - /* 122 */ "UNION", - /* 123 */ "ALL", - /* 124 */ "EXCEPT", - /* 125 */ "INTERSECT", - /* 126 */ "SELECT", - /* 127 */ "VALUES", - /* 128 */ "DISTINCT", - /* 129 */ "DOT", - /* 130 */ "FROM", - /* 131 */ "JOIN", - /* 132 */ "USING", - /* 133 */ "ORDER", - /* 134 */ "GROUP", - /* 135 */ "HAVING", - /* 136 */ "LIMIT", - /* 137 */ "WHERE", - /* 138 */ "INTO", - /* 139 */ "NOTHING", - /* 140 */ "FLOAT", - /* 141 */ "BLOB", - /* 142 */ "INTEGER", - /* 143 */ "VARIABLE", - /* 144 */ "CASE", - /* 145 */ "WHEN", - /* 146 */ "THEN", - /* 147 */ "ELSE", - /* 148 */ "INDEX", - /* 149 */ "ALTER", - /* 150 */ "ADD", - /* 151 */ "COLUMN", - /* 152 */ "AGG_FUNCTION", - /* 153 */ "AGG_COLUMN", - /* 154 */ "TRUEFALSE", - /* 155 */ "ISNOT", - /* 156 */ "FUNCTION", - /* 157 */ "UMINUS", - /* 158 */ "UPLUS", - /* 159 */ "TRUTH", - /* 160 */ "REGISTER", - /* 161 */ "VECTOR", - /* 162 */ "SELECT_COLUMN", - /* 163 */ "IF_NULL_ROW", - /* 164 */ "ASTERISK", - /* 165 */ "SPAN", - /* 166 */ "SPACE", - /* 167 */ "ILLEGAL", - /* 168 */ "input", - /* 169 */ "cmdlist", - /* 170 */ "ecmd", - /* 171 */ "cmdx", - /* 172 */ "cmd", - /* 173 */ "transtype", - /* 174 */ "trans_opt", - /* 175 */ "nm", - /* 176 */ "savepoint_opt", - /* 177 */ "create_table", - /* 178 */ "create_table_args", - /* 179 */ "createkw", - /* 180 */ "temp", - /* 181 */ "ifnotexists", - /* 182 */ "dbnm", - /* 183 */ "columnlist", - /* 184 */ "conslist_opt", - /* 185 */ "table_options", - /* 186 */ "select", - /* 187 */ "columnname", - /* 188 */ "carglist", - /* 189 */ "typetoken", - /* 190 */ "typename", - /* 191 */ "signed", - /* 192 */ "plus_num", - /* 193 */ "minus_num", - /* 194 */ "scanpt", - /* 195 */ "scantok", - /* 196 */ "ccons", - /* 197 */ "term", - /* 198 */ "expr", - /* 199 */ "onconf", - /* 200 */ "sortorder", - /* 201 */ "autoinc", - /* 202 */ "eidlist_opt", - /* 203 */ "refargs", - /* 204 */ "defer_subclause", - /* 205 */ "generated", - /* 206 */ "refarg", - /* 207 */ "refact", - /* 208 */ "init_deferred_pred_opt", - /* 209 */ "conslist", - /* 210 */ "tconscomma", - /* 211 */ "tcons", - /* 212 */ "sortlist", - /* 213 */ "eidlist", - /* 214 */ "defer_subclause_opt", - /* 215 */ "orconf", - /* 216 */ "resolvetype", - /* 217 */ "raisetype", - /* 218 */ "ifexists", - /* 219 */ "fullname", - /* 220 */ "selectnowith", - /* 221 */ "oneselect", - /* 222 */ "wqlist", - /* 223 */ "multiselect_op", - /* 224 */ "distinct", - /* 225 */ "selcollist", - /* 226 */ "from", - /* 227 */ "where_opt", - /* 228 */ "groupby_opt", - /* 229 */ "having_opt", - /* 230 */ "orderby_opt", - /* 231 */ "limit_opt", - /* 232 */ "values", - /* 233 */ "nexprlist", - /* 234 */ "sclp", - /* 235 */ "as", - /* 236 */ "seltablist", - /* 237 */ "stl_prefix", - /* 238 */ "joinop", - /* 239 */ "indexed_opt", - /* 240 */ "on_opt", - /* 241 */ "using_opt", - /* 242 */ "exprlist", - /* 243 */ "xfullname", - /* 244 */ "idlist", - /* 245 */ "nulls", - /* 246 */ "with", - /* 247 */ "setlist", - /* 248 */ "insert_cmd", - /* 249 */ "idlist_opt", - /* 250 */ "upsert", - /* 251 */ "likeop", - /* 252 */ "between_op", - /* 253 */ "in_op", - /* 254 */ "paren_exprlist", - /* 255 */ "case_operand", - /* 256 */ "case_exprlist", - /* 257 */ "case_else", - /* 258 */ "uniqueflag", - /* 259 */ "collate", - /* 260 */ "vinto", - /* 261 */ "nmnum", - /* 262 */ "trigger_decl", - /* 263 */ "trigger_cmd_list", - /* 264 */ "trigger_time", - /* 265 */ "trigger_event", - /* 266 */ "foreach_clause", - /* 267 */ "when_clause", - /* 268 */ "trigger_cmd", - /* 269 */ "trnm", - /* 270 */ "tridxby", - /* 271 */ "database_kw_opt", - /* 272 */ "key_opt", - /* 273 */ "add_column_fullname", - /* 274 */ "kwcolumn_opt", - /* 275 */ "create_vtab", - /* 276 */ "vtabarglist", - /* 277 */ "vtabarg", - /* 278 */ "vtabargtoken", - /* 279 */ "lp", - /* 280 */ "anylist", + /* 87 */ "MATERIALIZED", + /* 88 */ "REINDEX", + /* 89 */ "RENAME", + /* 90 */ "CTIME_KW", + /* 91 */ "ANY", + /* 92 */ "BITAND", + /* 93 */ "BITOR", + /* 94 */ "LSHIFT", + /* 95 */ "RSHIFT", + /* 96 */ "PLUS", + /* 97 */ "MINUS", + /* 98 */ "STAR", + /* 99 */ "SLASH", + /* 100 */ "REM", + /* 101 */ "CONCAT", + /* 102 */ "COLLATE", + /* 103 */ "BITNOT", + /* 104 */ "ON", + /* 105 */ "INDEXED", + /* 106 */ "STRING", + /* 107 */ "JOIN_KW", + /* 108 */ "CONSTRAINT", + /* 109 */ "DEFAULT", + /* 110 */ "NULL", + /* 111 */ "PRIMARY", + /* 112 */ "UNIQUE", + /* 113 */ "CHECK", + /* 114 */ "REFERENCES", + /* 115 */ "AUTOINCR", + /* 116 */ "INSERT", + /* 117 */ "DELETE", + /* 118 */ "UPDATE", + /* 119 */ "SET", + /* 120 */ "DEFERRABLE", + /* 121 */ "FOREIGN", + /* 122 */ "DROP", + /* 123 */ "UNION", + /* 124 */ "ALL", + /* 125 */ "EXCEPT", + /* 126 */ "INTERSECT", + /* 127 */ "SELECT", + /* 128 */ "VALUES", + /* 129 */ "DISTINCT", + /* 130 */ "DOT", + /* 131 */ "FROM", + /* 132 */ "JOIN", + /* 133 */ "USING", + /* 134 */ "ORDER", + /* 135 */ "GROUP", + /* 136 */ "HAVING", + /* 137 */ "LIMIT", + /* 138 */ "WHERE", + /* 139 */ "RETURNING", + /* 140 */ "INTO", + /* 141 */ "NOTHING", + /* 142 */ "FLOAT", + /* 143 */ "BLOB", + /* 144 */ "INTEGER", + /* 145 */ "VARIABLE", + /* 146 */ "CASE", + /* 147 */ "WHEN", + /* 148 */ "THEN", + /* 149 */ "ELSE", + /* 150 */ "INDEX", + /* 151 */ "ALTER", + /* 152 */ "ADD", + /* 153 */ "COLUMN", + /* 154 */ "AGG_FUNCTION", + /* 155 */ "AGG_COLUMN", + /* 156 */ "TRUEFALSE", + /* 157 */ "ISNOT", + /* 158 */ "FUNCTION", + /* 159 */ "UMINUS", + /* 160 */ "UPLUS", + /* 161 */ "TRUTH", + /* 162 */ "REGISTER", + /* 163 */ "VECTOR", + /* 164 */ "SELECT_COLUMN", + /* 165 */ "IF_NULL_ROW", + /* 166 */ "ASTERISK", + /* 167 */ "SPAN", + /* 168 */ "SPACE", + /* 169 */ "ILLEGAL", + /* 170 */ "input", + /* 171 */ "cmdlist", + /* 172 */ "ecmd", + /* 173 */ "cmdx", + /* 174 */ "cmd", + /* 175 */ "transtype", + /* 176 */ "trans_opt", + /* 177 */ "nm", + /* 178 */ "savepoint_opt", + /* 179 */ "create_table", + /* 180 */ "create_table_args", + /* 181 */ "createkw", + /* 182 */ "temp", + /* 183 */ "ifnotexists", + /* 184 */ "dbnm", + /* 185 */ "columnlist", + /* 186 */ "conslist_opt", + /* 187 */ "table_options", + /* 188 */ "select", + /* 189 */ "columnname", + /* 190 */ "carglist", + /* 191 */ "typetoken", + /* 192 */ "typename", + /* 193 */ "signed", + /* 194 */ "plus_num", + /* 195 */ "minus_num", + /* 196 */ "scanpt", + /* 197 */ "scantok", + /* 198 */ "ccons", + /* 199 */ "term", + /* 200 */ "expr", + /* 201 */ "onconf", + /* 202 */ "sortorder", + /* 203 */ "autoinc", + /* 204 */ "eidlist_opt", + /* 205 */ "refargs", + /* 206 */ "defer_subclause", + /* 207 */ "generated", + /* 208 */ "refarg", + /* 209 */ "refact", + /* 210 */ "init_deferred_pred_opt", + /* 211 */ "conslist", + /* 212 */ "tconscomma", + /* 213 */ "tcons", + /* 214 */ "sortlist", + /* 215 */ "eidlist", + /* 216 */ "defer_subclause_opt", + /* 217 */ "orconf", + /* 218 */ "resolvetype", + /* 219 */ "raisetype", + /* 220 */ "ifexists", + /* 221 */ "fullname", + /* 222 */ "selectnowith", + /* 223 */ "oneselect", + /* 224 */ "wqlist", + /* 225 */ "multiselect_op", + /* 226 */ "distinct", + /* 227 */ "selcollist", + /* 228 */ "from", + /* 229 */ "where_opt", + /* 230 */ "groupby_opt", + /* 231 */ "having_opt", + /* 232 */ "orderby_opt", + /* 233 */ "limit_opt", + /* 234 */ "values", + /* 235 */ "nexprlist", + /* 236 */ "sclp", + /* 237 */ "as", + /* 238 */ "seltablist", + /* 239 */ "stl_prefix", + /* 240 */ "joinop", + /* 241 */ "indexed_opt", + /* 242 */ "on_opt", + /* 243 */ "using_opt", + /* 244 */ "exprlist", + /* 245 */ "xfullname", + /* 246 */ "idlist", + /* 247 */ "nulls", + /* 248 */ "with", + /* 249 */ "where_opt_ret", + /* 250 */ "setlist", + /* 251 */ "insert_cmd", + /* 252 */ "idlist_opt", + /* 253 */ "upsert", + /* 254 */ "returning", + /* 255 */ "likeop", + /* 256 */ "between_op", + /* 257 */ "in_op", + /* 258 */ "paren_exprlist", + /* 259 */ "case_operand", + /* 260 */ "case_exprlist", + /* 261 */ "case_else", + /* 262 */ "uniqueflag", + /* 263 */ "collate", + /* 264 */ "vinto", + /* 265 */ "nmnum", + /* 266 */ "trigger_decl", + /* 267 */ "trigger_cmd_list", + /* 268 */ "trigger_time", + /* 269 */ "trigger_event", + /* 270 */ "foreach_clause", + /* 271 */ "when_clause", + /* 272 */ "trigger_cmd", + /* 273 */ "trnm", + /* 274 */ "tridxby", + /* 275 */ "database_kw_opt", + /* 276 */ "key_opt", + /* 277 */ "add_column_fullname", + /* 278 */ "kwcolumn_opt", + /* 279 */ "create_vtab", + /* 280 */ "vtabarglist", + /* 281 */ "vtabarg", + /* 282 */ "vtabargtoken", + /* 283 */ "lp", + /* 284 */ "anylist", + /* 285 */ "wqitem", + /* 286 */ "wqas", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -156586,205 +158785,218 @@ static const char *const yyRuleName[] = { /* 142 */ "limit_opt ::= LIMIT expr", /* 143 */ "limit_opt ::= LIMIT expr OFFSET expr", /* 144 */ "limit_opt ::= LIMIT expr COMMA expr", - /* 145 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt", + /* 145 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret", /* 146 */ "where_opt ::=", /* 147 */ "where_opt ::= WHERE expr", - /* 148 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt", - /* 149 */ "setlist ::= setlist COMMA nm EQ expr", - /* 150 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", - /* 151 */ "setlist ::= nm EQ expr", - /* 152 */ "setlist ::= LP idlist RP EQ expr", - /* 153 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", - /* 154 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES", - /* 155 */ "upsert ::=", - /* 156 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt", - /* 157 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING", - /* 158 */ "upsert ::= ON CONFLICT DO NOTHING", - /* 159 */ "insert_cmd ::= INSERT orconf", - /* 160 */ "insert_cmd ::= REPLACE", - /* 161 */ "idlist_opt ::=", - /* 162 */ "idlist_opt ::= LP idlist RP", - /* 163 */ "idlist ::= idlist COMMA nm", - /* 164 */ "idlist ::= nm", - /* 165 */ "expr ::= LP expr RP", - /* 166 */ "expr ::= ID|INDEXED", - /* 167 */ "expr ::= JOIN_KW", - /* 168 */ "expr ::= nm DOT nm", - /* 169 */ "expr ::= nm DOT nm DOT nm", - /* 170 */ "term ::= NULL|FLOAT|BLOB", - /* 171 */ "term ::= STRING", - /* 172 */ "term ::= INTEGER", - /* 173 */ "expr ::= VARIABLE", - /* 174 */ "expr ::= expr COLLATE ID|STRING", - /* 175 */ "expr ::= CAST LP expr AS typetoken RP", - /* 176 */ "expr ::= ID|INDEXED LP distinct exprlist RP", - /* 177 */ "expr ::= ID|INDEXED LP STAR RP", - /* 178 */ "term ::= CTIME_KW", - /* 179 */ "expr ::= LP nexprlist COMMA expr RP", - /* 180 */ "expr ::= expr AND expr", - /* 181 */ "expr ::= expr OR expr", - /* 182 */ "expr ::= expr LT|GT|GE|LE expr", - /* 183 */ "expr ::= expr EQ|NE expr", - /* 184 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", - /* 185 */ "expr ::= expr PLUS|MINUS expr", - /* 186 */ "expr ::= expr STAR|SLASH|REM expr", - /* 187 */ "expr ::= expr CONCAT expr", - /* 188 */ "likeop ::= NOT LIKE_KW|MATCH", - /* 189 */ "expr ::= expr likeop expr", - /* 190 */ "expr ::= expr likeop expr ESCAPE expr", - /* 191 */ "expr ::= expr ISNULL|NOTNULL", - /* 192 */ "expr ::= expr NOT NULL", - /* 193 */ "expr ::= expr IS expr", - /* 194 */ "expr ::= expr IS NOT expr", - /* 195 */ "expr ::= NOT expr", - /* 196 */ "expr ::= BITNOT expr", - /* 197 */ "expr ::= PLUS|MINUS expr", - /* 198 */ "between_op ::= BETWEEN", - /* 199 */ "between_op ::= NOT BETWEEN", - /* 200 */ "expr ::= expr between_op expr AND expr", - /* 201 */ "in_op ::= IN", - /* 202 */ "in_op ::= NOT IN", - /* 203 */ "expr ::= expr in_op LP exprlist RP", - /* 204 */ "expr ::= LP select RP", - /* 205 */ "expr ::= expr in_op LP select RP", - /* 206 */ "expr ::= expr in_op nm dbnm paren_exprlist", - /* 207 */ "expr ::= EXISTS LP select RP", - /* 208 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 209 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 210 */ "case_exprlist ::= WHEN expr THEN expr", - /* 211 */ "case_else ::= ELSE expr", - /* 212 */ "case_else ::=", - /* 213 */ "case_operand ::= expr", - /* 214 */ "case_operand ::=", - /* 215 */ "exprlist ::=", - /* 216 */ "nexprlist ::= nexprlist COMMA expr", - /* 217 */ "nexprlist ::= expr", - /* 218 */ "paren_exprlist ::=", - /* 219 */ "paren_exprlist ::= LP exprlist RP", - /* 220 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", - /* 221 */ "uniqueflag ::= UNIQUE", - /* 222 */ "uniqueflag ::=", - /* 223 */ "eidlist_opt ::=", - /* 224 */ "eidlist_opt ::= LP eidlist RP", - /* 225 */ "eidlist ::= eidlist COMMA nm collate sortorder", - /* 226 */ "eidlist ::= nm collate sortorder", - /* 227 */ "collate ::=", - /* 228 */ "collate ::= COLLATE ID|STRING", - /* 229 */ "cmd ::= DROP INDEX ifexists fullname", - /* 230 */ "cmd ::= VACUUM vinto", - /* 231 */ "cmd ::= VACUUM nm vinto", - /* 232 */ "vinto ::= INTO expr", - /* 233 */ "vinto ::=", - /* 234 */ "cmd ::= PRAGMA nm dbnm", - /* 235 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 236 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 237 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 238 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 239 */ "plus_num ::= PLUS INTEGER|FLOAT", - /* 240 */ "minus_num ::= MINUS INTEGER|FLOAT", - /* 241 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 242 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 243 */ "trigger_time ::= BEFORE|AFTER", - /* 244 */ "trigger_time ::= INSTEAD OF", - /* 245 */ "trigger_time ::=", - /* 246 */ "trigger_event ::= DELETE|INSERT", - /* 247 */ "trigger_event ::= UPDATE", - /* 248 */ "trigger_event ::= UPDATE OF idlist", - /* 249 */ "when_clause ::=", - /* 250 */ "when_clause ::= WHEN expr", - /* 251 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 252 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 253 */ "trnm ::= nm DOT nm", - /* 254 */ "tridxby ::= INDEXED BY nm", - /* 255 */ "tridxby ::= NOT INDEXED", - /* 256 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", - /* 257 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", - /* 258 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", - /* 259 */ "trigger_cmd ::= scanpt select scanpt", - /* 260 */ "expr ::= RAISE LP IGNORE RP", - /* 261 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 262 */ "raisetype ::= ROLLBACK", - /* 263 */ "raisetype ::= ABORT", - /* 264 */ "raisetype ::= FAIL", - /* 265 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 266 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 267 */ "cmd ::= DETACH database_kw_opt expr", - /* 268 */ "key_opt ::=", - /* 269 */ "key_opt ::= KEY expr", - /* 270 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 271 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", - /* 272 */ "add_column_fullname ::= fullname", - /* 273 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", - /* 274 */ "cmd ::= create_vtab", - /* 275 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 276 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", - /* 277 */ "vtabarg ::=", - /* 278 */ "vtabargtoken ::= ANY", - /* 279 */ "vtabargtoken ::= lp anylist RP", - /* 280 */ "lp ::= LP", - /* 281 */ "with ::= WITH wqlist", - /* 282 */ "with ::= WITH RECURSIVE wqlist", - /* 283 */ "wqlist ::= nm eidlist_opt AS LP select RP", - /* 284 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP", - /* 285 */ "input ::= cmdlist", - /* 286 */ "cmdlist ::= cmdlist ecmd", - /* 287 */ "cmdlist ::= ecmd", - /* 288 */ "ecmd ::= SEMI", - /* 289 */ "ecmd ::= cmdx SEMI", - /* 290 */ "trans_opt ::=", - /* 291 */ "trans_opt ::= TRANSACTION", - /* 292 */ "trans_opt ::= TRANSACTION nm", - /* 293 */ "savepoint_opt ::= SAVEPOINT", - /* 294 */ "savepoint_opt ::=", - /* 295 */ "cmd ::= create_table create_table_args", - /* 296 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 297 */ "columnlist ::= columnname carglist", - /* 298 */ "nm ::= ID|INDEXED", - /* 299 */ "nm ::= STRING", - /* 300 */ "nm ::= JOIN_KW", - /* 301 */ "typetoken ::= typename", - /* 302 */ "typename ::= ID|STRING", - /* 303 */ "signed ::= plus_num", - /* 304 */ "signed ::= minus_num", - /* 305 */ "carglist ::= carglist ccons", - /* 306 */ "carglist ::=", - /* 307 */ "ccons ::= NULL onconf", - /* 308 */ "ccons ::= GENERATED ALWAYS AS generated", - /* 309 */ "ccons ::= AS generated", - /* 310 */ "conslist_opt ::= COMMA conslist", - /* 311 */ "conslist ::= conslist tconscomma tcons", - /* 312 */ "conslist ::= tcons", - /* 313 */ "tconscomma ::=", - /* 314 */ "defer_subclause_opt ::= defer_subclause", - /* 315 */ "resolvetype ::= raisetype", - /* 316 */ "selectnowith ::= oneselect", - /* 317 */ "oneselect ::= values", - /* 318 */ "sclp ::= selcollist COMMA", - /* 319 */ "as ::= ID|STRING", - /* 320 */ "expr ::= term", - /* 321 */ "likeop ::= LIKE_KW|MATCH", - /* 322 */ "exprlist ::= nexprlist", - /* 323 */ "nmnum ::= plus_num", - /* 324 */ "nmnum ::= nm", - /* 325 */ "nmnum ::= ON", - /* 326 */ "nmnum ::= DELETE", - /* 327 */ "nmnum ::= DEFAULT", - /* 328 */ "plus_num ::= INTEGER|FLOAT", - /* 329 */ "foreach_clause ::=", - /* 330 */ "foreach_clause ::= FOR EACH ROW", - /* 331 */ "trnm ::= nm", - /* 332 */ "tridxby ::=", - /* 333 */ "database_kw_opt ::= DATABASE", - /* 334 */ "database_kw_opt ::=", - /* 335 */ "kwcolumn_opt ::=", - /* 336 */ "kwcolumn_opt ::= COLUMNKW", - /* 337 */ "vtabarglist ::= vtabarg", - /* 338 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 339 */ "vtabarg ::= vtabarg vtabargtoken", - /* 340 */ "anylist ::=", - /* 341 */ "anylist ::= anylist LP anylist RP", - /* 342 */ "anylist ::= anylist ANY", - /* 343 */ "with ::=", + /* 148 */ "where_opt_ret ::=", + /* 149 */ "where_opt_ret ::= WHERE expr", + /* 150 */ "where_opt_ret ::= RETURNING selcollist", + /* 151 */ "where_opt_ret ::= WHERE expr RETURNING selcollist", + /* 152 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret", + /* 153 */ "setlist ::= setlist COMMA nm EQ expr", + /* 154 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", + /* 155 */ "setlist ::= nm EQ expr", + /* 156 */ "setlist ::= LP idlist RP EQ expr", + /* 157 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", + /* 158 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning", + /* 159 */ "upsert ::=", + /* 160 */ "upsert ::= RETURNING selcollist", + /* 161 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert", + /* 162 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert", + /* 163 */ "upsert ::= ON CONFLICT DO NOTHING returning", + /* 164 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning", + /* 165 */ "returning ::= RETURNING selcollist", + /* 166 */ "insert_cmd ::= INSERT orconf", + /* 167 */ "insert_cmd ::= REPLACE", + /* 168 */ "idlist_opt ::=", + /* 169 */ "idlist_opt ::= LP idlist RP", + /* 170 */ "idlist ::= idlist COMMA nm", + /* 171 */ "idlist ::= nm", + /* 172 */ "expr ::= LP expr RP", + /* 173 */ "expr ::= ID|INDEXED", + /* 174 */ "expr ::= JOIN_KW", + /* 175 */ "expr ::= nm DOT nm", + /* 176 */ "expr ::= nm DOT nm DOT nm", + /* 177 */ "term ::= NULL|FLOAT|BLOB", + /* 178 */ "term ::= STRING", + /* 179 */ "term ::= INTEGER", + /* 180 */ "expr ::= VARIABLE", + /* 181 */ "expr ::= expr COLLATE ID|STRING", + /* 182 */ "expr ::= CAST LP expr AS typetoken RP", + /* 183 */ "expr ::= ID|INDEXED LP distinct exprlist RP", + /* 184 */ "expr ::= ID|INDEXED LP STAR RP", + /* 185 */ "term ::= CTIME_KW", + /* 186 */ "expr ::= LP nexprlist COMMA expr RP", + /* 187 */ "expr ::= expr AND expr", + /* 188 */ "expr ::= expr OR expr", + /* 189 */ "expr ::= expr LT|GT|GE|LE expr", + /* 190 */ "expr ::= expr EQ|NE expr", + /* 191 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 192 */ "expr ::= expr PLUS|MINUS expr", + /* 193 */ "expr ::= expr STAR|SLASH|REM expr", + /* 194 */ "expr ::= expr CONCAT expr", + /* 195 */ "likeop ::= NOT LIKE_KW|MATCH", + /* 196 */ "expr ::= expr likeop expr", + /* 197 */ "expr ::= expr likeop expr ESCAPE expr", + /* 198 */ "expr ::= expr ISNULL|NOTNULL", + /* 199 */ "expr ::= expr NOT NULL", + /* 200 */ "expr ::= expr IS expr", + /* 201 */ "expr ::= expr IS NOT expr", + /* 202 */ "expr ::= NOT expr", + /* 203 */ "expr ::= BITNOT expr", + /* 204 */ "expr ::= PLUS|MINUS expr", + /* 205 */ "between_op ::= BETWEEN", + /* 206 */ "between_op ::= NOT BETWEEN", + /* 207 */ "expr ::= expr between_op expr AND expr", + /* 208 */ "in_op ::= IN", + /* 209 */ "in_op ::= NOT IN", + /* 210 */ "expr ::= expr in_op LP exprlist RP", + /* 211 */ "expr ::= LP select RP", + /* 212 */ "expr ::= expr in_op LP select RP", + /* 213 */ "expr ::= expr in_op nm dbnm paren_exprlist", + /* 214 */ "expr ::= EXISTS LP select RP", + /* 215 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 216 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 217 */ "case_exprlist ::= WHEN expr THEN expr", + /* 218 */ "case_else ::= ELSE expr", + /* 219 */ "case_else ::=", + /* 220 */ "case_operand ::= expr", + /* 221 */ "case_operand ::=", + /* 222 */ "exprlist ::=", + /* 223 */ "nexprlist ::= nexprlist COMMA expr", + /* 224 */ "nexprlist ::= expr", + /* 225 */ "paren_exprlist ::=", + /* 226 */ "paren_exprlist ::= LP exprlist RP", + /* 227 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", + /* 228 */ "uniqueflag ::= UNIQUE", + /* 229 */ "uniqueflag ::=", + /* 230 */ "eidlist_opt ::=", + /* 231 */ "eidlist_opt ::= LP eidlist RP", + /* 232 */ "eidlist ::= eidlist COMMA nm collate sortorder", + /* 233 */ "eidlist ::= nm collate sortorder", + /* 234 */ "collate ::=", + /* 235 */ "collate ::= COLLATE ID|STRING", + /* 236 */ "cmd ::= DROP INDEX ifexists fullname", + /* 237 */ "cmd ::= VACUUM vinto", + /* 238 */ "cmd ::= VACUUM nm vinto", + /* 239 */ "vinto ::= INTO expr", + /* 240 */ "vinto ::=", + /* 241 */ "cmd ::= PRAGMA nm dbnm", + /* 242 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 243 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 244 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 245 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 246 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 247 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 248 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 249 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 250 */ "trigger_time ::= BEFORE|AFTER", + /* 251 */ "trigger_time ::= INSTEAD OF", + /* 252 */ "trigger_time ::=", + /* 253 */ "trigger_event ::= DELETE|INSERT", + /* 254 */ "trigger_event ::= UPDATE", + /* 255 */ "trigger_event ::= UPDATE OF idlist", + /* 256 */ "when_clause ::=", + /* 257 */ "when_clause ::= WHEN expr", + /* 258 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 259 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 260 */ "trnm ::= nm DOT nm", + /* 261 */ "tridxby ::= INDEXED BY nm", + /* 262 */ "tridxby ::= NOT INDEXED", + /* 263 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", + /* 264 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", + /* 265 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", + /* 266 */ "trigger_cmd ::= scanpt select scanpt", + /* 267 */ "expr ::= RAISE LP IGNORE RP", + /* 268 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 269 */ "raisetype ::= ROLLBACK", + /* 270 */ "raisetype ::= ABORT", + /* 271 */ "raisetype ::= FAIL", + /* 272 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 273 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 274 */ "cmd ::= DETACH database_kw_opt expr", + /* 275 */ "key_opt ::=", + /* 276 */ "key_opt ::= KEY expr", + /* 277 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 278 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 279 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", + /* 280 */ "add_column_fullname ::= fullname", + /* 281 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 282 */ "cmd ::= create_vtab", + /* 283 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 284 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 285 */ "vtabarg ::=", + /* 286 */ "vtabargtoken ::= ANY", + /* 287 */ "vtabargtoken ::= lp anylist RP", + /* 288 */ "lp ::= LP", + /* 289 */ "with ::= WITH wqlist", + /* 290 */ "with ::= WITH RECURSIVE wqlist", + /* 291 */ "wqas ::= AS", + /* 292 */ "wqas ::= AS MATERIALIZED", + /* 293 */ "wqas ::= AS NOT MATERIALIZED", + /* 294 */ "wqitem ::= nm eidlist_opt wqas LP select RP", + /* 295 */ "wqlist ::= wqitem", + /* 296 */ "wqlist ::= wqlist COMMA wqitem", + /* 297 */ "input ::= cmdlist", + /* 298 */ "cmdlist ::= cmdlist ecmd", + /* 299 */ "cmdlist ::= ecmd", + /* 300 */ "ecmd ::= SEMI", + /* 301 */ "ecmd ::= cmdx SEMI", + /* 302 */ "trans_opt ::=", + /* 303 */ "trans_opt ::= TRANSACTION", + /* 304 */ "trans_opt ::= TRANSACTION nm", + /* 305 */ "savepoint_opt ::= SAVEPOINT", + /* 306 */ "savepoint_opt ::=", + /* 307 */ "cmd ::= create_table create_table_args", + /* 308 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 309 */ "columnlist ::= columnname carglist", + /* 310 */ "nm ::= ID|INDEXED", + /* 311 */ "nm ::= STRING", + /* 312 */ "nm ::= JOIN_KW", + /* 313 */ "typetoken ::= typename", + /* 314 */ "typename ::= ID|STRING", + /* 315 */ "signed ::= plus_num", + /* 316 */ "signed ::= minus_num", + /* 317 */ "carglist ::= carglist ccons", + /* 318 */ "carglist ::=", + /* 319 */ "ccons ::= NULL onconf", + /* 320 */ "ccons ::= GENERATED ALWAYS AS generated", + /* 321 */ "ccons ::= AS generated", + /* 322 */ "conslist_opt ::= COMMA conslist", + /* 323 */ "conslist ::= conslist tconscomma tcons", + /* 324 */ "conslist ::= tcons", + /* 325 */ "tconscomma ::=", + /* 326 */ "defer_subclause_opt ::= defer_subclause", + /* 327 */ "resolvetype ::= raisetype", + /* 328 */ "selectnowith ::= oneselect", + /* 329 */ "oneselect ::= values", + /* 330 */ "sclp ::= selcollist COMMA", + /* 331 */ "as ::= ID|STRING", + /* 332 */ "returning ::=", + /* 333 */ "expr ::= term", + /* 334 */ "likeop ::= LIKE_KW|MATCH", + /* 335 */ "exprlist ::= nexprlist", + /* 336 */ "nmnum ::= plus_num", + /* 337 */ "nmnum ::= nm", + /* 338 */ "nmnum ::= ON", + /* 339 */ "nmnum ::= DELETE", + /* 340 */ "nmnum ::= DEFAULT", + /* 341 */ "plus_num ::= INTEGER|FLOAT", + /* 342 */ "foreach_clause ::=", + /* 343 */ "foreach_clause ::= FOR EACH ROW", + /* 344 */ "trnm ::= nm", + /* 345 */ "tridxby ::=", + /* 346 */ "database_kw_opt ::= DATABASE", + /* 347 */ "database_kw_opt ::=", + /* 348 */ "kwcolumn_opt ::=", + /* 349 */ "kwcolumn_opt ::= COLUMNKW", + /* 350 */ "vtabarglist ::= vtabarg", + /* 351 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 352 */ "vtabarg ::= vtabarg vtabargtoken", + /* 353 */ "anylist ::=", + /* 354 */ "anylist ::= anylist LP anylist RP", + /* 355 */ "anylist ::= anylist ANY", + /* 356 */ "with ::=", }; #endif /* NDEBUG */ @@ -156910,74 +159122,75 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 186: /* select */ - case 220: /* selectnowith */ - case 221: /* oneselect */ - case 232: /* values */ + case 188: /* select */ + case 222: /* selectnowith */ + case 223: /* oneselect */ + case 234: /* values */ { -sqlite3SelectDelete(pParse->db, (yypminor->yy341)); +sqlite3SelectDelete(pParse->db, (yypminor->yy457)); } break; - case 197: /* term */ - case 198: /* expr */ - case 227: /* where_opt */ - case 229: /* having_opt */ - case 240: /* on_opt */ - case 255: /* case_operand */ - case 257: /* case_else */ - case 260: /* vinto */ - case 267: /* when_clause */ - case 272: /* key_opt */ + case 199: /* term */ + case 200: /* expr */ + case 229: /* where_opt */ + case 231: /* having_opt */ + case 242: /* on_opt */ + case 249: /* where_opt_ret */ + case 259: /* case_operand */ + case 261: /* case_else */ + case 264: /* vinto */ + case 271: /* when_clause */ + case 276: /* key_opt */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy244)); +sqlite3ExprDelete(pParse->db, (yypminor->yy62)); } break; - case 202: /* eidlist_opt */ - case 212: /* sortlist */ - case 213: /* eidlist */ - case 225: /* selcollist */ - case 228: /* groupby_opt */ - case 230: /* orderby_opt */ - case 233: /* nexprlist */ - case 234: /* sclp */ - case 242: /* exprlist */ - case 247: /* setlist */ - case 254: /* paren_exprlist */ - case 256: /* case_exprlist */ + case 204: /* eidlist_opt */ + case 214: /* sortlist */ + case 215: /* eidlist */ + case 227: /* selcollist */ + case 230: /* groupby_opt */ + case 232: /* orderby_opt */ + case 235: /* nexprlist */ + case 236: /* sclp */ + case 244: /* exprlist */ + case 250: /* setlist */ + case 258: /* paren_exprlist */ + case 260: /* case_exprlist */ { -sqlite3ExprListDelete(pParse->db, (yypminor->yy328)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy336)); } break; - case 219: /* fullname */ - case 226: /* from */ - case 236: /* seltablist */ - case 237: /* stl_prefix */ - case 243: /* xfullname */ + case 221: /* fullname */ + case 228: /* from */ + case 238: /* seltablist */ + case 239: /* stl_prefix */ + case 245: /* xfullname */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy475)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy315)); } break; - case 222: /* wqlist */ + case 224: /* wqlist */ { -sqlite3WithDelete(pParse->db, (yypminor->yy523)); +sqlite3WithDelete(pParse->db, (yypminor->yy535)); } break; - case 241: /* using_opt */ - case 244: /* idlist */ - case 249: /* idlist_opt */ + case 243: /* using_opt */ + case 246: /* idlist */ + case 252: /* idlist_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy14)); +sqlite3IdListDelete(pParse->db, (yypminor->yy76)); } break; - case 263: /* trigger_cmd_list */ - case 268: /* trigger_cmd */ + case 267: /* trigger_cmd_list */ + case 272: /* trigger_cmd */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy39)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy441)); } break; - case 265: /* trigger_event */ + case 269: /* trigger_event */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy168).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy440).b); } break; /********* End destructor definitions *****************************************/ @@ -157268,350 +159481,363 @@ static void yy_shift( /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side ** of that rule */ static const YYCODETYPE yyRuleInfoLhs[] = { - 171, /* (0) cmdx ::= cmd */ - 172, /* (1) cmd ::= BEGIN transtype trans_opt */ - 173, /* (2) transtype ::= */ - 173, /* (3) transtype ::= DEFERRED */ - 173, /* (4) transtype ::= IMMEDIATE */ - 173, /* (5) transtype ::= EXCLUSIVE */ - 172, /* (6) cmd ::= COMMIT|END trans_opt */ - 172, /* (7) cmd ::= ROLLBACK trans_opt */ - 172, /* (8) cmd ::= SAVEPOINT nm */ - 172, /* (9) cmd ::= RELEASE savepoint_opt nm */ - 172, /* (10) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ - 177, /* (11) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ - 179, /* (12) createkw ::= CREATE */ - 181, /* (13) ifnotexists ::= */ - 181, /* (14) ifnotexists ::= IF NOT EXISTS */ - 180, /* (15) temp ::= TEMP */ - 180, /* (16) temp ::= */ - 178, /* (17) create_table_args ::= LP columnlist conslist_opt RP table_options */ - 178, /* (18) create_table_args ::= AS select */ - 185, /* (19) table_options ::= */ - 185, /* (20) table_options ::= WITHOUT nm */ - 187, /* (21) columnname ::= nm typetoken */ - 189, /* (22) typetoken ::= */ - 189, /* (23) typetoken ::= typename LP signed RP */ - 189, /* (24) typetoken ::= typename LP signed COMMA signed RP */ - 190, /* (25) typename ::= typename ID|STRING */ - 194, /* (26) scanpt ::= */ - 195, /* (27) scantok ::= */ - 196, /* (28) ccons ::= CONSTRAINT nm */ - 196, /* (29) ccons ::= DEFAULT scantok term */ - 196, /* (30) ccons ::= DEFAULT LP expr RP */ - 196, /* (31) ccons ::= DEFAULT PLUS scantok term */ - 196, /* (32) ccons ::= DEFAULT MINUS scantok term */ - 196, /* (33) ccons ::= DEFAULT scantok ID|INDEXED */ - 196, /* (34) ccons ::= NOT NULL onconf */ - 196, /* (35) ccons ::= PRIMARY KEY sortorder onconf autoinc */ - 196, /* (36) ccons ::= UNIQUE onconf */ - 196, /* (37) ccons ::= CHECK LP expr RP */ - 196, /* (38) ccons ::= REFERENCES nm eidlist_opt refargs */ - 196, /* (39) ccons ::= defer_subclause */ - 196, /* (40) ccons ::= COLLATE ID|STRING */ - 205, /* (41) generated ::= LP expr RP */ - 205, /* (42) generated ::= LP expr RP ID */ - 201, /* (43) autoinc ::= */ - 201, /* (44) autoinc ::= AUTOINCR */ - 203, /* (45) refargs ::= */ - 203, /* (46) refargs ::= refargs refarg */ - 206, /* (47) refarg ::= MATCH nm */ - 206, /* (48) refarg ::= ON INSERT refact */ - 206, /* (49) refarg ::= ON DELETE refact */ - 206, /* (50) refarg ::= ON UPDATE refact */ - 207, /* (51) refact ::= SET NULL */ - 207, /* (52) refact ::= SET DEFAULT */ - 207, /* (53) refact ::= CASCADE */ - 207, /* (54) refact ::= RESTRICT */ - 207, /* (55) refact ::= NO ACTION */ - 204, /* (56) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ - 204, /* (57) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - 208, /* (58) init_deferred_pred_opt ::= */ - 208, /* (59) init_deferred_pred_opt ::= INITIALLY DEFERRED */ - 208, /* (60) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ - 184, /* (61) conslist_opt ::= */ - 210, /* (62) tconscomma ::= COMMA */ - 211, /* (63) tcons ::= CONSTRAINT nm */ - 211, /* (64) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ - 211, /* (65) tcons ::= UNIQUE LP sortlist RP onconf */ - 211, /* (66) tcons ::= CHECK LP expr RP onconf */ - 211, /* (67) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ - 214, /* (68) defer_subclause_opt ::= */ - 199, /* (69) onconf ::= */ - 199, /* (70) onconf ::= ON CONFLICT resolvetype */ - 215, /* (71) orconf ::= */ - 215, /* (72) orconf ::= OR resolvetype */ - 216, /* (73) resolvetype ::= IGNORE */ - 216, /* (74) resolvetype ::= REPLACE */ - 172, /* (75) cmd ::= DROP TABLE ifexists fullname */ - 218, /* (76) ifexists ::= IF EXISTS */ - 218, /* (77) ifexists ::= */ - 172, /* (78) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ - 172, /* (79) cmd ::= DROP VIEW ifexists fullname */ - 172, /* (80) cmd ::= select */ - 186, /* (81) select ::= WITH wqlist selectnowith */ - 186, /* (82) select ::= WITH RECURSIVE wqlist selectnowith */ - 186, /* (83) select ::= selectnowith */ - 220, /* (84) selectnowith ::= selectnowith multiselect_op oneselect */ - 223, /* (85) multiselect_op ::= UNION */ - 223, /* (86) multiselect_op ::= UNION ALL */ - 223, /* (87) multiselect_op ::= EXCEPT|INTERSECT */ - 221, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ - 232, /* (89) values ::= VALUES LP nexprlist RP */ - 232, /* (90) values ::= values COMMA LP nexprlist RP */ - 224, /* (91) distinct ::= DISTINCT */ - 224, /* (92) distinct ::= ALL */ - 224, /* (93) distinct ::= */ - 234, /* (94) sclp ::= */ - 225, /* (95) selcollist ::= sclp scanpt expr scanpt as */ - 225, /* (96) selcollist ::= sclp scanpt STAR */ - 225, /* (97) selcollist ::= sclp scanpt nm DOT STAR */ - 235, /* (98) as ::= AS nm */ - 235, /* (99) as ::= */ - 226, /* (100) from ::= */ - 226, /* (101) from ::= FROM seltablist */ - 237, /* (102) stl_prefix ::= seltablist joinop */ - 237, /* (103) stl_prefix ::= */ - 236, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ - 236, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ - 236, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ - 236, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ - 182, /* (108) dbnm ::= */ - 182, /* (109) dbnm ::= DOT nm */ - 219, /* (110) fullname ::= nm */ - 219, /* (111) fullname ::= nm DOT nm */ - 243, /* (112) xfullname ::= nm */ - 243, /* (113) xfullname ::= nm DOT nm */ - 243, /* (114) xfullname ::= nm DOT nm AS nm */ - 243, /* (115) xfullname ::= nm AS nm */ - 238, /* (116) joinop ::= COMMA|JOIN */ - 238, /* (117) joinop ::= JOIN_KW JOIN */ - 238, /* (118) joinop ::= JOIN_KW nm JOIN */ - 238, /* (119) joinop ::= JOIN_KW nm nm JOIN */ - 240, /* (120) on_opt ::= ON expr */ - 240, /* (121) on_opt ::= */ - 239, /* (122) indexed_opt ::= */ - 239, /* (123) indexed_opt ::= INDEXED BY nm */ - 239, /* (124) indexed_opt ::= NOT INDEXED */ - 241, /* (125) using_opt ::= USING LP idlist RP */ - 241, /* (126) using_opt ::= */ - 230, /* (127) orderby_opt ::= */ - 230, /* (128) orderby_opt ::= ORDER BY sortlist */ - 212, /* (129) sortlist ::= sortlist COMMA expr sortorder nulls */ - 212, /* (130) sortlist ::= expr sortorder nulls */ - 200, /* (131) sortorder ::= ASC */ - 200, /* (132) sortorder ::= DESC */ - 200, /* (133) sortorder ::= */ - 245, /* (134) nulls ::= NULLS FIRST */ - 245, /* (135) nulls ::= NULLS LAST */ - 245, /* (136) nulls ::= */ - 228, /* (137) groupby_opt ::= */ - 228, /* (138) groupby_opt ::= GROUP BY nexprlist */ - 229, /* (139) having_opt ::= */ - 229, /* (140) having_opt ::= HAVING expr */ - 231, /* (141) limit_opt ::= */ - 231, /* (142) limit_opt ::= LIMIT expr */ - 231, /* (143) limit_opt ::= LIMIT expr OFFSET expr */ - 231, /* (144) limit_opt ::= LIMIT expr COMMA expr */ - 172, /* (145) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ - 227, /* (146) where_opt ::= */ - 227, /* (147) where_opt ::= WHERE expr */ - 172, /* (148) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt */ - 247, /* (149) setlist ::= setlist COMMA nm EQ expr */ - 247, /* (150) setlist ::= setlist COMMA LP idlist RP EQ expr */ - 247, /* (151) setlist ::= nm EQ expr */ - 247, /* (152) setlist ::= LP idlist RP EQ expr */ - 172, /* (153) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - 172, /* (154) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ - 250, /* (155) upsert ::= */ - 250, /* (156) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ - 250, /* (157) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ - 250, /* (158) upsert ::= ON CONFLICT DO NOTHING */ - 248, /* (159) insert_cmd ::= INSERT orconf */ - 248, /* (160) insert_cmd ::= REPLACE */ - 249, /* (161) idlist_opt ::= */ - 249, /* (162) idlist_opt ::= LP idlist RP */ - 244, /* (163) idlist ::= idlist COMMA nm */ - 244, /* (164) idlist ::= nm */ - 198, /* (165) expr ::= LP expr RP */ - 198, /* (166) expr ::= ID|INDEXED */ - 198, /* (167) expr ::= JOIN_KW */ - 198, /* (168) expr ::= nm DOT nm */ - 198, /* (169) expr ::= nm DOT nm DOT nm */ - 197, /* (170) term ::= NULL|FLOAT|BLOB */ - 197, /* (171) term ::= STRING */ - 197, /* (172) term ::= INTEGER */ - 198, /* (173) expr ::= VARIABLE */ - 198, /* (174) expr ::= expr COLLATE ID|STRING */ - 198, /* (175) expr ::= CAST LP expr AS typetoken RP */ - 198, /* (176) expr ::= ID|INDEXED LP distinct exprlist RP */ - 198, /* (177) expr ::= ID|INDEXED LP STAR RP */ - 197, /* (178) term ::= CTIME_KW */ - 198, /* (179) expr ::= LP nexprlist COMMA expr RP */ - 198, /* (180) expr ::= expr AND expr */ - 198, /* (181) expr ::= expr OR expr */ - 198, /* (182) expr ::= expr LT|GT|GE|LE expr */ - 198, /* (183) expr ::= expr EQ|NE expr */ - 198, /* (184) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - 198, /* (185) expr ::= expr PLUS|MINUS expr */ - 198, /* (186) expr ::= expr STAR|SLASH|REM expr */ - 198, /* (187) expr ::= expr CONCAT expr */ - 251, /* (188) likeop ::= NOT LIKE_KW|MATCH */ - 198, /* (189) expr ::= expr likeop expr */ - 198, /* (190) expr ::= expr likeop expr ESCAPE expr */ - 198, /* (191) expr ::= expr ISNULL|NOTNULL */ - 198, /* (192) expr ::= expr NOT NULL */ - 198, /* (193) expr ::= expr IS expr */ - 198, /* (194) expr ::= expr IS NOT expr */ - 198, /* (195) expr ::= NOT expr */ - 198, /* (196) expr ::= BITNOT expr */ - 198, /* (197) expr ::= PLUS|MINUS expr */ - 252, /* (198) between_op ::= BETWEEN */ - 252, /* (199) between_op ::= NOT BETWEEN */ - 198, /* (200) expr ::= expr between_op expr AND expr */ - 253, /* (201) in_op ::= IN */ - 253, /* (202) in_op ::= NOT IN */ - 198, /* (203) expr ::= expr in_op LP exprlist RP */ - 198, /* (204) expr ::= LP select RP */ - 198, /* (205) expr ::= expr in_op LP select RP */ - 198, /* (206) expr ::= expr in_op nm dbnm paren_exprlist */ - 198, /* (207) expr ::= EXISTS LP select RP */ - 198, /* (208) expr ::= CASE case_operand case_exprlist case_else END */ - 256, /* (209) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - 256, /* (210) case_exprlist ::= WHEN expr THEN expr */ - 257, /* (211) case_else ::= ELSE expr */ - 257, /* (212) case_else ::= */ - 255, /* (213) case_operand ::= expr */ - 255, /* (214) case_operand ::= */ - 242, /* (215) exprlist ::= */ - 233, /* (216) nexprlist ::= nexprlist COMMA expr */ - 233, /* (217) nexprlist ::= expr */ - 254, /* (218) paren_exprlist ::= */ - 254, /* (219) paren_exprlist ::= LP exprlist RP */ - 172, /* (220) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - 258, /* (221) uniqueflag ::= UNIQUE */ - 258, /* (222) uniqueflag ::= */ - 202, /* (223) eidlist_opt ::= */ - 202, /* (224) eidlist_opt ::= LP eidlist RP */ - 213, /* (225) eidlist ::= eidlist COMMA nm collate sortorder */ - 213, /* (226) eidlist ::= nm collate sortorder */ - 259, /* (227) collate ::= */ - 259, /* (228) collate ::= COLLATE ID|STRING */ - 172, /* (229) cmd ::= DROP INDEX ifexists fullname */ - 172, /* (230) cmd ::= VACUUM vinto */ - 172, /* (231) cmd ::= VACUUM nm vinto */ - 260, /* (232) vinto ::= INTO expr */ - 260, /* (233) vinto ::= */ - 172, /* (234) cmd ::= PRAGMA nm dbnm */ - 172, /* (235) cmd ::= PRAGMA nm dbnm EQ nmnum */ - 172, /* (236) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - 172, /* (237) cmd ::= PRAGMA nm dbnm EQ minus_num */ - 172, /* (238) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - 192, /* (239) plus_num ::= PLUS INTEGER|FLOAT */ - 193, /* (240) minus_num ::= MINUS INTEGER|FLOAT */ - 172, /* (241) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - 262, /* (242) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - 264, /* (243) trigger_time ::= BEFORE|AFTER */ - 264, /* (244) trigger_time ::= INSTEAD OF */ - 264, /* (245) trigger_time ::= */ - 265, /* (246) trigger_event ::= DELETE|INSERT */ - 265, /* (247) trigger_event ::= UPDATE */ - 265, /* (248) trigger_event ::= UPDATE OF idlist */ - 267, /* (249) when_clause ::= */ - 267, /* (250) when_clause ::= WHEN expr */ - 263, /* (251) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - 263, /* (252) trigger_cmd_list ::= trigger_cmd SEMI */ - 269, /* (253) trnm ::= nm DOT nm */ - 270, /* (254) tridxby ::= INDEXED BY nm */ - 270, /* (255) tridxby ::= NOT INDEXED */ - 268, /* (256) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - 268, /* (257) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - 268, /* (258) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - 268, /* (259) trigger_cmd ::= scanpt select scanpt */ - 198, /* (260) expr ::= RAISE LP IGNORE RP */ - 198, /* (261) expr ::= RAISE LP raisetype COMMA nm RP */ - 217, /* (262) raisetype ::= ROLLBACK */ - 217, /* (263) raisetype ::= ABORT */ - 217, /* (264) raisetype ::= FAIL */ - 172, /* (265) cmd ::= DROP TRIGGER ifexists fullname */ - 172, /* (266) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - 172, /* (267) cmd ::= DETACH database_kw_opt expr */ - 272, /* (268) key_opt ::= */ - 272, /* (269) key_opt ::= KEY expr */ - 172, /* (270) cmd ::= ALTER TABLE fullname RENAME TO nm */ - 172, /* (271) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - 273, /* (272) add_column_fullname ::= fullname */ - 172, /* (273) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - 172, /* (274) cmd ::= create_vtab */ - 172, /* (275) cmd ::= create_vtab LP vtabarglist RP */ - 275, /* (276) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 277, /* (277) vtabarg ::= */ - 278, /* (278) vtabargtoken ::= ANY */ - 278, /* (279) vtabargtoken ::= lp anylist RP */ - 279, /* (280) lp ::= LP */ - 246, /* (281) with ::= WITH wqlist */ - 246, /* (282) with ::= WITH RECURSIVE wqlist */ - 222, /* (283) wqlist ::= nm eidlist_opt AS LP select RP */ - 222, /* (284) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ - 168, /* (285) input ::= cmdlist */ - 169, /* (286) cmdlist ::= cmdlist ecmd */ - 169, /* (287) cmdlist ::= ecmd */ - 170, /* (288) ecmd ::= SEMI */ - 170, /* (289) ecmd ::= cmdx SEMI */ - 174, /* (290) trans_opt ::= */ - 174, /* (291) trans_opt ::= TRANSACTION */ - 174, /* (292) trans_opt ::= TRANSACTION nm */ - 176, /* (293) savepoint_opt ::= SAVEPOINT */ - 176, /* (294) savepoint_opt ::= */ - 172, /* (295) cmd ::= create_table create_table_args */ - 183, /* (296) columnlist ::= columnlist COMMA columnname carglist */ - 183, /* (297) columnlist ::= columnname carglist */ - 175, /* (298) nm ::= ID|INDEXED */ - 175, /* (299) nm ::= STRING */ - 175, /* (300) nm ::= JOIN_KW */ - 189, /* (301) typetoken ::= typename */ - 190, /* (302) typename ::= ID|STRING */ - 191, /* (303) signed ::= plus_num */ - 191, /* (304) signed ::= minus_num */ - 188, /* (305) carglist ::= carglist ccons */ - 188, /* (306) carglist ::= */ - 196, /* (307) ccons ::= NULL onconf */ - 196, /* (308) ccons ::= GENERATED ALWAYS AS generated */ - 196, /* (309) ccons ::= AS generated */ - 184, /* (310) conslist_opt ::= COMMA conslist */ - 209, /* (311) conslist ::= conslist tconscomma tcons */ - 209, /* (312) conslist ::= tcons */ - 210, /* (313) tconscomma ::= */ - 214, /* (314) defer_subclause_opt ::= defer_subclause */ - 216, /* (315) resolvetype ::= raisetype */ - 220, /* (316) selectnowith ::= oneselect */ - 221, /* (317) oneselect ::= values */ - 234, /* (318) sclp ::= selcollist COMMA */ - 235, /* (319) as ::= ID|STRING */ - 198, /* (320) expr ::= term */ - 251, /* (321) likeop ::= LIKE_KW|MATCH */ - 242, /* (322) exprlist ::= nexprlist */ - 261, /* (323) nmnum ::= plus_num */ - 261, /* (324) nmnum ::= nm */ - 261, /* (325) nmnum ::= ON */ - 261, /* (326) nmnum ::= DELETE */ - 261, /* (327) nmnum ::= DEFAULT */ - 192, /* (328) plus_num ::= INTEGER|FLOAT */ - 266, /* (329) foreach_clause ::= */ - 266, /* (330) foreach_clause ::= FOR EACH ROW */ - 269, /* (331) trnm ::= nm */ - 270, /* (332) tridxby ::= */ - 271, /* (333) database_kw_opt ::= DATABASE */ - 271, /* (334) database_kw_opt ::= */ - 274, /* (335) kwcolumn_opt ::= */ - 274, /* (336) kwcolumn_opt ::= COLUMNKW */ - 276, /* (337) vtabarglist ::= vtabarg */ - 276, /* (338) vtabarglist ::= vtabarglist COMMA vtabarg */ - 277, /* (339) vtabarg ::= vtabarg vtabargtoken */ - 280, /* (340) anylist ::= */ - 280, /* (341) anylist ::= anylist LP anylist RP */ - 280, /* (342) anylist ::= anylist ANY */ - 246, /* (343) with ::= */ + 173, /* (0) cmdx ::= cmd */ + 174, /* (1) cmd ::= BEGIN transtype trans_opt */ + 175, /* (2) transtype ::= */ + 175, /* (3) transtype ::= DEFERRED */ + 175, /* (4) transtype ::= IMMEDIATE */ + 175, /* (5) transtype ::= EXCLUSIVE */ + 174, /* (6) cmd ::= COMMIT|END trans_opt */ + 174, /* (7) cmd ::= ROLLBACK trans_opt */ + 174, /* (8) cmd ::= SAVEPOINT nm */ + 174, /* (9) cmd ::= RELEASE savepoint_opt nm */ + 174, /* (10) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + 179, /* (11) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + 181, /* (12) createkw ::= CREATE */ + 183, /* (13) ifnotexists ::= */ + 183, /* (14) ifnotexists ::= IF NOT EXISTS */ + 182, /* (15) temp ::= TEMP */ + 182, /* (16) temp ::= */ + 180, /* (17) create_table_args ::= LP columnlist conslist_opt RP table_options */ + 180, /* (18) create_table_args ::= AS select */ + 187, /* (19) table_options ::= */ + 187, /* (20) table_options ::= WITHOUT nm */ + 189, /* (21) columnname ::= nm typetoken */ + 191, /* (22) typetoken ::= */ + 191, /* (23) typetoken ::= typename LP signed RP */ + 191, /* (24) typetoken ::= typename LP signed COMMA signed RP */ + 192, /* (25) typename ::= typename ID|STRING */ + 196, /* (26) scanpt ::= */ + 197, /* (27) scantok ::= */ + 198, /* (28) ccons ::= CONSTRAINT nm */ + 198, /* (29) ccons ::= DEFAULT scantok term */ + 198, /* (30) ccons ::= DEFAULT LP expr RP */ + 198, /* (31) ccons ::= DEFAULT PLUS scantok term */ + 198, /* (32) ccons ::= DEFAULT MINUS scantok term */ + 198, /* (33) ccons ::= DEFAULT scantok ID|INDEXED */ + 198, /* (34) ccons ::= NOT NULL onconf */ + 198, /* (35) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + 198, /* (36) ccons ::= UNIQUE onconf */ + 198, /* (37) ccons ::= CHECK LP expr RP */ + 198, /* (38) ccons ::= REFERENCES nm eidlist_opt refargs */ + 198, /* (39) ccons ::= defer_subclause */ + 198, /* (40) ccons ::= COLLATE ID|STRING */ + 207, /* (41) generated ::= LP expr RP */ + 207, /* (42) generated ::= LP expr RP ID */ + 203, /* (43) autoinc ::= */ + 203, /* (44) autoinc ::= AUTOINCR */ + 205, /* (45) refargs ::= */ + 205, /* (46) refargs ::= refargs refarg */ + 208, /* (47) refarg ::= MATCH nm */ + 208, /* (48) refarg ::= ON INSERT refact */ + 208, /* (49) refarg ::= ON DELETE refact */ + 208, /* (50) refarg ::= ON UPDATE refact */ + 209, /* (51) refact ::= SET NULL */ + 209, /* (52) refact ::= SET DEFAULT */ + 209, /* (53) refact ::= CASCADE */ + 209, /* (54) refact ::= RESTRICT */ + 209, /* (55) refact ::= NO ACTION */ + 206, /* (56) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + 206, /* (57) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 210, /* (58) init_deferred_pred_opt ::= */ + 210, /* (59) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + 210, /* (60) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 186, /* (61) conslist_opt ::= */ + 212, /* (62) tconscomma ::= COMMA */ + 213, /* (63) tcons ::= CONSTRAINT nm */ + 213, /* (64) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + 213, /* (65) tcons ::= UNIQUE LP sortlist RP onconf */ + 213, /* (66) tcons ::= CHECK LP expr RP onconf */ + 213, /* (67) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 216, /* (68) defer_subclause_opt ::= */ + 201, /* (69) onconf ::= */ + 201, /* (70) onconf ::= ON CONFLICT resolvetype */ + 217, /* (71) orconf ::= */ + 217, /* (72) orconf ::= OR resolvetype */ + 218, /* (73) resolvetype ::= IGNORE */ + 218, /* (74) resolvetype ::= REPLACE */ + 174, /* (75) cmd ::= DROP TABLE ifexists fullname */ + 220, /* (76) ifexists ::= IF EXISTS */ + 220, /* (77) ifexists ::= */ + 174, /* (78) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + 174, /* (79) cmd ::= DROP VIEW ifexists fullname */ + 174, /* (80) cmd ::= select */ + 188, /* (81) select ::= WITH wqlist selectnowith */ + 188, /* (82) select ::= WITH RECURSIVE wqlist selectnowith */ + 188, /* (83) select ::= selectnowith */ + 222, /* (84) selectnowith ::= selectnowith multiselect_op oneselect */ + 225, /* (85) multiselect_op ::= UNION */ + 225, /* (86) multiselect_op ::= UNION ALL */ + 225, /* (87) multiselect_op ::= EXCEPT|INTERSECT */ + 223, /* (88) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + 234, /* (89) values ::= VALUES LP nexprlist RP */ + 234, /* (90) values ::= values COMMA LP nexprlist RP */ + 226, /* (91) distinct ::= DISTINCT */ + 226, /* (92) distinct ::= ALL */ + 226, /* (93) distinct ::= */ + 236, /* (94) sclp ::= */ + 227, /* (95) selcollist ::= sclp scanpt expr scanpt as */ + 227, /* (96) selcollist ::= sclp scanpt STAR */ + 227, /* (97) selcollist ::= sclp scanpt nm DOT STAR */ + 237, /* (98) as ::= AS nm */ + 237, /* (99) as ::= */ + 228, /* (100) from ::= */ + 228, /* (101) from ::= FROM seltablist */ + 239, /* (102) stl_prefix ::= seltablist joinop */ + 239, /* (103) stl_prefix ::= */ + 238, /* (104) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ + 238, /* (105) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ + 238, /* (106) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ + 238, /* (107) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ + 184, /* (108) dbnm ::= */ + 184, /* (109) dbnm ::= DOT nm */ + 221, /* (110) fullname ::= nm */ + 221, /* (111) fullname ::= nm DOT nm */ + 245, /* (112) xfullname ::= nm */ + 245, /* (113) xfullname ::= nm DOT nm */ + 245, /* (114) xfullname ::= nm DOT nm AS nm */ + 245, /* (115) xfullname ::= nm AS nm */ + 240, /* (116) joinop ::= COMMA|JOIN */ + 240, /* (117) joinop ::= JOIN_KW JOIN */ + 240, /* (118) joinop ::= JOIN_KW nm JOIN */ + 240, /* (119) joinop ::= JOIN_KW nm nm JOIN */ + 242, /* (120) on_opt ::= ON expr */ + 242, /* (121) on_opt ::= */ + 241, /* (122) indexed_opt ::= */ + 241, /* (123) indexed_opt ::= INDEXED BY nm */ + 241, /* (124) indexed_opt ::= NOT INDEXED */ + 243, /* (125) using_opt ::= USING LP idlist RP */ + 243, /* (126) using_opt ::= */ + 232, /* (127) orderby_opt ::= */ + 232, /* (128) orderby_opt ::= ORDER BY sortlist */ + 214, /* (129) sortlist ::= sortlist COMMA expr sortorder nulls */ + 214, /* (130) sortlist ::= expr sortorder nulls */ + 202, /* (131) sortorder ::= ASC */ + 202, /* (132) sortorder ::= DESC */ + 202, /* (133) sortorder ::= */ + 247, /* (134) nulls ::= NULLS FIRST */ + 247, /* (135) nulls ::= NULLS LAST */ + 247, /* (136) nulls ::= */ + 230, /* (137) groupby_opt ::= */ + 230, /* (138) groupby_opt ::= GROUP BY nexprlist */ + 231, /* (139) having_opt ::= */ + 231, /* (140) having_opt ::= HAVING expr */ + 233, /* (141) limit_opt ::= */ + 233, /* (142) limit_opt ::= LIMIT expr */ + 233, /* (143) limit_opt ::= LIMIT expr OFFSET expr */ + 233, /* (144) limit_opt ::= LIMIT expr COMMA expr */ + 174, /* (145) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + 229, /* (146) where_opt ::= */ + 229, /* (147) where_opt ::= WHERE expr */ + 249, /* (148) where_opt_ret ::= */ + 249, /* (149) where_opt_ret ::= WHERE expr */ + 249, /* (150) where_opt_ret ::= RETURNING selcollist */ + 249, /* (151) where_opt_ret ::= WHERE expr RETURNING selcollist */ + 174, /* (152) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + 250, /* (153) setlist ::= setlist COMMA nm EQ expr */ + 250, /* (154) setlist ::= setlist COMMA LP idlist RP EQ expr */ + 250, /* (155) setlist ::= nm EQ expr */ + 250, /* (156) setlist ::= LP idlist RP EQ expr */ + 174, /* (157) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + 174, /* (158) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 253, /* (159) upsert ::= */ + 253, /* (160) upsert ::= RETURNING selcollist */ + 253, /* (161) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + 253, /* (162) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + 253, /* (163) upsert ::= ON CONFLICT DO NOTHING returning */ + 253, /* (164) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + 254, /* (165) returning ::= RETURNING selcollist */ + 251, /* (166) insert_cmd ::= INSERT orconf */ + 251, /* (167) insert_cmd ::= REPLACE */ + 252, /* (168) idlist_opt ::= */ + 252, /* (169) idlist_opt ::= LP idlist RP */ + 246, /* (170) idlist ::= idlist COMMA nm */ + 246, /* (171) idlist ::= nm */ + 200, /* (172) expr ::= LP expr RP */ + 200, /* (173) expr ::= ID|INDEXED */ + 200, /* (174) expr ::= JOIN_KW */ + 200, /* (175) expr ::= nm DOT nm */ + 200, /* (176) expr ::= nm DOT nm DOT nm */ + 199, /* (177) term ::= NULL|FLOAT|BLOB */ + 199, /* (178) term ::= STRING */ + 199, /* (179) term ::= INTEGER */ + 200, /* (180) expr ::= VARIABLE */ + 200, /* (181) expr ::= expr COLLATE ID|STRING */ + 200, /* (182) expr ::= CAST LP expr AS typetoken RP */ + 200, /* (183) expr ::= ID|INDEXED LP distinct exprlist RP */ + 200, /* (184) expr ::= ID|INDEXED LP STAR RP */ + 199, /* (185) term ::= CTIME_KW */ + 200, /* (186) expr ::= LP nexprlist COMMA expr RP */ + 200, /* (187) expr ::= expr AND expr */ + 200, /* (188) expr ::= expr OR expr */ + 200, /* (189) expr ::= expr LT|GT|GE|LE expr */ + 200, /* (190) expr ::= expr EQ|NE expr */ + 200, /* (191) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + 200, /* (192) expr ::= expr PLUS|MINUS expr */ + 200, /* (193) expr ::= expr STAR|SLASH|REM expr */ + 200, /* (194) expr ::= expr CONCAT expr */ + 255, /* (195) likeop ::= NOT LIKE_KW|MATCH */ + 200, /* (196) expr ::= expr likeop expr */ + 200, /* (197) expr ::= expr likeop expr ESCAPE expr */ + 200, /* (198) expr ::= expr ISNULL|NOTNULL */ + 200, /* (199) expr ::= expr NOT NULL */ + 200, /* (200) expr ::= expr IS expr */ + 200, /* (201) expr ::= expr IS NOT expr */ + 200, /* (202) expr ::= NOT expr */ + 200, /* (203) expr ::= BITNOT expr */ + 200, /* (204) expr ::= PLUS|MINUS expr */ + 256, /* (205) between_op ::= BETWEEN */ + 256, /* (206) between_op ::= NOT BETWEEN */ + 200, /* (207) expr ::= expr between_op expr AND expr */ + 257, /* (208) in_op ::= IN */ + 257, /* (209) in_op ::= NOT IN */ + 200, /* (210) expr ::= expr in_op LP exprlist RP */ + 200, /* (211) expr ::= LP select RP */ + 200, /* (212) expr ::= expr in_op LP select RP */ + 200, /* (213) expr ::= expr in_op nm dbnm paren_exprlist */ + 200, /* (214) expr ::= EXISTS LP select RP */ + 200, /* (215) expr ::= CASE case_operand case_exprlist case_else END */ + 260, /* (216) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + 260, /* (217) case_exprlist ::= WHEN expr THEN expr */ + 261, /* (218) case_else ::= ELSE expr */ + 261, /* (219) case_else ::= */ + 259, /* (220) case_operand ::= expr */ + 259, /* (221) case_operand ::= */ + 244, /* (222) exprlist ::= */ + 235, /* (223) nexprlist ::= nexprlist COMMA expr */ + 235, /* (224) nexprlist ::= expr */ + 258, /* (225) paren_exprlist ::= */ + 258, /* (226) paren_exprlist ::= LP exprlist RP */ + 174, /* (227) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + 262, /* (228) uniqueflag ::= UNIQUE */ + 262, /* (229) uniqueflag ::= */ + 204, /* (230) eidlist_opt ::= */ + 204, /* (231) eidlist_opt ::= LP eidlist RP */ + 215, /* (232) eidlist ::= eidlist COMMA nm collate sortorder */ + 215, /* (233) eidlist ::= nm collate sortorder */ + 263, /* (234) collate ::= */ + 263, /* (235) collate ::= COLLATE ID|STRING */ + 174, /* (236) cmd ::= DROP INDEX ifexists fullname */ + 174, /* (237) cmd ::= VACUUM vinto */ + 174, /* (238) cmd ::= VACUUM nm vinto */ + 264, /* (239) vinto ::= INTO expr */ + 264, /* (240) vinto ::= */ + 174, /* (241) cmd ::= PRAGMA nm dbnm */ + 174, /* (242) cmd ::= PRAGMA nm dbnm EQ nmnum */ + 174, /* (243) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + 174, /* (244) cmd ::= PRAGMA nm dbnm EQ minus_num */ + 174, /* (245) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + 194, /* (246) plus_num ::= PLUS INTEGER|FLOAT */ + 195, /* (247) minus_num ::= MINUS INTEGER|FLOAT */ + 174, /* (248) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + 266, /* (249) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + 268, /* (250) trigger_time ::= BEFORE|AFTER */ + 268, /* (251) trigger_time ::= INSTEAD OF */ + 268, /* (252) trigger_time ::= */ + 269, /* (253) trigger_event ::= DELETE|INSERT */ + 269, /* (254) trigger_event ::= UPDATE */ + 269, /* (255) trigger_event ::= UPDATE OF idlist */ + 271, /* (256) when_clause ::= */ + 271, /* (257) when_clause ::= WHEN expr */ + 267, /* (258) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 267, /* (259) trigger_cmd_list ::= trigger_cmd SEMI */ + 273, /* (260) trnm ::= nm DOT nm */ + 274, /* (261) tridxby ::= INDEXED BY nm */ + 274, /* (262) tridxby ::= NOT INDEXED */ + 272, /* (263) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + 272, /* (264) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + 272, /* (265) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + 272, /* (266) trigger_cmd ::= scanpt select scanpt */ + 200, /* (267) expr ::= RAISE LP IGNORE RP */ + 200, /* (268) expr ::= RAISE LP raisetype COMMA nm RP */ + 219, /* (269) raisetype ::= ROLLBACK */ + 219, /* (270) raisetype ::= ABORT */ + 219, /* (271) raisetype ::= FAIL */ + 174, /* (272) cmd ::= DROP TRIGGER ifexists fullname */ + 174, /* (273) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 174, /* (274) cmd ::= DETACH database_kw_opt expr */ + 276, /* (275) key_opt ::= */ + 276, /* (276) key_opt ::= KEY expr */ + 174, /* (277) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 174, /* (278) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + 174, /* (279) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + 277, /* (280) add_column_fullname ::= fullname */ + 174, /* (281) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 174, /* (282) cmd ::= create_vtab */ + 174, /* (283) cmd ::= create_vtab LP vtabarglist RP */ + 279, /* (284) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 281, /* (285) vtabarg ::= */ + 282, /* (286) vtabargtoken ::= ANY */ + 282, /* (287) vtabargtoken ::= lp anylist RP */ + 283, /* (288) lp ::= LP */ + 248, /* (289) with ::= WITH wqlist */ + 248, /* (290) with ::= WITH RECURSIVE wqlist */ + 286, /* (291) wqas ::= AS */ + 286, /* (292) wqas ::= AS MATERIALIZED */ + 286, /* (293) wqas ::= AS NOT MATERIALIZED */ + 285, /* (294) wqitem ::= nm eidlist_opt wqas LP select RP */ + 224, /* (295) wqlist ::= wqitem */ + 224, /* (296) wqlist ::= wqlist COMMA wqitem */ + 170, /* (297) input ::= cmdlist */ + 171, /* (298) cmdlist ::= cmdlist ecmd */ + 171, /* (299) cmdlist ::= ecmd */ + 172, /* (300) ecmd ::= SEMI */ + 172, /* (301) ecmd ::= cmdx SEMI */ + 176, /* (302) trans_opt ::= */ + 176, /* (303) trans_opt ::= TRANSACTION */ + 176, /* (304) trans_opt ::= TRANSACTION nm */ + 178, /* (305) savepoint_opt ::= SAVEPOINT */ + 178, /* (306) savepoint_opt ::= */ + 174, /* (307) cmd ::= create_table create_table_args */ + 185, /* (308) columnlist ::= columnlist COMMA columnname carglist */ + 185, /* (309) columnlist ::= columnname carglist */ + 177, /* (310) nm ::= ID|INDEXED */ + 177, /* (311) nm ::= STRING */ + 177, /* (312) nm ::= JOIN_KW */ + 191, /* (313) typetoken ::= typename */ + 192, /* (314) typename ::= ID|STRING */ + 193, /* (315) signed ::= plus_num */ + 193, /* (316) signed ::= minus_num */ + 190, /* (317) carglist ::= carglist ccons */ + 190, /* (318) carglist ::= */ + 198, /* (319) ccons ::= NULL onconf */ + 198, /* (320) ccons ::= GENERATED ALWAYS AS generated */ + 198, /* (321) ccons ::= AS generated */ + 186, /* (322) conslist_opt ::= COMMA conslist */ + 211, /* (323) conslist ::= conslist tconscomma tcons */ + 211, /* (324) conslist ::= tcons */ + 212, /* (325) tconscomma ::= */ + 216, /* (326) defer_subclause_opt ::= defer_subclause */ + 218, /* (327) resolvetype ::= raisetype */ + 222, /* (328) selectnowith ::= oneselect */ + 223, /* (329) oneselect ::= values */ + 236, /* (330) sclp ::= selcollist COMMA */ + 237, /* (331) as ::= ID|STRING */ + 254, /* (332) returning ::= */ + 200, /* (333) expr ::= term */ + 255, /* (334) likeop ::= LIKE_KW|MATCH */ + 244, /* (335) exprlist ::= nexprlist */ + 265, /* (336) nmnum ::= plus_num */ + 265, /* (337) nmnum ::= nm */ + 265, /* (338) nmnum ::= ON */ + 265, /* (339) nmnum ::= DELETE */ + 265, /* (340) nmnum ::= DEFAULT */ + 194, /* (341) plus_num ::= INTEGER|FLOAT */ + 270, /* (342) foreach_clause ::= */ + 270, /* (343) foreach_clause ::= FOR EACH ROW */ + 273, /* (344) trnm ::= nm */ + 274, /* (345) tridxby ::= */ + 275, /* (346) database_kw_opt ::= DATABASE */ + 275, /* (347) database_kw_opt ::= */ + 278, /* (348) kwcolumn_opt ::= */ + 278, /* (349) kwcolumn_opt ::= COLUMNKW */ + 280, /* (350) vtabarglist ::= vtabarg */ + 280, /* (351) vtabarglist ::= vtabarglist COMMA vtabarg */ + 281, /* (352) vtabarg ::= vtabarg vtabargtoken */ + 284, /* (353) anylist ::= */ + 284, /* (354) anylist ::= anylist LP anylist RP */ + 284, /* (355) anylist ::= anylist ANY */ + 248, /* (356) with ::= */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -157762,205 +159988,218 @@ static const signed char yyRuleInfoNRhs[] = { -2, /* (142) limit_opt ::= LIMIT expr */ -4, /* (143) limit_opt ::= LIMIT expr OFFSET expr */ -4, /* (144) limit_opt ::= LIMIT expr COMMA expr */ - -6, /* (145) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ + -6, /* (145) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ 0, /* (146) where_opt ::= */ -2, /* (147) where_opt ::= WHERE expr */ - -9, /* (148) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt */ - -5, /* (149) setlist ::= setlist COMMA nm EQ expr */ - -7, /* (150) setlist ::= setlist COMMA LP idlist RP EQ expr */ - -3, /* (151) setlist ::= nm EQ expr */ - -5, /* (152) setlist ::= LP idlist RP EQ expr */ - -7, /* (153) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - -7, /* (154) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ - 0, /* (155) upsert ::= */ - -11, /* (156) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ - -8, /* (157) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ - -4, /* (158) upsert ::= ON CONFLICT DO NOTHING */ - -2, /* (159) insert_cmd ::= INSERT orconf */ - -1, /* (160) insert_cmd ::= REPLACE */ - 0, /* (161) idlist_opt ::= */ - -3, /* (162) idlist_opt ::= LP idlist RP */ - -3, /* (163) idlist ::= idlist COMMA nm */ - -1, /* (164) idlist ::= nm */ - -3, /* (165) expr ::= LP expr RP */ - -1, /* (166) expr ::= ID|INDEXED */ - -1, /* (167) expr ::= JOIN_KW */ - -3, /* (168) expr ::= nm DOT nm */ - -5, /* (169) expr ::= nm DOT nm DOT nm */ - -1, /* (170) term ::= NULL|FLOAT|BLOB */ - -1, /* (171) term ::= STRING */ - -1, /* (172) term ::= INTEGER */ - -1, /* (173) expr ::= VARIABLE */ - -3, /* (174) expr ::= expr COLLATE ID|STRING */ - -6, /* (175) expr ::= CAST LP expr AS typetoken RP */ - -5, /* (176) expr ::= ID|INDEXED LP distinct exprlist RP */ - -4, /* (177) expr ::= ID|INDEXED LP STAR RP */ - -1, /* (178) term ::= CTIME_KW */ - -5, /* (179) expr ::= LP nexprlist COMMA expr RP */ - -3, /* (180) expr ::= expr AND expr */ - -3, /* (181) expr ::= expr OR expr */ - -3, /* (182) expr ::= expr LT|GT|GE|LE expr */ - -3, /* (183) expr ::= expr EQ|NE expr */ - -3, /* (184) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - -3, /* (185) expr ::= expr PLUS|MINUS expr */ - -3, /* (186) expr ::= expr STAR|SLASH|REM expr */ - -3, /* (187) expr ::= expr CONCAT expr */ - -2, /* (188) likeop ::= NOT LIKE_KW|MATCH */ - -3, /* (189) expr ::= expr likeop expr */ - -5, /* (190) expr ::= expr likeop expr ESCAPE expr */ - -2, /* (191) expr ::= expr ISNULL|NOTNULL */ - -3, /* (192) expr ::= expr NOT NULL */ - -3, /* (193) expr ::= expr IS expr */ - -4, /* (194) expr ::= expr IS NOT expr */ - -2, /* (195) expr ::= NOT expr */ - -2, /* (196) expr ::= BITNOT expr */ - -2, /* (197) expr ::= PLUS|MINUS expr */ - -1, /* (198) between_op ::= BETWEEN */ - -2, /* (199) between_op ::= NOT BETWEEN */ - -5, /* (200) expr ::= expr between_op expr AND expr */ - -1, /* (201) in_op ::= IN */ - -2, /* (202) in_op ::= NOT IN */ - -5, /* (203) expr ::= expr in_op LP exprlist RP */ - -3, /* (204) expr ::= LP select RP */ - -5, /* (205) expr ::= expr in_op LP select RP */ - -5, /* (206) expr ::= expr in_op nm dbnm paren_exprlist */ - -4, /* (207) expr ::= EXISTS LP select RP */ - -5, /* (208) expr ::= CASE case_operand case_exprlist case_else END */ - -5, /* (209) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - -4, /* (210) case_exprlist ::= WHEN expr THEN expr */ - -2, /* (211) case_else ::= ELSE expr */ - 0, /* (212) case_else ::= */ - -1, /* (213) case_operand ::= expr */ - 0, /* (214) case_operand ::= */ - 0, /* (215) exprlist ::= */ - -3, /* (216) nexprlist ::= nexprlist COMMA expr */ - -1, /* (217) nexprlist ::= expr */ - 0, /* (218) paren_exprlist ::= */ - -3, /* (219) paren_exprlist ::= LP exprlist RP */ - -12, /* (220) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - -1, /* (221) uniqueflag ::= UNIQUE */ - 0, /* (222) uniqueflag ::= */ - 0, /* (223) eidlist_opt ::= */ - -3, /* (224) eidlist_opt ::= LP eidlist RP */ - -5, /* (225) eidlist ::= eidlist COMMA nm collate sortorder */ - -3, /* (226) eidlist ::= nm collate sortorder */ - 0, /* (227) collate ::= */ - -2, /* (228) collate ::= COLLATE ID|STRING */ - -4, /* (229) cmd ::= DROP INDEX ifexists fullname */ - -2, /* (230) cmd ::= VACUUM vinto */ - -3, /* (231) cmd ::= VACUUM nm vinto */ - -2, /* (232) vinto ::= INTO expr */ - 0, /* (233) vinto ::= */ - -3, /* (234) cmd ::= PRAGMA nm dbnm */ - -5, /* (235) cmd ::= PRAGMA nm dbnm EQ nmnum */ - -6, /* (236) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - -5, /* (237) cmd ::= PRAGMA nm dbnm EQ minus_num */ - -6, /* (238) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - -2, /* (239) plus_num ::= PLUS INTEGER|FLOAT */ - -2, /* (240) minus_num ::= MINUS INTEGER|FLOAT */ - -5, /* (241) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - -11, /* (242) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - -1, /* (243) trigger_time ::= BEFORE|AFTER */ - -2, /* (244) trigger_time ::= INSTEAD OF */ - 0, /* (245) trigger_time ::= */ - -1, /* (246) trigger_event ::= DELETE|INSERT */ - -1, /* (247) trigger_event ::= UPDATE */ - -3, /* (248) trigger_event ::= UPDATE OF idlist */ - 0, /* (249) when_clause ::= */ - -2, /* (250) when_clause ::= WHEN expr */ - -3, /* (251) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - -2, /* (252) trigger_cmd_list ::= trigger_cmd SEMI */ - -3, /* (253) trnm ::= nm DOT nm */ - -3, /* (254) tridxby ::= INDEXED BY nm */ - -2, /* (255) tridxby ::= NOT INDEXED */ - -9, /* (256) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - -8, /* (257) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - -6, /* (258) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - -3, /* (259) trigger_cmd ::= scanpt select scanpt */ - -4, /* (260) expr ::= RAISE LP IGNORE RP */ - -6, /* (261) expr ::= RAISE LP raisetype COMMA nm RP */ - -1, /* (262) raisetype ::= ROLLBACK */ - -1, /* (263) raisetype ::= ABORT */ - -1, /* (264) raisetype ::= FAIL */ - -4, /* (265) cmd ::= DROP TRIGGER ifexists fullname */ - -6, /* (266) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - -3, /* (267) cmd ::= DETACH database_kw_opt expr */ - 0, /* (268) key_opt ::= */ - -2, /* (269) key_opt ::= KEY expr */ - -6, /* (270) cmd ::= ALTER TABLE fullname RENAME TO nm */ - -7, /* (271) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - -1, /* (272) add_column_fullname ::= fullname */ - -8, /* (273) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - -1, /* (274) cmd ::= create_vtab */ - -4, /* (275) cmd ::= create_vtab LP vtabarglist RP */ - -8, /* (276) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 0, /* (277) vtabarg ::= */ - -1, /* (278) vtabargtoken ::= ANY */ - -3, /* (279) vtabargtoken ::= lp anylist RP */ - -1, /* (280) lp ::= LP */ - -2, /* (281) with ::= WITH wqlist */ - -3, /* (282) with ::= WITH RECURSIVE wqlist */ - -6, /* (283) wqlist ::= nm eidlist_opt AS LP select RP */ - -8, /* (284) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ - -1, /* (285) input ::= cmdlist */ - -2, /* (286) cmdlist ::= cmdlist ecmd */ - -1, /* (287) cmdlist ::= ecmd */ - -1, /* (288) ecmd ::= SEMI */ - -2, /* (289) ecmd ::= cmdx SEMI */ - 0, /* (290) trans_opt ::= */ - -1, /* (291) trans_opt ::= TRANSACTION */ - -2, /* (292) trans_opt ::= TRANSACTION nm */ - -1, /* (293) savepoint_opt ::= SAVEPOINT */ - 0, /* (294) savepoint_opt ::= */ - -2, /* (295) cmd ::= create_table create_table_args */ - -4, /* (296) columnlist ::= columnlist COMMA columnname carglist */ - -2, /* (297) columnlist ::= columnname carglist */ - -1, /* (298) nm ::= ID|INDEXED */ - -1, /* (299) nm ::= STRING */ - -1, /* (300) nm ::= JOIN_KW */ - -1, /* (301) typetoken ::= typename */ - -1, /* (302) typename ::= ID|STRING */ - -1, /* (303) signed ::= plus_num */ - -1, /* (304) signed ::= minus_num */ - -2, /* (305) carglist ::= carglist ccons */ - 0, /* (306) carglist ::= */ - -2, /* (307) ccons ::= NULL onconf */ - -4, /* (308) ccons ::= GENERATED ALWAYS AS generated */ - -2, /* (309) ccons ::= AS generated */ - -2, /* (310) conslist_opt ::= COMMA conslist */ - -3, /* (311) conslist ::= conslist tconscomma tcons */ - -1, /* (312) conslist ::= tcons */ - 0, /* (313) tconscomma ::= */ - -1, /* (314) defer_subclause_opt ::= defer_subclause */ - -1, /* (315) resolvetype ::= raisetype */ - -1, /* (316) selectnowith ::= oneselect */ - -1, /* (317) oneselect ::= values */ - -2, /* (318) sclp ::= selcollist COMMA */ - -1, /* (319) as ::= ID|STRING */ - -1, /* (320) expr ::= term */ - -1, /* (321) likeop ::= LIKE_KW|MATCH */ - -1, /* (322) exprlist ::= nexprlist */ - -1, /* (323) nmnum ::= plus_num */ - -1, /* (324) nmnum ::= nm */ - -1, /* (325) nmnum ::= ON */ - -1, /* (326) nmnum ::= DELETE */ - -1, /* (327) nmnum ::= DEFAULT */ - -1, /* (328) plus_num ::= INTEGER|FLOAT */ - 0, /* (329) foreach_clause ::= */ - -3, /* (330) foreach_clause ::= FOR EACH ROW */ - -1, /* (331) trnm ::= nm */ - 0, /* (332) tridxby ::= */ - -1, /* (333) database_kw_opt ::= DATABASE */ - 0, /* (334) database_kw_opt ::= */ - 0, /* (335) kwcolumn_opt ::= */ - -1, /* (336) kwcolumn_opt ::= COLUMNKW */ - -1, /* (337) vtabarglist ::= vtabarg */ - -3, /* (338) vtabarglist ::= vtabarglist COMMA vtabarg */ - -2, /* (339) vtabarg ::= vtabarg vtabargtoken */ - 0, /* (340) anylist ::= */ - -4, /* (341) anylist ::= anylist LP anylist RP */ - -2, /* (342) anylist ::= anylist ANY */ - 0, /* (343) with ::= */ + 0, /* (148) where_opt_ret ::= */ + -2, /* (149) where_opt_ret ::= WHERE expr */ + -2, /* (150) where_opt_ret ::= RETURNING selcollist */ + -4, /* (151) where_opt_ret ::= WHERE expr RETURNING selcollist */ + -9, /* (152) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + -5, /* (153) setlist ::= setlist COMMA nm EQ expr */ + -7, /* (154) setlist ::= setlist COMMA LP idlist RP EQ expr */ + -3, /* (155) setlist ::= nm EQ expr */ + -5, /* (156) setlist ::= LP idlist RP EQ expr */ + -7, /* (157) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + -8, /* (158) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 0, /* (159) upsert ::= */ + -2, /* (160) upsert ::= RETURNING selcollist */ + -12, /* (161) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + -9, /* (162) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + -5, /* (163) upsert ::= ON CONFLICT DO NOTHING returning */ + -8, /* (164) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + -2, /* (165) returning ::= RETURNING selcollist */ + -2, /* (166) insert_cmd ::= INSERT orconf */ + -1, /* (167) insert_cmd ::= REPLACE */ + 0, /* (168) idlist_opt ::= */ + -3, /* (169) idlist_opt ::= LP idlist RP */ + -3, /* (170) idlist ::= idlist COMMA nm */ + -1, /* (171) idlist ::= nm */ + -3, /* (172) expr ::= LP expr RP */ + -1, /* (173) expr ::= ID|INDEXED */ + -1, /* (174) expr ::= JOIN_KW */ + -3, /* (175) expr ::= nm DOT nm */ + -5, /* (176) expr ::= nm DOT nm DOT nm */ + -1, /* (177) term ::= NULL|FLOAT|BLOB */ + -1, /* (178) term ::= STRING */ + -1, /* (179) term ::= INTEGER */ + -1, /* (180) expr ::= VARIABLE */ + -3, /* (181) expr ::= expr COLLATE ID|STRING */ + -6, /* (182) expr ::= CAST LP expr AS typetoken RP */ + -5, /* (183) expr ::= ID|INDEXED LP distinct exprlist RP */ + -4, /* (184) expr ::= ID|INDEXED LP STAR RP */ + -1, /* (185) term ::= CTIME_KW */ + -5, /* (186) expr ::= LP nexprlist COMMA expr RP */ + -3, /* (187) expr ::= expr AND expr */ + -3, /* (188) expr ::= expr OR expr */ + -3, /* (189) expr ::= expr LT|GT|GE|LE expr */ + -3, /* (190) expr ::= expr EQ|NE expr */ + -3, /* (191) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + -3, /* (192) expr ::= expr PLUS|MINUS expr */ + -3, /* (193) expr ::= expr STAR|SLASH|REM expr */ + -3, /* (194) expr ::= expr CONCAT expr */ + -2, /* (195) likeop ::= NOT LIKE_KW|MATCH */ + -3, /* (196) expr ::= expr likeop expr */ + -5, /* (197) expr ::= expr likeop expr ESCAPE expr */ + -2, /* (198) expr ::= expr ISNULL|NOTNULL */ + -3, /* (199) expr ::= expr NOT NULL */ + -3, /* (200) expr ::= expr IS expr */ + -4, /* (201) expr ::= expr IS NOT expr */ + -2, /* (202) expr ::= NOT expr */ + -2, /* (203) expr ::= BITNOT expr */ + -2, /* (204) expr ::= PLUS|MINUS expr */ + -1, /* (205) between_op ::= BETWEEN */ + -2, /* (206) between_op ::= NOT BETWEEN */ + -5, /* (207) expr ::= expr between_op expr AND expr */ + -1, /* (208) in_op ::= IN */ + -2, /* (209) in_op ::= NOT IN */ + -5, /* (210) expr ::= expr in_op LP exprlist RP */ + -3, /* (211) expr ::= LP select RP */ + -5, /* (212) expr ::= expr in_op LP select RP */ + -5, /* (213) expr ::= expr in_op nm dbnm paren_exprlist */ + -4, /* (214) expr ::= EXISTS LP select RP */ + -5, /* (215) expr ::= CASE case_operand case_exprlist case_else END */ + -5, /* (216) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + -4, /* (217) case_exprlist ::= WHEN expr THEN expr */ + -2, /* (218) case_else ::= ELSE expr */ + 0, /* (219) case_else ::= */ + -1, /* (220) case_operand ::= expr */ + 0, /* (221) case_operand ::= */ + 0, /* (222) exprlist ::= */ + -3, /* (223) nexprlist ::= nexprlist COMMA expr */ + -1, /* (224) nexprlist ::= expr */ + 0, /* (225) paren_exprlist ::= */ + -3, /* (226) paren_exprlist ::= LP exprlist RP */ + -12, /* (227) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + -1, /* (228) uniqueflag ::= UNIQUE */ + 0, /* (229) uniqueflag ::= */ + 0, /* (230) eidlist_opt ::= */ + -3, /* (231) eidlist_opt ::= LP eidlist RP */ + -5, /* (232) eidlist ::= eidlist COMMA nm collate sortorder */ + -3, /* (233) eidlist ::= nm collate sortorder */ + 0, /* (234) collate ::= */ + -2, /* (235) collate ::= COLLATE ID|STRING */ + -4, /* (236) cmd ::= DROP INDEX ifexists fullname */ + -2, /* (237) cmd ::= VACUUM vinto */ + -3, /* (238) cmd ::= VACUUM nm vinto */ + -2, /* (239) vinto ::= INTO expr */ + 0, /* (240) vinto ::= */ + -3, /* (241) cmd ::= PRAGMA nm dbnm */ + -5, /* (242) cmd ::= PRAGMA nm dbnm EQ nmnum */ + -6, /* (243) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + -5, /* (244) cmd ::= PRAGMA nm dbnm EQ minus_num */ + -6, /* (245) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + -2, /* (246) plus_num ::= PLUS INTEGER|FLOAT */ + -2, /* (247) minus_num ::= MINUS INTEGER|FLOAT */ + -5, /* (248) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + -11, /* (249) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + -1, /* (250) trigger_time ::= BEFORE|AFTER */ + -2, /* (251) trigger_time ::= INSTEAD OF */ + 0, /* (252) trigger_time ::= */ + -1, /* (253) trigger_event ::= DELETE|INSERT */ + -1, /* (254) trigger_event ::= UPDATE */ + -3, /* (255) trigger_event ::= UPDATE OF idlist */ + 0, /* (256) when_clause ::= */ + -2, /* (257) when_clause ::= WHEN expr */ + -3, /* (258) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (259) trigger_cmd_list ::= trigger_cmd SEMI */ + -3, /* (260) trnm ::= nm DOT nm */ + -3, /* (261) tridxby ::= INDEXED BY nm */ + -2, /* (262) tridxby ::= NOT INDEXED */ + -9, /* (263) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + -8, /* (264) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + -6, /* (265) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + -3, /* (266) trigger_cmd ::= scanpt select scanpt */ + -4, /* (267) expr ::= RAISE LP IGNORE RP */ + -6, /* (268) expr ::= RAISE LP raisetype COMMA nm RP */ + -1, /* (269) raisetype ::= ROLLBACK */ + -1, /* (270) raisetype ::= ABORT */ + -1, /* (271) raisetype ::= FAIL */ + -4, /* (272) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (273) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (274) cmd ::= DETACH database_kw_opt expr */ + 0, /* (275) key_opt ::= */ + -2, /* (276) key_opt ::= KEY expr */ + -6, /* (277) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -7, /* (278) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + -6, /* (279) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + -1, /* (280) add_column_fullname ::= fullname */ + -8, /* (281) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -1, /* (282) cmd ::= create_vtab */ + -4, /* (283) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (284) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (285) vtabarg ::= */ + -1, /* (286) vtabargtoken ::= ANY */ + -3, /* (287) vtabargtoken ::= lp anylist RP */ + -1, /* (288) lp ::= LP */ + -2, /* (289) with ::= WITH wqlist */ + -3, /* (290) with ::= WITH RECURSIVE wqlist */ + -1, /* (291) wqas ::= AS */ + -2, /* (292) wqas ::= AS MATERIALIZED */ + -3, /* (293) wqas ::= AS NOT MATERIALIZED */ + -6, /* (294) wqitem ::= nm eidlist_opt wqas LP select RP */ + -1, /* (295) wqlist ::= wqitem */ + -3, /* (296) wqlist ::= wqlist COMMA wqitem */ + -1, /* (297) input ::= cmdlist */ + -2, /* (298) cmdlist ::= cmdlist ecmd */ + -1, /* (299) cmdlist ::= ecmd */ + -1, /* (300) ecmd ::= SEMI */ + -2, /* (301) ecmd ::= cmdx SEMI */ + 0, /* (302) trans_opt ::= */ + -1, /* (303) trans_opt ::= TRANSACTION */ + -2, /* (304) trans_opt ::= TRANSACTION nm */ + -1, /* (305) savepoint_opt ::= SAVEPOINT */ + 0, /* (306) savepoint_opt ::= */ + -2, /* (307) cmd ::= create_table create_table_args */ + -4, /* (308) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (309) columnlist ::= columnname carglist */ + -1, /* (310) nm ::= ID|INDEXED */ + -1, /* (311) nm ::= STRING */ + -1, /* (312) nm ::= JOIN_KW */ + -1, /* (313) typetoken ::= typename */ + -1, /* (314) typename ::= ID|STRING */ + -1, /* (315) signed ::= plus_num */ + -1, /* (316) signed ::= minus_num */ + -2, /* (317) carglist ::= carglist ccons */ + 0, /* (318) carglist ::= */ + -2, /* (319) ccons ::= NULL onconf */ + -4, /* (320) ccons ::= GENERATED ALWAYS AS generated */ + -2, /* (321) ccons ::= AS generated */ + -2, /* (322) conslist_opt ::= COMMA conslist */ + -3, /* (323) conslist ::= conslist tconscomma tcons */ + -1, /* (324) conslist ::= tcons */ + 0, /* (325) tconscomma ::= */ + -1, /* (326) defer_subclause_opt ::= defer_subclause */ + -1, /* (327) resolvetype ::= raisetype */ + -1, /* (328) selectnowith ::= oneselect */ + -1, /* (329) oneselect ::= values */ + -2, /* (330) sclp ::= selcollist COMMA */ + -1, /* (331) as ::= ID|STRING */ + 0, /* (332) returning ::= */ + -1, /* (333) expr ::= term */ + -1, /* (334) likeop ::= LIKE_KW|MATCH */ + -1, /* (335) exprlist ::= nexprlist */ + -1, /* (336) nmnum ::= plus_num */ + -1, /* (337) nmnum ::= nm */ + -1, /* (338) nmnum ::= ON */ + -1, /* (339) nmnum ::= DELETE */ + -1, /* (340) nmnum ::= DEFAULT */ + -1, /* (341) plus_num ::= INTEGER|FLOAT */ + 0, /* (342) foreach_clause ::= */ + -3, /* (343) foreach_clause ::= FOR EACH ROW */ + -1, /* (344) trnm ::= nm */ + 0, /* (345) tridxby ::= */ + -1, /* (346) database_kw_opt ::= DATABASE */ + 0, /* (347) database_kw_opt ::= */ + 0, /* (348) kwcolumn_opt ::= */ + -1, /* (349) kwcolumn_opt ::= COLUMNKW */ + -1, /* (350) vtabarglist ::= vtabarg */ + -3, /* (351) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (352) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (353) anylist ::= */ + -4, /* (354) anylist ::= anylist LP anylist RP */ + -2, /* (355) anylist ::= anylist ANY */ + 0, /* (356) with ::= */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -157990,55 +160229,6 @@ static YYACTIONTYPE yy_reduce( (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; - assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); -#ifndef NDEBUG - if( yyTraceFILE ){ - yysize = yyRuleInfoNRhs[yyruleno]; - if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", - yyTracePrompt, - yyruleno, yyRuleName[yyruleno], - yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action", - yymsp[yysize].stateno); - }else{ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", - yyTracePrompt, yyruleno, yyRuleName[yyruleno], - yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action"); - } - } -#endif /* NDEBUG */ - - /* Check that the stack is large enough to grow by a single entry - ** if the RHS of the rule is empty. This ensures that there is room - ** enough on the stack to push the LHS value */ - if( yyRuleInfoNRhs[yyruleno]==0 ){ -#ifdef YYTRACKMAXSTACKDEPTH - if( (int)(yypParser->yytos - 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 @@ -158055,15 +160245,15 @@ static YYACTIONTYPE yy_reduce( { sqlite3FinishCoding(pParse); } break; case 1: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy222);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy116);} break; case 2: /* transtype ::= */ -{yymsp[1].minor.yy222 = TK_DEFERRED;} +{yymsp[1].minor.yy116 = TK_DEFERRED;} break; case 3: /* transtype ::= DEFERRED */ case 4: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==4); case 5: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==5); -{yymsp[0].minor.yy222 = yymsp[0].major; /*A-overwrites-X*/} +{yymsp[0].minor.yy116 = yymsp[0].major; /*A-overwrites-X*/} break; case 6: /* cmd ::= COMMIT|END trans_opt */ case 7: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==7); @@ -158086,7 +160276,7 @@ static YYACTIONTYPE yy_reduce( break; case 11: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { - sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy222,0,0,yymsp[-2].minor.yy222); + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy116,0,0,yymsp[-2].minor.yy116); } break; case 12: /* createkw ::= CREATE */ @@ -158100,33 +160290,33 @@ static YYACTIONTYPE yy_reduce( case 68: /* defer_subclause_opt ::= */ yytestcase(yyruleno==68); case 77: /* ifexists ::= */ yytestcase(yyruleno==77); case 93: /* distinct ::= */ yytestcase(yyruleno==93); - case 227: /* collate ::= */ yytestcase(yyruleno==227); -{yymsp[1].minor.yy222 = 0;} + case 234: /* collate ::= */ yytestcase(yyruleno==234); +{yymsp[1].minor.yy116 = 0;} break; case 14: /* ifnotexists ::= IF NOT EXISTS */ -{yymsp[-2].minor.yy222 = 1;} +{yymsp[-2].minor.yy116 = 1;} break; case 15: /* temp ::= TEMP */ case 44: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==44); -{yymsp[0].minor.yy222 = 1;} +{yymsp[0].minor.yy116 = 1;} break; case 17: /* create_table_args ::= LP columnlist conslist_opt RP table_options */ { - sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy222,0); + sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy116,0); } break; case 18: /* create_table_args ::= AS select */ { - sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy341); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy341); + sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy457); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy457); } break; case 20: /* table_options ::= WITHOUT nm */ { if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ - yymsp[-1].minor.yy222 = TF_WithoutRowid | TF_NoVisibleRowid; + yymsp[-1].minor.yy116 = TF_WithoutRowid | TF_NoVisibleRowid; }else{ - yymsp[-1].minor.yy222 = 0; + yymsp[-1].minor.yy116 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } @@ -158155,7 +160345,7 @@ static YYACTIONTYPE yy_reduce( case 26: /* scanpt ::= */ { assert( yyLookahead!=YYNOCODE ); - yymsp[1].minor.yy386 = yyLookaheadToken.z; + yymsp[1].minor.yy224 = yyLookaheadToken.z; } break; case 27: /* scantok ::= */ @@ -158169,17 +160359,17 @@ static YYACTIONTYPE yy_reduce( {pParse->constraintName = yymsp[0].minor.yy0;} break; case 29: /* ccons ::= DEFAULT scantok term */ -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy244,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy62,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; case 30: /* ccons ::= DEFAULT LP expr RP */ -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy244,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy62,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} break; case 31: /* ccons ::= DEFAULT PLUS scantok term */ -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy244,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy62,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; case 32: /* ccons ::= DEFAULT MINUS scantok term */ { - Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy244, 0); + Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy62, 0); sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); } break; @@ -158194,176 +160384,158 @@ static YYACTIONTYPE yy_reduce( } break; case 34: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy222);} +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy116);} break; case 35: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy222,yymsp[0].minor.yy222,yymsp[-2].minor.yy222);} +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy116,yymsp[0].minor.yy116,yymsp[-2].minor.yy116);} break; case 36: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy222,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy116,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 37: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy244,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy62,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} break; case 38: /* ccons ::= REFERENCES nm eidlist_opt refargs */ -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy328,yymsp[0].minor.yy222);} +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy336,yymsp[0].minor.yy116);} break; case 39: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy222);} +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy116);} break; case 40: /* ccons ::= COLLATE ID|STRING */ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; case 41: /* generated ::= LP expr RP */ -{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy244,0);} +{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy62,0);} break; case 42: /* generated ::= LP expr RP ID */ -{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy244,&yymsp[0].minor.yy0);} +{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy62,&yymsp[0].minor.yy0);} break; case 45: /* refargs ::= */ -{ yymsp[1].minor.yy222 = OE_None*0x0101; /* EV: R-19803-45884 */} +{ yymsp[1].minor.yy116 = OE_None*0x0101; /* EV: R-19803-45884 */} break; case 46: /* refargs ::= refargs refarg */ -{ yymsp[-1].minor.yy222 = (yymsp[-1].minor.yy222 & ~yymsp[0].minor.yy501.mask) | yymsp[0].minor.yy501.value; } +{ yymsp[-1].minor.yy116 = (yymsp[-1].minor.yy116 & ~yymsp[0].minor.yy523.mask) | yymsp[0].minor.yy523.value; } break; case 47: /* refarg ::= MATCH nm */ -{ yymsp[-1].minor.yy501.value = 0; yymsp[-1].minor.yy501.mask = 0x000000; } +{ yymsp[-1].minor.yy523.value = 0; yymsp[-1].minor.yy523.mask = 0x000000; } break; case 48: /* refarg ::= ON INSERT refact */ -{ yymsp[-2].minor.yy501.value = 0; yymsp[-2].minor.yy501.mask = 0x000000; } +{ yymsp[-2].minor.yy523.value = 0; yymsp[-2].minor.yy523.mask = 0x000000; } break; case 49: /* refarg ::= ON DELETE refact */ -{ yymsp[-2].minor.yy501.value = yymsp[0].minor.yy222; yymsp[-2].minor.yy501.mask = 0x0000ff; } +{ yymsp[-2].minor.yy523.value = yymsp[0].minor.yy116; yymsp[-2].minor.yy523.mask = 0x0000ff; } break; case 50: /* refarg ::= ON UPDATE refact */ -{ yymsp[-2].minor.yy501.value = yymsp[0].minor.yy222<<8; yymsp[-2].minor.yy501.mask = 0x00ff00; } +{ yymsp[-2].minor.yy523.value = yymsp[0].minor.yy116<<8; yymsp[-2].minor.yy523.mask = 0x00ff00; } break; case 51: /* refact ::= SET NULL */ -{ yymsp[-1].minor.yy222 = OE_SetNull; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy116 = OE_SetNull; /* EV: R-33326-45252 */} break; case 52: /* refact ::= SET DEFAULT */ -{ yymsp[-1].minor.yy222 = OE_SetDflt; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy116 = OE_SetDflt; /* EV: R-33326-45252 */} break; case 53: /* refact ::= CASCADE */ -{ yymsp[0].minor.yy222 = OE_Cascade; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy116 = OE_Cascade; /* EV: R-33326-45252 */} break; case 54: /* refact ::= RESTRICT */ -{ yymsp[0].minor.yy222 = OE_Restrict; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy116 = OE_Restrict; /* EV: R-33326-45252 */} break; case 55: /* refact ::= NO ACTION */ -{ yymsp[-1].minor.yy222 = OE_None; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy116 = OE_None; /* EV: R-33326-45252 */} break; case 56: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -{yymsp[-2].minor.yy222 = 0;} +{yymsp[-2].minor.yy116 = 0;} break; case 57: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ case 72: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==72); - case 159: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==159); -{yymsp[-1].minor.yy222 = yymsp[0].minor.yy222;} + case 166: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==166); +{yymsp[-1].minor.yy116 = yymsp[0].minor.yy116;} break; case 59: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ case 76: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==76); - case 199: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==199); - case 202: /* in_op ::= NOT IN */ yytestcase(yyruleno==202); - case 228: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==228); -{yymsp[-1].minor.yy222 = 1;} + case 206: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==206); + case 209: /* in_op ::= NOT IN */ yytestcase(yyruleno==209); + case 235: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==235); +{yymsp[-1].minor.yy116 = 1;} break; case 60: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -{yymsp[-1].minor.yy222 = 0;} +{yymsp[-1].minor.yy116 = 0;} break; case 62: /* tconscomma ::= COMMA */ {pParse->constraintName.n = 0;} break; case 64: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy328,yymsp[0].minor.yy222,yymsp[-2].minor.yy222,0);} +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy336,yymsp[0].minor.yy116,yymsp[-2].minor.yy116,0);} break; case 65: /* tcons ::= UNIQUE LP sortlist RP onconf */ -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy328,yymsp[0].minor.yy222,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy336,yymsp[0].minor.yy116,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 66: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy244,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy62,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} break; case 67: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy328, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy328, yymsp[-1].minor.yy222); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy222); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy336, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy336, yymsp[-1].minor.yy116); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy116); } break; case 69: /* onconf ::= */ case 71: /* orconf ::= */ yytestcase(yyruleno==71); -{yymsp[1].minor.yy222 = OE_Default;} +{yymsp[1].minor.yy116 = OE_Default;} break; case 70: /* onconf ::= ON CONFLICT resolvetype */ -{yymsp[-2].minor.yy222 = yymsp[0].minor.yy222;} +{yymsp[-2].minor.yy116 = yymsp[0].minor.yy116;} break; case 73: /* resolvetype ::= IGNORE */ -{yymsp[0].minor.yy222 = OE_Ignore;} +{yymsp[0].minor.yy116 = OE_Ignore;} break; case 74: /* resolvetype ::= REPLACE */ - case 160: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==160); -{yymsp[0].minor.yy222 = OE_Replace;} + case 167: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==167); +{yymsp[0].minor.yy116 = OE_Replace;} break; case 75: /* cmd ::= DROP TABLE ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy475, 0, yymsp[-1].minor.yy222); + sqlite3DropTable(pParse, yymsp[0].minor.yy315, 0, yymsp[-1].minor.yy116); } break; case 78: /* 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.yy328, yymsp[0].minor.yy341, yymsp[-7].minor.yy222, yymsp[-5].minor.yy222); + sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy336, yymsp[0].minor.yy457, yymsp[-7].minor.yy116, yymsp[-5].minor.yy116); } break; case 79: /* cmd ::= DROP VIEW ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy475, 1, yymsp[-1].minor.yy222); + sqlite3DropTable(pParse, yymsp[0].minor.yy315, 1, yymsp[-1].minor.yy116); } break; case 80: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy341, &dest); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy341); + sqlite3Select(pParse, yymsp[0].minor.yy457, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy457); } break; case 81: /* select ::= WITH wqlist selectnowith */ -{ - Select *p = yymsp[0].minor.yy341; - if( p ){ - p->pWith = yymsp[-1].minor.yy523; - parserDoubleLinkSelect(pParse, p); - }else{ - sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy523); - } - yymsp[-2].minor.yy341 = p; -} +{yymsp[-2].minor.yy457 = attachWithToSelect(pParse,yymsp[0].minor.yy457,yymsp[-1].minor.yy535);} break; case 82: /* select ::= WITH RECURSIVE wqlist selectnowith */ -{ - Select *p = yymsp[0].minor.yy341; - if( p ){ - p->pWith = yymsp[-1].minor.yy523; - parserDoubleLinkSelect(pParse, p); - }else{ - sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy523); - } - yymsp[-3].minor.yy341 = p; -} +{yymsp[-3].minor.yy457 = attachWithToSelect(pParse,yymsp[0].minor.yy457,yymsp[-1].minor.yy535);} break; case 83: /* select ::= selectnowith */ { - Select *p = yymsp[0].minor.yy341; + Select *p = yymsp[0].minor.yy457; if( p ){ parserDoubleLinkSelect(pParse, p); } - yymsp[0].minor.yy341 = p; /*A-overwrites-X*/ + yymsp[0].minor.yy457 = p; /*A-overwrites-X*/ } break; case 84: /* selectnowith ::= selectnowith multiselect_op oneselect */ { - Select *pRhs = yymsp[0].minor.yy341; - Select *pLhs = yymsp[-2].minor.yy341; + Select *pRhs = yymsp[0].minor.yy457; + Select *pLhs = yymsp[-2].minor.yy457; if( pRhs && pRhs->pPrior ){ SrcList *pFrom; Token x; @@ -158373,73 +160545,73 @@ static YYACTIONTYPE yy_reduce( pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ - pRhs->op = (u8)yymsp[-1].minor.yy222; + pRhs->op = (u8)yymsp[-1].minor.yy116; pRhs->pPrior = pLhs; if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; pRhs->selFlags &= ~SF_MultiValue; - if( yymsp[-1].minor.yy222!=TK_ALL ) pParse->hasCompound = 1; + if( yymsp[-1].minor.yy116!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); } - yymsp[-2].minor.yy341 = pRhs; + yymsp[-2].minor.yy457 = pRhs; } break; case 85: /* multiselect_op ::= UNION */ case 87: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==87); -{yymsp[0].minor.yy222 = yymsp[0].major; /*A-overwrites-OP*/} +{yymsp[0].minor.yy116 = yymsp[0].major; /*A-overwrites-OP*/} break; case 86: /* multiselect_op ::= UNION ALL */ -{yymsp[-1].minor.yy222 = TK_ALL;} +{yymsp[-1].minor.yy116 = TK_ALL;} break; case 88: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { - yymsp[-8].minor.yy341 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy328,yymsp[-5].minor.yy475,yymsp[-4].minor.yy244,yymsp[-3].minor.yy328,yymsp[-2].minor.yy244,yymsp[-1].minor.yy328,yymsp[-7].minor.yy222,yymsp[0].minor.yy244); + yymsp[-8].minor.yy457 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy336,yymsp[-5].minor.yy315,yymsp[-4].minor.yy62,yymsp[-3].minor.yy336,yymsp[-2].minor.yy62,yymsp[-1].minor.yy336,yymsp[-7].minor.yy116,yymsp[0].minor.yy62); } break; case 89: /* values ::= VALUES LP nexprlist RP */ { - yymsp[-3].minor.yy341 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy328,0,0,0,0,0,SF_Values,0); + yymsp[-3].minor.yy457 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy336,0,0,0,0,0,SF_Values,0); } break; case 90: /* values ::= values COMMA LP nexprlist RP */ { - Select *pRight, *pLeft = yymsp[-4].minor.yy341; - pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy328,0,0,0,0,0,SF_Values|SF_MultiValue,0); + Select *pRight, *pLeft = yymsp[-4].minor.yy457; + pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy336,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.yy341 = pRight; + yymsp[-4].minor.yy457 = pRight; }else{ - yymsp[-4].minor.yy341 = pLeft; + yymsp[-4].minor.yy457 = pLeft; } } break; case 91: /* distinct ::= DISTINCT */ -{yymsp[0].minor.yy222 = SF_Distinct;} +{yymsp[0].minor.yy116 = SF_Distinct;} break; case 92: /* distinct ::= ALL */ -{yymsp[0].minor.yy222 = SF_All;} +{yymsp[0].minor.yy116 = SF_All;} break; case 94: /* sclp ::= */ case 127: /* orderby_opt ::= */ yytestcase(yyruleno==127); case 137: /* groupby_opt ::= */ yytestcase(yyruleno==137); - case 215: /* exprlist ::= */ yytestcase(yyruleno==215); - case 218: /* paren_exprlist ::= */ yytestcase(yyruleno==218); - case 223: /* eidlist_opt ::= */ yytestcase(yyruleno==223); -{yymsp[1].minor.yy328 = 0;} + case 222: /* exprlist ::= */ yytestcase(yyruleno==222); + case 225: /* paren_exprlist ::= */ yytestcase(yyruleno==225); + case 230: /* eidlist_opt ::= */ yytestcase(yyruleno==230); +{yymsp[1].minor.yy336 = 0;} break; case 95: /* selcollist ::= sclp scanpt expr scanpt as */ { - yymsp[-4].minor.yy328 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy328, yymsp[-2].minor.yy244); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy328, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy328,yymsp[-3].minor.yy386,yymsp[-1].minor.yy386); + yymsp[-4].minor.yy336 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy336, yymsp[-2].minor.yy62); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy336, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy336,yymsp[-3].minor.yy224,yymsp[-1].minor.yy224); } break; case 96: /* selcollist ::= sclp scanpt STAR */ { Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); - yymsp[-2].minor.yy328 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy328, p); + yymsp[-2].minor.yy336 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy336, p); } break; case 97: /* selcollist ::= sclp scanpt nm DOT STAR */ @@ -158447,56 +160619,56 @@ static YYACTIONTYPE yy_reduce( Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); - yymsp[-4].minor.yy328 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy328, pDot); + yymsp[-4].minor.yy336 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy336, pDot); } break; case 98: /* as ::= AS nm */ case 109: /* dbnm ::= DOT nm */ yytestcase(yyruleno==109); - case 239: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==239); - case 240: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==240); + case 246: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==246); + case 247: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==247); {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} break; case 100: /* from ::= */ case 103: /* stl_prefix ::= */ yytestcase(yyruleno==103); -{yymsp[1].minor.yy475 = 0;} +{yymsp[1].minor.yy315 = 0;} break; case 101: /* from ::= FROM seltablist */ { - yymsp[-1].minor.yy475 = yymsp[0].minor.yy475; - sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy475); + yymsp[-1].minor.yy315 = yymsp[0].minor.yy315; + sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy315); } break; case 102: /* stl_prefix ::= seltablist joinop */ { - if( ALWAYS(yymsp[-1].minor.yy475 && yymsp[-1].minor.yy475->nSrc>0) ) yymsp[-1].minor.yy475->a[yymsp[-1].minor.yy475->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy222; + if( ALWAYS(yymsp[-1].minor.yy315 && yymsp[-1].minor.yy315->nSrc>0) ) yymsp[-1].minor.yy315->a[yymsp[-1].minor.yy315->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy116; } break; case 104: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ { - yymsp[-6].minor.yy475 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy475,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy244,yymsp[0].minor.yy14); - sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy475, &yymsp[-2].minor.yy0); + yymsp[-6].minor.yy315 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy315,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy62,yymsp[0].minor.yy76); + sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy315, &yymsp[-2].minor.yy0); } break; case 105: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ { - yymsp[-8].minor.yy475 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy475,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy244,yymsp[0].minor.yy14); - sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy475, yymsp[-4].minor.yy328); + yymsp[-8].minor.yy315 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy315,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy62,yymsp[0].minor.yy76); + sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy315, yymsp[-4].minor.yy336); } break; case 106: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ { - yymsp[-6].minor.yy475 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy475,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy341,yymsp[-1].minor.yy244,yymsp[0].minor.yy14); + yymsp[-6].minor.yy315 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy315,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy457,yymsp[-1].minor.yy62,yymsp[0].minor.yy76); } break; case 107: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ { - if( yymsp[-6].minor.yy475==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy244==0 && yymsp[0].minor.yy14==0 ){ - yymsp[-6].minor.yy475 = yymsp[-4].minor.yy475; - }else if( yymsp[-4].minor.yy475->nSrc==1 ){ - yymsp[-6].minor.yy475 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy475,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy244,yymsp[0].minor.yy14); - if( yymsp[-6].minor.yy475 ){ - struct SrcList_item *pNew = &yymsp[-6].minor.yy475->a[yymsp[-6].minor.yy475->nSrc-1]; - struct SrcList_item *pOld = yymsp[-4].minor.yy475->a; + if( yymsp[-6].minor.yy315==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy62==0 && yymsp[0].minor.yy76==0 ){ + yymsp[-6].minor.yy315 = yymsp[-4].minor.yy315; + }else if( yymsp[-4].minor.yy315->nSrc==1 ){ + yymsp[-6].minor.yy315 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy315,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy62,yymsp[0].minor.yy76); + if( yymsp[-6].minor.yy315 ){ + SrcItem *pNew = &yymsp[-6].minor.yy315->a[yymsp[-6].minor.yy315->nSrc-1]; + SrcItem *pOld = yymsp[-4].minor.yy315->a; pNew->zName = pOld->zName; pNew->zDatabase = pOld->zDatabase; pNew->pSelect = pOld->pSelect; @@ -158509,12 +160681,12 @@ static YYACTIONTYPE yy_reduce( pOld->zName = pOld->zDatabase = 0; pOld->pSelect = 0; } - sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy475); + sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy315); }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy475); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy475,0,0,0,0,SF_NestedFrom,0); - yymsp[-6].minor.yy475 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy475,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy244,yymsp[0].minor.yy14); + sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy315); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy315,0,0,0,0,SF_NestedFrom,0); + yymsp[-6].minor.yy315 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy315,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy62,yymsp[0].minor.yy76); } } break; @@ -158524,63 +160696,65 @@ static YYACTIONTYPE yy_reduce( break; case 110: /* fullname ::= nm */ { - yylhsminor.yy475 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); - if( IN_RENAME_OBJECT && yylhsminor.yy475 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy475->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy315 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); + if( IN_RENAME_OBJECT && yylhsminor.yy315 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy315->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy475 = yylhsminor.yy475; + yymsp[0].minor.yy315 = yylhsminor.yy315; break; case 111: /* fullname ::= nm DOT nm */ { - yylhsminor.yy475 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); - if( IN_RENAME_OBJECT && yylhsminor.yy475 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy475->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy315 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + if( IN_RENAME_OBJECT && yylhsminor.yy315 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy315->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy475 = yylhsminor.yy475; + yymsp[-2].minor.yy315 = yylhsminor.yy315; break; case 112: /* xfullname ::= nm */ -{yymsp[0].minor.yy475 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} +{yymsp[0].minor.yy315 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} break; case 113: /* xfullname ::= nm DOT nm */ -{yymsp[-2].minor.yy475 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} +{yymsp[-2].minor.yy315 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} break; case 114: /* xfullname ::= nm DOT nm AS nm */ { - yymsp[-4].minor.yy475 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ - if( yymsp[-4].minor.yy475 ) yymsp[-4].minor.yy475->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-4].minor.yy315 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ + if( yymsp[-4].minor.yy315 ) yymsp[-4].minor.yy315->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; case 115: /* xfullname ::= nm AS nm */ { - yymsp[-2].minor.yy475 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ - if( yymsp[-2].minor.yy475 ) yymsp[-2].minor.yy475->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-2].minor.yy315 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ + if( yymsp[-2].minor.yy315 ) yymsp[-2].minor.yy315->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; case 116: /* joinop ::= COMMA|JOIN */ -{ yymsp[0].minor.yy222 = JT_INNER; } +{ yymsp[0].minor.yy116 = JT_INNER; } break; case 117: /* joinop ::= JOIN_KW JOIN */ -{yymsp[-1].minor.yy222 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} +{yymsp[-1].minor.yy116 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} break; case 118: /* joinop ::= JOIN_KW nm JOIN */ -{yymsp[-2].minor.yy222 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} +{yymsp[-2].minor.yy116 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} break; case 119: /* joinop ::= JOIN_KW nm nm JOIN */ -{yymsp[-3].minor.yy222 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} +{yymsp[-3].minor.yy116 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} break; case 120: /* on_opt ::= ON expr */ case 140: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==140); case 147: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==147); - case 211: /* case_else ::= ELSE expr */ yytestcase(yyruleno==211); - case 232: /* vinto ::= INTO expr */ yytestcase(yyruleno==232); -{yymsp[-1].minor.yy244 = yymsp[0].minor.yy244;} + case 149: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==149); + case 218: /* case_else ::= ELSE expr */ yytestcase(yyruleno==218); + case 239: /* vinto ::= INTO expr */ yytestcase(yyruleno==239); +{yymsp[-1].minor.yy62 = yymsp[0].minor.yy62;} break; case 121: /* on_opt ::= */ case 139: /* having_opt ::= */ yytestcase(yyruleno==139); case 141: /* limit_opt ::= */ yytestcase(yyruleno==141); case 146: /* where_opt ::= */ yytestcase(yyruleno==146); - case 212: /* case_else ::= */ yytestcase(yyruleno==212); - case 214: /* case_operand ::= */ yytestcase(yyruleno==214); - case 233: /* vinto ::= */ yytestcase(yyruleno==233); -{yymsp[1].minor.yy244 = 0;} + case 148: /* where_opt_ret ::= */ yytestcase(yyruleno==148); + case 219: /* case_else ::= */ yytestcase(yyruleno==219); + case 221: /* case_operand ::= */ yytestcase(yyruleno==221); + case 240: /* vinto ::= */ yytestcase(yyruleno==240); +{yymsp[1].minor.yy62 = 0;} break; case 123: /* indexed_opt ::= INDEXED BY nm */ {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} @@ -158589,129 +160763,144 @@ static YYACTIONTYPE yy_reduce( {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} break; case 125: /* using_opt ::= USING LP idlist RP */ -{yymsp[-3].minor.yy14 = yymsp[-1].minor.yy14;} +{yymsp[-3].minor.yy76 = yymsp[-1].minor.yy76;} break; case 126: /* using_opt ::= */ - case 161: /* idlist_opt ::= */ yytestcase(yyruleno==161); -{yymsp[1].minor.yy14 = 0;} + case 168: /* idlist_opt ::= */ yytestcase(yyruleno==168); +{yymsp[1].minor.yy76 = 0;} break; case 128: /* orderby_opt ::= ORDER BY sortlist */ case 138: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==138); -{yymsp[-2].minor.yy328 = yymsp[0].minor.yy328;} +{yymsp[-2].minor.yy336 = yymsp[0].minor.yy336;} break; case 129: /* sortlist ::= sortlist COMMA expr sortorder nulls */ { - yymsp[-4].minor.yy328 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy328,yymsp[-2].minor.yy244); - sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy328,yymsp[-1].minor.yy222,yymsp[0].minor.yy222); + yymsp[-4].minor.yy336 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy336,yymsp[-2].minor.yy62); + sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy336,yymsp[-1].minor.yy116,yymsp[0].minor.yy116); } break; case 130: /* sortlist ::= expr sortorder nulls */ { - yymsp[-2].minor.yy328 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy244); /*A-overwrites-Y*/ - sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy328,yymsp[-1].minor.yy222,yymsp[0].minor.yy222); + yymsp[-2].minor.yy336 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy62); /*A-overwrites-Y*/ + sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy336,yymsp[-1].minor.yy116,yymsp[0].minor.yy116); } break; case 131: /* sortorder ::= ASC */ -{yymsp[0].minor.yy222 = SQLITE_SO_ASC;} +{yymsp[0].minor.yy116 = SQLITE_SO_ASC;} break; case 132: /* sortorder ::= DESC */ -{yymsp[0].minor.yy222 = SQLITE_SO_DESC;} +{yymsp[0].minor.yy116 = SQLITE_SO_DESC;} break; case 133: /* sortorder ::= */ case 136: /* nulls ::= */ yytestcase(yyruleno==136); -{yymsp[1].minor.yy222 = SQLITE_SO_UNDEFINED;} +{yymsp[1].minor.yy116 = SQLITE_SO_UNDEFINED;} break; case 134: /* nulls ::= NULLS FIRST */ -{yymsp[-1].minor.yy222 = SQLITE_SO_ASC;} +{yymsp[-1].minor.yy116 = SQLITE_SO_ASC;} break; case 135: /* nulls ::= NULLS LAST */ -{yymsp[-1].minor.yy222 = SQLITE_SO_DESC;} +{yymsp[-1].minor.yy116 = SQLITE_SO_DESC;} break; case 142: /* limit_opt ::= LIMIT expr */ -{yymsp[-1].minor.yy244 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy244,0);} +{yymsp[-1].minor.yy62 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy62,0);} break; case 143: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yymsp[-3].minor.yy244 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy244,yymsp[0].minor.yy244);} +{yymsp[-3].minor.yy62 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy62,yymsp[0].minor.yy62);} break; case 144: /* limit_opt ::= LIMIT expr COMMA expr */ -{yymsp[-3].minor.yy244 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy244,yymsp[-2].minor.yy244);} +{yymsp[-3].minor.yy62 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy62,yymsp[-2].minor.yy62);} break; - case 145: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ + case 145: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy475, &yymsp[-1].minor.yy0); - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy475,yymsp[0].minor.yy244,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy315, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy315,yymsp[0].minor.yy62,0,0); } break; - case 148: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt */ + case 150: /* where_opt_ret ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy336); yymsp[-1].minor.yy62 = 0;} + break; + case 151: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy336); yymsp[-3].minor.yy62 = yymsp[-2].minor.yy62;} + break; + case 152: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy475, &yymsp[-4].minor.yy0); - sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy328,"set list"); - yymsp[-5].minor.yy475 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy475, yymsp[-1].minor.yy475); - sqlite3Update(pParse,yymsp[-5].minor.yy475,yymsp[-2].minor.yy328,yymsp[0].minor.yy244,yymsp[-6].minor.yy222,0,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy315, &yymsp[-4].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy336,"set list"); + yymsp[-5].minor.yy315 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy315, yymsp[-1].minor.yy315); + sqlite3Update(pParse,yymsp[-5].minor.yy315,yymsp[-2].minor.yy336,yymsp[0].minor.yy62,yymsp[-6].minor.yy116,0,0,0); } break; - case 149: /* setlist ::= setlist COMMA nm EQ expr */ + case 153: /* setlist ::= setlist COMMA nm EQ expr */ { - yymsp[-4].minor.yy328 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy328, yymsp[0].minor.yy244); - sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy328, &yymsp[-2].minor.yy0, 1); + yymsp[-4].minor.yy336 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy336, yymsp[0].minor.yy62); + sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy336, &yymsp[-2].minor.yy0, 1); } break; - case 150: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ + case 154: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ { - yymsp[-6].minor.yy328 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy328, yymsp[-3].minor.yy14, yymsp[0].minor.yy244); + yymsp[-6].minor.yy336 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy336, yymsp[-3].minor.yy76, yymsp[0].minor.yy62); } break; - case 151: /* setlist ::= nm EQ expr */ + case 155: /* setlist ::= nm EQ expr */ { - yylhsminor.yy328 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy244); - sqlite3ExprListSetName(pParse, yylhsminor.yy328, &yymsp[-2].minor.yy0, 1); + yylhsminor.yy336 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy62); + sqlite3ExprListSetName(pParse, yylhsminor.yy336, &yymsp[-2].minor.yy0, 1); } - yymsp[-2].minor.yy328 = yylhsminor.yy328; + yymsp[-2].minor.yy336 = yylhsminor.yy336; break; - case 152: /* setlist ::= LP idlist RP EQ expr */ + case 156: /* setlist ::= LP idlist RP EQ expr */ { - yymsp[-4].minor.yy328 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy14, yymsp[0].minor.yy244); + yymsp[-4].minor.yy336 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy76, yymsp[0].minor.yy62); } break; - case 153: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + case 157: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy475, yymsp[-1].minor.yy341, yymsp[-2].minor.yy14, yymsp[-5].minor.yy222, yymsp[0].minor.yy90); + sqlite3Insert(pParse, yymsp[-3].minor.yy315, yymsp[-1].minor.yy457, yymsp[-2].minor.yy76, yymsp[-5].minor.yy116, yymsp[0].minor.yy402); } break; - case 154: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ + case 158: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy475, 0, yymsp[-2].minor.yy14, yymsp[-5].minor.yy222, 0); + sqlite3Insert(pParse, yymsp[-4].minor.yy315, 0, yymsp[-3].minor.yy76, yymsp[-6].minor.yy116, 0); } break; - case 155: /* upsert ::= */ -{ yymsp[1].minor.yy90 = 0; } + case 159: /* upsert ::= */ +{ yymsp[1].minor.yy402 = 0; } + break; + case 160: /* upsert ::= RETURNING selcollist */ +{ yymsp[-1].minor.yy402 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy336); } break; - case 156: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ -{ yymsp[-10].minor.yy90 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy328,yymsp[-5].minor.yy244,yymsp[-1].minor.yy328,yymsp[0].minor.yy244);} + case 161: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ +{ yymsp[-11].minor.yy402 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy336,yymsp[-6].minor.yy62,yymsp[-2].minor.yy336,yymsp[-1].minor.yy62,yymsp[0].minor.yy402);} break; - case 157: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ -{ yymsp[-7].minor.yy90 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy328,yymsp[-2].minor.yy244,0,0); } + case 162: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ +{ yymsp[-8].minor.yy402 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy336,yymsp[-3].minor.yy62,0,0,yymsp[0].minor.yy402); } break; - case 158: /* upsert ::= ON CONFLICT DO NOTHING */ -{ yymsp[-3].minor.yy90 = sqlite3UpsertNew(pParse->db,0,0,0,0); } + case 163: /* upsert ::= ON CONFLICT DO NOTHING returning */ +{ yymsp[-4].minor.yy402 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } break; - case 162: /* idlist_opt ::= LP idlist RP */ -{yymsp[-2].minor.yy14 = yymsp[-1].minor.yy14;} + case 164: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ +{ yymsp[-7].minor.yy402 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy336,yymsp[-1].minor.yy62,0);} break; - case 163: /* idlist ::= idlist COMMA nm */ -{yymsp[-2].minor.yy14 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy14,&yymsp[0].minor.yy0);} + case 165: /* returning ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy336);} break; - case 164: /* idlist ::= nm */ -{yymsp[0].minor.yy14 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} + case 169: /* idlist_opt ::= LP idlist RP */ +{yymsp[-2].minor.yy76 = yymsp[-1].minor.yy76;} break; - case 165: /* expr ::= LP expr RP */ -{yymsp[-2].minor.yy244 = yymsp[-1].minor.yy244;} + case 170: /* idlist ::= idlist COMMA nm */ +{yymsp[-2].minor.yy76 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy76,&yymsp[0].minor.yy0);} break; - case 166: /* expr ::= ID|INDEXED */ - case 167: /* expr ::= JOIN_KW */ yytestcase(yyruleno==167); -{yymsp[0].minor.yy244=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 171: /* idlist ::= nm */ +{yymsp[0].minor.yy76 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} break; - case 168: /* expr ::= nm DOT nm */ + case 172: /* expr ::= LP expr RP */ +{yymsp[-2].minor.yy62 = yymsp[-1].minor.yy62;} + break; + case 173: /* expr ::= ID|INDEXED */ + case 174: /* expr ::= JOIN_KW */ yytestcase(yyruleno==174); +{yymsp[0].minor.yy62=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} + break; + case 175: /* 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); @@ -158719,11 +160908,11 @@ static YYACTIONTYPE yy_reduce( sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0); sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0); } - yylhsminor.yy244 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); + yylhsminor.yy62 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } - yymsp[-2].minor.yy244 = yylhsminor.yy244; + yymsp[-2].minor.yy62 = yylhsminor.yy62; break; - case 169: /* expr ::= nm DOT nm DOT nm */ + case 176: /* 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); @@ -158733,26 +160922,26 @@ static YYACTIONTYPE yy_reduce( sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0); sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0); } - yylhsminor.yy244 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); + yylhsminor.yy62 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } - yymsp[-4].minor.yy244 = yylhsminor.yy244; + yymsp[-4].minor.yy62 = yylhsminor.yy62; break; - case 170: /* term ::= NULL|FLOAT|BLOB */ - case 171: /* term ::= STRING */ yytestcase(yyruleno==171); -{yymsp[0].minor.yy244=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 177: /* term ::= NULL|FLOAT|BLOB */ + case 178: /* term ::= STRING */ yytestcase(yyruleno==178); +{yymsp[0].minor.yy62=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 172: /* term ::= INTEGER */ + case 179: /* term ::= INTEGER */ { - yylhsminor.yy244 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); + yylhsminor.yy62 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); } - yymsp[0].minor.yy244 = yylhsminor.yy244; + yymsp[0].minor.yy62 = yylhsminor.yy62; break; - case 173: /* expr ::= VARIABLE */ + case 180: /* 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.yy244 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy244, n); + yymsp[0].minor.yy62 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy62, 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 @@ -158761,145 +160950,145 @@ static YYACTIONTYPE yy_reduce( assert( t.n>=2 ); if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); - yymsp[0].minor.yy244 = 0; + yymsp[0].minor.yy62 = 0; }else{ - yymsp[0].minor.yy244 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); - if( yymsp[0].minor.yy244 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy244->iTable); + yymsp[0].minor.yy62 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( yymsp[0].minor.yy62 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy62->iTable); } } } break; - case 174: /* expr ::= expr COLLATE ID|STRING */ + case 181: /* expr ::= expr COLLATE ID|STRING */ { - yymsp[-2].minor.yy244 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy244, &yymsp[0].minor.yy0, 1); + yymsp[-2].minor.yy62 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy62, &yymsp[0].minor.yy0, 1); } break; - case 175: /* expr ::= CAST LP expr AS typetoken RP */ + case 182: /* expr ::= CAST LP expr AS typetoken RP */ { - yymsp[-5].minor.yy244 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); - sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy244, yymsp[-3].minor.yy244, 0); + yymsp[-5].minor.yy62 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); + sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy62, yymsp[-3].minor.yy62, 0); } break; - case 176: /* expr ::= ID|INDEXED LP distinct exprlist RP */ + case 183: /* expr ::= ID|INDEXED LP distinct exprlist RP */ { - yylhsminor.yy244 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy328, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy222); + yylhsminor.yy62 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy336, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy116); } - yymsp[-4].minor.yy244 = yylhsminor.yy244; + yymsp[-4].minor.yy62 = yylhsminor.yy62; break; - case 177: /* expr ::= ID|INDEXED LP STAR RP */ + case 184: /* expr ::= ID|INDEXED LP STAR RP */ { - yylhsminor.yy244 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); + yylhsminor.yy62 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } - yymsp[-3].minor.yy244 = yylhsminor.yy244; + yymsp[-3].minor.yy62 = yylhsminor.yy62; break; - case 178: /* term ::= CTIME_KW */ + case 185: /* term ::= CTIME_KW */ { - yylhsminor.yy244 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); + yylhsminor.yy62 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } - yymsp[0].minor.yy244 = yylhsminor.yy244; + yymsp[0].minor.yy62 = yylhsminor.yy62; break; - case 179: /* expr ::= LP nexprlist COMMA expr RP */ + case 186: /* expr ::= LP nexprlist COMMA expr RP */ { - ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy328, yymsp[-1].minor.yy244); - yymsp[-4].minor.yy244 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); - if( yymsp[-4].minor.yy244 ){ - yymsp[-4].minor.yy244->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy336, yymsp[-1].minor.yy62); + yymsp[-4].minor.yy62 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( yymsp[-4].minor.yy62 ){ + yymsp[-4].minor.yy62->x.pList = pList; if( ALWAYS(pList->nExpr) ){ - yymsp[-4].minor.yy244->flags |= pList->a[0].pExpr->flags & EP_Propagate; + yymsp[-4].minor.yy62->flags |= pList->a[0].pExpr->flags & EP_Propagate; } }else{ sqlite3ExprListDelete(pParse->db, pList); } } break; - case 180: /* expr ::= expr AND expr */ -{yymsp[-2].minor.yy244=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy244,yymsp[0].minor.yy244);} + case 187: /* expr ::= expr AND expr */ +{yymsp[-2].minor.yy62=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy62,yymsp[0].minor.yy62);} break; - case 181: /* expr ::= expr OR expr */ - case 182: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==182); - case 183: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==183); - case 184: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==184); - case 185: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==185); - case 186: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==186); - case 187: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==187); -{yymsp[-2].minor.yy244=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy244,yymsp[0].minor.yy244);} + case 188: /* expr ::= expr OR expr */ + case 189: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==189); + case 190: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==190); + case 191: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==191); + case 192: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==192); + case 193: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==193); + case 194: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==194); +{yymsp[-2].minor.yy62=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy62,yymsp[0].minor.yy62);} break; - case 188: /* likeop ::= NOT LIKE_KW|MATCH */ + case 195: /* 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 189: /* expr ::= expr likeop expr */ + case 196: /* 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.yy244); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy244); - yymsp[-2].minor.yy244 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); - if( bNot ) yymsp[-2].minor.yy244 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy244, 0); - if( yymsp[-2].minor.yy244 ) yymsp[-2].minor.yy244->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy62); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy62); + yymsp[-2].minor.yy62 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + if( bNot ) yymsp[-2].minor.yy62 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy62, 0); + if( yymsp[-2].minor.yy62 ) yymsp[-2].minor.yy62->flags |= EP_InfixFunc; } break; - case 190: /* expr ::= expr likeop expr ESCAPE expr */ + case 197: /* 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.yy244); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy244); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy244); - yymsp[-4].minor.yy244 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); - if( bNot ) yymsp[-4].minor.yy244 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy244, 0); - if( yymsp[-4].minor.yy244 ) yymsp[-4].minor.yy244->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy62); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy62); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy62); + yymsp[-4].minor.yy62 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); + if( bNot ) yymsp[-4].minor.yy62 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy62, 0); + if( yymsp[-4].minor.yy62 ) yymsp[-4].minor.yy62->flags |= EP_InfixFunc; } break; - case 191: /* expr ::= expr ISNULL|NOTNULL */ -{yymsp[-1].minor.yy244 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy244,0);} + case 198: /* expr ::= expr ISNULL|NOTNULL */ +{yymsp[-1].minor.yy62 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy62,0);} break; - case 192: /* expr ::= expr NOT NULL */ -{yymsp[-2].minor.yy244 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy244,0);} + case 199: /* expr ::= expr NOT NULL */ +{yymsp[-2].minor.yy62 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy62,0);} break; - case 193: /* expr ::= expr IS expr */ + case 200: /* expr ::= expr IS expr */ { - yymsp[-2].minor.yy244 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy244,yymsp[0].minor.yy244); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy244, yymsp[-2].minor.yy244, TK_ISNULL); + yymsp[-2].minor.yy62 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy62,yymsp[0].minor.yy62); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy62, yymsp[-2].minor.yy62, TK_ISNULL); } break; - case 194: /* expr ::= expr IS NOT expr */ + case 201: /* expr ::= expr IS NOT expr */ { - yymsp[-3].minor.yy244 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy244,yymsp[0].minor.yy244); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy244, yymsp[-3].minor.yy244, TK_NOTNULL); + yymsp[-3].minor.yy62 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy62,yymsp[0].minor.yy62); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy62, yymsp[-3].minor.yy62, TK_NOTNULL); } break; - case 195: /* expr ::= NOT expr */ - case 196: /* expr ::= BITNOT expr */ yytestcase(yyruleno==196); -{yymsp[-1].minor.yy244 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy244, 0);/*A-overwrites-B*/} + case 202: /* expr ::= NOT expr */ + case 203: /* expr ::= BITNOT expr */ yytestcase(yyruleno==203); +{yymsp[-1].minor.yy62 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy62, 0);/*A-overwrites-B*/} break; - case 197: /* expr ::= PLUS|MINUS expr */ + case 204: /* expr ::= PLUS|MINUS expr */ { - yymsp[-1].minor.yy244 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy244, 0); + yymsp[-1].minor.yy62 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy62, 0); /*A-overwrites-B*/ } break; - case 198: /* between_op ::= BETWEEN */ - case 201: /* in_op ::= IN */ yytestcase(yyruleno==201); -{yymsp[0].minor.yy222 = 0;} + case 205: /* between_op ::= BETWEEN */ + case 208: /* in_op ::= IN */ yytestcase(yyruleno==208); +{yymsp[0].minor.yy116 = 0;} break; - case 200: /* expr ::= expr between_op expr AND expr */ + case 207: /* expr ::= expr between_op expr AND expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy244); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy244); - yymsp[-4].minor.yy244 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy244, 0); - if( yymsp[-4].minor.yy244 ){ - yymsp[-4].minor.yy244->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy62); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy62); + yymsp[-4].minor.yy62 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy62, 0); + if( yymsp[-4].minor.yy62 ){ + yymsp[-4].minor.yy62->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } - if( yymsp[-3].minor.yy222 ) yymsp[-4].minor.yy244 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy244, 0); + if( yymsp[-3].minor.yy116 ) yymsp[-4].minor.yy62 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy62, 0); } break; - case 203: /* expr ::= expr in_op LP exprlist RP */ + case 210: /* expr ::= expr in_op LP exprlist RP */ { - if( yymsp[-1].minor.yy328==0 ){ + if( yymsp[-1].minor.yy336==0 ){ /* Expressions of the form ** ** expr1 IN () @@ -158908,197 +161097,197 @@ static YYACTIONTYPE yy_reduce( ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ - sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy244); - yymsp[-4].minor.yy244 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy222 ? "1" : "0"); - }else if( yymsp[-1].minor.yy328->nExpr==1 && sqlite3ExprIsConstant(yymsp[-1].minor.yy328->a[0].pExpr) ){ - Expr *pRHS = yymsp[-1].minor.yy328->a[0].pExpr; - yymsp[-1].minor.yy328->a[0].pExpr = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy328); + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy62); + yymsp[-4].minor.yy62 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy116 ? "1" : "0"); + }else if( yymsp[-1].minor.yy336->nExpr==1 && sqlite3ExprIsConstant(yymsp[-1].minor.yy336->a[0].pExpr) ){ + Expr *pRHS = yymsp[-1].minor.yy336->a[0].pExpr; + yymsp[-1].minor.yy336->a[0].pExpr = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy336); pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); - yymsp[-4].minor.yy244 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy244, pRHS); - if( yymsp[-3].minor.yy222 ) yymsp[-4].minor.yy244 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy244, 0); + yymsp[-4].minor.yy62 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy62, pRHS); + if( yymsp[-3].minor.yy116 ) yymsp[-4].minor.yy62 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy62, 0); }else{ - yymsp[-4].minor.yy244 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy244, 0); - if( yymsp[-4].minor.yy244 ){ - yymsp[-4].minor.yy244->x.pList = yymsp[-1].minor.yy328; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy244); + yymsp[-4].minor.yy62 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy62, 0); + if( yymsp[-4].minor.yy62 ){ + yymsp[-4].minor.yy62->x.pList = yymsp[-1].minor.yy336; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy62); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy328); + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy336); } - if( yymsp[-3].minor.yy222 ) yymsp[-4].minor.yy244 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy244, 0); + if( yymsp[-3].minor.yy116 ) yymsp[-4].minor.yy62 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy62, 0); } } break; - case 204: /* expr ::= LP select RP */ + case 211: /* expr ::= LP select RP */ { - yymsp[-2].minor.yy244 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); - sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy244, yymsp[-1].minor.yy341); + yymsp[-2].minor.yy62 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy62, yymsp[-1].minor.yy457); } break; - case 205: /* expr ::= expr in_op LP select RP */ + case 212: /* expr ::= expr in_op LP select RP */ { - yymsp[-4].minor.yy244 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy244, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy244, yymsp[-1].minor.yy341); - if( yymsp[-3].minor.yy222 ) yymsp[-4].minor.yy244 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy244, 0); + yymsp[-4].minor.yy62 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy62, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy62, yymsp[-1].minor.yy457); + if( yymsp[-3].minor.yy116 ) yymsp[-4].minor.yy62 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy62, 0); } break; - case 206: /* expr ::= expr in_op nm dbnm paren_exprlist */ + case 213: /* 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.yy328 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy328); - yymsp[-4].minor.yy244 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy244, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy244, pSelect); - if( yymsp[-3].minor.yy222 ) yymsp[-4].minor.yy244 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy244, 0); + if( yymsp[0].minor.yy336 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy336); + yymsp[-4].minor.yy62 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy62, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy62, pSelect); + if( yymsp[-3].minor.yy116 ) yymsp[-4].minor.yy62 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy62, 0); } break; - case 207: /* expr ::= EXISTS LP select RP */ + case 214: /* expr ::= EXISTS LP select RP */ { Expr *p; - p = yymsp[-3].minor.yy244 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); - sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy341); + p = yymsp[-3].minor.yy62 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy457); } break; - case 208: /* expr ::= CASE case_operand case_exprlist case_else END */ + case 215: /* expr ::= CASE case_operand case_exprlist case_else END */ { - yymsp[-4].minor.yy244 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy244, 0); - if( yymsp[-4].minor.yy244 ){ - yymsp[-4].minor.yy244->x.pList = yymsp[-1].minor.yy244 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy328,yymsp[-1].minor.yy244) : yymsp[-2].minor.yy328; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy244); + yymsp[-4].minor.yy62 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy62, 0); + if( yymsp[-4].minor.yy62 ){ + yymsp[-4].minor.yy62->x.pList = yymsp[-1].minor.yy62 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy336,yymsp[-1].minor.yy62) : yymsp[-2].minor.yy336; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy62); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy328); - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy244); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy336); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy62); } } break; - case 209: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + case 216: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { - yymsp[-4].minor.yy328 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy328, yymsp[-2].minor.yy244); - yymsp[-4].minor.yy328 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy328, yymsp[0].minor.yy244); + yymsp[-4].minor.yy336 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy336, yymsp[-2].minor.yy62); + yymsp[-4].minor.yy336 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy336, yymsp[0].minor.yy62); } break; - case 210: /* case_exprlist ::= WHEN expr THEN expr */ + case 217: /* case_exprlist ::= WHEN expr THEN expr */ { - yymsp[-3].minor.yy328 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy244); - yymsp[-3].minor.yy328 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy328, yymsp[0].minor.yy244); + yymsp[-3].minor.yy336 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy62); + yymsp[-3].minor.yy336 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy336, yymsp[0].minor.yy62); } break; - case 213: /* case_operand ::= expr */ -{yymsp[0].minor.yy244 = yymsp[0].minor.yy244; /*A-overwrites-X*/} + case 220: /* case_operand ::= expr */ +{yymsp[0].minor.yy62 = yymsp[0].minor.yy62; /*A-overwrites-X*/} break; - case 216: /* nexprlist ::= nexprlist COMMA expr */ -{yymsp[-2].minor.yy328 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy328,yymsp[0].minor.yy244);} + case 223: /* nexprlist ::= nexprlist COMMA expr */ +{yymsp[-2].minor.yy336 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy336,yymsp[0].minor.yy62);} break; - case 217: /* nexprlist ::= expr */ -{yymsp[0].minor.yy328 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy244); /*A-overwrites-Y*/} + case 224: /* nexprlist ::= expr */ +{yymsp[0].minor.yy336 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy62); /*A-overwrites-Y*/} break; - case 219: /* paren_exprlist ::= LP exprlist RP */ - case 224: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==224); -{yymsp[-2].minor.yy328 = yymsp[-1].minor.yy328;} + case 226: /* paren_exprlist ::= LP exprlist RP */ + case 231: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==231); +{yymsp[-2].minor.yy336 = yymsp[-1].minor.yy336;} break; - case 220: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + case 227: /* 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.yy328, yymsp[-10].minor.yy222, - &yymsp[-11].minor.yy0, yymsp[0].minor.yy244, SQLITE_SO_ASC, yymsp[-8].minor.yy222, SQLITE_IDXTYPE_APPDEF); + sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy336, yymsp[-10].minor.yy116, + &yymsp[-11].minor.yy0, yymsp[0].minor.yy62, SQLITE_SO_ASC, yymsp[-8].minor.yy116, SQLITE_IDXTYPE_APPDEF); if( IN_RENAME_OBJECT && pParse->pNewIndex ){ sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); } } break; - case 221: /* uniqueflag ::= UNIQUE */ - case 263: /* raisetype ::= ABORT */ yytestcase(yyruleno==263); -{yymsp[0].minor.yy222 = OE_Abort;} + case 228: /* uniqueflag ::= UNIQUE */ + case 270: /* raisetype ::= ABORT */ yytestcase(yyruleno==270); +{yymsp[0].minor.yy116 = OE_Abort;} break; - case 222: /* uniqueflag ::= */ -{yymsp[1].minor.yy222 = OE_None;} + case 229: /* uniqueflag ::= */ +{yymsp[1].minor.yy116 = OE_None;} break; - case 225: /* eidlist ::= eidlist COMMA nm collate sortorder */ + case 232: /* eidlist ::= eidlist COMMA nm collate sortorder */ { - yymsp[-4].minor.yy328 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy328, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy222, yymsp[0].minor.yy222); + yymsp[-4].minor.yy336 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy336, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy116, yymsp[0].minor.yy116); } break; - case 226: /* eidlist ::= nm collate sortorder */ + case 233: /* eidlist ::= nm collate sortorder */ { - yymsp[-2].minor.yy328 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy222, yymsp[0].minor.yy222); /*A-overwrites-Y*/ + yymsp[-2].minor.yy336 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy116, yymsp[0].minor.yy116); /*A-overwrites-Y*/ } break; - case 229: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy475, yymsp[-1].minor.yy222);} + case 236: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy315, yymsp[-1].minor.yy116);} break; - case 230: /* cmd ::= VACUUM vinto */ -{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy244);} + case 237: /* cmd ::= VACUUM vinto */ +{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy62);} break; - case 231: /* cmd ::= VACUUM nm vinto */ -{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy244);} + case 238: /* cmd ::= VACUUM nm vinto */ +{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy62);} break; - case 234: /* cmd ::= PRAGMA nm dbnm */ + case 241: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 235: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ + case 242: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; - case 236: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ + case 243: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; - case 237: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ + case 244: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; - case 238: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ + case 245: /* 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 241: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + case 248: /* 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.yy39, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy441, &all); } break; - case 242: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 249: /* 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.yy222, yymsp[-4].minor.yy168.a, yymsp[-4].minor.yy168.b, yymsp[-2].minor.yy475, yymsp[0].minor.yy244, yymsp[-10].minor.yy222, yymsp[-8].minor.yy222); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy116, yymsp[-4].minor.yy440.a, yymsp[-4].minor.yy440.b, yymsp[-2].minor.yy315, yymsp[0].minor.yy62, yymsp[-10].minor.yy116, yymsp[-8].minor.yy116); yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ } break; - case 243: /* trigger_time ::= BEFORE|AFTER */ -{ yymsp[0].minor.yy222 = yymsp[0].major; /*A-overwrites-X*/ } + case 250: /* trigger_time ::= BEFORE|AFTER */ +{ yymsp[0].minor.yy116 = yymsp[0].major; /*A-overwrites-X*/ } break; - case 244: /* trigger_time ::= INSTEAD OF */ -{ yymsp[-1].minor.yy222 = TK_INSTEAD;} + case 251: /* trigger_time ::= INSTEAD OF */ +{ yymsp[-1].minor.yy116 = TK_INSTEAD;} break; - case 245: /* trigger_time ::= */ -{ yymsp[1].minor.yy222 = TK_BEFORE; } + case 252: /* trigger_time ::= */ +{ yymsp[1].minor.yy116 = TK_BEFORE; } break; - case 246: /* trigger_event ::= DELETE|INSERT */ - case 247: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==247); -{yymsp[0].minor.yy168.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy168.b = 0;} + case 253: /* trigger_event ::= DELETE|INSERT */ + case 254: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==254); +{yymsp[0].minor.yy440.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy440.b = 0;} break; - case 248: /* trigger_event ::= UPDATE OF idlist */ -{yymsp[-2].minor.yy168.a = TK_UPDATE; yymsp[-2].minor.yy168.b = yymsp[0].minor.yy14;} + case 255: /* trigger_event ::= UPDATE OF idlist */ +{yymsp[-2].minor.yy440.a = TK_UPDATE; yymsp[-2].minor.yy440.b = yymsp[0].minor.yy76;} break; - case 249: /* when_clause ::= */ - case 268: /* key_opt ::= */ yytestcase(yyruleno==268); -{ yymsp[1].minor.yy244 = 0; } + case 256: /* when_clause ::= */ + case 275: /* key_opt ::= */ yytestcase(yyruleno==275); +{ yymsp[1].minor.yy62 = 0; } break; - case 250: /* when_clause ::= WHEN expr */ - case 269: /* key_opt ::= KEY expr */ yytestcase(yyruleno==269); -{ yymsp[-1].minor.yy244 = yymsp[0].minor.yy244; } + case 257: /* when_clause ::= WHEN expr */ + case 276: /* key_opt ::= KEY expr */ yytestcase(yyruleno==276); +{ yymsp[-1].minor.yy62 = yymsp[0].minor.yy62; } break; - case 251: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 258: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { - assert( yymsp[-2].minor.yy39!=0 ); - yymsp[-2].minor.yy39->pLast->pNext = yymsp[-1].minor.yy39; - yymsp[-2].minor.yy39->pLast = yymsp[-1].minor.yy39; + assert( yymsp[-2].minor.yy441!=0 ); + yymsp[-2].minor.yy441->pLast->pNext = yymsp[-1].minor.yy441; + yymsp[-2].minor.yy441->pLast = yymsp[-1].minor.yy441; } break; - case 252: /* trigger_cmd_list ::= trigger_cmd SEMI */ + case 259: /* trigger_cmd_list ::= trigger_cmd SEMI */ { - assert( yymsp[-1].minor.yy39!=0 ); - yymsp[-1].minor.yy39->pLast = yymsp[-1].minor.yy39; + assert( yymsp[-1].minor.yy441!=0 ); + yymsp[-1].minor.yy441->pLast = yymsp[-1].minor.yy441; } break; - case 253: /* trnm ::= nm DOT nm */ + case 260: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, @@ -159106,190 +161295,210 @@ static YYACTIONTYPE yy_reduce( "statements within triggers"); } break; - case 254: /* tridxby ::= INDEXED BY nm */ + case 261: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 255: /* tridxby ::= NOT INDEXED */ + case 262: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 256: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ -{yylhsminor.yy39 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy475, yymsp[-3].minor.yy328, yymsp[-1].minor.yy244, yymsp[-7].minor.yy222, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy386);} - yymsp[-8].minor.yy39 = yylhsminor.yy39; + case 263: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ +{yylhsminor.yy441 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy315, yymsp[-3].minor.yy336, yymsp[-1].minor.yy62, yymsp[-7].minor.yy116, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy224);} + yymsp[-8].minor.yy441 = yylhsminor.yy441; break; - case 257: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + case 264: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ { - yylhsminor.yy39 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy14,yymsp[-2].minor.yy341,yymsp[-6].minor.yy222,yymsp[-1].minor.yy90,yymsp[-7].minor.yy386,yymsp[0].minor.yy386);/*yylhsminor.yy39-overwrites-yymsp[-6].minor.yy222*/ + yylhsminor.yy441 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy76,yymsp[-2].minor.yy457,yymsp[-6].minor.yy116,yymsp[-1].minor.yy402,yymsp[-7].minor.yy224,yymsp[0].minor.yy224);/*yylhsminor.yy441-overwrites-yymsp[-6].minor.yy116*/ } - yymsp[-7].minor.yy39 = yylhsminor.yy39; + yymsp[-7].minor.yy441 = yylhsminor.yy441; break; - case 258: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -{yylhsminor.yy39 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy244, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy386);} - yymsp[-5].minor.yy39 = yylhsminor.yy39; + case 265: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ +{yylhsminor.yy441 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy62, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy224);} + yymsp[-5].minor.yy441 = yylhsminor.yy441; break; - case 259: /* trigger_cmd ::= scanpt select scanpt */ -{yylhsminor.yy39 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy341, yymsp[-2].minor.yy386, yymsp[0].minor.yy386); /*yylhsminor.yy39-overwrites-yymsp[-1].minor.yy341*/} - yymsp[-2].minor.yy39 = yylhsminor.yy39; + case 266: /* trigger_cmd ::= scanpt select scanpt */ +{yylhsminor.yy441 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy457, yymsp[-2].minor.yy224, yymsp[0].minor.yy224); /*yylhsminor.yy441-overwrites-yymsp[-1].minor.yy457*/} + yymsp[-2].minor.yy441 = yylhsminor.yy441; break; - case 260: /* expr ::= RAISE LP IGNORE RP */ + case 267: /* expr ::= RAISE LP IGNORE RP */ { - yymsp[-3].minor.yy244 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); - if( yymsp[-3].minor.yy244 ){ - yymsp[-3].minor.yy244->affExpr = OE_Ignore; + yymsp[-3].minor.yy62 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); + if( yymsp[-3].minor.yy62 ){ + yymsp[-3].minor.yy62->affExpr = OE_Ignore; } } break; - case 261: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 268: /* expr ::= RAISE LP raisetype COMMA nm RP */ { - yymsp[-5].minor.yy244 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); - if( yymsp[-5].minor.yy244 ) { - yymsp[-5].minor.yy244->affExpr = (char)yymsp[-3].minor.yy222; + yymsp[-5].minor.yy62 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); + if( yymsp[-5].minor.yy62 ) { + yymsp[-5].minor.yy62->affExpr = (char)yymsp[-3].minor.yy116; } } break; - case 262: /* raisetype ::= ROLLBACK */ -{yymsp[0].minor.yy222 = OE_Rollback;} + case 269: /* raisetype ::= ROLLBACK */ +{yymsp[0].minor.yy116 = OE_Rollback;} break; - case 264: /* raisetype ::= FAIL */ -{yymsp[0].minor.yy222 = OE_Fail;} + case 271: /* raisetype ::= FAIL */ +{yymsp[0].minor.yy116 = OE_Fail;} break; - case 265: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 272: /* cmd ::= DROP TRIGGER ifexists fullname */ { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy475,yymsp[-1].minor.yy222); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy315,yymsp[-1].minor.yy116); } break; - case 266: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 273: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { - sqlite3Attach(pParse, yymsp[-3].minor.yy244, yymsp[-1].minor.yy244, yymsp[0].minor.yy244); + sqlite3Attach(pParse, yymsp[-3].minor.yy62, yymsp[-1].minor.yy62, yymsp[0].minor.yy62); } break; - case 267: /* cmd ::= DETACH database_kw_opt expr */ + case 274: /* cmd ::= DETACH database_kw_opt expr */ { - sqlite3Detach(pParse, yymsp[0].minor.yy244); + sqlite3Detach(pParse, yymsp[0].minor.yy62); } break; - case 270: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 277: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy475,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy315,&yymsp[0].minor.yy0); } break; - case 271: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + case 278: /* 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 272: /* add_column_fullname ::= fullname */ + case 279: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ +{ + sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy315, &yymsp[0].minor.yy0); +} + break; + case 280: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy475); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy315); } break; - case 273: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + case 281: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ { - sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy475, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy315, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 274: /* cmd ::= create_vtab */ + case 282: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 275: /* cmd ::= create_vtab LP vtabarglist RP */ + case 283: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 276: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + case 284: /* 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.yy222); + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy116); } break; - case 277: /* vtabarg ::= */ + case 285: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 278: /* vtabargtoken ::= ANY */ - case 279: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==279); - case 280: /* lp ::= LP */ yytestcase(yyruleno==280); + case 286: /* vtabargtoken ::= ANY */ + case 287: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==287); + case 288: /* lp ::= LP */ yytestcase(yyruleno==288); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; - case 281: /* with ::= WITH wqlist */ - case 282: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==282); -{ sqlite3WithPush(pParse, yymsp[0].minor.yy523, 1); } + case 289: /* with ::= WITH wqlist */ + case 290: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==290); +{ sqlite3WithPush(pParse, yymsp[0].minor.yy535, 1); } + break; + case 291: /* wqas ::= AS */ +{yymsp[0].minor.yy518 = M10d_Any;} + break; + case 292: /* wqas ::= AS MATERIALIZED */ +{yymsp[-1].minor.yy518 = M10d_Yes;} + break; + case 293: /* wqas ::= AS NOT MATERIALIZED */ +{yymsp[-2].minor.yy518 = M10d_No;} + break; + case 294: /* wqitem ::= nm eidlist_opt wqas LP select RP */ +{ + yymsp[-5].minor.yy403 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy336, yymsp[-1].minor.yy457, yymsp[-3].minor.yy518); /*A-overwrites-X*/ +} break; - case 283: /* wqlist ::= nm eidlist_opt AS LP select RP */ + case 295: /* wqlist ::= wqitem */ { - yymsp[-5].minor.yy523 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy328, yymsp[-1].minor.yy341); /*A-overwrites-X*/ + yymsp[0].minor.yy535 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy403); /*A-overwrites-X*/ } break; - case 284: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ + case 296: /* wqlist ::= wqlist COMMA wqitem */ { - yymsp[-7].minor.yy523 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy523, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy328, yymsp[-1].minor.yy341); + yymsp[-2].minor.yy535 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy535, yymsp[0].minor.yy403); } break; default: - /* (285) input ::= cmdlist */ yytestcase(yyruleno==285); - /* (286) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==286); - /* (287) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=287); - /* (288) ecmd ::= SEMI */ yytestcase(yyruleno==288); - /* (289) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==289); - /* (290) trans_opt ::= */ yytestcase(yyruleno==290); - /* (291) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==291); - /* (292) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==292); - /* (293) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==293); - /* (294) savepoint_opt ::= */ yytestcase(yyruleno==294); - /* (295) cmd ::= create_table create_table_args */ yytestcase(yyruleno==295); - /* (296) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==296); - /* (297) columnlist ::= columnname carglist */ yytestcase(yyruleno==297); - /* (298) nm ::= ID|INDEXED */ yytestcase(yyruleno==298); - /* (299) nm ::= STRING */ yytestcase(yyruleno==299); - /* (300) nm ::= JOIN_KW */ yytestcase(yyruleno==300); - /* (301) typetoken ::= typename */ yytestcase(yyruleno==301); - /* (302) typename ::= ID|STRING */ yytestcase(yyruleno==302); - /* (303) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=303); - /* (304) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=304); - /* (305) carglist ::= carglist ccons */ yytestcase(yyruleno==305); - /* (306) carglist ::= */ yytestcase(yyruleno==306); - /* (307) ccons ::= NULL onconf */ yytestcase(yyruleno==307); - /* (308) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==308); - /* (309) ccons ::= AS generated */ yytestcase(yyruleno==309); - /* (310) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==310); - /* (311) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==311); - /* (312) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=312); - /* (313) tconscomma ::= */ yytestcase(yyruleno==313); - /* (314) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=314); - /* (315) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=315); - /* (316) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=316); - /* (317) oneselect ::= values */ yytestcase(yyruleno==317); - /* (318) sclp ::= selcollist COMMA */ yytestcase(yyruleno==318); - /* (319) as ::= ID|STRING */ yytestcase(yyruleno==319); - /* (320) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=320); - /* (321) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==321); - /* (322) exprlist ::= nexprlist */ yytestcase(yyruleno==322); - /* (323) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=323); - /* (324) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=324); - /* (325) nmnum ::= ON */ yytestcase(yyruleno==325); - /* (326) nmnum ::= DELETE */ yytestcase(yyruleno==326); - /* (327) nmnum ::= DEFAULT */ yytestcase(yyruleno==327); - /* (328) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==328); - /* (329) foreach_clause ::= */ yytestcase(yyruleno==329); - /* (330) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==330); - /* (331) trnm ::= nm */ yytestcase(yyruleno==331); - /* (332) tridxby ::= */ yytestcase(yyruleno==332); - /* (333) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==333); - /* (334) database_kw_opt ::= */ yytestcase(yyruleno==334); - /* (335) kwcolumn_opt ::= */ yytestcase(yyruleno==335); - /* (336) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==336); - /* (337) vtabarglist ::= vtabarg */ yytestcase(yyruleno==337); - /* (338) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==338); - /* (339) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==339); - /* (340) anylist ::= */ yytestcase(yyruleno==340); - /* (341) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==341); - /* (342) anylist ::= anylist ANY */ yytestcase(yyruleno==342); - /* (343) with ::= */ yytestcase(yyruleno==343); + /* (297) input ::= cmdlist */ yytestcase(yyruleno==297); + /* (298) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==298); + /* (299) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=299); + /* (300) ecmd ::= SEMI */ yytestcase(yyruleno==300); + /* (301) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==301); + /* (302) trans_opt ::= */ yytestcase(yyruleno==302); + /* (303) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==303); + /* (304) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==304); + /* (305) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==305); + /* (306) savepoint_opt ::= */ yytestcase(yyruleno==306); + /* (307) cmd ::= create_table create_table_args */ yytestcase(yyruleno==307); + /* (308) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==308); + /* (309) columnlist ::= columnname carglist */ yytestcase(yyruleno==309); + /* (310) nm ::= ID|INDEXED */ yytestcase(yyruleno==310); + /* (311) nm ::= STRING */ yytestcase(yyruleno==311); + /* (312) nm ::= JOIN_KW */ yytestcase(yyruleno==312); + /* (313) typetoken ::= typename */ yytestcase(yyruleno==313); + /* (314) typename ::= ID|STRING */ yytestcase(yyruleno==314); + /* (315) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=315); + /* (316) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=316); + /* (317) carglist ::= carglist ccons */ yytestcase(yyruleno==317); + /* (318) carglist ::= */ yytestcase(yyruleno==318); + /* (319) ccons ::= NULL onconf */ yytestcase(yyruleno==319); + /* (320) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==320); + /* (321) ccons ::= AS generated */ yytestcase(yyruleno==321); + /* (322) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==322); + /* (323) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==323); + /* (324) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=324); + /* (325) tconscomma ::= */ yytestcase(yyruleno==325); + /* (326) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=326); + /* (327) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=327); + /* (328) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=328); + /* (329) oneselect ::= values */ yytestcase(yyruleno==329); + /* (330) sclp ::= selcollist COMMA */ yytestcase(yyruleno==330); + /* (331) as ::= ID|STRING */ yytestcase(yyruleno==331); + /* (332) returning ::= */ yytestcase(yyruleno==332); + /* (333) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=333); + /* (334) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==334); + /* (335) exprlist ::= nexprlist */ yytestcase(yyruleno==335); + /* (336) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=336); + /* (337) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=337); + /* (338) nmnum ::= ON */ yytestcase(yyruleno==338); + /* (339) nmnum ::= DELETE */ yytestcase(yyruleno==339); + /* (340) nmnum ::= DEFAULT */ yytestcase(yyruleno==340); + /* (341) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==341); + /* (342) foreach_clause ::= */ yytestcase(yyruleno==342); + /* (343) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==343); + /* (344) trnm ::= nm */ yytestcase(yyruleno==344); + /* (345) tridxby ::= */ yytestcase(yyruleno==345); + /* (346) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==346); + /* (347) database_kw_opt ::= */ yytestcase(yyruleno==347); + /* (348) kwcolumn_opt ::= */ yytestcase(yyruleno==348); + /* (349) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==349); + /* (350) vtabarglist ::= vtabarg */ yytestcase(yyruleno==350); + /* (351) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==351); + /* (352) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==352); + /* (353) anylist ::= */ yytestcase(yyruleno==353); + /* (354) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==354); + /* (355) anylist ::= anylist ANY */ yytestcase(yyruleno==355); + /* (356) with ::= */ yytestcase(yyruleno==356); break; /********** End reduce actions ************************************************/ }; @@ -159441,12 +161650,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 */ + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); +#ifndef NDEBUG + if( yyTraceFILE ){ + int yysize = yyRuleInfoNRhs[yyruleno]; + if( yysize ){ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + yyTracePrompt, + yyruleno, yyRuleName[yyruleno], + yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action", + yypParser->yytos[yysize].stateno); + }else{ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", + yyTracePrompt, yyruleno, yyRuleName[yyruleno], + yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action"); + } + } +#endif /* NDEBUG */ + + /* Check that the stack is large enough to grow by a single entry + ** if the RHS of the rule is empty. This ensures that there is room + ** enough on the stack to push the LHS value */ + if( yyRuleInfoNRhs[yyruleno]==0 ){ +#ifdef YYTRACKMAXSTACKDEPTH + if( (int)(yypParser->yytos - 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 @@ -159559,7 +161812,7 @@ SQLITE_PRIVATE void sqlite3Parser( break; #endif } - }while( yypParser->yytos>yypParser->yystack ); + } #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; @@ -159620,8 +161873,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 */ @@ -159646,20 +161899,21 @@ 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 */ 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, +/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 28, 10, 28, 25, 28, /* 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, @@ -159671,22 +161925,22 @@ static const unsigned char aiClass[] = { #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 }; @@ -159751,19 +162005,19 @@ const unsigned char ebcdicToAscii[] = { ** is substantially reduced. This is important for embedded applications ** on platforms with limited memory. */ -/* Hash score: 189 */ -/* zKWText[] encodes 838 bytes of keyword text in 562 bytes */ +/* Hash score: 193 */ +/* zKWText[] encodes 861 bytes of keyword text in 581 bytes */ /* BEFOREIGNOREFERENCESCAPEACHECKEYISNULLSAVEPOINTERSECTABLEFTHEN */ /* DESCONSTRAINTOFFSETRANSACTIONOTNULLIKELSELECTRIGGERAISEXCEPT */ /* EMPORARYWITHOUTERELEASEXCLUSIVEXISTSATTACHAVINGROUPDATEBEGIN */ /* STEADDATABASEBETWEENATURALTERECURSIVECASCADEFERRABLECASE */ /* COLLATECREATECURRENT_DATEDELETEDETACHIMMEDIATEJOINDEXEDEFAULT */ -/* MATCHPRAGMABORTVALUESVIRTUALWAYSWHENWHEREGEXPRIMARYAFTERENAME */ -/* ANDEFERREDISTINCTAUTOINCREMENTCASTCOLUMNCOMMITCONFLICTCROSS */ -/* CURRENT_TIMESTAMPDROPFAILASTFIRSTFROMFULLIMITGENERATEDGLOBYIF */ -/* INNEREPLACEINSERTORDERESTRICTRIGHTROLLBACKROWSUNIONUNIQUEUSING */ -/* VACUUMVIEWINITIALLY */ -static const char zKWText[561] = { +/* MATCHPRAGMATERIALIZEDEFERREDISTINCTVALUESVIRTUALWAYSWHENWHERE */ +/* GEXPRIMARYABORTAFTERENAMEANDROPAUTOINCREMENTCASTCOLUMNCOMMIT */ +/* CONFLICTCROSSCURRENT_TIMESTAMPFAILASTFIRSTFROMFULLIMIT */ +/* GENERATEDGLOBYIFINNEREPLACEINSERTORDERESTRICTRETURNINGRIGHT */ +/* ROLLBACKROWSUNIONUNIQUEUSINGVACUUMVIEWINITIALLY */ +static const char zKWText[580] = { 'B','E','F','O','R','E','I','G','N','O','R','E','F','E','R','E','N','C', 'E','S','C','A','P','E','A','C','H','E','C','K','E','Y','I','S','N','U', 'L','L','S','A','V','E','P','O','I','N','T','E','R','S','E','C','T','A', @@ -159781,79 +162035,80 @@ static const char zKWText[561] = { 'U','R','R','E','N','T','_','D','A','T','E','D','E','L','E','T','E','D', 'E','T','A','C','H','I','M','M','E','D','I','A','T','E','J','O','I','N', 'D','E','X','E','D','E','F','A','U','L','T','M','A','T','C','H','P','R', - 'A','G','M','A','B','O','R','T','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','G','E', - 'X','P','R','I','M','A','R','Y','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','D','R','O','P','F','A','I','L','A','S','T','F','I','R', - 'S','T','F','R','O','M','F','U','L','L','I','M','I','T','G','E','N','E', - 'R','A','T','E','D','G','L','O','B','Y','I','F','I','N','N','E','R','E', - 'P','L','A','C','E','I','N','S','E','R','T','O','R','D','E','R','E','S', - 'T','R','I','C','T','R','I','G','H','T','R','O','L','L','B','A','C','K', - 'R','O','W','S','U','N','I','O','N','U','N','I','Q','U','E','U','S','I', - 'N','G','V','A','C','U','U','M','V','I','E','W','I','N','I','T','I','A', - 'L','L','Y', + 'A','G','M','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','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', + 'G','E','X','P','R','I','M','A','R','Y','A','B','O','R','T','A','F','T', + 'E','R','E','N','A','M','E','A','N','D','R','O','P','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', + 'F','A','I','L','A','S','T','F','I','R','S','T','F','R','O','M','F','U', + 'L','L','I','M','I','T','G','E','N','E','R','A','T','E','D','G','L','O', + 'B','Y','I','F','I','N','N','E','R','E','P','L','A','C','E','I','N','S', + 'E','R','T','O','R','D','E','R','E','S','T','R','I','C','T','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','I','O','N','U','N','I','Q','U','E','U','S', + 'I','N','G','V','A','C','U','U','M','V','I','E','W','I','N','I','T','I', + 'A','L','L','Y', }; /* aKWHash[i] is the hash value for the i-th keyword */ static const unsigned char aKWHash[127] = { - 112, 88, 116, 68, 0, 38, 0, 0, 76, 0, 73, 0, 0, - 22, 4, 0, 51, 0, 24, 79, 23, 109, 117, 33, 0, 0, - 122, 0, 31, 114, 0, 81, 90, 0, 1, 0, 0, 63, 64, - 0, 62, 7, 0, 0, 85, 82, 0, 118, 98, 0, 0, 44, - 0, 86, 61, 0, 53, 0, 66, 46, 17, 0, 6, 107, 32, - 93, 102, 0, 125, 87, 55, 124, 50, 8, 48, 0, 45, 0, - 3, 36, 0, 96, 0, 0, 0, 92, 2, 94, 83, 104, 0, - 19, 103, 0, 75, 0, 54, 111, 108, 35, 0, 121, 74, 69, - 28, 39, 105, 0, 0, 91, 20, 58, 113, 0, 13, 0, 0, - 26, 0, 80, 29, 30, 0, 14, 56, 0, 49, + 113, 78, 118, 68, 0, 38, 0, 0, 79, 0, 73, 0, 0, + 22, 4, 0, 51, 0, 24, 82, 23, 75, 119, 33, 0, 0, + 124, 0, 31, 115, 0, 84, 92, 0, 1, 0, 0, 63, 64, + 0, 62, 7, 0, 0, 89, 85, 0, 120, 100, 0, 0, 44, + 0, 76, 61, 0, 53, 0, 66, 46, 17, 0, 6, 108, 32, + 95, 103, 0, 127, 77, 55, 126, 50, 8, 48, 0, 45, 0, + 3, 36, 0, 98, 0, 0, 0, 94, 2, 96, 87, 105, 0, + 19, 104, 0, 86, 0, 54, 112, 109, 35, 0, 123, 74, 69, + 28, 39, 106, 0, 0, 93, 20, 58, 114, 0, 13, 0, 0, + 116, 0, 83, 29, 30, 0, 14, 56, 0, 49, }; /* 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[125] = { - 0, 89, 97, 0, 0, 18, 0, 25, 0, 21, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 115, 0, 0, - 0, 0, 110, 0, 119, 0, 0, 0, 0, 0, 0, 0, 101, - 0, 43, 0, 0, 37, 72, 0, 0, 71, 120, 0, 70, 0, +static const unsigned char aKWNext[127] = { + 0, 91, 99, 0, 0, 18, 0, 25, 0, 21, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 117, 0, 0, + 0, 0, 111, 0, 121, 0, 0, 0, 0, 0, 0, 0, 102, + 0, 43, 0, 0, 37, 72, 0, 0, 71, 122, 0, 70, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 59, 0, 0, - 123, 60, 0, 10, 0, 0, 0, 0, 0, 0, 40, 5, 0, - 0, 0, 16, 0, 57, 0, 52, 0, 99, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 65, 9, 95, 15, 0, 78, 100, - 0, 0, 0, 84, 0, 0, 41, 0, 42, 0, 0, 34, 0, - 67, 77, 0, 11, 12, 106, 0, 0, + 125, 60, 0, 10, 0, 0, 0, 0, 0, 110, 0, 90, 0, + 40, 5, 0, 0, 0, 16, 0, 0, 57, 0, 52, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 65, 97, 15, 0, 81, + 101, 0, 0, 0, 88, 0, 0, 41, 0, 42, 0, 26, 0, + 34, 0, 67, 80, 0, 11, 12, 107, 0, 0, }; /* aKWLen[i] is the length (in bytes) of the i-th keyword */ -static const unsigned char aKWLen[125] = { +static const unsigned char aKWLen[127] = { 6, 7, 3, 6, 10, 6, 4, 5, 3, 6, 5, 9, 9, 5, 4, 4, 3, 4, 10, 4, 6, 2, 3, 11, 6, 2, 7, 3, 2, 4, 4, 4, 6, 7, 5, 6, 9, 4, 2, 7, 4, 5, 7, 9, 6, 6, 6, 5, 6, 5, 7, 3, 8, 2, 7, 7, 5, 9, 7, 3, 10, 4, 7, 6, 12, - 6, 6, 9, 4, 7, 5, 7, 5, 6, 5, 6, 7, 6, - 4, 5, 6, 7, 5, 6, 3, 8, 8, 2, 13, 2, 2, - 4, 6, 6, 8, 5, 17, 12, 4, 4, 4, 5, 4, 4, - 5, 9, 4, 2, 2, 5, 7, 6, 5, 8, 5, 8, 4, - 3, 5, 6, 5, 6, 4, 9, 3, + 6, 6, 9, 4, 7, 5, 7, 5, 6, 12, 8, 8, 2, + 6, 7, 6, 4, 5, 6, 7, 5, 5, 6, 3, 4, 13, + 2, 2, 4, 6, 6, 8, 5, 17, 12, 4, 4, 5, 4, + 4, 5, 9, 4, 2, 2, 5, 7, 6, 5, 8, 9, 5, + 8, 4, 3, 5, 6, 5, 6, 4, 9, 3, }; /* aKWOffset[i] is the index into zKWText[] of the start of ** the text for the i-th keyword. */ -static const unsigned short int aKWOffset[125] = { +static const unsigned short int aKWOffset[127] = { 0, 2, 2, 6, 10, 18, 23, 25, 29, 32, 34, 38, 44, 52, 55, 58, 60, 62, 65, 72, 75, 75, 78, 80, 85, 89, 90, 90, 90, 93, 96, 99, 101, 106, 112, 116, 121, 121, 125, 130, 130, 134, 138, 144, 152, 158, 163, 168, 171, 177, 180, 185, 187, 192, 195, 201, 206, 210, 219, 220, 224, 234, 238, 245, 251, - 263, 269, 275, 284, 286, 286, 292, 299, 304, 309, 314, 320, 325, - 331, 335, 338, 343, 350, 354, 360, 362, 369, 370, 377, 379, 381, - 390, 394, 400, 406, 414, 419, 419, 436, 440, 443, 447, 452, 456, - 459, 464, 473, 476, 478, 480, 484, 491, 497, 501, 509, 514, 522, - 522, 526, 531, 537, 542, 548, 552, 557, + 263, 269, 275, 284, 286, 286, 292, 299, 304, 308, 319, 326, 327, + 334, 340, 345, 351, 355, 358, 363, 370, 375, 379, 385, 387, 391, + 393, 395, 404, 408, 414, 420, 428, 433, 433, 450, 453, 457, 462, + 466, 469, 474, 483, 486, 488, 490, 494, 501, 507, 511, 519, 528, + 533, 541, 541, 545, 550, 556, 561, 567, 571, 576, }; /* aKWCode[i] is the parser symbol code for the i-th keyword */ -static const unsigned char aKWCode[125] = { +static const unsigned char aKWCode[127] = { TK_BEFORE, TK_FOREIGN, TK_FOR, TK_IGNORE, TK_REFERENCES, TK_ESCAPE, TK_EACH, TK_CHECK, TK_KEY, TK_ISNULL, TK_NULLS, TK_SAVEPOINT, TK_INTERSECT, TK_TABLE, TK_JOIN_KW, @@ -159868,17 +162123,18 @@ static const unsigned char aKWCode[125] = { TK_JOIN_KW, TK_ALTER, TK_RECURSIVE, TK_CASCADE, TK_ASC, TK_DEFERRABLE, TK_CASE, TK_COLLATE, TK_CREATE, TK_CTIME_KW, TK_DELETE, TK_DETACH, TK_IMMEDIATE, TK_JOIN, TK_INDEXED, - TK_INDEX, TK_DEFAULT, TK_MATCH, TK_PRAGMA, TK_ABORT, - TK_VALUES, TK_VIRTUAL, TK_ALWAYS, TK_WHEN, TK_WHERE, - TK_LIKE_KW, TK_PRIMARY, 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_DROP, TK_FAIL, - TK_LAST, TK_FIRST, TK_FROM, TK_JOIN_KW, TK_LIMIT, - TK_GENERATED, TK_LIKE_KW, TK_BY, TK_IF, TK_JOIN_KW, - TK_REPLACE, TK_INSERT, TK_ORDER, TK_RESTRICT, TK_JOIN_KW, - TK_ROLLBACK, TK_ROWS, TK_ROW, TK_UNION, TK_UNIQUE, - TK_USING, TK_VACUUM, TK_VIEW, TK_INITIALLY, TK_ALL, + TK_INDEX, TK_DEFAULT, TK_MATCH, TK_PRAGMA, TK_MATERIALIZED, + TK_DEFERRED, TK_DISTINCT, TK_IS, TK_VALUES, TK_VIRTUAL, + TK_ALWAYS, TK_WHEN, TK_WHERE, TK_LIKE_KW, TK_PRIMARY, + TK_ABORT, TK_AFTER, TK_RENAME, TK_AND, TK_DROP, + TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, + TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, + TK_FAIL, TK_LAST, TK_FIRST, TK_FROM, TK_JOIN_KW, + TK_LIMIT, TK_GENERATED, TK_LIKE_KW, TK_BY, TK_IF, + TK_JOIN_KW, TK_REPLACE, TK_INSERT, TK_ORDER, TK_RESTRICT, + TK_RETURNING, TK_JOIN_KW, TK_ROLLBACK, TK_ROWS, TK_ROW, + TK_UNION, TK_UNIQUE, TK_USING, TK_VACUUM, TK_VIEW, + TK_INITIALLY, TK_ALL, }; /* Hash table decoded: ** 0: INSERT @@ -159902,7 +162158,7 @@ static const unsigned char aKWCode[125] = { ** 18: TRANSACTION RIGHT ** 19: WHEN ** 20: SET HAVING -** 21: IF +** 21: MATERIALIZED IF ** 22: ROWS ** 23: SELECT ** 24: @@ -159998,7 +162254,7 @@ static const unsigned char aKWCode[125] = { ** 114: INTERSECT ** 115: ** 116: -** 117: ON +** 117: RETURNING ON ** 118: ** 119: WHERE ** 120: NO INNER @@ -160016,7 +162272,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]]; @@ -160107,57 +162363,59 @@ static int keywordCode(const char *z, int n, int *pType){ testcase( i==71 ); /* DEFAULT */ testcase( i==72 ); /* MATCH */ testcase( i==73 ); /* PRAGMA */ - testcase( i==74 ); /* ABORT */ - testcase( i==75 ); /* VALUES */ - testcase( i==76 ); /* VIRTUAL */ - testcase( i==77 ); /* ALWAYS */ - testcase( i==78 ); /* WHEN */ - testcase( i==79 ); /* WHERE */ - testcase( i==80 ); /* REGEXP */ - testcase( i==81 ); /* PRIMARY */ - testcase( i==82 ); /* AFTER */ - testcase( i==83 ); /* RENAME */ - testcase( i==84 ); /* AND */ - testcase( i==85 ); /* DEFERRED */ - testcase( i==86 ); /* DISTINCT */ - testcase( i==87 ); /* IS */ - testcase( i==88 ); /* AUTOINCREMENT */ - testcase( i==89 ); /* TO */ - testcase( i==90 ); /* IN */ - testcase( i==91 ); /* CAST */ - testcase( i==92 ); /* COLUMN */ - testcase( i==93 ); /* COMMIT */ - testcase( i==94 ); /* CONFLICT */ - testcase( i==95 ); /* CROSS */ - testcase( i==96 ); /* CURRENT_TIMESTAMP */ - testcase( i==97 ); /* CURRENT_TIME */ - testcase( i==98 ); /* DROP */ - testcase( i==99 ); /* FAIL */ - testcase( i==100 ); /* LAST */ - testcase( i==101 ); /* FIRST */ - testcase( i==102 ); /* FROM */ - testcase( i==103 ); /* FULL */ - testcase( i==104 ); /* LIMIT */ - testcase( i==105 ); /* GENERATED */ - testcase( i==106 ); /* GLOB */ - testcase( i==107 ); /* BY */ - testcase( i==108 ); /* IF */ - testcase( i==109 ); /* INNER */ - testcase( i==110 ); /* REPLACE */ - testcase( i==111 ); /* INSERT */ - testcase( i==112 ); /* ORDER */ - testcase( i==113 ); /* RESTRICT */ - testcase( i==114 ); /* RIGHT */ - testcase( i==115 ); /* ROLLBACK */ - testcase( i==116 ); /* ROWS */ - testcase( i==117 ); /* ROW */ - testcase( i==118 ); /* UNION */ - testcase( i==119 ); /* UNIQUE */ - testcase( i==120 ); /* USING */ - testcase( i==121 ); /* VACUUM */ - testcase( i==122 ); /* VIEW */ - testcase( i==123 ); /* INITIALLY */ - testcase( i==124 ); /* ALL */ + testcase( i==74 ); /* MATERIALIZED */ + testcase( i==75 ); /* DEFERRED */ + testcase( i==76 ); /* DISTINCT */ + testcase( i==77 ); /* IS */ + testcase( i==78 ); /* VALUES */ + testcase( i==79 ); /* VIRTUAL */ + testcase( i==80 ); /* ALWAYS */ + testcase( i==81 ); /* WHEN */ + testcase( i==82 ); /* WHERE */ + testcase( i==83 ); /* REGEXP */ + testcase( i==84 ); /* PRIMARY */ + testcase( i==85 ); /* ABORT */ + testcase( i==86 ); /* AFTER */ + testcase( i==87 ); /* RENAME */ + testcase( i==88 ); /* AND */ + testcase( i==89 ); /* DROP */ + testcase( i==90 ); /* AUTOINCREMENT */ + testcase( i==91 ); /* TO */ + testcase( i==92 ); /* IN */ + testcase( i==93 ); /* CAST */ + testcase( i==94 ); /* COLUMN */ + testcase( i==95 ); /* COMMIT */ + testcase( i==96 ); /* CONFLICT */ + testcase( i==97 ); /* CROSS */ + testcase( i==98 ); /* CURRENT_TIMESTAMP */ + testcase( i==99 ); /* CURRENT_TIME */ + testcase( i==100 ); /* FAIL */ + testcase( i==101 ); /* LAST */ + testcase( i==102 ); /* FIRST */ + testcase( i==103 ); /* FROM */ + testcase( i==104 ); /* FULL */ + testcase( i==105 ); /* LIMIT */ + testcase( i==106 ); /* GENERATED */ + testcase( i==107 ); /* GLOB */ + testcase( i==108 ); /* BY */ + testcase( i==109 ); /* IF */ + testcase( i==110 ); /* INNER */ + testcase( i==111 ); /* REPLACE */ + testcase( i==112 ); /* INSERT */ + testcase( i==113 ); /* ORDER */ + testcase( i==114 ); /* RESTRICT */ + testcase( i==115 ); /* RETURNING */ + testcase( i==116 ); /* RIGHT */ + testcase( i==117 ); /* ROLLBACK */ + testcase( i==118 ); /* ROWS */ + testcase( i==119 ); /* ROW */ + testcase( i==120 ); /* UNION */ + testcase( i==121 ); /* UNIQUE */ + testcase( i==122 ); /* USING */ + testcase( i==123 ); /* VACUUM */ + testcase( i==124 ); /* VIEW */ + testcase( i==125 ); /* INITIALLY */ + testcase( i==126 ); /* ALL */ *pType = aKWCode[i]; break; } @@ -160169,7 +162427,7 @@ SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){ keywordCode((char*)z, n, &id); return id; } -#define SQLITE_N_KEYWORD 125 +#define SQLITE_N_KEYWORD 127 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]; @@ -160538,7 +162796,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, @@ -160568,6 +162826,7 @@ 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; @@ -160750,19 +163009,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr if( !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; assert( nErr==0 || pParse->rc!=SQLITE_OK ); @@ -163669,7 +165916,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; @@ -163692,6 +165939,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; @@ -163740,7 +165989,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. ** @@ -163755,9 +166004,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; i<db->nDb && 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; @@ -165375,7 +167626,7 @@ 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; } @@ -165550,7 +167801,26 @@ SQLITE_API int sqlite3_test_control(int op, ...){ 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; + } } va_end(ap); #endif /* SQLITE_UNTESTABLE */ @@ -172435,9 +174705,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; } @@ -174371,6 +176641,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; @@ -181774,17 +184049,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; @@ -185272,6 +187550,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{ @@ -201027,22 +203306,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<<n) - 1) << ofst; } } } @@ -202829,6 +205110,7 @@ struct sqlite3_session { 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 */ sqlite3_value *pZeroBlob; /* Value containing X'' */ sqlite3_session *pNext; /* Next session object on same db. */ SessionTable *pTable; /* List of attached tables */ @@ -202871,6 +205153,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 */ @@ -203212,6 +205495,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 @@ -203679,13 +205982,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; @@ -203706,7 +206015,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ } } - sqlite3_free(pTab->apChange); + sessionFree(pSession, pTab->apChange); pTab->nChange = nNew; pTab->apChange = apNew; } @@ -203740,6 +206049,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 */ @@ -203794,7 +206104,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; } @@ -203837,7 +206147,7 @@ static int sessionTableInfo( *pabPK = 0; *pnCol = 0; if( pzTab ) *pzTab = 0; - sqlite3_free(azCol); + sessionFree(pSession, azCol); } sqlite3_finalize(pStmt); return rc; @@ -203859,7 +206169,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 ){ @@ -203950,7 +206260,7 @@ static void sessionPreupdateOneChange( } /* Grow the hash table if required */ - if( sessionGrowHash(0, pTab) ){ + if( sessionGrowHash(pSession, 0, pTab) ){ pSession->rc = SQLITE_NOMEM; return; } @@ -204017,7 +206327,7 @@ static void sessionPreupdateOneChange( } /* Allocate the change object */ - pChange = (SessionChange *)sqlite3_malloc64(nByte); + pChange = (SessionChange *)sessionMalloc64(pSession, nByte); if( !pChange ){ rc = SQLITE_NOMEM; goto error_out; @@ -204390,7 +206700,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; @@ -204488,7 +206798,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; @@ -204500,12 +206810,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); } } @@ -204533,9 +206843,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); } @@ -204582,7 +206894,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{ @@ -205179,7 +207492,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; } @@ -205355,6 +207668,13 @@ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession){ } /* +** Return the amount of heap memory in use. +*/ +SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession){ + return pSession->nMalloc; +} + +/* ** Do the work for either sqlite3changeset_start() or start_strm(). */ static int sessionChangesetStart( @@ -205363,7 +207683,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 */ @@ -205384,6 +207705,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; @@ -205398,7 +207720,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 */ @@ -205407,7 +207729,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); } /* @@ -205418,7 +207740,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 */ @@ -205427,7 +207749,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); } /* @@ -205553,11 +207875,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; i<nCol && rc==SQLITE_OK; i++){ int eType = 0; /* Type of value (SQLITE_NULL, TEXT etc.) */ if( abPK && abPK[i]==0 ) continue; @@ -205569,6 +207894,7 @@ static int sessionReadRecord( eType = pIn->aData[pIn->iNext++]; assert( apOut[i]==0 ); if( eType ){ + if( pbEmpty ) *pbEmpty = 0; apOut[i] = sqlite3ValueNew(0); if( !apOut[i] ) rc = SQLITE_NOMEM; } @@ -205748,31 +208074,27 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ } /* -** Advance the changeset iterator to the next change. +** Advance the changeset iterator to the next change. The differences between +** this function and sessionChangesetNext() are that ** -** 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. +** * 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; @@ -205845,13 +208167,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; } @@ -205879,6 +208201,37 @@ static int sessionChangesetNext( } /* +** 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 ** or SQLITE_CORRUPT. @@ -206150,9 +208503,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 @@ -206253,16 +208606,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 */ @@ -206272,6 +208634,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; ii<pIter->nCol; 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; ii<pIter->nCol; 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; ii<pIter->nCol; 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: @@ -206342,103 +208865,6 @@ static int sessionDeleteRow( } /* -** 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; i<p->nCol; 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; i<p->nCol; 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; i<p->nCol; 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: ** @@ -206519,17 +208945,6 @@ static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){ ); } 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 " "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END " @@ -206845,7 +209260,7 @@ static int sessionApplyOneOp( int nCol; int rc = SQLITE_OK; - assert( p->pDelete && p->pUpdate && p->pInsert && p->pSelect ); + assert( p->pDelete && p->pInsert && p->pSelect ); assert( p->azCol && p->abPK ); assert( !pbReplace || *pbReplace==0 ); @@ -206885,29 +209300,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 && i<nCol; i++){ sqlite3_value *pOld = sessionChangesetOld(pIter, i); sqlite3_value *pNew = sessionChangesetNew(pIter, i); - - sqlite3_bind_int(p->pUpdate, 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 @@ -207039,7 +209453,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*); @@ -207130,14 +209544,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; @@ -207165,7 +209578,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; @@ -207201,11 +209614,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; @@ -207264,9 +209676,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); @@ -207297,8 +209709,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 @@ -207356,7 +209768,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 @@ -207644,7 +210056,7 @@ static int sessionChangesetToHash( } } - if( sessionGrowHash(pIter->bPatchset, pTab) ){ + if( sessionGrowHash(0, pIter->bPatchset, pTab) ){ rc = SQLITE_NOMEM; break; } @@ -207830,7 +210242,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); } } @@ -207976,7 +210388,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 ){ @@ -208231,7 +210643,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); } } @@ -210693,55 +213105,6 @@ static fts5YYACTIONTYPE fts5yy_reduce( (void)fts5yyLookahead; (void)fts5yyLookaheadToken; fts5yymsp = fts5yypParser->fts5yytos; - assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ); -#ifndef NDEBUG - if( fts5yyTraceFILE ){ - fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno]; - if( fts5yysize ){ - fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", - fts5yyTracePrompt, - fts5yyruleno, fts5yyRuleName[fts5yyruleno], - fts5yyruleno<fts5YYNRULE_WITH_ACTION ? "" : " without external action", - fts5yymsp[fts5yysize].stateno); - }else{ - fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s.\n", - fts5yyTracePrompt, fts5yyruleno, fts5yyRuleName[fts5yyruleno], - fts5yyruleno<fts5YYNRULE_WITH_ACTION ? "" : " without external action"); - } - } -#endif /* NDEBUG */ - - /* Check that the stack is large enough to grow by a single entry - ** if the RHS of the rule is empty. This ensures that there is room - ** enough on the stack to push the LHS value */ - if( fts5yyRuleInfoNRhs[fts5yyruleno]==0 ){ -#ifdef fts5YYTRACKMAXSTACKDEPTH - if( (int)(fts5yypParser->fts5yytos - 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 @@ -211044,12 +213407,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 */ + assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ); +#ifndef NDEBUG + if( fts5yyTraceFILE ){ + int fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno]; + if( fts5yysize ){ + fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + fts5yyTracePrompt, + fts5yyruleno, fts5yyRuleName[fts5yyruleno], + fts5yyruleno<fts5YYNRULE_WITH_ACTION ? "" : " without external action", + fts5yypParser->fts5yytos[fts5yysize].stateno); + }else{ + fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s.\n", + fts5yyTracePrompt, fts5yyruleno, fts5yyRuleName[fts5yyruleno], + fts5yyruleno<fts5YYNRULE_WITH_ACTION ? "" : " without external action"); + } + } +#endif /* NDEBUG */ + + /* Check that the stack is large enough to grow by a single entry + ** if the RHS of the rule is empty. This ensures that there is room + ** enough on the stack to push the LHS value */ + if( fts5yyRuleInfoNRhs[fts5yyruleno]==0 ){ +#ifdef fts5YYTRACKMAXSTACKDEPTH + if( (int)(fts5yypParser->fts5yytos - 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 @@ -211162,7 +213569,7 @@ static void sqlite3Fts5Parser( break; #endif } - }while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ); + } #ifndef NDEBUG if( fts5yyTraceFILE ){ fts5yyStackEntry *i; @@ -214774,8 +217181,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; @@ -218960,14 +221367,10 @@ 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; @@ -219959,7 +222362,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 ){ @@ -219972,6 +222375,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)); @@ -220023,66 +222429,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( p<pEnd && *p!=0x01 ){ - while( *p++ & 0x80 ); - } - - return p - (*pa); -} - static void fts5IndexExtractColset( int *pRc, Fts5Colset *pColset, /* Colset to filter on */ const u8 *pPos, int nPos, /* Position list */ - Fts5Buffer *pBuf /* Output buffer */ + Fts5Iter *pIter ){ if( *pRc==SQLITE_OK ){ - int i; - fts5BufferZero(pBuf); - for(i=0; i<pColset->nCol; 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]<iCurrent ){ + i++; + if( i==pColset->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( p<pEnd && *p!=0x01 ){ + while( *p++ & 0x80 ); + } + + if( pColset->aiCol[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); } } } + } /* @@ -220202,16 +222614,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 @@ -221694,7 +224099,7 @@ static void fts5AppendPoslist( static void fts5DoclistIterNext(Fts5DoclistIter *pIter){ u8 *p = pIter->aPoslist + pIter->nSize + pIter->nPoslist; - assert( pIter->aPoslist ); + assert( pIter->aPoslist || (p==0 && pIter->aPoslist==0) ); if( p>=pIter->aEof ){ pIter->aPoslist = 0; }else{ @@ -221714,6 +224119,9 @@ static void fts5DoclistIterNext(Fts5DoclistIter *pIter){ } pIter->aPoslist = p; + if( &pIter->aPoslist[pIter->nPoslist]>pIter->aEof ){ + pIter->aPoslist = 0; + } } } @@ -221722,9 +224130,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 @@ -221778,16 +224188,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; @@ -221814,180 +224228,213 @@ 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; i<nBuf; i++){ + fts5DoclistIterInit(&aBuf[i], &aMerger[i].iter); + fts5PrefixMergerInsertByRowid(&pHead, &aMerger[i]); + nOut += aBuf[i].n; + } + if( nOut==0 ) return; + nOut += p1->n + 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.iRowid<i2.iRowid ){ - /* Copy entry from i1 */ - fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid); - fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.nPoslist+i1.nSize); - fts5DoclistIterNext(&i1); - if( i1.aPoslist==0 ) break; - assert( out.n<=((i1.aPoslist-p1->p) + (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 + FTS5_DATA_ZERO_PADDING - ); - if( p->rc ) break; + fts5BufferZero(&tmp); - sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - assert_nc( iPos1>=0 && iPos2>=0 ); + pThis = pHead; + pHead = pThis->pNext; + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos); + fts5PrefixMergerNextPosition(pThis); + fts5PrefixMergerInsertByPosition(&pHead, pThis); - if( iPos1<iPos2 ){ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); - sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - }else{ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); - sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - } - if( iPos1>=0 && iPos2>=0 ){ - while( 1 ){ - if( iPos1<iPos2 ){ - if( iPos1!=iPrev ){ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); - } - sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - if( iPos1<0 ) break; - }else{ - assert_nc( iPos2!=iPrev ); - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); - sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - if( iPos2<0 ) break; - } - } + while( pHead->pNext ){ + pThis = pHead; + if( pThis->iPos!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos); } + fts5PrefixMergerNextPosition(pThis); + pHead = pThis->pNext; + fts5PrefixMergerInsertByPosition(&pHead, pThis); + } - 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); - } + if( pHead->iPos!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pHead->iPos); + } + nTail = pHead->iter.nPoslist - pHead->iOff; - /* 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; + /* WRITEPOSLISTSIZE */ + assert( tmp.n+nTail<=nTmp ); + 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; i<nBuf+1; i++){ + PrefixMerger *pX = &aMerger[i]; + if( pX->iter.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) ); - - fts5BufferFree(p1); - fts5BufferFree(&tmp); - memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING); - *p1 = 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; } @@ -222007,6 +224454,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 */ ; @@ -222027,13 +224495,21 @@ static void fts5SetupPrefixIter( if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ - assert( i<nBuf ); - if( aBuf[i].n==0 ){ - fts5BufferSwap(&doclist, &aBuf[i]); - fts5BufferZero(&doclist); - }else{ - xMerge(p, &doclist, &aBuf[i]); - fts5BufferZero(&aBuf[i]); + int i1 = i*nMerge; + int iStore; + assert( i1+nMerge<=nBuf ); + for(iStore=i1; iStore<i1+nMerge; iStore++){ + if( aBuf[iStore].n==0 ){ + fts5BufferSwap(&doclist, &aBuf[iStore]); + fts5BufferZero(&doclist); + break; + } + } + if( iStore==i1+nMerge ){ + xMerge(p, &doclist, nMerge, &aBuf[i1]); + for(iStore=i1; iStore<i1+nMerge; iStore++){ + fts5BufferZero(&aBuf[iStore]); + } } } iLastRowid = 0; @@ -222043,11 +224519,15 @@ static void fts5SetupPrefixIter( iLastRowid = p1->base.iRowid; } - for(i=0; i<nBuf; i++){ + assert( (nBuf%nMerge)==0 ); + for(i=0; i<nBuf; i+=nMerge){ + int iFree; if( p->rc==SQLITE_OK ){ - xMerge(p, &doclist, &aBuf[i]); + xMerge(p, &doclist, nMerge, &aBuf[i]); + } + for(iFree=i; iFree<i+nMerge; iFree++){ + fts5BufferFree(&aBuf[iFree]); } - fts5BufferFree(&aBuf[i]); } fts5MultiIterFree(p1); @@ -222302,6 +224782,7 @@ static int sqlite3Fts5IndexQuery( if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ + int iPrefixIdx = 0; /* +1 prefix index */ if( nToken ) memcpy(&buf.p[1], pToken, nToken); /* Figure out which index to search and set iIdx accordingly. If this @@ -222323,7 +224804,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; } } @@ -222340,8 +224823,7 @@ 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); + fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet); assert( p->rc!=SQLITE_OK || pRet->pColset==0 ); fts5IterSetOutputCb(&p->rc, pRet); if( p->rc==SQLITE_OK ){ @@ -222414,8 +224896,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); } /* @@ -225701,7 +228184,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); @@ -225760,7 +228244,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); } @@ -225768,7 +228253,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 ){ @@ -226246,7 +228732,7 @@ static int sqlite3Fts5GetTokenizer( *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); }else{ rc = pMod->x.xCreate( - pMod->pUserData, &azArg[1], (nArg?nArg-1:0), &pConfig->pTok + pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok ); pConfig->pTokApi = &pMod->x; if( rc!=SQLITE_OK ){ @@ -226309,7 +228795,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2020-12-01 16:14:00 0000000000000000000000000000000000000000000000000000000000000000", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2021-04-19 18:32:05 1b256d97b553a9611efca188a3d995a2fff712759044ba480f9a0c9e98fae886", -1, SQLITE_TRANSIENT); } /* @@ -231235,9 +233721,9 @@ SQLITE_API int sqlite3_stmt_init( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ -#if __LINE__!=231238 +#if __LINE__!=233724 #undef SQLITE_SOURCE_ID -#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 b7738010bc8ef02ba84820368e557306390a33c38adaa5c7703154bae3edalt2" +#define SQLITE_SOURCE_ID "2021-04-19 18:32:05 1b256d97b553a9611efca188a3d995a2fff712759044ba480f9a0c9e98faalt2" #endif /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } diff --git a/chromium/third_party/sqlite/src/amalgamation/sqlite3.h b/chromium/third_party/sqlite/src/amalgamation/sqlite3.h index 44be7872663..19ee767fe86 100644 --- a/chromium/third_party/sqlite/src/amalgamation/sqlite3.h +++ b/chromium/third_party/sqlite/src/amalgamation/sqlite3.h @@ -123,9 +123,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.34.0" -#define SQLITE_VERSION_NUMBER 3034000 -#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 b7738010bc8ef02ba84820368e557306390a33c38adaa5c7703154bae3edalt1" +#define SQLITE_VERSION "3.35.5" +#define SQLITE_VERSION_NUMBER 3035005 +#define SQLITE_SOURCE_ID "2021-04-19 18:32:05 1b256d97b553a9611efca188a3d995a2fff712759044ba480f9a0c9e98fae886" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -2115,7 +2115,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. </dd> +** which case the trigger setting is not reported back. +** +** <p>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.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] ** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt> @@ -2126,7 +2132,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. </dd> +** which case the view setting is not reported back. +** +** <p>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.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> @@ -3499,6 +3511,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** that uses dot-files in place of posix advisory locking. ** <tr><td> file:data.db?mode=readonly <td> ** An error. "readonly" is not a valid option for the "mode" parameter. +** Use "ro" instead: "file:data.db?mode=ro". ** </table> ** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and @@ -3697,7 +3710,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 @@ -7765,7 +7778,8 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 #define SQLITE_TESTCTRL_SEEK_COUNT 30 -#define SQLITE_TESTCTRL_LAST 30 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_TRACEFLAGS 31 +#define SQLITE_TESTCTRL_LAST 31 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -10439,6 +10453,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 ** @@ -10540,18 +10562,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/chromium/third_party/sqlite/src/amalgamation_dev/rename_exports.h b/chromium/third_party/sqlite/src/amalgamation_dev/rename_exports.h index cd7e4ad3e79..09cab91526f 100644 --- a/chromium/third_party/sqlite/src/amalgamation_dev/rename_exports.h +++ b/chromium/third_party/sqlite/src/amalgamation_dev/rename_exports.h @@ -7,335 +7,336 @@ #ifndef THIRD_PARTY_SQLITE_AMALGAMATION_RENAME_EXPORTS_H_ #define THIRD_PARTY_SQLITE_AMALGAMATION_RENAME_EXPORTS_H_ -#define sqlite3_activate_cerod chrome_sqlite3_activate_cerod // Lines 5957-5959 -#define sqlite3_aggregate_context chrome_sqlite3_aggregate_context // Line 5518 -#define sqlite3_aggregate_count chrome_sqlite3_aggregate_count // Line 5293 -#define sqlite3_auto_extension chrome_sqlite3_auto_extension // Line 6707 -#define sqlite3_backup_finish chrome_sqlite3_backup_finish // Line 8739 -#define sqlite3_backup_init chrome_sqlite3_backup_init // Lines 8732-8737 -#define sqlite3_backup_pagecount chrome_sqlite3_backup_pagecount // Line 8741 -#define sqlite3_backup_remaining chrome_sqlite3_backup_remaining // Line 8740 -#define sqlite3_backup_step chrome_sqlite3_backup_step // Line 8738 -#define sqlite3_bind_blob chrome_sqlite3_bind_blob // Line 4397 -#define sqlite3_bind_blob64 chrome_sqlite3_bind_blob64 // Lines 4398-4399 -#define sqlite3_bind_double chrome_sqlite3_bind_double // Line 4400 -#define sqlite3_bind_int chrome_sqlite3_bind_int // Line 4401 -#define sqlite3_bind_int64 chrome_sqlite3_bind_int64 // Line 4402 -#define sqlite3_bind_null chrome_sqlite3_bind_null // Line 4403 -#define sqlite3_bind_parameter_count chrome_sqlite3_bind_parameter_count // Line 4432 -#define sqlite3_bind_parameter_index chrome_sqlite3_bind_parameter_index // Line 4478 -#define sqlite3_bind_parameter_name chrome_sqlite3_bind_parameter_name // Line 4460 -#define sqlite3_bind_pointer chrome_sqlite3_bind_pointer // Line 4409 -#define sqlite3_bind_text chrome_sqlite3_bind_text // Line 4404 -#define sqlite3_bind_text16 chrome_sqlite3_bind_text16 // Line 4405 -#define sqlite3_bind_text64 chrome_sqlite3_bind_text64 // Lines 4406-4407 -#define sqlite3_bind_value chrome_sqlite3_bind_value // Line 4408 -#define sqlite3_bind_zeroblob chrome_sqlite3_bind_zeroblob // Line 4410 -#define sqlite3_bind_zeroblob64 chrome_sqlite3_bind_zeroblob64 // Line 4411 -#define sqlite3_blob_bytes chrome_sqlite3_blob_bytes // Line 7285 -#define sqlite3_blob_close chrome_sqlite3_blob_close // Line 7269 -#define sqlite3_blob_open chrome_sqlite3_blob_open // Lines 7213-7221 -#define sqlite3_blob_read chrome_sqlite3_blob_read // Line 7314 -#define sqlite3_blob_reopen chrome_sqlite3_blob_reopen // Line 7246 -#define sqlite3_blob_write chrome_sqlite3_blob_write // Line 7356 -#define sqlite3_busy_handler chrome_sqlite3_busy_handler // Line 2659 -#define sqlite3_busy_timeout chrome_sqlite3_busy_timeout // Line 2682 -#define sqlite3_cancel_auto_extension chrome_sqlite3_cancel_auto_extension // Line 6719 -#define sqlite3_changes chrome_sqlite3_changes // Line 2488 -#define sqlite3_clear_bindings chrome_sqlite3_clear_bindings // Line 4488 +#define sqlite3_activate_cerod chrome_sqlite3_activate_cerod // Lines 5970-5972 +#define sqlite3_aggregate_context chrome_sqlite3_aggregate_context // Line 5531 +#define sqlite3_aggregate_count chrome_sqlite3_aggregate_count // Line 5306 +#define sqlite3_auto_extension chrome_sqlite3_auto_extension // Line 6720 +#define sqlite3_backup_finish chrome_sqlite3_backup_finish // Line 8753 +#define sqlite3_backup_init chrome_sqlite3_backup_init // Lines 8746-8751 +#define sqlite3_backup_pagecount chrome_sqlite3_backup_pagecount // Line 8755 +#define sqlite3_backup_remaining chrome_sqlite3_backup_remaining // Line 8754 +#define sqlite3_backup_step chrome_sqlite3_backup_step // Line 8752 +#define sqlite3_bind_blob chrome_sqlite3_bind_blob // Line 4410 +#define sqlite3_bind_blob64 chrome_sqlite3_bind_blob64 // Lines 4411-4412 +#define sqlite3_bind_double chrome_sqlite3_bind_double // Line 4413 +#define sqlite3_bind_int chrome_sqlite3_bind_int // Line 4414 +#define sqlite3_bind_int64 chrome_sqlite3_bind_int64 // Line 4415 +#define sqlite3_bind_null chrome_sqlite3_bind_null // Line 4416 +#define sqlite3_bind_parameter_count chrome_sqlite3_bind_parameter_count // Line 4445 +#define sqlite3_bind_parameter_index chrome_sqlite3_bind_parameter_index // Line 4491 +#define sqlite3_bind_parameter_name chrome_sqlite3_bind_parameter_name // Line 4473 +#define sqlite3_bind_pointer chrome_sqlite3_bind_pointer // Line 4422 +#define sqlite3_bind_text chrome_sqlite3_bind_text // Line 4417 +#define sqlite3_bind_text16 chrome_sqlite3_bind_text16 // Line 4418 +#define sqlite3_bind_text64 chrome_sqlite3_bind_text64 // Lines 4419-4420 +#define sqlite3_bind_value chrome_sqlite3_bind_value // Line 4421 +#define sqlite3_bind_zeroblob chrome_sqlite3_bind_zeroblob // Line 4423 +#define sqlite3_bind_zeroblob64 chrome_sqlite3_bind_zeroblob64 // Line 4424 +#define sqlite3_blob_bytes chrome_sqlite3_blob_bytes // Line 7298 +#define sqlite3_blob_close chrome_sqlite3_blob_close // Line 7282 +#define sqlite3_blob_open chrome_sqlite3_blob_open // Lines 7226-7234 +#define sqlite3_blob_read chrome_sqlite3_blob_read // Line 7327 +#define sqlite3_blob_reopen chrome_sqlite3_blob_reopen // Line 7259 +#define sqlite3_blob_write chrome_sqlite3_blob_write // Line 7369 +#define sqlite3_busy_handler chrome_sqlite3_busy_handler // Line 2671 +#define sqlite3_busy_timeout chrome_sqlite3_busy_timeout // Line 2694 +#define sqlite3_cancel_auto_extension chrome_sqlite3_cancel_auto_extension // Line 6732 +#define sqlite3_changes chrome_sqlite3_changes // Line 2500 +#define sqlite3_clear_bindings chrome_sqlite3_clear_bindings // Line 4501 #define sqlite3_close chrome_sqlite3_close // Line 330 #define sqlite3_close_v2 chrome_sqlite3_close_v2 // Line 331 -#define sqlite3_collation_needed chrome_sqlite3_collation_needed // Lines 5941-5945 -#define sqlite3_collation_needed16 chrome_sqlite3_collation_needed16 // Lines 5946-5950 -#define sqlite3_column_blob chrome_sqlite3_column_blob // Line 4964 -#define sqlite3_column_bytes chrome_sqlite3_column_bytes // Line 4971 -#define sqlite3_column_bytes16 chrome_sqlite3_column_bytes16 // Line 4972 -#define sqlite3_column_count chrome_sqlite3_column_count // Line 4504 -#define sqlite3_column_database_name chrome_sqlite3_column_database_name // Line 4578 -#define sqlite3_column_database_name16 chrome_sqlite3_column_database_name16 // Line 4579 -#define sqlite3_column_decltype chrome_sqlite3_column_decltype // Line 4615 -#define sqlite3_column_decltype16 chrome_sqlite3_column_decltype16 // Line 4616 -#define sqlite3_column_double chrome_sqlite3_column_double // Line 4965 -#define sqlite3_column_int chrome_sqlite3_column_int // Line 4966 -#define sqlite3_column_int64 chrome_sqlite3_column_int64 // Line 4967 -#define sqlite3_column_name chrome_sqlite3_column_name // Line 4533 -#define sqlite3_column_name16 chrome_sqlite3_column_name16 // Line 4534 -#define sqlite3_column_origin_name chrome_sqlite3_column_origin_name // Line 4582 -#define sqlite3_column_origin_name16 chrome_sqlite3_column_origin_name16 // Line 4583 -#define sqlite3_column_table_name chrome_sqlite3_column_table_name // Line 4580 -#define sqlite3_column_table_name16 chrome_sqlite3_column_table_name16 // Line 4581 -#define sqlite3_column_text chrome_sqlite3_column_text // Line 4968 -#define sqlite3_column_text16 chrome_sqlite3_column_text16 // Line 4969 -#define sqlite3_column_type chrome_sqlite3_column_type // Line 4973 -#define sqlite3_column_value chrome_sqlite3_column_value // Line 4970 -#define sqlite3_commit_hook chrome_sqlite3_commit_hook // Line 6304 +#define sqlite3_collation_needed chrome_sqlite3_collation_needed // Lines 5954-5958 +#define sqlite3_collation_needed16 chrome_sqlite3_collation_needed16 // Lines 5959-5963 +#define sqlite3_column_blob chrome_sqlite3_column_blob // Line 4977 +#define sqlite3_column_bytes chrome_sqlite3_column_bytes // Line 4984 +#define sqlite3_column_bytes16 chrome_sqlite3_column_bytes16 // Line 4985 +#define sqlite3_column_count chrome_sqlite3_column_count // Line 4517 +#define sqlite3_column_database_name chrome_sqlite3_column_database_name // Line 4591 +#define sqlite3_column_database_name16 chrome_sqlite3_column_database_name16 // Line 4592 +#define sqlite3_column_decltype chrome_sqlite3_column_decltype // Line 4628 +#define sqlite3_column_decltype16 chrome_sqlite3_column_decltype16 // Line 4629 +#define sqlite3_column_double chrome_sqlite3_column_double // Line 4978 +#define sqlite3_column_int chrome_sqlite3_column_int // Line 4979 +#define sqlite3_column_int64 chrome_sqlite3_column_int64 // Line 4980 +#define sqlite3_column_name chrome_sqlite3_column_name // Line 4546 +#define sqlite3_column_name16 chrome_sqlite3_column_name16 // Line 4547 +#define sqlite3_column_origin_name chrome_sqlite3_column_origin_name // Line 4595 +#define sqlite3_column_origin_name16 chrome_sqlite3_column_origin_name16 // Line 4596 +#define sqlite3_column_table_name chrome_sqlite3_column_table_name // Line 4593 +#define sqlite3_column_table_name16 chrome_sqlite3_column_table_name16 // Line 4594 +#define sqlite3_column_text chrome_sqlite3_column_text // Line 4981 +#define sqlite3_column_text16 chrome_sqlite3_column_text16 // Line 4982 +#define sqlite3_column_type chrome_sqlite3_column_type // Line 4986 +#define sqlite3_column_value chrome_sqlite3_column_value // Line 4983 +#define sqlite3_commit_hook chrome_sqlite3_commit_hook // Line 6317 #define sqlite3_compileoption_get chrome_sqlite3_compileoption_get // Line 191 #define sqlite3_compileoption_used chrome_sqlite3_compileoption_used // Line 190 -#define sqlite3_complete chrome_sqlite3_complete // Line 2597 -#define sqlite3_complete16 chrome_sqlite3_complete16 // Line 2598 +#define sqlite3_complete chrome_sqlite3_complete // Line 2609 +#define sqlite3_complete16 chrome_sqlite3_complete16 // Line 2610 #define sqlite3_config chrome_sqlite3_config // Line 1582 -#define sqlite3_context_db_handle chrome_sqlite3_context_db_handle // Line 5545 -#define sqlite3_create_collation chrome_sqlite3_create_collation // Lines 5891-5897 -#define sqlite3_create_collation16 chrome_sqlite3_create_collation16 // Lines 5906-5912 -#define sqlite3_create_collation_v2 chrome_sqlite3_create_collation_v2 // Lines 5898-5905 -#define sqlite3_create_filename chrome_sqlite3_create_filename // Lines 3706-3712 -#define sqlite3_create_function chrome_sqlite3_create_function // Lines 5155-5164 -#define sqlite3_create_function16 chrome_sqlite3_create_function16 // Lines 5165-5174 -#define sqlite3_create_function_v2 chrome_sqlite3_create_function_v2 // Lines 5175-5185 -#define sqlite3_create_module chrome_sqlite3_create_module // Lines 6999-7004 -#define sqlite3_create_module_v2 chrome_sqlite3_create_module_v2 // Lines 7005-7011 -#define sqlite3_create_window_function chrome_sqlite3_create_window_function // Lines 5186-5197 -#define sqlite3_data_count chrome_sqlite3_data_count // Line 4721 -#define sqlite3_data_directory chrome_sqlite3_data_directory // Line 6074 -#define sqlite3_database_file_object chrome_sqlite3_database_file_object // Line 3659 -#define sqlite3_db_cacheflush chrome_sqlite3_db_cacheflush // Line 9437 +#define sqlite3_context_db_handle chrome_sqlite3_context_db_handle // Line 5558 +#define sqlite3_create_collation chrome_sqlite3_create_collation // Lines 5904-5910 +#define sqlite3_create_collation16 chrome_sqlite3_create_collation16 // Lines 5919-5925 +#define sqlite3_create_collation_v2 chrome_sqlite3_create_collation_v2 // Lines 5911-5918 +#define sqlite3_create_filename chrome_sqlite3_create_filename // Lines 3719-3725 +#define sqlite3_create_function chrome_sqlite3_create_function // Lines 5168-5177 +#define sqlite3_create_function16 chrome_sqlite3_create_function16 // Lines 5178-5187 +#define sqlite3_create_function_v2 chrome_sqlite3_create_function_v2 // Lines 5188-5198 +#define sqlite3_create_module chrome_sqlite3_create_module // Lines 7012-7017 +#define sqlite3_create_module_v2 chrome_sqlite3_create_module_v2 // Lines 7018-7024 +#define sqlite3_create_window_function chrome_sqlite3_create_window_function // Lines 5199-5210 +#define sqlite3_data_count chrome_sqlite3_data_count // Line 4734 +#define sqlite3_data_directory chrome_sqlite3_data_directory // Line 6087 +#define sqlite3_database_file_object chrome_sqlite3_database_file_object // Line 3672 +#define sqlite3_db_cacheflush chrome_sqlite3_db_cacheflush // Line 9451 #define sqlite3_db_config chrome_sqlite3_db_config // Line 1601 -#define sqlite3_db_filename chrome_sqlite3_db_filename // Line 6178 -#define sqlite3_db_handle chrome_sqlite3_db_handle // Line 6146 -#define sqlite3_db_mutex chrome_sqlite3_db_mutex // Line 7664 -#define sqlite3_db_readonly chrome_sqlite3_db_readonly // Line 6188 -#define sqlite3_db_release_memory chrome_sqlite3_db_release_memory // Line 6431 -#define sqlite3_db_status chrome_sqlite3_db_status // Line 8089 -#define sqlite3_declare_vtab chrome_sqlite3_declare_vtab // Line 7085 -#define sqlite3_deserialize chrome_sqlite3_deserialize // Lines 9833-9840 -#define sqlite3_drop_modules chrome_sqlite3_drop_modules // Lines 7025-7028 -#define sqlite3_enable_load_extension chrome_sqlite3_enable_load_extension // Line 6669 -#define sqlite3_enable_shared_cache chrome_sqlite3_enable_shared_cache // Line 6401 -#define sqlite3_errcode chrome_sqlite3_errcode // Line 3767 -#define sqlite3_errmsg chrome_sqlite3_errmsg // Line 3769 -#define sqlite3_errmsg16 chrome_sqlite3_errmsg16 // Line 3770 -#define sqlite3_errstr chrome_sqlite3_errstr // Line 3771 +#define sqlite3_db_filename chrome_sqlite3_db_filename // Line 6191 +#define sqlite3_db_handle chrome_sqlite3_db_handle // Line 6159 +#define sqlite3_db_mutex chrome_sqlite3_db_mutex // Line 7677 +#define sqlite3_db_readonly chrome_sqlite3_db_readonly // Line 6201 +#define sqlite3_db_release_memory chrome_sqlite3_db_release_memory // Line 6444 +#define sqlite3_db_status chrome_sqlite3_db_status // Line 8103 +#define sqlite3_declare_vtab chrome_sqlite3_declare_vtab // Line 7098 +#define sqlite3_deserialize chrome_sqlite3_deserialize // Lines 9847-9854 +#define sqlite3_drop_modules chrome_sqlite3_drop_modules // Lines 7038-7041 +#define sqlite3_enable_load_extension chrome_sqlite3_enable_load_extension // Line 6682 +#define sqlite3_enable_shared_cache chrome_sqlite3_enable_shared_cache // Line 6414 +#define sqlite3_errcode chrome_sqlite3_errcode // Line 3780 +#define sqlite3_errmsg chrome_sqlite3_errmsg // Line 3782 +#define sqlite3_errmsg16 chrome_sqlite3_errmsg16 // Line 3783 +#define sqlite3_errstr chrome_sqlite3_errstr // Line 3784 #define sqlite3_exec chrome_sqlite3_exec // Lines 402-408 -#define sqlite3_expanded_sql chrome_sqlite3_expanded_sql // Line 4133 -#define sqlite3_expired chrome_sqlite3_expired // Line 5294 -#define sqlite3_extended_errcode chrome_sqlite3_extended_errcode // Line 3768 -#define sqlite3_extended_result_codes chrome_sqlite3_extended_result_codes // Line 2358 -#define sqlite3_file_control chrome_sqlite3_file_control // Line 7707 -#define sqlite3_filename_database chrome_sqlite3_filename_database // Line 3638 -#define sqlite3_filename_journal chrome_sqlite3_filename_journal // Line 3639 -#define sqlite3_filename_wal chrome_sqlite3_filename_wal // Line 3640 -#define sqlite3_finalize chrome_sqlite3_finalize // Line 5001 -#define sqlite3_free chrome_sqlite3_free // Line 2891 -#define sqlite3_free_filename chrome_sqlite3_free_filename // Line 3713 -#define sqlite3_free_table chrome_sqlite3_free_table // Line 2765 -#define sqlite3_get_autocommit chrome_sqlite3_get_autocommit // Line 6133 -#define sqlite3_get_auxdata chrome_sqlite3_get_auxdata // Line 5604 -#define sqlite3_get_table chrome_sqlite3_get_table // Lines 2757-2764 -#define sqlite3_global_recover chrome_sqlite3_global_recover // Line 5296 -#define sqlite3_hard_heap_limit64 chrome_sqlite3_hard_heap_limit64 // Line 6498 +#define sqlite3_expanded_sql chrome_sqlite3_expanded_sql // Line 4146 +#define sqlite3_expired chrome_sqlite3_expired // Line 5307 +#define sqlite3_extended_errcode chrome_sqlite3_extended_errcode // Line 3781 +#define sqlite3_extended_result_codes chrome_sqlite3_extended_result_codes // Line 2370 +#define sqlite3_file_control chrome_sqlite3_file_control // Line 7720 +#define sqlite3_filename_database chrome_sqlite3_filename_database // Line 3651 +#define sqlite3_filename_journal chrome_sqlite3_filename_journal // Line 3652 +#define sqlite3_filename_wal chrome_sqlite3_filename_wal // Line 3653 +#define sqlite3_finalize chrome_sqlite3_finalize // Line 5014 +#define sqlite3_free chrome_sqlite3_free // Line 2903 +#define sqlite3_free_filename chrome_sqlite3_free_filename // Line 3726 +#define sqlite3_free_table chrome_sqlite3_free_table // Line 2777 +#define sqlite3_get_autocommit chrome_sqlite3_get_autocommit // Line 6146 +#define sqlite3_get_auxdata chrome_sqlite3_get_auxdata // Line 5617 +#define sqlite3_get_table chrome_sqlite3_get_table // Lines 2769-2776 +#define sqlite3_global_recover chrome_sqlite3_global_recover // Line 5309 +#define sqlite3_hard_heap_limit64 chrome_sqlite3_hard_heap_limit64 // Line 6511 #define sqlite3_initialize chrome_sqlite3_initialize // Line 1546 -#define sqlite3_interrupt chrome_sqlite3_interrupt // Line 2562 -#define sqlite3_keyword_check chrome_sqlite3_keyword_check // Line 7819 -#define sqlite3_keyword_count chrome_sqlite3_keyword_count // Line 7817 -#define sqlite3_keyword_name chrome_sqlite3_keyword_name // Line 7818 -#define sqlite3_last_insert_rowid chrome_sqlite3_last_insert_rowid // Line 2420 +#define sqlite3_interrupt chrome_sqlite3_interrupt // Line 2574 +#define sqlite3_keyword_check chrome_sqlite3_keyword_check // Line 7833 +#define sqlite3_keyword_count chrome_sqlite3_keyword_count // Line 7831 +#define sqlite3_keyword_name chrome_sqlite3_keyword_name // Line 7832 +#define sqlite3_last_insert_rowid chrome_sqlite3_last_insert_rowid // Line 2432 #define sqlite3_libversion chrome_sqlite3_libversion // Line 163 #define sqlite3_libversion_number chrome_sqlite3_libversion_number // Line 165 -#define sqlite3_limit chrome_sqlite3_limit // Line 3839 -#define sqlite3_load_extension chrome_sqlite3_load_extension // Lines 6637-6642 -#define sqlite3_log chrome_sqlite3_log // Line 8937 -#define sqlite3_malloc chrome_sqlite3_malloc // Line 2887 -#define sqlite3_malloc64 chrome_sqlite3_malloc64 // Line 2888 -#define sqlite3_memory_alarm chrome_sqlite3_memory_alarm // Lines 5298-5299 -#define sqlite3_memory_highwater chrome_sqlite3_memory_highwater // Line 2918 -#define sqlite3_memory_used chrome_sqlite3_memory_used // Line 2917 -#define sqlite3_mprintf chrome_sqlite3_mprintf // Line 2807 -#define sqlite3_msize chrome_sqlite3_msize // Line 2892 -#define sqlite3_mutex_alloc chrome_sqlite3_mutex_alloc // Line 7505 -#define sqlite3_mutex_enter chrome_sqlite3_mutex_enter // Line 7507 -#define sqlite3_mutex_free chrome_sqlite3_mutex_free // Line 7506 -#define sqlite3_mutex_held chrome_sqlite3_mutex_held // Line 7619 -#define sqlite3_mutex_leave chrome_sqlite3_mutex_leave // Line 7509 -#define sqlite3_mutex_notheld chrome_sqlite3_mutex_notheld // Line 7620 -#define sqlite3_mutex_try chrome_sqlite3_mutex_try // Line 7508 -#define sqlite3_next_stmt chrome_sqlite3_next_stmt // Line 6255 -#define sqlite3_normalized_sql chrome_sqlite3_normalized_sql // Line 4134 -#define sqlite3_open chrome_sqlite3_open // Lines 3525-3528 -#define sqlite3_open16 chrome_sqlite3_open16 // Lines 3529-3532 -#define sqlite3_open_v2 chrome_sqlite3_open_v2 // Lines 3533-3538 +#define sqlite3_limit chrome_sqlite3_limit // Line 3852 +#define sqlite3_load_extension chrome_sqlite3_load_extension // Lines 6650-6655 +#define sqlite3_log chrome_sqlite3_log // Line 8951 +#define sqlite3_malloc chrome_sqlite3_malloc // Line 2899 +#define sqlite3_malloc64 chrome_sqlite3_malloc64 // Line 2900 +#define sqlite3_memory_alarm chrome_sqlite3_memory_alarm // Lines 5311-5312 +#define sqlite3_memory_highwater chrome_sqlite3_memory_highwater // Line 2930 +#define sqlite3_memory_used chrome_sqlite3_memory_used // Line 2929 +#define sqlite3_mprintf chrome_sqlite3_mprintf // Line 2819 +#define sqlite3_msize chrome_sqlite3_msize // Line 2904 +#define sqlite3_mutex_alloc chrome_sqlite3_mutex_alloc // Line 7518 +#define sqlite3_mutex_enter chrome_sqlite3_mutex_enter // Line 7520 +#define sqlite3_mutex_free chrome_sqlite3_mutex_free // Line 7519 +#define sqlite3_mutex_held chrome_sqlite3_mutex_held // Line 7632 +#define sqlite3_mutex_leave chrome_sqlite3_mutex_leave // Line 7522 +#define sqlite3_mutex_notheld chrome_sqlite3_mutex_notheld // Line 7633 +#define sqlite3_mutex_try chrome_sqlite3_mutex_try // Line 7521 +#define sqlite3_next_stmt chrome_sqlite3_next_stmt // Line 6268 +#define sqlite3_normalized_sql chrome_sqlite3_normalized_sql // Line 4147 +#define sqlite3_open chrome_sqlite3_open // Lines 3538-3541 +#define sqlite3_open16 chrome_sqlite3_open16 // Lines 3542-3545 +#define sqlite3_open_v2 chrome_sqlite3_open_v2 // Lines 3546-3551 #define sqlite3_os_end chrome_sqlite3_os_end // Line 1549 #define sqlite3_os_init chrome_sqlite3_os_init // Line 1548 -#define sqlite3_overload_function chrome_sqlite3_overload_function // Line 7104 -#define sqlite3_prepare chrome_sqlite3_prepare // Lines 4049-4055 -#define sqlite3_prepare16 chrome_sqlite3_prepare16 // Lines 4071-4077 -#define sqlite3_prepare16_v2 chrome_sqlite3_prepare16_v2 // Lines 4078-4084 -#define sqlite3_prepare16_v3 chrome_sqlite3_prepare16_v3 // Lines 4085-4092 -#define sqlite3_prepare_v2 chrome_sqlite3_prepare_v2 // Lines 4056-4062 -#define sqlite3_prepare_v3 chrome_sqlite3_prepare_v3 // Lines 4063-4070 -#define sqlite3_preupdate_count chrome_sqlite3_preupdate_count // Line 9537 -#define sqlite3_preupdate_depth chrome_sqlite3_preupdate_depth // Line 9538 -#define sqlite3_preupdate_hook chrome_sqlite3_preupdate_hook // Lines 9523-9535 -#define sqlite3_preupdate_new chrome_sqlite3_preupdate_new // Line 9539 -#define sqlite3_preupdate_old chrome_sqlite3_preupdate_old // Line 9536 -#define sqlite3_profile chrome_sqlite3_profile // Lines 3142-3143 -#define sqlite3_progress_handler chrome_sqlite3_progress_handler // Line 3270 -#define sqlite3_randomness chrome_sqlite3_randomness // Line 2941 -#define sqlite3_realloc chrome_sqlite3_realloc // Line 2889 -#define sqlite3_realloc64 chrome_sqlite3_realloc64 // Line 2890 -#define sqlite3_release_memory chrome_sqlite3_release_memory // Line 6417 -#define sqlite3_reset chrome_sqlite3_reset // Line 5028 -#define sqlite3_reset_auto_extension chrome_sqlite3_reset_auto_extension // Line 6727 -#define sqlite3_result_blob chrome_sqlite3_result_blob // Line 5772 -#define sqlite3_result_blob64 chrome_sqlite3_result_blob64 // Lines 5773-5774 -#define sqlite3_result_double chrome_sqlite3_result_double // Line 5775 -#define sqlite3_result_error chrome_sqlite3_result_error // Line 5776 -#define sqlite3_result_error16 chrome_sqlite3_result_error16 // Line 5777 -#define sqlite3_result_error_code chrome_sqlite3_result_error_code // Line 5780 -#define sqlite3_result_error_nomem chrome_sqlite3_result_error_nomem // Line 5779 -#define sqlite3_result_error_toobig chrome_sqlite3_result_error_toobig // Line 5778 -#define sqlite3_result_int chrome_sqlite3_result_int // Line 5781 -#define sqlite3_result_int64 chrome_sqlite3_result_int64 // Line 5782 -#define sqlite3_result_null chrome_sqlite3_result_null // Line 5783 -#define sqlite3_result_pointer chrome_sqlite3_result_pointer // Line 5791 -#define sqlite3_result_subtype chrome_sqlite3_result_subtype // Line 5808 -#define sqlite3_result_text chrome_sqlite3_result_text // Line 5784 -#define sqlite3_result_text16 chrome_sqlite3_result_text16 // Line 5787 -#define sqlite3_result_text16be chrome_sqlite3_result_text16be // Line 5789 -#define sqlite3_result_text16le chrome_sqlite3_result_text16le // Line 5788 -#define sqlite3_result_text64 chrome_sqlite3_result_text64 // Lines 5785-5786 -#define sqlite3_result_value chrome_sqlite3_result_value // Line 5790 -#define sqlite3_result_zeroblob chrome_sqlite3_result_zeroblob // Line 5792 -#define sqlite3_result_zeroblob64 chrome_sqlite3_result_zeroblob64 // Line 5793 -#define sqlite3_rollback_hook chrome_sqlite3_rollback_hook // Line 6305 -#define sqlite3_rtree_geometry_callback chrome_sqlite3_rtree_geometry_callback // Lines 9920-9925 -#define sqlite3_rtree_query_callback chrome_sqlite3_rtree_query_callback // Lines 9946-9952 -#define sqlite3_serialize chrome_sqlite3_serialize // Lines 9781-9786 -#define sqlite3_set_authorizer chrome_sqlite3_set_authorizer // Lines 3032-3036 -#define sqlite3_set_auxdata chrome_sqlite3_set_auxdata // Line 5605 -#define sqlite3_set_last_insert_rowid chrome_sqlite3_set_last_insert_rowid // Line 2430 +#define sqlite3_overload_function chrome_sqlite3_overload_function // Line 7117 +#define sqlite3_prepare chrome_sqlite3_prepare // Lines 4062-4068 +#define sqlite3_prepare16 chrome_sqlite3_prepare16 // Lines 4084-4090 +#define sqlite3_prepare16_v2 chrome_sqlite3_prepare16_v2 // Lines 4091-4097 +#define sqlite3_prepare16_v3 chrome_sqlite3_prepare16_v3 // Lines 4098-4105 +#define sqlite3_prepare_v2 chrome_sqlite3_prepare_v2 // Lines 4069-4075 +#define sqlite3_prepare_v3 chrome_sqlite3_prepare_v3 // Lines 4076-4083 +#define sqlite3_preupdate_count chrome_sqlite3_preupdate_count // Line 9551 +#define sqlite3_preupdate_depth chrome_sqlite3_preupdate_depth // Line 9552 +#define sqlite3_preupdate_hook chrome_sqlite3_preupdate_hook // Lines 9537-9549 +#define sqlite3_preupdate_new chrome_sqlite3_preupdate_new // Line 9553 +#define sqlite3_preupdate_old chrome_sqlite3_preupdate_old // Line 9550 +#define sqlite3_profile chrome_sqlite3_profile // Lines 3154-3155 +#define sqlite3_progress_handler chrome_sqlite3_progress_handler // Line 3282 +#define sqlite3_randomness chrome_sqlite3_randomness // Line 2953 +#define sqlite3_realloc chrome_sqlite3_realloc // Line 2901 +#define sqlite3_realloc64 chrome_sqlite3_realloc64 // Line 2902 +#define sqlite3_release_memory chrome_sqlite3_release_memory // Line 6430 +#define sqlite3_reset chrome_sqlite3_reset // Line 5041 +#define sqlite3_reset_auto_extension chrome_sqlite3_reset_auto_extension // Line 6740 +#define sqlite3_result_blob chrome_sqlite3_result_blob // Line 5785 +#define sqlite3_result_blob64 chrome_sqlite3_result_blob64 // Lines 5786-5787 +#define sqlite3_result_double chrome_sqlite3_result_double // Line 5788 +#define sqlite3_result_error chrome_sqlite3_result_error // Line 5789 +#define sqlite3_result_error16 chrome_sqlite3_result_error16 // Line 5790 +#define sqlite3_result_error_code chrome_sqlite3_result_error_code // Line 5793 +#define sqlite3_result_error_nomem chrome_sqlite3_result_error_nomem // Line 5792 +#define sqlite3_result_error_toobig chrome_sqlite3_result_error_toobig // Line 5791 +#define sqlite3_result_int chrome_sqlite3_result_int // Line 5794 +#define sqlite3_result_int64 chrome_sqlite3_result_int64 // Line 5795 +#define sqlite3_result_null chrome_sqlite3_result_null // Line 5796 +#define sqlite3_result_pointer chrome_sqlite3_result_pointer // Line 5804 +#define sqlite3_result_subtype chrome_sqlite3_result_subtype // Line 5821 +#define sqlite3_result_text chrome_sqlite3_result_text // Line 5797 +#define sqlite3_result_text16 chrome_sqlite3_result_text16 // Line 5800 +#define sqlite3_result_text16be chrome_sqlite3_result_text16be // Line 5802 +#define sqlite3_result_text16le chrome_sqlite3_result_text16le // Line 5801 +#define sqlite3_result_text64 chrome_sqlite3_result_text64 // Lines 5798-5799 +#define sqlite3_result_value chrome_sqlite3_result_value // Line 5803 +#define sqlite3_result_zeroblob chrome_sqlite3_result_zeroblob // Line 5805 +#define sqlite3_result_zeroblob64 chrome_sqlite3_result_zeroblob64 // Line 5806 +#define sqlite3_rollback_hook chrome_sqlite3_rollback_hook // Line 6318 +#define sqlite3_rtree_geometry_callback chrome_sqlite3_rtree_geometry_callback // Lines 9934-9939 +#define sqlite3_rtree_query_callback chrome_sqlite3_rtree_query_callback // Lines 9960-9966 +#define sqlite3_serialize chrome_sqlite3_serialize // Lines 9795-9800 +#define sqlite3_set_authorizer chrome_sqlite3_set_authorizer // Lines 3044-3048 +#define sqlite3_set_auxdata chrome_sqlite3_set_auxdata // Line 5618 +#define sqlite3_set_last_insert_rowid chrome_sqlite3_set_last_insert_rowid // Line 2442 #define sqlite3_shutdown chrome_sqlite3_shutdown // Line 1547 -#define sqlite3_sleep chrome_sqlite3_sleep // Line 5979 -#define sqlite3_snapshot_cmp chrome_sqlite3_snapshot_cmp // Lines 9715-9718 -#define sqlite3_snapshot_free chrome_sqlite3_snapshot_free // Line 9688 -#define sqlite3_snapshot_get chrome_sqlite3_snapshot_get // Lines 9622-9626 -#define sqlite3_snapshot_open chrome_sqlite3_snapshot_open // Lines 9671-9675 -#define sqlite3_snapshot_recover chrome_sqlite3_snapshot_recover // Line 9743 -#define sqlite3_snprintf chrome_sqlite3_snprintf // Line 2809 -#define sqlite3_soft_heap_limit chrome_sqlite3_soft_heap_limit // Line 6509 -#define sqlite3_soft_heap_limit64 chrome_sqlite3_soft_heap_limit64 // Line 6497 +#define sqlite3_sleep chrome_sqlite3_sleep // Line 5992 +#define sqlite3_snapshot_cmp chrome_sqlite3_snapshot_cmp // Lines 9729-9732 +#define sqlite3_snapshot_free chrome_sqlite3_snapshot_free // Line 9702 +#define sqlite3_snapshot_get chrome_sqlite3_snapshot_get // Lines 9636-9640 +#define sqlite3_snapshot_open chrome_sqlite3_snapshot_open // Lines 9685-9689 +#define sqlite3_snapshot_recover chrome_sqlite3_snapshot_recover // Line 9757 +#define sqlite3_snprintf chrome_sqlite3_snprintf // Line 2821 +#define sqlite3_soft_heap_limit chrome_sqlite3_soft_heap_limit // Line 6522 +#define sqlite3_soft_heap_limit64 chrome_sqlite3_soft_heap_limit64 // Line 6510 #define sqlite3_sourceid chrome_sqlite3_sourceid // Line 164 -#define sqlite3_sql chrome_sqlite3_sql // Line 4132 -#define sqlite3_status chrome_sqlite3_status // Line 7979 -#define sqlite3_status64 chrome_sqlite3_status64 // Lines 7980-7985 -#define sqlite3_step chrome_sqlite3_step // Line 4700 -#define sqlite3_stmt_busy chrome_sqlite3_stmt_busy // Line 4203 -#define sqlite3_stmt_isexplain chrome_sqlite3_stmt_isexplain // Line 4182 -#define sqlite3_stmt_readonly chrome_sqlite3_stmt_readonly // Line 4170 -#define sqlite3_stmt_scanstatus chrome_sqlite3_stmt_scanstatus // Lines 9388-9393 -#define sqlite3_stmt_scanstatus_reset chrome_sqlite3_stmt_scanstatus_reset // Line 9404 -#define sqlite3_stmt_status chrome_sqlite3_stmt_status // Line 8242 -#define sqlite3_str_append chrome_sqlite3_str_append // Line 7915 -#define sqlite3_str_appendall chrome_sqlite3_str_appendall // Line 7916 -#define sqlite3_str_appendchar chrome_sqlite3_str_appendchar // Line 7917 -#define sqlite3_str_appendf chrome_sqlite3_str_appendf // Line 7913 -#define sqlite3_str_errcode chrome_sqlite3_str_errcode // Line 7949 -#define sqlite3_str_finish chrome_sqlite3_str_finish // Line 7879 -#define sqlite3_str_length chrome_sqlite3_str_length // Line 7950 -#define sqlite3_str_new chrome_sqlite3_str_new // Line 7864 -#define sqlite3_str_reset chrome_sqlite3_str_reset // Line 7918 -#define sqlite3_str_value chrome_sqlite3_str_value // Line 7951 -#define sqlite3_str_vappendf chrome_sqlite3_str_vappendf // Line 7914 -#define sqlite3_strglob chrome_sqlite3_strglob // Line 8891 -#define sqlite3_stricmp chrome_sqlite3_stricmp // Line 8873 -#define sqlite3_strlike chrome_sqlite3_strlike // Line 8914 -#define sqlite3_strnicmp chrome_sqlite3_strnicmp // Line 8874 -#define sqlite3_system_errno chrome_sqlite3_system_errno // Line 9553 -#define sqlite3_table_column_metadata chrome_sqlite3_table_column_metadata // Lines 6581-6591 -#define sqlite3_temp_directory chrome_sqlite3_temp_directory // Line 6037 -#define sqlite3_test_control chrome_sqlite3_test_control // Line 7726 -#define sqlite3_thread_cleanup chrome_sqlite3_thread_cleanup // Line 5297 +#define sqlite3_sql chrome_sqlite3_sql // Line 4145 +#define sqlite3_status chrome_sqlite3_status // Line 7993 +#define sqlite3_status64 chrome_sqlite3_status64 // Lines 7994-7999 +#define sqlite3_step chrome_sqlite3_step // Line 4713 +#define sqlite3_stmt_busy chrome_sqlite3_stmt_busy // Line 4216 +#define sqlite3_stmt_isexplain chrome_sqlite3_stmt_isexplain // Line 4195 +#define sqlite3_stmt_readonly chrome_sqlite3_stmt_readonly // Line 4183 +#define sqlite3_stmt_scanstatus chrome_sqlite3_stmt_scanstatus // Lines 9402-9407 +#define sqlite3_stmt_scanstatus_reset chrome_sqlite3_stmt_scanstatus_reset // Line 9418 +#define sqlite3_stmt_status chrome_sqlite3_stmt_status // Line 8256 +#define sqlite3_str_append chrome_sqlite3_str_append // Line 7929 +#define sqlite3_str_appendall chrome_sqlite3_str_appendall // Line 7930 +#define sqlite3_str_appendchar chrome_sqlite3_str_appendchar // Line 7931 +#define sqlite3_str_appendf chrome_sqlite3_str_appendf // Line 7927 +#define sqlite3_str_errcode chrome_sqlite3_str_errcode // Line 7963 +#define sqlite3_str_finish chrome_sqlite3_str_finish // Line 7893 +#define sqlite3_str_length chrome_sqlite3_str_length // Line 7964 +#define sqlite3_str_new chrome_sqlite3_str_new // Line 7878 +#define sqlite3_str_reset chrome_sqlite3_str_reset // Line 7932 +#define sqlite3_str_value chrome_sqlite3_str_value // Line 7965 +#define sqlite3_str_vappendf chrome_sqlite3_str_vappendf // Line 7928 +#define sqlite3_strglob chrome_sqlite3_strglob // Line 8905 +#define sqlite3_stricmp chrome_sqlite3_stricmp // Line 8887 +#define sqlite3_strlike chrome_sqlite3_strlike // Line 8928 +#define sqlite3_strnicmp chrome_sqlite3_strnicmp // Line 8888 +#define sqlite3_system_errno chrome_sqlite3_system_errno // Line 9567 +#define sqlite3_table_column_metadata chrome_sqlite3_table_column_metadata // Lines 6594-6604 +#define sqlite3_temp_directory chrome_sqlite3_temp_directory // Line 6050 +#define sqlite3_test_control chrome_sqlite3_test_control // Line 7739 +#define sqlite3_thread_cleanup chrome_sqlite3_thread_cleanup // Line 5310 #define sqlite3_threadsafe chrome_sqlite3_threadsafe // Line 233 -#define sqlite3_total_changes chrome_sqlite3_total_changes // Line 2525 -#define sqlite3_trace chrome_sqlite3_trace // Lines 3140-3141 -#define sqlite3_trace_v2 chrome_sqlite3_trace_v2 // Lines 3231-3236 -#define sqlite3_transfer_bindings chrome_sqlite3_transfer_bindings // Line 5295 -#define sqlite3_txn_state chrome_sqlite3_txn_state // Line 6206 -#define sqlite3_unlock_notify chrome_sqlite3_unlock_notify // Lines 8858-8862 -#define sqlite3_update_hook chrome_sqlite3_update_hook // Lines 6356-6360 -#define sqlite3_uri_boolean chrome_sqlite3_uri_boolean // Line 3607 -#define sqlite3_uri_int64 chrome_sqlite3_uri_int64 // Line 3608 -#define sqlite3_uri_key chrome_sqlite3_uri_key // Line 3609 -#define sqlite3_uri_parameter chrome_sqlite3_uri_parameter // Line 3606 -#define sqlite3_user_data chrome_sqlite3_user_data // Line 5533 -#define sqlite3_value_blob chrome_sqlite3_value_blob // Line 5430 -#define sqlite3_value_bytes chrome_sqlite3_value_bytes // Line 5439 -#define sqlite3_value_bytes16 chrome_sqlite3_value_bytes16 // Line 5440 -#define sqlite3_value_double chrome_sqlite3_value_double // Line 5431 -#define sqlite3_value_dup chrome_sqlite3_value_dup // Line 5472 -#define sqlite3_value_free chrome_sqlite3_value_free // Line 5473 -#define sqlite3_value_frombind chrome_sqlite3_value_frombind // Line 5444 -#define sqlite3_value_int chrome_sqlite3_value_int // Line 5432 -#define sqlite3_value_int64 chrome_sqlite3_value_int64 // Line 5433 -#define sqlite3_value_nochange chrome_sqlite3_value_nochange // Line 5443 -#define sqlite3_value_numeric_type chrome_sqlite3_value_numeric_type // Line 5442 -#define sqlite3_value_pointer chrome_sqlite3_value_pointer // Line 5434 -#define sqlite3_value_subtype chrome_sqlite3_value_subtype // Line 5456 -#define sqlite3_value_text chrome_sqlite3_value_text // Line 5435 -#define sqlite3_value_text16 chrome_sqlite3_value_text16 // Line 5436 -#define sqlite3_value_text16be chrome_sqlite3_value_text16be // Line 5438 -#define sqlite3_value_text16le chrome_sqlite3_value_text16le // Line 5437 -#define sqlite3_value_type chrome_sqlite3_value_type // Line 5441 +#define sqlite3_total_changes chrome_sqlite3_total_changes // Line 2537 +#define sqlite3_trace chrome_sqlite3_trace // Lines 3152-3153 +#define sqlite3_trace_v2 chrome_sqlite3_trace_v2 // Lines 3243-3248 +#define sqlite3_transfer_bindings chrome_sqlite3_transfer_bindings // Line 5308 +#define sqlite3_txn_state chrome_sqlite3_txn_state // Line 6219 +#define sqlite3_unlock_notify chrome_sqlite3_unlock_notify // Lines 8872-8876 +#define sqlite3_update_hook chrome_sqlite3_update_hook // Lines 6369-6373 +#define sqlite3_uri_boolean chrome_sqlite3_uri_boolean // Line 3620 +#define sqlite3_uri_int64 chrome_sqlite3_uri_int64 // Line 3621 +#define sqlite3_uri_key chrome_sqlite3_uri_key // Line 3622 +#define sqlite3_uri_parameter chrome_sqlite3_uri_parameter // Line 3619 +#define sqlite3_user_data chrome_sqlite3_user_data // Line 5546 +#define sqlite3_value_blob chrome_sqlite3_value_blob // Line 5443 +#define sqlite3_value_bytes chrome_sqlite3_value_bytes // Line 5452 +#define sqlite3_value_bytes16 chrome_sqlite3_value_bytes16 // Line 5453 +#define sqlite3_value_double chrome_sqlite3_value_double // Line 5444 +#define sqlite3_value_dup chrome_sqlite3_value_dup // Line 5485 +#define sqlite3_value_free chrome_sqlite3_value_free // Line 5486 +#define sqlite3_value_frombind chrome_sqlite3_value_frombind // Line 5457 +#define sqlite3_value_int chrome_sqlite3_value_int // Line 5445 +#define sqlite3_value_int64 chrome_sqlite3_value_int64 // Line 5446 +#define sqlite3_value_nochange chrome_sqlite3_value_nochange // Line 5456 +#define sqlite3_value_numeric_type chrome_sqlite3_value_numeric_type // Line 5455 +#define sqlite3_value_pointer chrome_sqlite3_value_pointer // Line 5447 +#define sqlite3_value_subtype chrome_sqlite3_value_subtype // Line 5469 +#define sqlite3_value_text chrome_sqlite3_value_text // Line 5448 +#define sqlite3_value_text16 chrome_sqlite3_value_text16 // Line 5449 +#define sqlite3_value_text16be chrome_sqlite3_value_text16be // Line 5451 +#define sqlite3_value_text16le chrome_sqlite3_value_text16le // Line 5450 +#define sqlite3_value_type chrome_sqlite3_value_type // Line 5454 #define sqlite3_version chrome_sqlite3_version // Line 162 -#define sqlite3_vfs_find chrome_sqlite3_vfs_find // Line 7387 -#define sqlite3_vfs_register chrome_sqlite3_vfs_register // Line 7388 -#define sqlite3_vfs_unregister chrome_sqlite3_vfs_unregister // Line 7389 -#define sqlite3_vmprintf chrome_sqlite3_vmprintf // Line 2808 -#define sqlite3_vsnprintf chrome_sqlite3_vsnprintf // Line 2810 -#define sqlite3_vtab_collation chrome_sqlite3_vtab_collation // Line 9283 -#define sqlite3_vtab_config chrome_sqlite3_vtab_config // Line 9164 -#define sqlite3_vtab_nochange chrome_sqlite3_vtab_nochange // Line 9268 -#define sqlite3_vtab_on_conflict chrome_sqlite3_vtab_on_conflict // Line 9242 -#define sqlite3_wal_autocheckpoint chrome_sqlite3_wal_autocheckpoint // Line 9008 -#define sqlite3_wal_checkpoint chrome_sqlite3_wal_checkpoint // Line 9030 -#define sqlite3_wal_checkpoint_v2 chrome_sqlite3_wal_checkpoint_v2 // Lines 9124-9130 -#define sqlite3_wal_hook chrome_sqlite3_wal_hook // Lines 8973-8977 -#define sqlite3_win32_set_directory chrome_sqlite3_win32_set_directory // Lines 6095-6098 -#define sqlite3_win32_set_directory16 chrome_sqlite3_win32_set_directory16 // Line 6100 -#define sqlite3_win32_set_directory8 chrome_sqlite3_win32_set_directory8 // Line 6099 -#define sqlite3changegroup_add chrome_sqlite3changegroup_add // Line 10933 -#define sqlite3changegroup_add_strm chrome_sqlite3changegroup_add_strm // Lines 11595-11598 -#define sqlite3changegroup_delete chrome_sqlite3changegroup_delete // Line 10970 -#define sqlite3changegroup_new chrome_sqlite3changegroup_new // Line 10855 -#define sqlite3changegroup_output chrome_sqlite3changegroup_output // Lines 10960-10964 -#define sqlite3changegroup_output_strm chrome_sqlite3changegroup_output_strm // Lines 11599-11602 -#define sqlite3changeset_apply chrome_sqlite3changeset_apply // Lines 11130-11144 -#define sqlite3changeset_apply_strm chrome_sqlite3changeset_apply_strm // Lines 11528-11542 -#define sqlite3changeset_apply_v2 chrome_sqlite3changeset_apply_v2 // Lines 11145-11161 -#define sqlite3changeset_apply_v2_strm chrome_sqlite3changeset_apply_v2_strm // Lines 11543-11559 -#define sqlite3changeset_concat chrome_sqlite3changeset_concat // Lines 10801-10808 -#define sqlite3changeset_concat_strm chrome_sqlite3changeset_concat_strm // Lines 11560-11567 -#define sqlite3changeset_conflict chrome_sqlite3changeset_conflict // Lines 10687-10691 -#define sqlite3changeset_finalize chrome_sqlite3changeset_finalize // Line 10740 -#define sqlite3changeset_fk_conflicts chrome_sqlite3changeset_fk_conflicts // Lines 10704-10707 -#define sqlite3changeset_invert chrome_sqlite3changeset_invert // Lines 10770-10773 -#define sqlite3changeset_invert_strm chrome_sqlite3changeset_invert_strm // Lines 11568-11573 -#define sqlite3changeset_new chrome_sqlite3changeset_new // Lines 10659-10663 -#define sqlite3changeset_next chrome_sqlite3changeset_next // Line 10531 -#define sqlite3changeset_old chrome_sqlite3changeset_old // Lines 10625-10629 -#define sqlite3changeset_op chrome_sqlite3changeset_op // Lines 10560-10566 -#define sqlite3changeset_pk chrome_sqlite3changeset_pk // Lines 10594-10598 -#define sqlite3changeset_start chrome_sqlite3changeset_start // Lines 10482-10486 -#define sqlite3changeset_start_strm chrome_sqlite3changeset_start_strm // Lines 11574-11578 -#define sqlite3changeset_start_v2 chrome_sqlite3changeset_start_v2 // Lines 10487-10492 -#define sqlite3changeset_start_v2_strm chrome_sqlite3changeset_start_v2_strm // Lines 11579-11584 -#define sqlite3rebaser_configure chrome_sqlite3rebaser_configure // Lines 11403-11406 -#define sqlite3rebaser_create chrome_sqlite3rebaser_create // Line 11392 -#define sqlite3rebaser_delete chrome_sqlite3rebaser_delete // Line 11436 -#define sqlite3rebaser_rebase chrome_sqlite3rebaser_rebase // Lines 11422-11426 -#define sqlite3rebaser_rebase_strm chrome_sqlite3rebaser_rebase_strm // Lines 11603-11609 -#define sqlite3session_attach chrome_sqlite3session_attach // Lines 10189-10192 -#define sqlite3session_changeset chrome_sqlite3session_changeset // Lines 10318-10322 -#define sqlite3session_changeset_strm chrome_sqlite3session_changeset_strm // Lines 11585-11589 -#define sqlite3session_config chrome_sqlite3session_config // Line 11644 -#define sqlite3session_create chrome_sqlite3session_create // Lines 10059-10063 -#define sqlite3session_delete chrome_sqlite3session_delete // Line 10078 -#define sqlite3session_diff chrome_sqlite3session_diff // Lines 10381-10386 -#define sqlite3session_enable chrome_sqlite3session_enable // Line 10099 -#define sqlite3session_indirect chrome_sqlite3session_indirect // Line 10129 -#define sqlite3session_isempty chrome_sqlite3session_isempty // Line 10439 -#define sqlite3session_patchset chrome_sqlite3session_patchset // Lines 10418-10422 -#define sqlite3session_patchset_strm chrome_sqlite3session_patchset_strm // Lines 11590-11594 -#define sqlite3session_table_filter chrome_sqlite3session_table_filter // Lines 10204-10211 +#define sqlite3_vfs_find chrome_sqlite3_vfs_find // Line 7400 +#define sqlite3_vfs_register chrome_sqlite3_vfs_register // Line 7401 +#define sqlite3_vfs_unregister chrome_sqlite3_vfs_unregister // Line 7402 +#define sqlite3_vmprintf chrome_sqlite3_vmprintf // Line 2820 +#define sqlite3_vsnprintf chrome_sqlite3_vsnprintf // Line 2822 +#define sqlite3_vtab_collation chrome_sqlite3_vtab_collation // Line 9297 +#define sqlite3_vtab_config chrome_sqlite3_vtab_config // Line 9178 +#define sqlite3_vtab_nochange chrome_sqlite3_vtab_nochange // Line 9282 +#define sqlite3_vtab_on_conflict chrome_sqlite3_vtab_on_conflict // Line 9256 +#define sqlite3_wal_autocheckpoint chrome_sqlite3_wal_autocheckpoint // Line 9022 +#define sqlite3_wal_checkpoint chrome_sqlite3_wal_checkpoint // Line 9044 +#define sqlite3_wal_checkpoint_v2 chrome_sqlite3_wal_checkpoint_v2 // Lines 9138-9144 +#define sqlite3_wal_hook chrome_sqlite3_wal_hook // Lines 8987-8991 +#define sqlite3_win32_set_directory chrome_sqlite3_win32_set_directory // Lines 6108-6111 +#define sqlite3_win32_set_directory16 chrome_sqlite3_win32_set_directory16 // Line 6113 +#define sqlite3_win32_set_directory8 chrome_sqlite3_win32_set_directory8 // Line 6112 +#define sqlite3changegroup_add chrome_sqlite3changegroup_add // Line 10960 +#define sqlite3changegroup_add_strm chrome_sqlite3changegroup_add_strm // Lines 11622-11625 +#define sqlite3changegroup_delete chrome_sqlite3changegroup_delete // Line 10997 +#define sqlite3changegroup_new chrome_sqlite3changegroup_new // Line 10882 +#define sqlite3changegroup_output chrome_sqlite3changegroup_output // Lines 10987-10991 +#define sqlite3changegroup_output_strm chrome_sqlite3changegroup_output_strm // Lines 11626-11629 +#define sqlite3changeset_apply chrome_sqlite3changeset_apply // Lines 11157-11171 +#define sqlite3changeset_apply_strm chrome_sqlite3changeset_apply_strm // Lines 11555-11569 +#define sqlite3changeset_apply_v2 chrome_sqlite3changeset_apply_v2 // Lines 11172-11188 +#define sqlite3changeset_apply_v2_strm chrome_sqlite3changeset_apply_v2_strm // Lines 11570-11586 +#define sqlite3changeset_concat chrome_sqlite3changeset_concat // Lines 10828-10835 +#define sqlite3changeset_concat_strm chrome_sqlite3changeset_concat_strm // Lines 11587-11594 +#define sqlite3changeset_conflict chrome_sqlite3changeset_conflict // Lines 10714-10718 +#define sqlite3changeset_finalize chrome_sqlite3changeset_finalize // Line 10767 +#define sqlite3changeset_fk_conflicts chrome_sqlite3changeset_fk_conflicts // Lines 10731-10734 +#define sqlite3changeset_invert chrome_sqlite3changeset_invert // Lines 10797-10800 +#define sqlite3changeset_invert_strm chrome_sqlite3changeset_invert_strm // Lines 11595-11600 +#define sqlite3changeset_new chrome_sqlite3changeset_new // Lines 10686-10690 +#define sqlite3changeset_next chrome_sqlite3changeset_next // Line 10553 +#define sqlite3changeset_old chrome_sqlite3changeset_old // Lines 10652-10656 +#define sqlite3changeset_op chrome_sqlite3changeset_op // Lines 10587-10593 +#define sqlite3changeset_pk chrome_sqlite3changeset_pk // Lines 10621-10625 +#define sqlite3changeset_start chrome_sqlite3changeset_start // Lines 10504-10508 +#define sqlite3changeset_start_strm chrome_sqlite3changeset_start_strm // Lines 11601-11605 +#define sqlite3changeset_start_v2 chrome_sqlite3changeset_start_v2 // Lines 10509-10514 +#define sqlite3changeset_start_v2_strm chrome_sqlite3changeset_start_v2_strm // Lines 11606-11611 +#define sqlite3rebaser_configure chrome_sqlite3rebaser_configure // Lines 11430-11433 +#define sqlite3rebaser_create chrome_sqlite3rebaser_create // Line 11419 +#define sqlite3rebaser_delete chrome_sqlite3rebaser_delete // Line 11463 +#define sqlite3rebaser_rebase chrome_sqlite3rebaser_rebase // Lines 11449-11453 +#define sqlite3rebaser_rebase_strm chrome_sqlite3rebaser_rebase_strm // Lines 11630-11636 +#define sqlite3session_attach chrome_sqlite3session_attach // Lines 10203-10206 +#define sqlite3session_changeset chrome_sqlite3session_changeset // Lines 10332-10336 +#define sqlite3session_changeset_strm chrome_sqlite3session_changeset_strm // Lines 11612-11616 +#define sqlite3session_config chrome_sqlite3session_config // Line 11671 +#define sqlite3session_create chrome_sqlite3session_create // Lines 10073-10077 +#define sqlite3session_delete chrome_sqlite3session_delete // Line 10092 +#define sqlite3session_diff chrome_sqlite3session_diff // Lines 10395-10400 +#define sqlite3session_enable chrome_sqlite3session_enable // Line 10113 +#define sqlite3session_indirect chrome_sqlite3session_indirect // Line 10143 +#define sqlite3session_isempty chrome_sqlite3session_isempty // Line 10453 +#define sqlite3session_memory_used chrome_sqlite3session_memory_used // Line 10461 +#define sqlite3session_patchset chrome_sqlite3session_patchset // Lines 10432-10436 +#define sqlite3session_patchset_strm chrome_sqlite3session_patchset_strm // Lines 11617-11621 +#define sqlite3session_table_filter chrome_sqlite3session_table_filter // Lines 10218-10225 #endif // THIRD_PARTY_SQLITE_AMALGAMATION_RENAME_EXPORTS_H_ diff --git a/chromium/third_party/sqlite/src/amalgamation_dev/shell/shell.c b/chromium/third_party/sqlite/src/amalgamation_dev/shell/shell.c index c13769f5e96..27de22a3819 100644 --- a/chromium/third_party/sqlite/src/amalgamation_dev/shell/shell.c +++ b/chromium/third_party/sqlite/src/amalgamation_dev/shell/shell.c @@ -1424,7 +1424,10 @@ SQLITE_EXTENSION_INIT1 #include <assert.h> #include <string.h> #include <stdarg.h> + +#ifndef SQLITE_AMALGAMATION /* typedef sqlite3_uint64 u64; */ +#endif /* SQLITE_AMALGAMATION */ /****************************************************************************** ** The Hash Engine @@ -2014,9 +2017,11 @@ static void sha3QueryFunc( } nCol = sqlite3_column_count(pStmt); z = sqlite3_sql(pStmt); - n = (int)strlen(z); - hash_step_vformat(&cx,"S%d:",n); - SHA3Update(&cx,(unsigned char*)z,n); + if( z ){ + n = (int)strlen(z); + hash_step_vformat(&cx,"S%d:",n); + SHA3Update(&cx,(unsigned char*)z,n); + } /* Compute a hash over the result of the query */ while( SQLITE_ROW==sqlite3_step(pStmt) ){ @@ -3635,24 +3640,23 @@ int sqlite3_completion_init( ** appended onto the end of some other file, such as an executable. ** ** A special record must appear at the end of the file that identifies the -** file as an appended database and provides an offset to page 1. For -** best performance page 1 should be located at a disk page boundary, though -** that is not required. +** file as an appended database and provides the offset to the first page +** of the exposed content. (Or, it is the length of the content prefix.) +** For best performance page 1 should be located at a disk page boundary, +** though that is not required. ** ** When opening a database using this VFS, the connection might treat -** the file as an ordinary SQLite database, or it might treat is as a -** database appended onto some other file. Here are the rules: +** the file as an ordinary SQLite database, or it might treat it as a +** database appended onto some other file. The decision is made by +** applying the following rules in order: ** -** (1) When opening a new empty file, that file is treated as an ordinary -** database. +** (1) An empty file is an ordinary database. ** -** (2) When opening a file that begins with the standard SQLite prefix -** string "SQLite format 3", that file is treated as an ordinary -** database. +** (2) If the file ends with the appendvfs trailer string +** "Start-Of-SQLite3-NNNNNNNN" that file is an appended database. ** -** (3) When opening a file that ends with the appendvfs trailer string -** "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended -** database. +** (3) If the file begins with the standard SQLite prefix string +** "SQLite format 3", that file is an ordinary database. ** ** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is ** set, then a new database is appended to the already existing file. @@ -3660,13 +3664,13 @@ int sqlite3_completion_init( ** (5) Otherwise, SQLITE_CANTOPEN is returned. ** ** To avoid unnecessary complications with the PENDING_BYTE, the size of -** the file containing the database is limited to 1GB. This VFS will refuse -** to read or write past the 1GB mark. This restriction might be lifted in -** future versions. For now, if you need a large database, then keep the -** database in a separate file. +** the file containing the database is limited to 1GiB. (1073741824 bytes) +** This VFS will not read or write past the 1GiB mark. This restriction +** might be lifted in future versions. For now, if you need a larger +** database, then keep it in a separate file. ** -** If the file being opened is not an appended database, then this shim is -** a pass-through into the default underlying VFS. +** If the file being opened is a plain database (not an appended one), then +** this shim is a pass-through into the default underlying VFS. (rule 3) **/ /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 @@ -3679,17 +3683,27 @@ SQLITE_EXTENSION_INIT1 ** 123456789 123456789 12345 ** ** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is -** the offset to page 1. +** the offset to page 1, and also the length of the prefix content. */ #define APND_MARK_PREFIX "Start-Of-SQLite3-" #define APND_MARK_PREFIX_SZ 17 -#define APND_MARK_SIZE 25 +#define APND_MARK_FOS_SZ 8 +#define APND_MARK_SIZE (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ) /* ** Maximum size of the combined prefix + database + append-mark. This ** must be less than 0x40000000 to avoid locking issues on Windows. */ -#define APND_MAX_SIZE (65536*15259) +#define APND_MAX_SIZE (0x40000000) + +/* +** Try to align the database to an even multiple of APND_ROUNDUP bytes. +*/ +#ifndef APND_ROUNDUP +#define APND_ROUNDUP 4096 +#endif +#define APND_ALIGN_MASK ((sqlite3_int64)(APND_ROUNDUP-1)) +#define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK) /* ** Forward declaration of objects used by this utility @@ -3703,11 +3717,45 @@ typedef struct ApndFile ApndFile; #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) #define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1)) -/* An open file */ +/* An open appendvfs file +** +** An instance of this structure describes the appended database file. +** A separate sqlite3_file object is always appended. The appended +** sqlite3_file object (which can be accessed using ORIGFILE()) describes +** the entire file, including the prefix, the database, and the +** append-mark. +** +** The structure of an AppendVFS database is like this: +** +** +-------------+---------+----------+-------------+ +** | prefix-file | padding | database | append-mark | +** +-------------+---------+----------+-------------+ +** ^ ^ +** | | +** iPgOne iMark +** +** +** "prefix file" - file onto which the database has been appended. +** "padding" - zero or more bytes inserted so that "database" +** starts on an APND_ROUNDUP boundary +** "database" - The SQLite database file +** "append-mark" - The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates +** the offset from the start of prefix-file to the start +** of "database". +** +** The size of the database is iMark - iPgOne. +** +** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value +** of iPgOne stored as a big-ending 64-bit integer. +** +** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE). +** Or, iMark is -1 to indicate that it has not yet been written. +*/ struct ApndFile { - sqlite3_file base; /* IO methods */ - sqlite3_int64 iPgOne; /* File offset to page 1 */ - sqlite3_int64 iMark; /* Start of the append-mark */ + sqlite3_file base; /* Subclass. MUST BE FIRST! */ + sqlite3_int64 iPgOne; /* Offset to the start of the database */ + sqlite3_int64 iMark; /* Offset of the append mark. -1 if unwritten */ + /* Always followed by another sqlite3_file that describes the whole file */ }; /* @@ -3799,8 +3847,6 @@ static const sqlite3_io_methods apnd_io_methods = { apndUnfetch /* xUnfetch */ }; - - /* ** Close an apnd-file. */ @@ -3818,22 +3864,37 @@ static int apndRead( int iAmt, sqlite_int64 iOfst ){ - ApndFile *p = (ApndFile *)pFile; + ApndFile *paf = (ApndFile *)pFile; pFile = ORIGFILE(pFile); - return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst+p->iPgOne); + return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst); } /* -** Add the append-mark onto the end of the file. +** Add the append-mark onto what should become the end of the file. +* If and only if this succeeds, internal ApndFile.iMark is updated. +* Parameter iWriteEnd is the appendvfs-relative offset of the new mark. */ -static int apndWriteMark(ApndFile *p, sqlite3_file *pFile){ - int i; +static int apndWriteMark( + ApndFile *paf, + sqlite3_file *pFile, + sqlite_int64 iWriteEnd +){ + sqlite_int64 iPgOne = paf->iPgOne; unsigned char a[APND_MARK_SIZE]; + int i = APND_MARK_FOS_SZ; + int rc; + assert(pFile == ORIGFILE(paf)); memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ); - for(i=0; i<8; i++){ - a[APND_MARK_PREFIX_SZ+i] = (p->iPgOne >> (56 - i*8)) & 0xff; + while( --i >= 0 ){ + a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff); + iPgOne >>= 8; } - return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark); + iWriteEnd += paf->iPgOne; + if( SQLITE_OK==(rc = pFile->pMethods->xWrite + (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){ + paf->iMark = iWriteEnd; + } + return rc; } /* @@ -3845,38 +3906,28 @@ static int apndWrite( int iAmt, sqlite_int64 iOfst ){ - int rc; - ApndFile *p = (ApndFile *)pFile; + ApndFile *paf = (ApndFile *)pFile; + sqlite_int64 iWriteEnd = iOfst + iAmt; + if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL; pFile = ORIGFILE(pFile); - if( iOfst+iAmt>=APND_MAX_SIZE ) return SQLITE_FULL; - rc = pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst+p->iPgOne); - if( rc==SQLITE_OK && iOfst + iAmt + p->iPgOne > p->iMark ){ - sqlite3_int64 sz = 0; - rc = pFile->pMethods->xFileSize(pFile, &sz); - if( rc==SQLITE_OK ){ - p->iMark = sz - APND_MARK_SIZE; - if( iOfst + iAmt + p->iPgOne > p->iMark ){ - p->iMark = p->iPgOne + iOfst + iAmt; - rc = apndWriteMark(p, pFile); - } - } + /* If append-mark is absent or will be overwritten, write it. */ + if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){ + int rc = apndWriteMark(paf, pFile, iWriteEnd); + if( SQLITE_OK!=rc ) return rc; } - return rc; + return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst); } /* ** Truncate an apnd-file. */ static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){ - int rc; - ApndFile *p = (ApndFile *)pFile; + ApndFile *paf = (ApndFile *)pFile; pFile = ORIGFILE(pFile); - rc = pFile->pMethods->xTruncate(pFile, size+p->iPgOne+APND_MARK_SIZE); - if( rc==SQLITE_OK ){ - p->iMark = p->iPgOne+size; - rc = apndWriteMark(p, pFile); - } - return rc; + /* The append mark goes out first so truncate failure does not lose it. */ + if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR; + /* Truncate underlying file just past append mark */ + return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE); } /* @@ -3889,16 +3940,12 @@ static int apndSync(sqlite3_file *pFile, int flags){ /* ** Return the current file-size of an apnd-file. +** If the append mark is not yet there, the file-size is 0. */ static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ - ApndFile *p = (ApndFile *)pFile; - int rc; - pFile = ORIGFILE(p); - rc = pFile->pMethods->xFileSize(pFile, pSize); - if( rc==SQLITE_OK && p->iPgOne ){ - *pSize -= p->iPgOne + APND_MARK_SIZE; - } - return rc; + ApndFile *paf = (ApndFile *)pFile; + *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0; + return SQLITE_OK; } /* @@ -3929,12 +3976,13 @@ static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){ ** File control method. For custom operations on an apnd-file. */ static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){ - ApndFile *p = (ApndFile *)pFile; + ApndFile *paf = (ApndFile *)pFile; int rc; pFile = ORIGFILE(pFile); + if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne; rc = pFile->pMethods->xFileControl(pFile, op, pArg); if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){ - *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", p->iPgOne, *(char**)pArg); + *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg); } return rc; } @@ -3993,6 +4041,9 @@ static int apndFetch( void **pp ){ ApndFile *p = (ApndFile *)pFile; + if( p->iMark < 0 || iOfst+iAmt > p->iMark ){ + return SQLITE_IOERR; /* Cannot read what is not yet there. */ + } pFile = ORIGFILE(pFile); return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp); } @@ -4005,94 +4056,152 @@ static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ } /* -** Check to see if the file is an ordinary SQLite database file. -*/ -static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){ - int rc; - char zHdr[16]; - static const char aSqliteHdr[] = "SQLite format 3"; - if( sz<512 ) return 0; - rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0); - if( rc ) return 0; - return memcmp(zHdr, aSqliteHdr, sizeof(zHdr))==0; -} - -/* ** Try to read the append-mark off the end of a file. Return the -** start of the appended database if the append-mark is present. If -** there is no append-mark, return -1; +** start of the appended database if the append-mark is present. +** If there is no valid append-mark, return -1; +** +** An append-mark is only valid if the NNNNNNNN start-of-database offset +** indicates that the appended database contains at least one page. The +** start-of-database value must be a multiple of 512. */ static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){ int rc, i; sqlite3_int64 iMark; + int msbs = 8 * (APND_MARK_FOS_SZ-1); unsigned char a[APND_MARK_SIZE]; - if( sz<=APND_MARK_SIZE ) return -1; + if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1; rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE); if( rc ) return -1; if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1; - iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ]&0x7f))<<56; - for(i=1; i<8; i++){ - iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<(56-8*i); + iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs; + for(i=1; i<8; i++){ + msbs -= 8; + iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs; } + if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1; + if( iMark & 0x1ff ) return -1; return iMark; } +static const char apvfsSqliteHdr[] = "SQLite format 3"; +/* +** Check to see if the file is an appendvfs SQLite database file. +** Return true iff it is such. Parameter sz is the file's size. +*/ +static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){ + int rc; + char zHdr[16]; + sqlite3_int64 iMark = apndReadMark(sz, pFile); + if( iMark>=0 ){ + /* If file has the correct end-marker, the expected odd size, and the + ** SQLite DB type marker where the end-marker puts it, then it + ** is an appendvfs database. + */ + rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark); + if( SQLITE_OK==rc + && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0 + && (sz & 0x1ff) == APND_MARK_SIZE + && sz>=512+APND_MARK_SIZE + ){ + return 1; /* It's an appendvfs database */ + } + } + return 0; +} + +/* +** Check to see if the file is an ordinary SQLite database file. +** Return true iff so. Parameter sz is the file's size. +*/ +static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){ + char zHdr[16]; + if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */ + || (sz & 0x1ff) != 0 + || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0) + || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0 + ){ + return 0; + }else{ + return 1; + } +} + /* ** Open an apnd file handle. */ static int apndOpen( - sqlite3_vfs *pVfs, + sqlite3_vfs *pApndVfs, const char *zName, sqlite3_file *pFile, int flags, int *pOutFlags ){ - ApndFile *p; - sqlite3_file *pSubFile; - sqlite3_vfs *pSubVfs; + ApndFile *pApndFile = (ApndFile*)pFile; + sqlite3_file *pBaseFile = ORIGFILE(pFile); + sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs); int rc; - sqlite3_int64 sz; - pSubVfs = ORIGVFS(pVfs); + sqlite3_int64 sz = 0; if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){ - return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags); + /* The appendvfs is not to be used for transient or temporary databases. + ** Just use the base VFS open to initialize the given file object and + ** open the underlying file. (Appendvfs is then unused for this file.) + */ + return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags); } - p = (ApndFile*)pFile; - memset(p, 0, sizeof(*p)); - pSubFile = ORIGFILE(pFile); + memset(pApndFile, 0, sizeof(ApndFile)); pFile->pMethods = &apnd_io_methods; - rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags); - if( rc ) goto apnd_open_done; - rc = pSubFile->pMethods->xFileSize(pSubFile, &sz); + pApndFile->iMark = -1; /* Append mark not yet written */ + + rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags); + if( rc==SQLITE_OK ){ + rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz); + } if( rc ){ - pSubFile->pMethods->xClose(pSubFile); - goto apnd_open_done; + pBaseFile->pMethods->xClose(pBaseFile); + pFile->pMethods = 0; + return rc; } - if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){ - memmove(pFile, pSubFile, pSubVfs->szOsFile); + if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){ + /* The file being opened appears to be just an ordinary DB. Copy + ** the base dispatch-table so this instance mimics the base VFS. + */ + memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile); return SQLITE_OK; } - p->iMark = 0; - p->iPgOne = apndReadMark(sz, pFile); - if( p->iPgOne>0 ){ + pApndFile->iPgOne = apndReadMark(sz, pFile); + if( pApndFile->iPgOne>=0 ){ + pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */ return SQLITE_OK; } if( (flags & SQLITE_OPEN_CREATE)==0 ){ - pSubFile->pMethods->xClose(pSubFile); + pBaseFile->pMethods->xClose(pBaseFile); rc = SQLITE_CANTOPEN; + pFile->pMethods = 0; + }else{ + /* Round newly added appendvfs location to #define'd page boundary. + ** Note that nothing has yet been written to the underlying file. + ** The append mark will be written along with first content write. + ** Until then, paf->iMark value indicates it is not yet written. + */ + pApndFile->iPgOne = APND_START_ROUNDUP(sz); } - p->iPgOne = (sz+0xfff) & ~(sqlite3_int64)0xfff; -apnd_open_done: - if( rc ) pFile->pMethods = 0; return rc; } /* -** All other VFS methods are pass-thrus. +** Delete an apnd file. +** For an appendvfs, this could mean delete the appendvfs portion, +** leaving the appendee as it was before it gained an appendvfs. +** For now, this code deletes the underlying file too. */ static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync); } + +/* +** All other VFS methods are pass-thrus. +*/ static int apndAccess( sqlite3_vfs *pVfs, const char *zPath, @@ -5199,6 +5308,14 @@ static void ieee754func( int isNeg = 0; m = sqlite3_value_int64(argv[0]); e = sqlite3_value_int64(argv[1]); + + /* Limit the range of e. Ticket 22dea1cfdb9151e4 2021-03-02 */ + if( e>10000 ){ + e = 10000; + }else if( e<-10000 ){ + e = -10000; + } + if( m<0 ){ isNeg = 1; m = -m; @@ -5563,7 +5680,8 @@ static int seriesEof(sqlite3_vtab_cursor *cur){ ** 4: step=VALUE ** ** Also, if bit 8 is set, that means that the series should be output -** in descending order rather than in ascending order. +** in descending order rather than in ascending order. If bit 16 is +** set, then output must appear in ascending order. ** ** This routine should initialize the cursor and position it so that it ** is pointing at the first row, or pointing off the end of the table @@ -5589,7 +5707,12 @@ static int seriesFilter( } if( idxNum & 4 ){ pCur->iStep = sqlite3_value_int64(argv[i++]); - if( pCur->iStep<1 ) pCur->iStep = 1; + if( pCur->iStep==0 ){ + pCur->iStep = 1; + }else if( pCur->iStep<0 ){ + pCur->iStep = -pCur->iStep; + if( (idxNum & 16)==0 ) idxNum |= 8; + } }else{ pCur->iStep = 1; } @@ -5683,7 +5806,11 @@ static int seriesBestIndex( pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0)); pIdxInfo->estimatedRows = 1000; if( pIdxInfo->nOrderBy==1 ){ - if( pIdxInfo->aOrderBy[0].desc ) idxNum |= 8; + if( pIdxInfo->aOrderBy[0].desc ){ + idxNum |= 8; + }else{ + idxNum |= 16; + } pIdxInfo->orderByConsumed = 1; } }else{ @@ -8934,7 +9061,7 @@ static int idxGetTableInfo( char *pCsr = 0; int nPk = 0; - rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab); + rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_xinfo=%Q", zTab); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ const char *zCol = (const char*)sqlite3_column_text(p1, 1); nByte += 1 + STRLEN(zCol); @@ -9968,10 +10095,12 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){ idxFinalize(&rc, pIndexXInfo); idxFinalize(&rc, pWrite); - for(i=0; i<pCtx->nSlot; i++){ - sqlite3_free(pCtx->aSlot[i].z); + if( pCtx ){ + for(i=0; i<pCtx->nSlot; i++){ + sqlite3_free(pCtx->aSlot[i].z); + } + sqlite3_free(pCtx); } - sqlite3_free(pCtx); if( rc==SQLITE_OK ){ rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0); @@ -11112,12 +11241,12 @@ struct ShellState { u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ u8 autoEQPtest; /* autoEQP is in test mode */ u8 autoEQPtrace; /* autoEQP is in trace mode */ - u8 statsOn; /* True to display memory stats before each finalize */ u8 scanstatsOn; /* True to display scan stats before each finalize */ u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */ u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */ u8 nEqpLevel; /* Depth of the EQP output graph */ u8 eTraceType; /* SHELL_TRACE_* value for type of trace */ + unsigned statsOn; /* True to display memory stats before each finalize */ unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */ int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ @@ -12054,6 +12183,7 @@ static int shell_callback( if( azArg==0 ) break; for(i=0; i<nArg; i++){ int w = aExplainWidth[i]; + if( i==nArg-1 ) w = 0; if( azArg[i] && strlenChar(azArg[i])>w ){ w = strlenChar(azArg[i]); } @@ -12618,7 +12748,7 @@ static int display_stats( if( pArg==0 || pArg->out==0 ) return 0; out = pArg->out; - if( pArg->pStmt && (pArg->statsOn & 2) ){ + if( pArg->pStmt && pArg->statsOn==2 ){ int nCol, i, x; sqlite3_stmt *pStmt = pArg->pStmt; char z[100]; @@ -12642,6 +12772,14 @@ static int display_stats( } } + if( pArg->statsOn==3 ){ + if( pArg->pStmt ){ + iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); + raw_printf(pArg->out, "VM-steps: %d\n", iCur); + } + return 0; + } + displayStatLine(pArg, "Memory Used:", "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); displayStatLine(pArg, "Number of Outstanding Allocations:", @@ -12908,31 +13046,18 @@ static void explain_data_delete(ShellState *p){ /* ** Disable and restore .wheretrace and .selecttrace settings. */ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) -extern unsigned int sqlite3_unsupported_selecttrace; -static int savedSelectTrace; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) -extern int sqlite3WhereTrace; -static int savedWhereTrace; -#endif +static unsigned int savedSelectTrace; +static unsigned int savedWhereTrace; static void disable_debug_trace_modes(void){ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - savedSelectTrace = sqlite3_unsupported_selecttrace; - sqlite3_unsupported_selecttrace = 0; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - savedWhereTrace = sqlite3WhereTrace; - sqlite3WhereTrace = 0; -#endif + unsigned int zero = 0; + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 0, &savedSelectTrace); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &zero); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 2, &savedWhereTrace); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &zero); } static void restore_debug_trace_modes(void){ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - sqlite3_unsupported_selecttrace = savedSelectTrace; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - sqlite3WhereTrace = savedWhereTrace; -#endif + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &savedSelectTrace); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &savedWhereTrace); } /* Create the TEMP table used to store parameter bindings */ @@ -13094,6 +13219,7 @@ static void exec_prepared_stmt_columnar( if( rc!=SQLITE_ROW ) return; nColumn = sqlite3_column_count(pStmt); nAlloc = nColumn*4; + if( nAlloc<=0 ) nAlloc = 1; azData = sqlite3_malloc64( nAlloc*sizeof(char*) ); if( azData==0 ) shell_out_of_memory(); for(i=0; i<nColumn; i++){ @@ -13133,6 +13259,7 @@ static void exec_prepared_stmt_columnar( if( n>p->actualWidth[j] ) p->actualWidth[j] = n; } if( seenInterrupt ) goto columnar_end; + if( nColumn==0 ) goto columnar_end; switch( p->cMode ){ case MODE_Column: { colSep = " "; @@ -13922,13 +14049,13 @@ static const char *(azHelp[]) = { ".databases List names and files of attached databases", ".dbconfig ?op? ?val? List or change sqlite3_db_config() options", ".dbinfo ?DB? Show status information about the database", - ".dump ?TABLE? Render database content as SQL", + ".dump ?OBJECTS? Render database content as SQL", " Options:", " --data-only Output only INSERT statements", " --newlines Allow unescaped newline characters in output", " --nosys Omit system tables (ex: \"sqlite_stat1\")", " --preserve-rowids Include ROWID values in the output", - " TABLE is a LIKE pattern for the tables to dump", + " OBJECTS is a LIKE pattern for tables, indexes, triggers or views to dump", " Additional LIKE patterns can be given in subsequent arguments", ".echo on|off Turn command echo on or off", ".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN", @@ -14087,7 +14214,11 @@ static const char *(azHelp[]) = { ".shell CMD ARGS... Run CMD ARGS... in a system shell", #endif ".show Show the current values for various settings", - ".stats ?on|off? Show stats or turn stats on or off", + ".stats ?ARG? Show stats or turn stats on or off", + " off Turn off automatic stat display", + " on Turn on automatic stat display", + " stmt Show statement stats", + " vmstep Show the virtual machine step count only", #ifndef SQLITE_NOHAVE_SYSTEM ".system CMD ARGS... Run CMD ARGS... in a system shell", #endif @@ -17903,16 +18034,17 @@ static int do_meta_command(char *zLine, ShellState *p){ int ctrlCode; /* Integer code for that option */ const char *zUsage; /* Usage notes */ } aCtrl[] = { - { "size_limit", SQLITE_FCNTL_SIZE_LIMIT, "[LIMIT]" }, { "chunk_size", SQLITE_FCNTL_CHUNK_SIZE, "SIZE" }, - /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY, "COUNT DELAY" },*/ - { "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" }, - { "psow", SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]" }, - /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/ - { "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" }, + { "data_version", SQLITE_FCNTL_DATA_VERSION, "" }, { "has_moved", SQLITE_FCNTL_HAS_MOVED, "" }, { "lock_timeout", SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" }, + { "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" }, + /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/ + { "psow", SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]" }, { "reserve_bytes", SQLITE_FCNTL_RESERVE_BYTES, "[N]" }, + { "size_limit", SQLITE_FCNTL_SIZE_LIMIT, "[LIMIT]" }, + { "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" }, + /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY, "COUNT DELAY" },*/ }; int filectrl = -1; int iCtrl = -1; @@ -17999,6 +18131,7 @@ static int do_meta_command(char *zLine, ShellState *p){ isOk = 1; break; } + case SQLITE_FCNTL_DATA_VERSION: case SQLITE_FCNTL_HAS_MOVED: { int x; if( nArg!=2 ) break; @@ -18707,9 +18840,9 @@ static int do_meta_command(char *zLine, ShellState *p){ #endif /* SQLITE_DEBUG */ if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){ - char *zNewFilename; /* Name of the database file to open */ - int iName = 1; /* Index in azArg[] of the filename */ - int newFlag = 0; /* True to delete file before opening */ + char *zNewFilename = 0; /* Name of the database file to open */ + int iName = 1; /* Index in azArg[] of the filename */ + int newFlag = 0; /* True to delete file before opening */ /* Close the existing database */ session_close_all(p); close_db(p->db); @@ -18721,7 +18854,7 @@ static int do_meta_command(char *zLine, ShellState *p){ p->openFlags = 0; p->szMax = 0; /* Check for command-line arguments */ - for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){ + for(iName=1; iName<nArg; iName++){ const char *z = azArg[iName]; if( optionMatch(z,"new") ){ newFlag = 1; @@ -18747,10 +18880,15 @@ static int do_meta_command(char *zLine, ShellState *p){ utf8_printf(stderr, "unknown option: %s\n", z); rc = 1; goto meta_command_exit; + }else if( zNewFilename ){ + utf8_printf(stderr, "extra argument: \"%s\"\n", z); + rc = 1; + goto meta_command_exit; + }else{ + zNewFilename = sqlite3_mprintf("%s", z); } } /* If a filename is specified, try to open it first */ - zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0; if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){ if( newFlag ) shellDeleteFile(zNewFilename); p->zDbFilename = zNewFilename; @@ -18773,7 +18911,7 @@ static int do_meta_command(char *zLine, ShellState *p){ && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0)) || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0) ){ - const char *zFile = 0; + char *zFile = 0; int bTxtMode = 0; int i; int eMode = 0; @@ -18803,17 +18941,22 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; } - }else if( zFile==0 ){ - zFile = z; + }else if( zFile==0 && eMode!='e' && eMode!='x' ){ + zFile = sqlite3_mprintf("%s", z); + if( zFile[0]=='|' ){ + while( i+1<nArg ) zFile = sqlite3_mprintf("%z %s", zFile, azArg[++i]); + break; + } }else{ utf8_printf(p->out,"ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]); showHelp(p->out, azArg[0]); rc = 1; + sqlite3_free(zFile); goto meta_command_exit; } } - if( zFile==0 ) zFile = "stdout"; + if( zFile==0 ) zFile = sqlite3_mprintf("stdout"); if( bOnce ){ p->outCount = 2; }else{ @@ -18836,7 +18979,8 @@ static int do_meta_command(char *zLine, ShellState *p){ newTempFile(p, "txt"); bTxtMode = 1; } - zFile = p->zTempFile; + sqlite3_free(zFile); + zFile = sqlite3_mprintf("%s", p->zTempFile); } #endif /* SQLITE_NOHAVE_SYSTEM */ if( zFile[0]=='|' ){ @@ -18868,6 +19012,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } } + sqlite3_free(zFile); }else if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){ @@ -19051,6 +19196,11 @@ static int do_meta_command(char *zLine, ShellState *p){ goto meta_command_exit; } if( azArg[1][0]=='|' ){ +#ifdef SQLITE_OMIT_POPEN + raw_printf(stderr, "Error: pipes are not supported in this OS\n"); + rc = 1; + p->out = stdout; +#else p->in = popen(azArg[1]+1, "r"); if( p->in==0 ){ utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]); @@ -19059,6 +19209,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = process_input(p); pclose(p->in); } +#endif }else if( notNormalFile(azArg[1]) || (p->in = fopen(azArg[1], "rb"))==0 ){ utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); rc = 1; @@ -19273,11 +19424,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ - sqlite3_unsupported_selecttrace = nArg>=2 ? (int)integerValue(azArg[1]) : 0xffff; + unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x); }else -#endif #if defined(SQLITE_ENABLE_SESSION) if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){ @@ -19758,6 +19908,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='s' && strncmp(azArg[0], "show", n)==0 ){ static const char *azBool[] = { "off", "on", "trigger", "full"}; + const char *zOut; int i; if( nArg!=1 ){ raw_printf(stderr, "Usage: .show\n"); @@ -19782,7 +19933,13 @@ static int do_meta_command(char *zLine, ShellState *p){ utf8_printf(p->out,"%12.12s: ", "rowseparator"); output_c_string(p->out, p->rowSeparator); raw_printf(p->out, "\n"); - utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]); + switch( p->statsOn ){ + case 0: zOut = "off"; break; + default: zOut = "on"; break; + case 2: zOut = "stmt"; break; + case 3: zOut = "vmstep"; break; + } + utf8_printf(p->out, "%12.12s: %s\n","stats", zOut); utf8_printf(p->out, "%12.12s: ", "width"); for (i=0;i<p->nWidth;i++) { raw_printf(p->out, "%d ", p->colWidth[i]); @@ -19794,11 +19951,17 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ if( nArg==2 ){ - p->statsOn = (u8)booleanValue(azArg[1]); + if( strcmp(azArg[1],"stmt")==0 ){ + p->statsOn = 2; + }else if( strcmp(azArg[1],"vmstep")==0 ){ + p->statsOn = 3; + }else{ + p->statsOn = (u8)booleanValue(azArg[1]); + } }else if( nArg==1 ){ display_stats(p->db, p, 0); }else{ - raw_printf(stderr, "Usage: .stats ?on|off?\n"); + raw_printf(stderr, "Usage: .stats ?on|off|stmt|vmstep?\n"); rc = 1; } }else @@ -20003,7 +20166,7 @@ static int do_meta_command(char *zLine, ShellState *p){ /* sqlite3_test_control(int, db, int) */ case SQLITE_TESTCTRL_OPTIMIZATIONS: if( nArg==3 ){ - int opt = (int)strtol(azArg[2], 0, 0); + unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0); rc2 = sqlite3_test_control(testctrl, p->db, opt); isOk = 3; } @@ -20332,11 +20495,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ - sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; + unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x); }else -#endif if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ int j; @@ -20825,7 +20987,8 @@ static char *cmdline_option_value(int argc, char **argv, int i){ } #ifndef SQLITE_SHELL_IS_UTF8 -# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER) +# if (defined(_WIN32) || defined(WIN32)) \ + && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__))) # define SQLITE_SHELL_IS_UTF8 (0) # else # define SQLITE_SHELL_IS_UTF8 (1) diff --git a/chromium/third_party/sqlite/src/amalgamation_dev/sqlite3.c b/chromium/third_party/sqlite/src/amalgamation_dev/sqlite3.c index 37c03a0dd12..df53e437baa 100644 --- a/chromium/third_party/sqlite/src/amalgamation_dev/sqlite3.c +++ b/chromium/third_party/sqlite/src/amalgamation_dev/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.34.0. By combining all the individual C code files into this +** version 3.35.5. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -284,6 +284,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ENABLE_LOCKING_STYLE "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), #endif +#if SQLITE_ENABLE_MATH_FUNCTIONS + "ENABLE_MATH_FUNCTIONS", +#endif #if SQLITE_ENABLE_MEMORY_MANAGEMENT "ENABLE_MEMORY_MANAGEMENT", #endif @@ -990,6 +993,18 @@ SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){ # define MSVC_VERSION 0 #endif +/* +** Some C99 functions in "math.h" are only present for MSVC when its version +** is associated with Visual Studio 2013 or higher. +*/ +#ifndef SQLITE_HAVE_C99_MATH_FUNCS +# if MSVC_VERSION==0 || MSVC_VERSION>=1800 +# define SQLITE_HAVE_C99_MATH_FUNCS (1) +# else +# define SQLITE_HAVE_C99_MATH_FUNCS (0) +# endif +#endif + /* Needed for various definitions... */ #if defined(__GNUC__) && !defined(_GNU_SOURCE) # define _GNU_SOURCE @@ -1171,9 +1186,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.34.0" -#define SQLITE_VERSION_NUMBER 3034000 -#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 b7738010bc8ef02ba84820368e557306390a33c38adaa5c7703154bae3edalt1" +#define SQLITE_VERSION "3.35.5" +#define SQLITE_VERSION_NUMBER 3035005 +#define SQLITE_SOURCE_ID "2021-04-19 18:32:05 1b256d97b553a9611efca188a3d995a2fff712759044ba480f9a0c9e98fae886" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -3163,7 +3178,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. </dd> +** which case the trigger setting is not reported back. +** +** <p>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.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] ** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt> @@ -3174,7 +3195,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. </dd> +** which case the view setting is not reported back. +** +** <p>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.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> @@ -4547,6 +4574,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** that uses dot-files in place of posix advisory locking. ** <tr><td> file:data.db?mode=readonly <td> ** An error. "readonly" is not a valid option for the "mode" parameter. +** Use "ro" instead: "file:data.db?mode=ro". ** </table> ** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and @@ -4745,7 +4773,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 @@ -8813,7 +8841,8 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 #define SQLITE_TESTCTRL_SEEK_COUNT 30 -#define SQLITE_TESTCTRL_LAST 30 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_TRACEFLAGS 31 +#define SQLITE_TESTCTRL_LAST 31 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -11487,6 +11516,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 ** @@ -11588,18 +11625,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 @@ -13528,7 +13570,8 @@ struct fts5_api { #ifndef __has_extension # define __has_extension(x) 0 /* compatibility with non-clang compilers */ #endif -#if GCC_VERSION>=4007000 || __has_extension(c_atomic) +#if GCC_VERSION>=4007000 || \ + (__has_extension(c_atomic) && __has_extension(c_atomic_store_n)) # define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED) # define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED) #else @@ -14095,90 +14138,92 @@ 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_COLLATE 112 +#define TK_BITNOT 113 +#define TK_ON 114 +#define TK_INDEXED 115 +#define TK_STRING 116 +#define TK_JOIN_KW 117 +#define TK_CONSTRAINT 118 +#define TK_DEFAULT 119 +#define TK_NULL 120 +#define TK_PRIMARY 121 +#define TK_UNIQUE 122 +#define TK_CHECK 123 +#define TK_REFERENCES 124 +#define TK_AUTOINCR 125 +#define TK_INSERT 126 +#define TK_DELETE 127 +#define TK_UPDATE 128 +#define TK_SET 129 +#define TK_DEFERRABLE 130 +#define TK_FOREIGN 131 +#define TK_DROP 132 +#define TK_UNION 133 +#define TK_ALL 134 +#define TK_EXCEPT 135 +#define TK_INTERSECT 136 +#define TK_SELECT 137 +#define TK_VALUES 138 +#define TK_DISTINCT 139 +#define TK_DOT 140 +#define TK_FROM 141 +#define TK_JOIN 142 +#define TK_USING 143 +#define TK_ORDER 144 +#define TK_GROUP 145 +#define TK_HAVING 146 +#define TK_LIMIT 147 +#define TK_WHERE 148 +#define TK_RETURNING 149 +#define TK_INTO 150 +#define TK_NOTHING 151 +#define TK_FLOAT 152 +#define TK_BLOB 153 +#define TK_INTEGER 154 +#define TK_VARIABLE 155 +#define TK_CASE 156 +#define TK_WHEN 157 +#define TK_THEN 158 +#define TK_ELSE 159 +#define TK_INDEX 160 +#define TK_ALTER 161 +#define TK_ADD 162 +#define TK_WINDOW 163 +#define TK_OVER 164 +#define TK_FILTER 165 +#define TK_COLUMN 166 +#define TK_AGG_FUNCTION 167 +#define TK_AGG_COLUMN 168 +#define TK_TRUEFALSE 169 +#define TK_ISNOT 170 +#define TK_FUNCTION 171 +#define TK_UMINUS 172 +#define TK_UPLUS 173 +#define TK_TRUTH 174 +#define TK_REGISTER 175 +#define TK_VECTOR 176 +#define TK_SELECT_COLUMN 177 +#define TK_IF_NULL_ROW 178 +#define TK_ASTERISK 179 +#define TK_SPAN 180 +#define TK_SPACE 181 +#define TK_ILLEGAL 182 /************** End of parse.h ***********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -14594,15 +14639,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 @@ -14611,6 +14655,19 @@ typedef INT16_TYPE LogEst; #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. ** @@ -14721,7 +14778,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; @@ -14739,14 +14799,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; @@ -15318,6 +15381,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. @@ -15417,6 +15481,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 @@ -15716,103 +15782,105 @@ typedef struct VdbeOpList VdbeOpList; #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_ShiftRight 104 /* same as TK_RSHIFT, 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_SeekScan 118 /* synopsis: Scan-ahead up to P1 rows */ -#define OP_SeekHit 119 /* synopsis: set P2<=seekHit<=P3 */ -#define OP_Sequence 120 /* synopsis: r[P2]=cursor[P1].ctr++ */ -#define OP_NewRowid 121 /* synopsis: r[P2]=rowid */ -#define OP_Insert 122 /* synopsis: intkey=r[P3] data=r[P2] */ -#define OP_Delete 123 -#define OP_ResetCount 124 -#define OP_SorterCompare 125 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ -#define OP_SorterData 126 /* synopsis: r[P2]=data */ -#define OP_RowData 127 /* synopsis: r[P2]=data */ -#define OP_Rowid 128 /* synopsis: r[P2]=rowid */ -#define OP_NullRow 129 -#define OP_SeekEnd 130 -#define OP_IdxInsert 131 /* synopsis: key=r[P2] */ -#define OP_SorterInsert 132 /* synopsis: key=r[P2] */ -#define OP_IdxDelete 133 /* synopsis: key=r[P2@P3] */ -#define OP_DeferredSeek 134 /* synopsis: Move P3 to P1.rowid if needed */ -#define OP_IdxRowid 135 /* synopsis: r[P2]=rowid */ -#define OP_FinishSeek 136 -#define OP_Destroy 137 -#define OP_Clear 138 -#define OP_ResetSorter 139 -#define OP_CreateBtree 140 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ -#define OP_SqlExec 141 -#define OP_ParseSchema 142 -#define OP_LoadAnalysis 143 -#define OP_DropTable 144 -#define OP_DropIndex 145 -#define OP_DropTrigger 146 -#define OP_IntegrityCk 147 -#define OP_RowSetAdd 148 /* synopsis: rowset(P1)=r[P2] */ -#define OP_Param 149 -#define OP_Real 150 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_FkCounter 151 /* synopsis: fkctr[P1]+=P2 */ -#define OP_MemMax 152 /* synopsis: r[P1]=max(r[P1],r[P2]) */ -#define OP_OffsetLimit 153 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -#define OP_AggInverse 154 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ -#define OP_AggStep 155 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggStep1 156 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggValue 157 /* synopsis: r[P3]=value N=P2 */ -#define OP_AggFinal 158 /* synopsis: accum=r[P1] N=P2 */ -#define OP_Expire 159 -#define OP_CursorLock 160 -#define OP_CursorUnlock 161 -#define OP_TableLock 162 /* synopsis: iDb=P1 root=P2 write=P3 */ -#define OP_VBegin 163 -#define OP_VCreate 164 -#define OP_VDestroy 165 -#define OP_VOpen 166 -#define OP_VColumn 167 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VRename 168 -#define OP_Pagecount 169 -#define OP_MaxPgcnt 170 -#define OP_Trace 171 -#define OP_CursorHint 172 -#define OP_ReleaseReg 173 /* synopsis: release r[P1@P2] mask P3 */ -#define OP_Noop 174 -#define OP_Explain 175 -#define OP_Abortable 176 +#define OP_ChngCntRow 80 /* synopsis: output=r[P1] */ +#define OP_ResultRow 81 /* synopsis: output=r[P1@P2] */ +#define OP_CollSeq 82 +#define OP_AddImm 83 /* synopsis: r[P1]=r[P1]+P2 */ +#define OP_RealAffinity 84 +#define OP_Cast 85 /* synopsis: affinity(r[P1]) */ +#define OP_Permutation 86 +#define OP_Compare 87 /* synopsis: r[P1@P3] <-> r[P2@P3] */ +#define OP_IsTrue 88 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ +#define OP_Offset 89 /* synopsis: r[P3] = sqlite_offset(P1) */ +#define OP_Column 90 /* synopsis: r[P3]=PX */ +#define OP_Affinity 91 /* synopsis: affinity(r[P1@P2]) */ +#define OP_MakeRecord 92 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ +#define OP_Count 93 /* synopsis: r[P2]=count() */ +#define OP_ReadCookie 94 +#define OP_SetCookie 95 +#define OP_ReopenIdx 96 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenRead 97 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenWrite 98 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenDup 99 +#define OP_OpenAutoindex 100 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 101 /* synopsis: nColumn=P2 */ +#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_ShiftRight 105 /* same as TK_RSHIFT, 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_SorterOpen 112 +#define OP_BitNot 113 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ +#define OP_SequenceTest 114 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ +#define OP_OpenPseudo 115 /* synopsis: P3 columns in r[P2] */ +#define OP_String8 116 /* same as TK_STRING, synopsis: r[P2]='P4' */ +#define OP_Close 117 +#define OP_ColumnsUsed 118 +#define OP_SeekScan 119 /* synopsis: Scan-ahead up to P1 rows */ +#define OP_SeekHit 120 /* synopsis: set P2<=seekHit<=P3 */ +#define OP_Sequence 121 /* synopsis: r[P2]=cursor[P1].ctr++ */ +#define OP_NewRowid 122 /* synopsis: r[P2]=rowid */ +#define OP_Insert 123 /* synopsis: intkey=r[P3] data=r[P2] */ +#define OP_RowCell 124 +#define OP_Delete 125 +#define OP_ResetCount 126 +#define OP_SorterCompare 127 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ +#define OP_SorterData 128 /* synopsis: r[P2]=data */ +#define OP_RowData 129 /* synopsis: r[P2]=data */ +#define OP_Rowid 130 /* synopsis: r[P2]=rowid */ +#define OP_NullRow 131 +#define OP_SeekEnd 132 +#define OP_IdxInsert 133 /* synopsis: key=r[P2] */ +#define OP_SorterInsert 134 /* synopsis: key=r[P2] */ +#define OP_IdxDelete 135 /* synopsis: key=r[P2@P3] */ +#define OP_DeferredSeek 136 /* synopsis: Move P3 to P1.rowid if needed */ +#define OP_IdxRowid 137 /* synopsis: r[P2]=rowid */ +#define OP_FinishSeek 138 +#define OP_Destroy 139 +#define OP_Clear 140 +#define OP_ResetSorter 141 +#define OP_CreateBtree 142 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ +#define OP_SqlExec 143 +#define OP_ParseSchema 144 +#define OP_LoadAnalysis 145 +#define OP_DropTable 146 +#define OP_DropIndex 147 +#define OP_DropTrigger 148 +#define OP_IntegrityCk 149 +#define OP_RowSetAdd 150 /* synopsis: rowset(P1)=r[P2] */ +#define OP_Param 151 +#define OP_Real 152 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ +#define OP_FkCounter 153 /* synopsis: fkctr[P1]+=P2 */ +#define OP_MemMax 154 /* synopsis: r[P1]=max(r[P1],r[P2]) */ +#define OP_OffsetLimit 155 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ +#define OP_AggInverse 156 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ +#define OP_AggStep 157 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggStep1 158 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggValue 159 /* synopsis: r[P3]=value N=P2 */ +#define OP_AggFinal 160 /* synopsis: accum=r[P1] N=P2 */ +#define OP_Expire 161 +#define OP_CursorLock 162 +#define OP_CursorUnlock 163 +#define OP_TableLock 164 /* synopsis: iDb=P1 root=P2 write=P3 */ +#define OP_VBegin 165 +#define OP_VCreate 166 +#define OP_VDestroy 167 +#define OP_VOpen 168 +#define OP_VColumn 169 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VRename 170 +#define OP_Pagecount 171 +#define OP_MaxPgcnt 172 +#define OP_Trace 173 +#define OP_CursorHint 174 +#define OP_ReleaseReg 175 /* synopsis: release r[P1@P2] mask P3 */ +#define OP_Noop 176 +#define OP_Explain 177 +#define OP_Abortable 178 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c @@ -15835,19 +15903,19 @@ typedef struct VdbeOpList VdbeOpList; /* 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, 0x00,\ -/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 128 */ 0x10, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10,\ -/* 136 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\ -/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00,\ -/* 152 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 80 */ 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\ +/* 88 */ 0x12, 0x20, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\ +/* 96 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x26,\ +/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ +/* 112 */ 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\ +/* 120 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 128 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x04, 0x04, 0x00,\ +/* 136 */ 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00,\ +/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10,\ +/* 152 */ 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00,\ /* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 168 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 176 */ 0x00,} +/* 168 */ 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00,\ +/* 176 */ 0x00, 0x00, 0x00,} /* The sqlite3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum @@ -15915,7 +15983,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); @@ -16887,6 +16955,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. @@ -16907,7 +16980,7 @@ struct sqlite3 { int errCode; /* Most recent error code (SQLITE_*) */ 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 */ @@ -16934,7 +17007,10 @@ 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 */ + unsigned bDropColumn : 1; /* Doing schema check after DROP COLUMN */ char **azInit; /* "type", "name", and "tbl_name" columns */ + /* or if bDropColumn, then azInit[0] is the */ + /* name of the column being dropped */ } init; int nVdbeActive; /* Number of VDBEs currently running */ int nVdbeRead; /* Number of active VDBEs that read or write */ @@ -17114,24 +17190,26 @@ 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_ExistsToIN 0x00020000 /* The EXISTS-to-IN optimization */ +#define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. @@ -17287,6 +17365,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 @@ -17322,6 +17403,9 @@ struct FuncDestructor { #define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } +#define MFUNCTION(zName, nArg, xPtr, xFunc) \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ + xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } @@ -17416,7 +17500,12 @@ struct Column { u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */ }; -/* Allowed values for Column.colFlags: +/* 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 */ @@ -17592,7 +17681,6 @@ struct Table { #endif Trigger *pTrigger; /* List of triggers stored in pSchema */ Schema *pSchema; /* Schema that contains this table */ - Table *pNextZombie; /* Next on the Parse.pZombieTab list */ }; /* @@ -17606,11 +17694,12 @@ struct Table { ** ** Constraints: ** -** TF_HasVirtual == COLFLAG_Virtual -** TF_HasStored == COLFLAG_Stored +** TF_HasVirtual == COLFLAG_VIRTUAL +** TF_HasStored == COLFLAG_STORED +** TF_HasHidden == COLFLAG_HIDDEN */ #define TF_Readonly 0x0001 /* Read-only system table */ -#define TF_Ephemeral 0x0002 /* An ephemeral table */ +#define TF_HasHidden 0x0002 /* Has one or more hidden columns */ #define TF_HasPrimaryKey 0x0004 /* Table has a primary key */ #define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */ #define TF_HasStat1 0x0010 /* nRowLogEst set from sqlite_stat1 */ @@ -17625,6 +17714,7 @@ struct Table { #define TF_HasNotNull 0x0800 /* Contains NOT NULL constraints */ #define TF_Shadow 0x1000 /* True for a shadow table */ #define TF_HasStat4 0x2000 /* STAT4 info available for this table */ +#define TF_Ephemeral 0x4000 /* An ephemeral table */ /* ** Test to see whether or not a table is a virtual table. This is @@ -17721,16 +17811,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 */ @@ -17987,7 +18083,6 @@ struct AggInfo { } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ - AggInfo *pNext; /* Next in list of them all */ }; /* @@ -18116,7 +18211,7 @@ 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 */ + int iRightJoinTable; /* If EP_FromJoin, the right table of the join */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ union { Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL @@ -18158,7 +18253,7 @@ struct Expr { #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 */ @@ -18307,6 +18402,45 @@ struct IdList { }; /* +** The SrcItem object represents a single term in the FROM clause of a query. +** The SrcList object is mostly an array of SrcItems. +*/ +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 */ + } 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<<N) set if column N of pTab is used */ + union { + char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" 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 ** the SrcList.a[] array. @@ -18328,36 +18462,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<<N) set if column N of pTab is used */ - union { - char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" 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 */ }; /* @@ -18433,6 +18538,7 @@ 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 */ @@ -18461,6 +18567,7 @@ struct NameContext { #define NC_UEList 0x00080 /* True if uNC.pEList is used */ #define NC_UAggInfo 0x00100 /* True if uNC.pAggInfo is used */ #define NC_UUpsert 0x00200 /* True if uNC.pUpsert is used */ +#define NC_UBaseReg 0x00400 /* True if uNC.iBaseReg is used */ #define NC_MinMaxAgg 0x01000 /* min/max aggregates seen. See note above */ #define NC_Complex 0x02000 /* True if a function or subquery seen */ #define NC_AllowWin 0x04000 /* Window functions are allowed here */ @@ -18484,15 +18591,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 */ @@ -18572,6 +18685,8 @@ struct Select { #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_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ +#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ /* ** The results of a SELECT can be distributed in several ways, as defined @@ -18743,6 +18858,17 @@ struct TriggerPrg { #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 ** carry around information that is global to the entire parse. @@ -18773,6 +18899,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 */ @@ -18800,12 +18929,15 @@ struct Parse { 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 */ + 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 */ @@ -18851,10 +18983,9 @@ 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 */ + ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */ #ifndef SQLITE_OMIT_ALTERTABLE RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */ #endif @@ -18934,6 +19065,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 @@ -18955,6 +19087,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 <column-list> trigger, the <column-list> is stored here */ @@ -19013,14 +19146,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 */ @@ -19029,18 +19163,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 */ }; /* @@ -19080,7 +19212,8 @@ typedef struct { /* ** Allowed values for mInitFlags */ -#define INITFLAG_AlterTable 0x0001 /* This is a reparse after ALTER TABLE */ +#define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */ +#define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */ /* ** Structure containing global configuration data for the SQLite library. @@ -19192,10 +19325,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*); @@ -19221,20 +19370,55 @@ 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 */ + 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 @@ -19580,6 +19764,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,Expr*,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*); @@ -19628,6 +19813,7 @@ 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 sqlite3AddReturning(Parse*,ExprList*); SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); #define sqlite3CodecQueryParameters(A,B,C) 0 @@ -19693,7 +19879,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*); @@ -19721,6 +19907,7 @@ 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*); @@ -19754,7 +19941,7 @@ 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 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*); @@ -19882,6 +20069,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); @@ -19904,7 +20092,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*); @@ -19967,6 +20154,7 @@ 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); @@ -20030,7 +20218,6 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; 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 @@ -20049,7 +20236,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*, struct SrcList_item*); +SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, SrcItem*); SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); SQLITE_PRIVATE int sqlite3MatchEName( const struct ExprList_item*, @@ -20067,6 +20254,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); +SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse*, SrcList*, Token*); SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse*, void*, Token*); SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*); @@ -20090,6 +20278,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 @@ -20220,6 +20409,7 @@ 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 *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*); #ifdef SQLITE_ENABLE_NORMALIZE SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*); #endif @@ -20234,23 +20424,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); #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) #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 @@ -20746,9 +20945,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" */ /* @@ -20872,6 +21072,7 @@ 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 hasBeenDuped:1; /* This cursor was source or target of OP_OpenDup */ u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ Btree *pBtx; /* Separate file holding temporary table */ i64 seqCount; /* Sequence counter */ @@ -21167,7 +21368,7 @@ 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 */ @@ -22672,6 +22873,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 @@ -23172,6 +23374,8 @@ SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ #ifdef SQLITE_TEST if( op!=SQLITE_FCNTL_COMMIT_PHASETWO && op!=SQLITE_FCNTL_LOCK_TIMEOUT + && op!=SQLITE_FCNTL_CKPT_DONE + && op!=SQLITE_FCNTL_CKPT_START ){ /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite ** is using a regular VFS, it is called after the corresponding @@ -23182,7 +23386,12 @@ SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ ** The core must call OsFileControl() though, not OsFileControlHint(), ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably ** means the commit really has failed and an error should be returned - ** to the user. */ + ** to the user. + ** + ** The CKPT_DONE and CKPT_START file-controls are write-only signals + ** to the cksumvfs. Their return code is meaningless and is ignored + ** by the SQLite core, so there is no point in simulating OOMs for them. + */ DO_OS_MALLOC_TEST(id); } #endif @@ -29081,7 +29290,7 @@ SQLITE_API void sqlite3_str_vappendf( case etSRCLIST: { SrcList *pSrc; int k; - struct SrcList_item *pItem; + SrcItem *pItem; if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; pSrc = va_arg(ap, SrcList*); k = va_arg(ap, int); @@ -29146,7 +29355,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ }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 */ @@ -29649,7 +29858,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, i<pWith->nCte-1); sqlite3TreeViewSelect(pView, pCte->pSelect, 0); @@ -29665,7 +29877,7 @@ 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; i<pSrc->nSrc; 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); @@ -29688,6 +29900,9 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) 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, i<pSrc->nSrc-1); if( pItem->pSelect ){ @@ -31385,6 +31600,16 @@ SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ } /* +** 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; + if( db->pErr ) sqlite3ValueSetNull(db->pErr); +} + +/* ** Load the sqlite3.iSysErrno field if that is an appropriate thing ** to do based on the SQLite error code in rc. */ @@ -33330,103 +33555,105 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 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]"), - /* 104 */ "ShiftRight" 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 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), - /* 119 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), - /* 120 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), - /* 121 */ "NewRowid" OpHelp("r[P2]=rowid"), - /* 122 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), - /* 123 */ "Delete" OpHelp(""), - /* 124 */ "ResetCount" OpHelp(""), - /* 125 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), - /* 126 */ "SorterData" OpHelp("r[P2]=data"), - /* 127 */ "RowData" OpHelp("r[P2]=data"), - /* 128 */ "Rowid" OpHelp("r[P2]=rowid"), - /* 129 */ "NullRow" OpHelp(""), - /* 130 */ "SeekEnd" OpHelp(""), - /* 131 */ "IdxInsert" OpHelp("key=r[P2]"), - /* 132 */ "SorterInsert" OpHelp("key=r[P2]"), - /* 133 */ "IdxDelete" OpHelp("key=r[P2@P3]"), - /* 134 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), - /* 135 */ "IdxRowid" OpHelp("r[P2]=rowid"), - /* 136 */ "FinishSeek" OpHelp(""), - /* 137 */ "Destroy" OpHelp(""), - /* 138 */ "Clear" OpHelp(""), - /* 139 */ "ResetSorter" OpHelp(""), - /* 140 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), - /* 141 */ "SqlExec" OpHelp(""), - /* 142 */ "ParseSchema" OpHelp(""), - /* 143 */ "LoadAnalysis" OpHelp(""), - /* 144 */ "DropTable" OpHelp(""), - /* 145 */ "DropIndex" OpHelp(""), - /* 146 */ "DropTrigger" OpHelp(""), - /* 147 */ "IntegrityCk" OpHelp(""), - /* 148 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), - /* 149 */ "Param" OpHelp(""), - /* 150 */ "Real" OpHelp("r[P2]=P4"), - /* 151 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), - /* 152 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), - /* 153 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), - /* 154 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), - /* 155 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 156 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 157 */ "AggValue" OpHelp("r[P3]=value N=P2"), - /* 158 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 159 */ "Expire" OpHelp(""), - /* 160 */ "CursorLock" OpHelp(""), - /* 161 */ "CursorUnlock" OpHelp(""), - /* 162 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), - /* 163 */ "VBegin" OpHelp(""), - /* 164 */ "VCreate" OpHelp(""), - /* 165 */ "VDestroy" OpHelp(""), - /* 166 */ "VOpen" OpHelp(""), - /* 167 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 168 */ "VRename" OpHelp(""), - /* 169 */ "Pagecount" OpHelp(""), - /* 170 */ "MaxPgcnt" OpHelp(""), - /* 171 */ "Trace" OpHelp(""), - /* 172 */ "CursorHint" OpHelp(""), - /* 173 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), - /* 174 */ "Noop" OpHelp(""), - /* 175 */ "Explain" OpHelp(""), - /* 176 */ "Abortable" OpHelp(""), + /* 80 */ "ChngCntRow" OpHelp("output=r[P1]"), + /* 81 */ "ResultRow" OpHelp("output=r[P1@P2]"), + /* 82 */ "CollSeq" OpHelp(""), + /* 83 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), + /* 84 */ "RealAffinity" OpHelp(""), + /* 85 */ "Cast" OpHelp("affinity(r[P1])"), + /* 86 */ "Permutation" OpHelp(""), + /* 87 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), + /* 88 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), + /* 89 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), + /* 90 */ "Column" OpHelp("r[P3]=PX"), + /* 91 */ "Affinity" OpHelp("affinity(r[P1@P2])"), + /* 92 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), + /* 93 */ "Count" OpHelp("r[P2]=count()"), + /* 94 */ "ReadCookie" OpHelp(""), + /* 95 */ "SetCookie" OpHelp(""), + /* 96 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), + /* 97 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 98 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 99 */ "OpenDup" OpHelp(""), + /* 100 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 101 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 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]"), + /* 105 */ "ShiftRight" 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 */ "SorterOpen" OpHelp(""), + /* 113 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), + /* 114 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), + /* 115 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), + /* 116 */ "String8" OpHelp("r[P2]='P4'"), + /* 117 */ "Close" OpHelp(""), + /* 118 */ "ColumnsUsed" OpHelp(""), + /* 119 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), + /* 120 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), + /* 121 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), + /* 122 */ "NewRowid" OpHelp("r[P2]=rowid"), + /* 123 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), + /* 124 */ "RowCell" OpHelp(""), + /* 125 */ "Delete" OpHelp(""), + /* 126 */ "ResetCount" OpHelp(""), + /* 127 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), + /* 128 */ "SorterData" OpHelp("r[P2]=data"), + /* 129 */ "RowData" OpHelp("r[P2]=data"), + /* 130 */ "Rowid" OpHelp("r[P2]=rowid"), + /* 131 */ "NullRow" OpHelp(""), + /* 132 */ "SeekEnd" OpHelp(""), + /* 133 */ "IdxInsert" OpHelp("key=r[P2]"), + /* 134 */ "SorterInsert" OpHelp("key=r[P2]"), + /* 135 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 136 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), + /* 137 */ "IdxRowid" OpHelp("r[P2]=rowid"), + /* 138 */ "FinishSeek" OpHelp(""), + /* 139 */ "Destroy" OpHelp(""), + /* 140 */ "Clear" OpHelp(""), + /* 141 */ "ResetSorter" OpHelp(""), + /* 142 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), + /* 143 */ "SqlExec" OpHelp(""), + /* 144 */ "ParseSchema" OpHelp(""), + /* 145 */ "LoadAnalysis" OpHelp(""), + /* 146 */ "DropTable" OpHelp(""), + /* 147 */ "DropIndex" OpHelp(""), + /* 148 */ "DropTrigger" OpHelp(""), + /* 149 */ "IntegrityCk" OpHelp(""), + /* 150 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), + /* 151 */ "Param" OpHelp(""), + /* 152 */ "Real" OpHelp("r[P2]=P4"), + /* 153 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 154 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), + /* 155 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), + /* 156 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), + /* 157 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 158 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 159 */ "AggValue" OpHelp("r[P3]=value N=P2"), + /* 160 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 161 */ "Expire" OpHelp(""), + /* 162 */ "CursorLock" OpHelp(""), + /* 163 */ "CursorUnlock" OpHelp(""), + /* 164 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 165 */ "VBegin" OpHelp(""), + /* 166 */ "VCreate" OpHelp(""), + /* 167 */ "VDestroy" OpHelp(""), + /* 168 */ "VOpen" OpHelp(""), + /* 169 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 170 */ "VRename" OpHelp(""), + /* 171 */ "Pagecount" OpHelp(""), + /* 172 */ "MaxPgcnt" OpHelp(""), + /* 173 */ "Trace" OpHelp(""), + /* 174 */ "CursorHint" OpHelp(""), + /* 175 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), + /* 176 */ "Noop" OpHelp(""), + /* 177 */ "Explain" OpHelp(""), + /* 178 */ "Abortable" OpHelp(""), }; return azName[i]; } @@ -39995,7 +40222,8 @@ static int unixBackupDir(const char *z, int *pJ){ int j = *pJ; int i; if( j<=0 ) return 0; - for(i=j-1; ALWAYS(i>0) && z[i-1]!='/'; i--){} + 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; @@ -52354,6 +52582,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 @@ -52989,6 +53218,9 @@ static int subjRequiresPage(PgHdr *pPg){ for(i=0; i<pPager->nSavepoint; i++){ p = &pPager->aSavepoint[i]; if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){ + for(i=i+1; i<pPager->nSavepoint; i++){ + pPager->aSavepoint[i].bTruncateOnRelease = 0; + } return 1; } } @@ -58767,6 +58999,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; } @@ -58848,13 +59081,15 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ /* If this is a release of the outermost savepoint, truncate ** the sub-journal to zero bytes in size. */ 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)*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. @@ -64045,7 +64280,7 @@ 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 @@ -64150,6 +64385,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() */ }; /* @@ -65864,6 +66100,24 @@ static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow( } /* +** 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. ** @@ -67439,19 +67693,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 @@ -67603,6 +67861,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); } @@ -68832,7 +69091,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); } @@ -69242,7 +69501,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; @@ -72676,6 +72942,9 @@ static int balance_nonroot( apOld[i] = 0; rc = sqlite3PagerWrite(pNew->pDbPage); nNew++; + if( sqlite3PagerPageRefcount(pNew->pDbPage)!=1+(i==(iParentIdx-nxDiv)) ){ + rc = SQLITE_CORRUPT_BKPT; + } if( rc ) goto balance_cleanup; }else{ assert( i>0 ); @@ -72712,7 +72981,7 @@ static int balance_nonroot( aPgOrder[i] = aPgno[i] = apNew[i]->pgno; aPgFlags[i] = apNew[i]->pDbPage->flags; for(j=0; j<i; j++){ - if( aPgno[j]==aPgno[i] ){ + if( NEVER(aPgno[j]==aPgno[i]) ){ /* This branch is taken if the set of sibling pages somehow contains ** duplicate entries. This can happen if the database is corrupt. ** It would be simpler to detect this as part of the loop below, but @@ -73380,7 +73649,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 ); @@ -73398,7 +73668,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. ** @@ -73508,7 +73778,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( || 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 ){ @@ -73525,7 +73795,21 @@ 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) ); @@ -73633,6 +73917,114 @@ end_insert: } /* +** 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 && nIn<pDest->pPage->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( nOut<pSrc->info.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 ){ + 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. ** ** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then @@ -74229,7 +74621,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]); } @@ -78020,7 +78412,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 ); @@ -78221,7 +78613,7 @@ 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); @@ -78456,9 +78848,10 @@ 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; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j); sqlite3MayAbort(p->pParse); } @@ -78550,7 +78943,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 @@ -78875,7 +79268,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; } @@ -78960,7 +79353,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; } @@ -79284,7 +79677,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); @@ -79413,7 +79806,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; } @@ -80098,7 +80491,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 @@ -80278,14 +80671,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; i<p->nMem; i++){ @@ -80341,8 +80734,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; @@ -80427,8 +80822,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( } } - p->pVList = pParse->pVList; - pParse->pVList = 0; if( db->mallocFailed ){ p->nVar = 0; p->nCursor = 0; @@ -80456,20 +80849,15 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ return; } assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE ); + assert( pCx->pBtx==0 || pCx->isEphemeral ); switch( pCx->eCurType ){ case CURTYPE_SORTER: { sqlite3VdbeSorterClose(p->db, pCx); 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 @@ -81026,7 +81414,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 ){ @@ -81184,7 +81572,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; @@ -81357,7 +81745,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ } } #endif - p->magic = VDBE_MAGIC_RESET; + p->iVdbeMagic = VDBE_MAGIC_RESET; return p->rc & db->errMask; } @@ -81367,7 +81755,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 ); } @@ -81428,7 +81816,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); @@ -81476,7 +81864,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); } @@ -81553,6 +81941,7 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){ assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); if( p->deferredMoveto ){ u32 iMap; + assert( !p->isEphemeral ); if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 && !p->nullRow ){ *pp = p->pAltCursor; *piCol = iMap - 1; @@ -83855,7 +84244,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 @@ -84571,7 +84960,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, @@ -84925,7 +85314,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; } /* @@ -85417,7 +85806,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 ){ @@ -85761,11 +86150,6 @@ static VdbeCursor *allocateCursor( assert( iCur>=0 && iCur<p->nCursor ); 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; } @@ -86263,7 +86647,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 ){ @@ -87023,6 +87407,26 @@ case OP_IntCopy: { /* out2 */ break; } +/* Opcode: ChngCntRow P1 P2 * * * +** Synopsis: output=r[P1] +** +** Output value in register P1 as the chance count for a DML statement, +** due to the "PRAGMA count_changes=ON" setting. Or, if there was a +** foreign key error in the statement, trigger the error now. +** +** This opcode is a variant of OP_ResultRow that checks the foreign key +** immediate constraint count and throws an error if the count is +** non-zero. The P2 opcode must be 1. +*/ +case OP_ChngCntRow: { + assert( pOp->p2==1 ); + if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){ + goto abort_due_to_error; + } + /* Fall through to the next case, OP_ResultRow */ + /* no break */ deliberate_fall_through +} + /* Opcode: ResultRow P1 P2 * * * ** Synopsis: output=r[P1@P2] ** @@ -87039,34 +87443,6 @@ case OP_ResultRow: { assert( pOp->p1>0 ); 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; @@ -89459,7 +89835,7 @@ 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); if( pCx==0 ) goto no_mem; @@ -89469,7 +89845,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->pBtx = pOrig->pBtx; + pCx->hasBeenDuped = 1; + pOrig->hasBeenDuped = 1; + rc = sqlite3BtreeCursor(pCx->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 @@ -89535,9 +89914,10 @@ case OP_OpenEphemeral: { 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 ){ + /* 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; @@ -89551,33 +89931,36 @@ case OP_OpenEphemeral: { 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); + 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); + } + pCx->isTable = 0; + }else{ + pCx->pgnoRoot = SCHEMA_ROOT; + rc = sqlite3BtreeCursor(pCx->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->pBtx); } } - pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); } if( rc ) goto abort_due_to_error; pCx->nullRow = 1; @@ -90011,13 +90394,13 @@ seek_not_found: ** ** There are three possible outcomes from this opcode:<ol> ** -** <li> If after This.P1 steps, the cursor is still point to a place that -** is earlier in the btree than the target row, -** then fall through into the subsquence OP_SeekGE opcode. +** <li> 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. ** ** <li> 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 opcode that follows the OP_SeekGE. +** past the OP_IdxGT or OP_IdxGE opcode that follows the OP_SeekGE. ** ** <li> 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. @@ -90034,7 +90417,8 @@ case OP_SeekScan: { /* 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 ); + 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 ); @@ -90487,8 +90871,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; @@ -90704,7 +91090,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; @@ -90721,6 +91108,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. @@ -91376,7 +91790,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 ); @@ -91387,7 +91801,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 ); @@ -91460,7 +91874,7 @@ case OP_IdxDelete: { rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); if( rc ) goto abort_due_to_error; }else if( pOp->p5 ){ - rc = SQLITE_CORRUPT_INDEX; + rc = sqlite3ReportError(SQLITE_CORRUPT_INDEX, __LINE__, "index corruption"); goto abort_due_to_error; } assert( pC->deferredMoveto==0 ); @@ -91539,6 +91953,8 @@ case OP_IdxRowid: { /* out2 */ pTabCur->deferredMoveto = 1; assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); pTabCur->aAltMap = pOp->p4.ai; + assert( !pC->isEphemeral ); + assert( !pTabCur->isEphemeral ); pTabCur->pAltCursor = pC; }else{ pOut = out2Prerelease(p, pOp); @@ -91886,7 +92302,7 @@ case OP_ParseSchema: { 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 @@ -97594,7 +98010,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() */ @@ -97655,14 +98070,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; } /* @@ -97689,7 +98103,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 ){ @@ -97772,7 +98186,6 @@ static int memjrnlWrite( nWrite -= iSpace; p->endpoint.iOffset += iSpace; } - p->nSize = iAmt + iOfst; } } @@ -97780,22 +98193,30 @@ 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; - p->readpoint.pChunk = 0; - p->readpoint.iOffset = 0; + FileChunk *pIter = 0; + + if( size==0 ){ + memjrnlFreeChunks(p->pFirst); + p->pFirst = 0; + }else{ + i64 iOff = p->nChunkSize; + for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){ + 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; return SQLITE_OK; } @@ -97804,7 +98225,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; } @@ -97978,7 +98399,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; @@ -97997,6 +98418,7 @@ static int walkWindowList(Walker *pWalker, Window *pList){ if( NEVER(rc) ) return WRC_Abort; rc = sqlite3WalkExpr(pWalker, pWin->pEnd); if( NEVER(rc) ) return WRC_Abort; + if( bOneOnly ) break; } return WRC_Continue; } @@ -98044,7 +98466,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 } @@ -98091,7 +98513,7 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ if( pParse && IN_RENAME_OBJECT ){ /* 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; } } @@ -98109,7 +98531,7 @@ 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 ){ @@ -98275,7 +98697,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 */ @@ -98288,7 +98709,7 @@ static void resolveAlias( db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); if( pDup!=0 ){ - if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); + incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } @@ -98317,7 +98738,6 @@ static void resolveAlias( } sqlite3DbFree(db, pDup); } - ExprSetProperty(pExpr, EP_Alias); } @@ -98452,8 +98872,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 */ @@ -98574,25 +98994,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; @@ -98620,6 +99048,7 @@ static int lookupName( } if( iCol<pTab->nCol ){ cnt++; + pMatch = 0; #ifndef SQLITE_OMIT_UPSERT if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){ testcase( iCol==(-1) ); @@ -98631,27 +99060,32 @@ 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)<<iCol)); - }else{ - testcase( iCol==31 ); - testcase( iCol==32 ); - pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); - } pExpr->y.pTab = pTab; - pExpr->iColumn = (i16)iCol; - eNewExprOp = TK_TRIGGER; + if( pParse->bReturning ){ + eNewExprOp = TK_REGISTER; + 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)<<iCol)); + }else{ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); + } #endif /* SQLITE_OMIT_TRIGGER */ + } } } } @@ -98721,7 +99155,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 ); @@ -98756,6 +99190,7 @@ static int lookupName( assert( pExpr->op==TK_ID ); if( ExprHasProperty(pExpr,EP_DblQuoted) && areDoubleQuotedStringsEnabled(db, pTopNC) + && (db->init.bDropColumn==0 || sqlite3StrICmp(zCol, db->init.azInit[0])!=0) ){ /* If a double-quoted identifier does not match any known column name, ** then treat it as a string. @@ -98770,6 +99205,11 @@ static int lookupName( ** Someday, I hope to get rid of this hack. Unfortunately there is ** a huge amount of legacy SQL that uses it. So for now, we just ** issue a warning. + ** + ** 2021-03-15: ticket 1c24a659e6d7f3a1 + ** Do not do the ID-to-STRING conversion when doing the schema + ** sanity check following a DROP COLUMN if the identifer name matches + ** the name of the column being dropped. */ sqlite3_log(SQLITE_WARNING, "double-quoted string literal: \"%w\"", zCol); @@ -98823,18 +99263,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(;;){ @@ -98856,7 +99302,7 @@ lookupname_end: 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]; + SrcItem *pItem = &pSrc->a[iSrc]; Table *pTab = p->y.pTab = pItem->pTab; p->iTable = pItem->iCursor; if( p->y.pTab->iPKey==iCol ){ @@ -98968,7 +99414,7 @@ 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; @@ -98979,6 +99425,47 @@ 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 && i<ArraySize(anRef); p=p->pNext, i++){ + anRef[i] = p->nRef; + } + sqlite3WalkExpr(pWalker, pExpr->pLeft); + if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){ + 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 && i<ArraySize(anRef); p=p->pNext, 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 @@ -99206,6 +99693,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( 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); @@ -99280,7 +99768,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 || pRight->op==TK_TRUEFALSE) ){ + 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 ){ @@ -99596,8 +100084,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy( resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); 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; @@ -99782,27 +100269,26 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Recursively resolve names in all subqueries */ for(i=0; i<p->pSrc->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; - 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); + } } } @@ -99844,7 +100330,7 @@ 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; @@ -99852,7 +100338,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Resolve names in table-valued-function arguments */ for(i=0; i<p->pSrc->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) ){ @@ -100261,7 +100747,18 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken( const Token *pCollName, /* Name of collating sequence */ int dequote /* True to dequote pCollName */ ){ - if( pCollName->n>0 ){ + assert( pExpr!=0 || pParse->db->mallocFailed ); + if( pExpr==0 ) return 0; + if( pExpr->op==TK_VECTOR ){ + ExprList *pList = pExpr->x.pList; + if( ALWAYS(pList!=0) ){ + int i; + for(i=0; i<pList->nExpr; i++){ + pList->a[i].pExpr = sqlite3ExprAddCollateToken(pParse,pList->a[i].pExpr, + pCollName, dequote); + } + } + }else if( pCollName->n>0 ){ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); if( pNew ){ pNew->pLeft = pExpr; @@ -101113,8 +101610,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); @@ -101311,6 +101808,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. */ @@ -101685,8 +102198,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; i<p->nSrc; i++){ - struct SrcList_item *pNewItem = &pNew->a[i]; - struct SrcList_item *pOldItem = &p->a[i]; + SrcItem *pNewItem = &pNew->a[i]; + SrcItem *pOldItem = &p->a[i]; Table *pTab; pNewItem->pSchema = pOldItem->pSchema; pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); @@ -101699,7 +102212,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); @@ -102737,7 +103253,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( /* Code an OP_Transaction and OP_TableLock for <table>. */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iDb>=0 && iDb<SQLITE_MAX_ATTACHED ); + assert( iDb>=0 && iDb<SQLITE_MAX_DB ); sqlite3CodeVerifySchema(pParse, iDb); sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); @@ -105933,8 +106449,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{ @@ -105943,8 +106458,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); } } } @@ -106016,7 +106530,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; i<pSrcList->nSrc; i++, pItem++){ struct AggInfo_col *pCol; assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); @@ -106305,15 +106819,22 @@ 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 */ + const char *zDropColumn /* Name of column being dropped */ +){ + pParse->colNamesSet = 1; sqlite3NestedParse(pParse, "SELECT 1 " "FROM \"%w\"." DFLT_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, %Q)=NULL ", zDb, - zDb, bTemp + zDb, bTemp, zWhen, zDropColumn ); if( bTemp==0 ){ @@ -106322,8 +106843,8 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ "FROM temp." DFLT_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, %Q)=NULL ", + zDb, zWhen, zDropColumn ); } } @@ -106332,12 +106853,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); } } @@ -106486,7 +107007,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); @@ -106505,8 +107026,8 @@ 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); @@ -106637,11 +107158,14 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ *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: */ sqlite3NestedParse(pParse, "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " - "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " + "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->addColOffset, zCol, pNew->addColOffset, zTab ); sqlite3DbFree(db, zCol); @@ -106665,7 +107189,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ } /* Reload the table definition */ - renameReloadSchema(pParse, iDb); + renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); } /* @@ -106765,7 +107289,7 @@ exit_begin_add_column: ** 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 ){ @@ -106778,15 +107302,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 /* @@ -106815,7 +107340,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); @@ -106869,8 +107394,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( ); /* 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", 0); exit_rename_column: sqlite3SrcListDelete(db, pSrc); @@ -107122,23 +107647,33 @@ 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, + void *pPtr +){ RenameToken **pp; assert( pPtr!=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; } /* @@ -107209,7 +107744,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 @@ -107218,8 +107753,8 @@ 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 = sqlite3_mprintf("error in %s %s%s%s: %s", + zT, zN, (zWhen[0] ? " " : ""), zWhen, pParse->zErrMsg ); sqlite3_result_error(pCtx, zErr, -1); @@ -107284,12 +107819,17 @@ static int renameParseSql( const char *zDb, /* Name of schema SQL belongs to */ sqlite3 *db, /* Database handle */ const char *zSql, /* SQL to parse */ - int bTemp /* True if SQL is from temp schema */ + int bTemp, /* True if SQL is from temp schema */ + const char *zDropColumn /* Name of column being dropped */ ){ int rc; char *zErr = 0; db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); + if( zDropColumn ){ + db->init.bDropColumn = 1; + db->init.azInit = (char**)&zDropColumn; + } /* 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 @@ -107298,7 +107838,7 @@ static int renameParseSql( p->eParseMode = PARSE_MODE_RENAME; p->db = db; p->nQueryLoop = 1; - rc = sqlite3RunParser(p, zSql, &zErr); + rc = zSql ? sqlite3RunParser(p, zSql, &zErr) : SQLITE_NOMEM; assert( p->zErrMsg==0 ); assert( rc!=SQLITE_OK || zErr==0 ); p->zErrMsg = zErr; @@ -107322,6 +107862,7 @@ static int renameParseSql( #endif db->init.iDb = 0; + db->init.bDropColumn = 0; return rc; } @@ -107451,7 +107992,7 @@ static int renameResolveTrigger(Parse *pParse){ if( pSrc ){ int i; for(i=0; i<pSrc->nSrc && rc==SQLITE_OK; i++){ - struct SrcList_item *p = &pSrc->a[i]; + SrcItem *p = &pSrc->a[i]; p->iCursor = pParse->nTab++; if( p->pSelect ){ sqlite3SelectPrep(pParse, p->pSelect, 0); @@ -107477,9 +108018,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; @@ -107624,7 +108164,7 @@ static void renameColumnFunc( #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = 0; #endif - rc = renameParseSql(&sParse, zDb, db, zSql, bTemp); + rc = renameParseSql(&sParse, zDb, db, zSql, bTemp, 0); /* Find tokens that need to be replaced. */ memset(&sWalker, 0, sizeof(Walker)); @@ -107666,12 +108206,12 @@ static void renameColumnFunc( for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){ sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } - } #ifndef SQLITE_OMIT_GENERATED_COLUMNS - for(i=0; i<sParse.pNewTable->nCol; i++){ - sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); - } + for(i=0; i<sParse.pNewTable->nCol; i++){ + sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); + } #endif + } for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ for(i=0; i<pFKey->nCol; i++){ @@ -107725,7 +108265,7 @@ static void renameColumnFunc( renameColumnFunc_done: if( rc!=SQLITE_OK ){ if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); } @@ -107763,7 +108303,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ return WRC_Abort; } for(i=0; i<pSrc->nSrc; i++){ - struct SrcList_item *pItem = &pSrc->a[i]; + SrcItem *pItem = &pSrc->a[i]; if( pItem->pTab==p->pTab ){ renameTokenFind(pWalker->pParse, p, pItem->zName); } @@ -107828,7 +108368,7 @@ static void renameTableFunc( sWalker.xSelectCallback = renameTableSelectCb; sWalker.u.pRename = &sCtx; - rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp, 0); if( rc==SQLITE_OK ){ int isLegacy = (db->flags & SQLITE_LegacyAlter); @@ -107914,7 +108454,7 @@ static void renameTableFunc( } if( rc!=SQLITE_OK ){ if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); } @@ -107943,6 +108483,8 @@ 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: Name of column being dropped, or NULL. ** ** Unless it finds an error, this function normally returns NULL. However, it ** returns integer value 1 if: @@ -107960,6 +108502,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]); + char const *zDropColumn = (const char*)sqlite3_value_text(argv[6]); #ifndef SQLITE_OMIT_AUTHORIZATION sqlite3_xauth xAuth = db->xAuth; @@ -107970,7 +108514,7 @@ static void renameTableTest( if( zDb && zInput ){ int rc; Parse sParse; - rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp, zDropColumn); if( rc==SQLITE_OK ){ if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){ NameContext sNC; @@ -107992,8 +108536,8 @@ static void renameTableTest( } } - if( rc!=SQLITE_OK ){ - renameColumnParseError(context, 1, argv[2], argv[3], &sParse); + if( rc!=SQLITE_OK && zWhen ){ + renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse); } renameParseCleanup(&sParse); } @@ -108004,13 +108548,216 @@ static void renameTableTest( } /* +** 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, 0); + 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].zName); + if( iCol<pTab->nCol-1 ){ + RenameToken *pEnd; + pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zName); + zEnd = (const char*)pEnd->t.z; + }else{ + zEnd = (const char*)&zSql[pTab->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, 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: \"%s\"", zCol); + 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; + renameTestSchema(pParse, zDb, iDb==1, "", 0); + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." DFLT_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", zCol); + + /* 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; i<pPk->nKeyCol; i++){ + sqlite3VdbeAddOp3(v, OP_Column, iCur, i, reg+i+1); + } + nField = pPk->nKeyCol; + } + regRec = ++pParse->nMem; + for(i=0; i<pTab->nCol; 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( iPos<pPk->nKeyCol ) 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++; + } + } + 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), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); } @@ -110400,6 +111147,62 @@ 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; i<pList->nSrc; 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 WRC_Abort; + } + 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( sqlite3WalkExpr(&pFix->w, pList->a[i].pOn) ) return WRC_Abort; +#endif + } + if( pSelect->pWith ){ + for(i=0; i<pSelect->pWith->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. */ @@ -110410,9 +111213,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; @@ -110420,6 +111221,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 = 0; + pFix->w.walkerDepth = 0; + pFix->w.eCode = 0; + pFix->w.u.pFix = pFix; } /* @@ -110440,115 +111248,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; i<pList->nSrc; 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; i<pSelect->pWith->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; i<pList->nExpr; i++, pItem++){ - if( sqlite3FixExpr(pFix, pItem->pExpr) ){ - return 1; - } - } - return 0; + return sqlite3WalkExpr(&pFix->w, pExpr); } #endif @@ -110558,25 +111278,20 @@ 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) + if( sqlite3WalkExprList(&pFix->w, pUp->pUpsertTarget) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertTargetWhere) + || sqlite3WalkExprList(&pFix->w, pUp->pUpsertSet) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertWhere) ){ return 1; } @@ -110584,6 +111299,7 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep( #endif pStep = pStep->pNext; } + return 0; } #endif @@ -110735,7 +111451,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 */ @@ -110743,8 +111458,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 @@ -110756,7 +111471,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( pTab = pParse->pTriggerTab; }else{ assert( pTabList ); - for(iSrc=0; ALWAYS(iSrc<pTabList->nSrc); iSrc++){ + for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ pTab = pTabList->a[iSrc].pTab; break; @@ -110764,7 +111479,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( } } iCol = pExpr->iColumn; - if( NEVER(pTab==0) ) return; + if( pTab==0 ) return; if( iCol>=0 ){ assert( iCol<pTab->nCol ); @@ -110775,7 +111490,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( }else{ zCol = "ROWID"; } - assert( iDb>=0 && iDb<db->nDb ); + assert( iDb>=0 && iDb<pParse->db->nDb ); if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ pExpr->op = TK_NULL; } @@ -110801,11 +111516,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; } @@ -111011,10 +111722,36 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ /* 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; + + addrRewind = + sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); + VdbeCoverage(v); + reg = pReturning->iRetReg; + for(i=0; i<pReturning->nRetCol; 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 @@ -111092,12 +111829,16 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ } } + if( pParse->bReturning ){ + Returning *pRet = pParse->u1.pReturning; + 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 ){ @@ -111316,7 +112057,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 ); @@ -112074,7 +112815,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); @@ -112101,12 +112843,85 @@ begin_table_error: SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ if( sqlite3_strnicmp(pCol->zName, "__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.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. @@ -112123,6 +112938,8 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ char *zType; Column *pCol; sqlite3 *db = pParse->db; + u8 hName; + if( (p = pParse->pNewTable)==0 ) return; if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); @@ -112134,8 +112951,9 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ memcpy(z, pName->z, pName->n); z[pName->n] = 0; sqlite3Dequote(z); + hName = sqlite3StrIHash(z); for(i=0; i<p->nCol; i++){ - if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){ + if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zName)==0 ){ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); sqlite3DbFree(db, z); return; @@ -112153,7 +112971,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); pCol->zName = z; - pCol->hName = sqlite3StrIHash(z); + pCol->hName = hName; sqlite3ColumnPropertiesFromName(p, pCol); if( pType->n==0 ){ @@ -112936,9 +113754,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 @@ -113402,7 +114221,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. @@ -113419,20 +114238,17 @@ 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( !pSelect && !p->pSelect ){ + assert( pCons && pEnd ); + if( pCons->z==0 ){ + pCons = pEnd; } -#endif + p->addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z); } +#endif } #ifndef SQLITE_OMIT_VIEW @@ -113623,6 +114439,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) ); @@ -114890,7 +115707,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); } @@ -114911,7 +115728,11 @@ 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 */ + 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 = &pTab->pIndex; Index *pThis; for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){ @@ -114925,6 +115746,16 @@ exit_create_index: } 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); @@ -115283,7 +116114,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 ); @@ -115324,7 +116155,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( */ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; - struct SrcList_item *pItem; + SrcItem *pItem; assert(pList || pParse->db->mallocFailed ); if( pList ){ for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ @@ -115342,7 +116173,7 @@ 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; i<pList->nSrc; i++, pItem++){ if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase); @@ -115384,7 +116215,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", @@ -115428,7 +116259,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 ); @@ -115458,7 +116289,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); } } @@ -115471,7 +116302,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 ); @@ -115626,7 +116457,7 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ static void sqlite3CodeVerifySchemaAtToplevel(Parse *pToplevel, int iDb){ assert( iDb>=0 && iDb<pToplevel->db->nDb ); assert( pToplevel->db->aDb[iDb].pBt!=0 || iDb==1 ); - assert( iDb<SQLITE_MAX_ATTACHED+2 ); + assert( iDb<SQLITE_MAX_DB ); assert( sqlite3SchemaMutexHeld(pToplevel->db, iDb, 0) ); if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ DbMaskSet(pToplevel->cookieMask, iDb); @@ -115969,23 +116800,75 @@ 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; i<pWith->nCte; i++){ @@ -116004,16 +116887,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; @@ -116026,10 +116904,7 @@ SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ if( pWith ){ int i; for(i=0; i<pWith->nCte; 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); } @@ -116608,7 +117483,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); @@ -116616,9 +117491,9 @@ 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; } @@ -116786,9 +117661,15 @@ 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 ){ + 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, @@ -116966,6 +117847,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); @@ -117187,7 +118069,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( ** invoke the callback function. */ if( memCnt ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, memCnt, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); } @@ -118235,7 +119117,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; } @@ -119406,7 +120289,9 @@ 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 ); + if( !pExpr->x.pList ){ return 0; } assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); @@ -119445,6 +120330,203 @@ 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 2-argument SQL math functions: +** +** power(X,Y) - Compute X to the Y-th power +*/ +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 @@ -119563,6 +120645,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 ), }; @@ -120618,7 +121737,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++; @@ -120706,7 +121825,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). ** @@ -120718,13 +121839,14 @@ SQLITE_PRIVATE int sqlite3FkRequired( int *aChange, /* Non-NULL for UPDATE operations */ int chngRowid /* True for UPDATE that affects rowid */ ){ - int eRet = 0; + int eRet = 1; /* Value to return if bHaveFK is true */ + int bHaveFK = 0; /* If FK processing is required */ if( pParse->db->flags&SQLITE_ForeignKeys ){ if( !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->pFKey); }else{ /* This is an UPDATE. Foreign key processing is only required if the ** operation modifies one or more child or parent key columns. */ @@ -120732,9 +121854,9 @@ SQLITE_PRIVATE int sqlite3FkRequired( /* 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; if( fkChildIsModified(pTab, p, aChange, chngRowid) ){ - eRet = 1; + if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) eRet = 2; + bHaveFK = 1; } } @@ -120742,12 +121864,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; } /* @@ -121416,7 +122538,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; @@ -121974,19 +123098,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; i<pTab->nCol; 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; i<pTab->nCol; 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, 0, pTab->nCol-nHidden, nColumn); + goto insert_cleanup; + } } if( pColumn!=0 && nColumn!=pColumn->nId ){ sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); @@ -121998,6 +123127,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); @@ -122021,6 +123151,7 @@ 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); @@ -122034,13 +123165,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 @@ -122181,11 +123318,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); @@ -122340,7 +123472,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. @@ -122355,7 +123489,7 @@ insert_end: ** invoke the callback function. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); } @@ -122446,6 +123580,70 @@ SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn( } /* +** 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. ** @@ -122553,7 +123751,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 */ @@ -122561,11 +123759,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 @@ -122575,6 +123773,7 @@ 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; @@ -122772,19 +123971,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 ); } } @@ -122847,11 +124090,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); } } @@ -122861,7 +124113,7 @@ 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 */ ){ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; @@ -122958,7 +124210,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); } @@ -122971,7 +124225,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 */ @@ -122979,15 +124236,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; } @@ -123058,8 +124314,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 */ @@ -123097,7 +124353,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); @@ -123249,13 +124505,16 @@ 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 */ @@ -123322,6 +124581,32 @@ SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ #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. ** A consecutive range of registers starting at regNewData contains the @@ -123369,17 +124654,9 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( 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, @@ -123577,7 +124854,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 */ @@ -123794,6 +125071,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 ); @@ -123829,11 +125107,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); @@ -123841,16 +125121,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); @@ -123892,13 +125184,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); @@ -128214,7 +129515,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 ){ @@ -128862,7 +130163,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; @@ -128870,14 +130171,18 @@ 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_AlterRename|INITFLAG_AlterDrop) ){ + *pData->pzErrMsg = sqlite3MPrintf(db, + "error in %s %s after %s: %s", azObj[0], azObj[1], + (pData->mInitFlags & INITFLAG_AlterRename) ? "rename" : "drop column", + 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; @@ -128935,19 +130240,26 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char db->mDbFlags |= DBFLAG_EncodingFixed; pData->nInitRow++; if( db->mallocFailed ){ - corruptSchema(pData, argv[1], 0); + corruptSchema(pData, argv, 0); return 1; } assert( iDb>=0 && iDb<db->nDb ); 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; @@ -128960,7 +130272,7 @@ 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; @@ -128979,13 +130291,13 @@ 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)); } } } 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 @@ -128996,7 +130308,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 @@ -129004,7 +130316,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"); } } } @@ -129385,27 +130697,20 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ } /* -** 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){ sqlite3 *db = pParse->db; - AggInfo *pThis = pParse->pAggList; - while( pThis ){ - AggInfo *pNext = pThis->pNext; - agginfoFree(db, pThis); - pThis = pNext; + 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( pParse->pConstExpr ){ + sqlite3ExprListDelete(db, pParse->pConstExpr); + } if( db ){ assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; @@ -129415,6 +130720,55 @@ SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ } /* +** 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 +** sqlite3ParserReset(), 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; +} + +/* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ static int sqlite3Prepare( @@ -129512,12 +130866,6 @@ static int sqlite3Prepare( } assert( 0==sParse.nQueryLoop ); - if( sParse.rc==SQLITE_DONE ){ - sParse.rc = SQLITE_OK; - } - if( sParse.checkSchema ){ - schemaIsValid(&sParse); - } if( pzTail ){ *pzTail = sParse.zTail; } @@ -129528,20 +130876,28 @@ static int sqlite3Prepare( if( db->mallocFailed ){ sParse.rc = SQLITE_NOMEM_BKPT; } - 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 ){ + schemaIsValid(&sParse); + } + if( sParse.pVdbe ){ + sqlite3VdbeFinalize(sParse.pVdbe); + } + assert( 0==(*ppStmt) ); + rc = sParse.rc; + if( zErrMsg ){ + sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); + sqlite3DbFree(db, zErrMsg); + }else{ + sqlite3Error(db, rc); + } }else{ + assert( 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 ){ @@ -129887,12 +131243,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; @@ -130064,7 +131424,7 @@ 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; @@ -130096,7 +131456,7 @@ static int tableAndColumnIndex( assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=0; i<N; i++){ - iCol = columnIndex(pSrc->a[i].pTab, zCol); + iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol); if( iCol>=0 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) ){ @@ -130149,7 +131509,7 @@ static void addWhereTerm( ExprSetProperty(pEq, EP_FromJoin); assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(pEq, EP_NoReduce); - pEq->iRightJoinTable = (i16)pE2->iTable; + pEq->iRightJoinTable = pE2->iTable; } *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq); } @@ -130185,7 +131545,7 @@ 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; + p->iRightJoinTable = iTable; if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; i<p->x.pList->nExpr; i++){ @@ -130209,6 +131569,9 @@ static void unsetJoinExpr(Expr *p, int iTable){ && (iTable<0 || p->iRightJoinTable==iTable) ){ ExprClearProperty(p, EP_FromJoin); } + if( p->op==TK_COLUMN && p->iTable==iTable ){ + ExprClearProperty(p, EP_CanBeNull); + } if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; i<p->x.pList->nExpr; i++){ @@ -130237,8 +131600,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]; @@ -130306,7 +131669,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) ){ @@ -131185,7 +132548,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; @@ -131781,7 +133144,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( 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; @@ -131888,6 +133251,7 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation( for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ const char *zType; int 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 */ @@ -132403,12 +133767,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 */ @@ -132465,7 +133825,7 @@ static int multiSelect( pPrior->iOffset = p->iOffset; pPrior->pLimit = p->pLimit; rc = sqlite3Select(pParse, pPrior, &dest); - p->pLimit = 0; + pPrior->pLimit = 0; if( rc ){ goto multi_select_end; } @@ -132486,8 +133846,8 @@ static int multiSelect( 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); @@ -132551,7 +133911,7 @@ static int multiSelect( p->pLimit = 0; uniondest.eDest = op; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", - selectOpName(p->op))); + sqlite3SelectOpName(p->op))); rc = sqlite3Select(pParse, p, &uniondest); testcase( rc!=SQLITE_OK ); assert( p->pOrderBy==0 ); @@ -132627,7 +133987,7 @@ static int multiSelect( p->pLimit = 0; intersectdest.iSDParm = tab2; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", - selectOpName(p->op))); + sqlite3SelectOpName(p->op))); rc = sqlite3Select(pParse, p, &intersectdest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; @@ -132736,7 +134096,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)); } } @@ -132833,10 +134194,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; } @@ -133128,7 +134487,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. @@ -133398,7 +134757,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{ @@ -133428,7 +134787,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; @@ -133438,7 +134797,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; @@ -133453,6 +134812,89 @@ static void recomputeColumnsUsed( #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] = iNew; +** +** The array is guaranteed by the caller to be large enough for all +** existing cursor numbers in pSrc. +** +** 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; i<pSrc->nSrc; i++, pItem++){ + if( i!=iExcept ){ + Select *p; + pItem->iCursor = aCsrMap[pItem->iCursor] = pParse->nTab++; + for(p=pItem->pSelect; p; p=p->pPrior){ + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); + } + } + } +} + +/* +** Expression walker callback used by renumberCursors() to update +** Expr objects to match newly assigned cursor numbers. +*/ +static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ + int *aCsrMap = pWalker->u.aiCol; + int op = pExpr->op; + if( (op==TK_COLUMN || op==TK_IF_NULL_ROW) && aCsrMap[pExpr->iTable] ){ + pExpr->iTable = aCsrMap[pExpr->iTable]; + } + if( ExprHasProperty(pExpr, EP_FromJoin) && aCsrMap[pExpr->iRightJoinTable] ){ + pExpr->iRightJoinTable = aCsrMap[pExpr->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. ** This routine returns 1 if it makes changes and 0 if no flattening occurs. ** @@ -133545,9 +134987,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, @@ -133563,8 +135005,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. @@ -133580,9 +135022,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(). ** @@ -133624,9 +135065,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. */ @@ -133722,13 +135164,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) */ @@ -133749,15 +135192,15 @@ 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, pParse->nTab*sizeof(int)); + } + } /***** If we reach this point, flattening is permitted. *****/ SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n", @@ -133769,6 +135212,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: @@ -133807,18 +135261,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 && db->mallocFailed==0 ){ + renumberCursors(pParse, pNew, iFrom, aCsrMap); + } pNew->pPrior = pPrior; if( pPrior ) pPrior->pNext = pNew; pNew->pNext = p; @@ -133826,24 +135285,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 @@ -133856,8 +135304,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--; } @@ -133877,6 +135327,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; @@ -133885,14 +135336,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 @@ -134012,7 +135457,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); } @@ -134207,6 +135652,35 @@ static int propagateConstants( } #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 ** the WHERE clause of subquery. Example: @@ -134253,9 +135727,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. @@ -134269,13 +135758,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 @@ -134311,6 +135804,7 @@ static int pushDownWhereTerms( } if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ nChng++; + pSubq->selFlags |= SF_PushDown; while( pSubq ){ SubstContext x; pNew = sqlite3ExprDup(pParse->db, pWhere, 0); @@ -134321,6 +135815,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{ @@ -134359,7 +135861,11 @@ 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) ){ + if( pEList==0 + || pEList->nExpr!=1 + || ExprHasProperty(pFunc, EP_WinFunc) + || OptimizationDisabled(db, SQLITE_MinMaxOpt) + ){ return eRet; } zFunc = pFunc->u.zToken; @@ -134422,24 +135928,26 @@ 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; } + pFrom->u2.pIBIndex = pIdx; return SQLITE_OK; } + /* ** Detect compound SELECT statements that use an ORDER BY clause with ** an alternative collating sequence. @@ -134526,7 +136034,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; @@ -134547,19 +136055,19 @@ 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; i<p->nCte; 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; i<p->nCte; i++){ + if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ + *ppContext = p; + return &p->a[i]; } } } @@ -134577,46 +136085,54 @@ static struct Cte *searchWith( ** statement with which it is associated. */ SQLITE_PRIVATE void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ - assert( bFree==0 || (pParse->pWith==0 && pParse->pWithToFree==0) ); if( pWith ){ assert( pParse->pWith!=pWith ); pWith->pOuter = pParse->pWith; pParse->pWith = pWith; - if( bFree ) pParse->pWithToFree = pWith; + if( bFree ){ + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3WithDelete, + pWith); + testcase( pParse->earlyCleanup ); + } } } /* ** 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->nErr ){ - return SQLITE_ERROR; + if( pParse->pWith==0 ){ + /* There are no WITH clauses in the stack. No match is possible */ + 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; } - pCte = searchWith(pParse->pWith, pFrom, &pWith); if( pCte ){ + sqlite3 *db = pParse->db; Table *pTab; ExprList *pEList; Select *pSel; @@ -134625,6 +136141,7 @@ static int withExpand( 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 @@ -134632,21 +136149,39 @@ 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; assert( pFrom->pSelect ); + 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. */ pRecTerm = pSel = pFrom->pSelect; @@ -134656,7 +136191,7 @@ static int withExpand( SrcList *pSrc = pRecTerm->pSrc; assert( pRecTerm->pPrior!=0 ); for(i=0; i<pSrc->nSrc; 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) @@ -134668,7 +136203,7 @@ static int withExpand( sqlite3ErrorMsg(pParse, "multiple references to recursive table: %s", pCte->zName ); - return SQLITE_ERROR; + return 2; } pRecTerm->selFlags |= SF_Recursive; if( iRecTab<0 ) iRecTab = pParse->nTab++; @@ -134683,16 +136218,24 @@ static int withExpand( pSavedWith = pParse->pWith; pParse->pWith = pWith; 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; - sqlite3WalkSelect(pWalker, pRecTerm); + 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; @@ -134704,7 +136247,7 @@ static int withExpand( pCte->zName, pEList->nExpr, pCte->pCols->nExpr ); pParse->pWith = pSavedWith; - return SQLITE_ERROR; + return 2; } pEList = pCte->pCols; } @@ -134720,9 +136263,9 @@ static int withExpand( } pCte->zCteErr = 0; pParse->pWith = pSavedWith; + return 1; /* Success */ } - - return SQLITE_OK; + return 0; /* No match */ } #endif @@ -134756,7 +136299,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; @@ -134804,10 +136347,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; @@ -134843,10 +136386,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; @@ -134856,6 +136395,12 @@ static int selectExpander(Walker *pWalker, Select *p){ 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 */ assert( pFrom->pTab==0 ); @@ -134877,7 +136422,10 @@ static int selectExpander(Walker *pWalker, Select *p){ u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); - if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){ + if( pTab->pSelect + && (db->flags & SQLITE_EnableView)==0 + && pTab->pSchema!=db->aDb[1].pSchema + ){ sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", pTab->zName); } @@ -134903,7 +136451,7 @@ 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; } } @@ -135146,7 +136694,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; @@ -135458,7 +137006,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); } @@ -135470,11 +137018,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; pItem<pThis; pItem++){ Select *pS1; if( pItem->pSelect==0 ) continue; @@ -135490,9 +137040,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; @@ -135502,6 +137050,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 @@ -135580,7 +137137,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); } @@ -135633,7 +137190,7 @@ SQLITE_PRIVATE int sqlite3Select( 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 @@ -135647,8 +137204,19 @@ SQLITE_PRIVATE int sqlite3Select( 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 */ - sqlite3ExprListDelete(db, p->pOrderBy); - p->pOrderBy = 0; + 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; } @@ -135658,7 +137226,7 @@ SQLITE_PRIVATE int sqlite3Select( } 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); } @@ -135669,9 +137237,9 @@ SQLITE_PRIVATE int sqlite3Select( ** 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]; + SrcItem *p0 = &p->pSrc->a[0]; for(i=1; i<p->pSrc->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", @@ -135693,7 +137261,7 @@ SQLITE_PRIVATE int sqlite3Select( 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); } @@ -135709,7 +137277,7 @@ SQLITE_PRIVATE int sqlite3Select( */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ - struct SrcList_item *pItem = &pTabList->a[i]; + SrcItem *pItem = &pTabList->a[i]; Select *pSub = pItem->pSelect; Table *pTab = pItem->pTab; @@ -135800,7 +137368,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 @@ -135819,7 +137387,7 @@ SQLITE_PRIVATE int sqlite3Select( && 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); } @@ -135843,7 +137411,8 @@ SQLITE_PRIVATE int sqlite3Select( ** (2) Generate code for all sub-queries */ for(i=0; i<pTabList->nSrc; 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) @@ -135903,16 +137472,18 @@ SQLITE_PRIVATE int sqlite3Select( ** inside the subquery. This can help the subquery to run more efficiently. */ if( OptimizationEnabled(db, SQLITE_PushDown) + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, (pItem->fg.jointype & JT_OUTER)!=0) ){ #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")); } @@ -135922,16 +137493,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. @@ -135951,16 +137524,32 @@ 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); + } + 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{ + /* Materalize 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; @@ -135975,22 +137564,22 @@ SQLITE_PRIVATE int sqlite3Select( }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; - }else{ - sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); - ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); - sqlite3Select(pParse, pSub, &dest); - } + sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); + ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); + 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)); 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); @@ -136007,7 +137596,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); } @@ -136043,7 +137632,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); } @@ -136135,6 +137724,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 @@ -136173,6 +137763,7 @@ SQLITE_PRIVATE int sqlite3Select( /* End the database scan loop. */ + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); } }else{ @@ -136243,11 +137834,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; @@ -136291,10 +137885,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; ii<pAggInfo->nColumn; ii++){ sqlite3DebugPrintf("agg-column[%d] iMem=%d\n", ii, pAggInfo->aCol[ii].iMem); @@ -136362,6 +137960,7 @@ SQLITE_PRIVATE int sqlite3Select( WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 ); if( pWInfo==0 ) goto select_end; + 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 @@ -136410,6 +138009,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); @@ -136484,9 +138084,10 @@ SQLITE_PRIVATE int sqlite3Select( /* 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); } @@ -136596,7 +138197,6 @@ SQLITE_PRIVATE int sqlite3Select( explainSimpleCount(pParse, pTab, pBest); }else{ int regAcc = 0; /* "populate accumulators" flag */ - int addrSkip; /* If there are accumulator registers but no min() or max() functions ** without FILTER clauses, allocate register regAcc. Register regAcc @@ -136643,12 +138243,13 @@ SQLITE_PRIVATE int sqlite3Select( if( pWInfo==0 ){ goto select_end; } + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); updateAccumulator(pParse, regAcc, pAggInfo); 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); } @@ -136693,15 +138294,13 @@ select_end: if( pAggInfo && !db->mallocFailed ){ for(i=0; i<pAggInfo->nColumn; 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; i<pAggInfo->nFunc; 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 ); } @@ -136710,7 +138309,7 @@ select_end: #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 @@ -136971,28 +138570,39 @@ 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; } - + pTmpSchema = pParse->db->aDb[1].pSchema; + p = sqliteHashFirst(&pTmpSchema->trigHash); + if( p==0 ){ + return pTab->pTrigger; + } + pList = pTab->pTrigger; if( pTmpSchema!=pTab->pSchema ){ - HashElem *p; - assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) ); - for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){ + while( p ){ Trigger *pTrig = (Trigger *)sqliteHashData(p); if( pTrig->pTabSchema==pTab->pSchema && 0==sqlite3StrICmp(pTrig->table, pTab->zName) ){ - pTrig->pNext = (pList ? pList : pTab->pTrigger); + pTrig->pNext = pList; + pList = pTrig; + }else if( pTrig->op==TK_RETURNING ){ + 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); + return pList; } /* @@ -137268,7 +138878,7 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( 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 ){ @@ -137481,7 +139091,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); @@ -137646,15 +139256,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; } @@ -137698,6 +139346,131 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc( } /* +** 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; i<pList->nExpr; i++){ + Expr *pOldExpr = pList->a[i].pExpr; + if( NEVER(pOldExpr==0) ) continue; + if( isAsteriskTerm(pParse, pOldExpr) ){ + int jj; + for(jj=0; jj<pTab->nCol; jj++){ + Expr *pNewExpr; + if( IsHiddenColumn(pTab->aCol+jj) ) continue; + pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zName); + pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); + if( !db->mallocFailed ){ + struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; + pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zName); + pItem->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; + } + } + } + if( !db->mallocFailed ){ + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + sqlite3VdbeSetNumCols(v, pNew->nExpr); + for(i=0; i<pNew->nExpr; i++){ + sqlite3VdbeSetColName(v, i, COLNAME_NAME, pNew->a[i].zEName, + SQLITE_TRANSIENT); + } + } + 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; + ExprList *pNew; + Returning *pReturning; + + assert( v!=0 ); + assert( pParse->bReturning ); + pReturning = pParse->u1.pReturning; + assert( pTrigger == &(pReturning->retTrig) ); + pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); + if( pNew ){ + 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 ){ + int i; + int nCol = pNew->nExpr; + int reg = pParse->nMem+1; + pParse->nMem += nCol+2; + pReturning->iRetReg = reg; + for(i=0; i<nCol; i++){ + sqlite3ExprCodeFactorable(pParse, pNew->a[i].pExpr, 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(pParse->db, pNew); + pParse->eTriggerOp = 0; + pParse->pTriggerTab = 0; + } +} + + + +/* ** Generate VDBE code for the statements inside the body of a single ** trigger. */ @@ -137746,6 +139519,7 @@ static int codeTriggerProgram( sqlite3ExprDup(db, pStep->pWhere, 0), pParse->eOrconf, 0, 0, 0 ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } case TK_INSERT: { @@ -137756,6 +139530,7 @@ static int codeTriggerProgram( pParse->eOrconf, sqlite3UpsertDup(db, pStep->pUpsert) ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } case TK_DELETE: { @@ -137763,6 +139538,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 ); { @@ -137774,9 +139550,6 @@ static int codeTriggerProgram( break; } } - if( pStep->op!=TK_SELECT ){ - sqlite3VdbeAddOp0(v, OP_ResetCount); - } } return 0; @@ -137923,7 +139696,6 @@ static TriggerPrg *codeRowTrigger( sqlite3VdbeDelete(v); } - assert( !pSubParse->pAinc && !pSubParse->pZombieTab ); assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); sqlite3ParserReset(pSubParse); sqlite3StackFree(db, pSubParse); @@ -138025,7 +139797,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 ** @@ -138070,12 +139842,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); + } } } } @@ -138120,13 +139900,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]; + } } } } @@ -138783,6 +140568,7 @@ SQLITE_PRIVATE void sqlite3Update( if( (db->flags&SQLITE_CountRows)!=0 && !pParse->pTriggerTab && !pParse->nested + && !pParse->bReturning && pUpsert==0 ){ regRowCount = ++pParse->nMem; @@ -139246,7 +141032,7 @@ SQLITE_PRIVATE void sqlite3Update( ** that information. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); } @@ -139481,16 +141267,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. */ @@ -139500,7 +141293,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) ); } @@ -139512,22 +141306,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; } @@ -139552,6 +141349,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 ); @@ -139565,87 +141363,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; ii<nn; ii++){ - Expr *pExpr; - sCol[0].u.zToken = (char*)pIdx->azColl[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; ii<nn; ii++){ + Expr *pExpr; + sCol[0].u.zToken = (char*)pIdx->azColl[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; jj<nn; jj++){ - if( sqlite3ExprCompare(pParse, pTarget->a[jj].pExpr, pExpr,iCursor)<2 ){ - break; /* Column ii of the index matches column jj of target */ + for(jj=0; jj<nn; jj++){ + if( sqlite3ExprCompare(pParse,pTarget->a[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( ii<nn ){ + /* Column ii of the index did not match any term of the conflict target. + ** Continue the search with the next index. */ + continue; } + pUpsert->pUpsertIdx = pIdx; + break; } - if( ii<nn ){ - /* Column ii of the index did not match any term of the conflict target. - ** Continue the search with the next index. */ - continue; + if( pUpsert->pUpsertIdx==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; } /* @@ -139669,11 +141511,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); @@ -139703,19 +141547,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; i<pTab->nCol; 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")); } @@ -140621,7 +142463,7 @@ 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; @@ -140792,6 +142634,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; @@ -140960,7 +142803,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ Table *pNew = sParse.pNewTable; Index *pIdx; pTab->aCol = pNew->aCol; - pTab->nCol = pNew->nCol; + pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); pNew->nCol = 0; pNew->aCol = 0; @@ -141492,19 +143335,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 */ @@ -141758,11 +143588,7 @@ struct WhereTerm { #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_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 */ @@ -142032,7 +143858,7 @@ 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*); @@ -142210,7 +144036,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. */ @@ -143003,7 +144829,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 */ @@ -143378,7 +145204,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 */ @@ -143824,6 +145650,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( 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. @@ -144160,7 +145992,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])); @@ -145083,6 +146915,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 @@ -145580,6 +147413,277 @@ static int exprMightBeIndexed( } /* +** Expression callback for exprUsesSrclist(). +*/ +static int exprUsesSrclistCb(Walker *p, Expr *pExpr){ + if( pExpr->op==TK_COLUMN ){ + SrcList *pSrc = p->u.pSrcList; + int iCsr = pExpr->iTable; + int ii; + for(ii=0; ii<pSrc->nSrc; ii++){ + if( pSrc->a[ii].iCursor==iCsr ){ + return p->eCode ? WRC_Abort : WRC_Continue; + } + } + return p->eCode ? WRC_Continue : WRC_Abort; + } + return WRC_Continue; +} + +/* +** Select callback for exprUsesSrclist(). +*/ +static int exprUsesSrclistSelectCb(Walker *NotUsed1, Select *NotUsed2){ + UNUSED_PARAMETER(NotUsed1); + UNUSED_PARAMETER(NotUsed2); + return WRC_Abort; +} + +/* +** This function always returns true if expression pExpr contains +** a sub-select. +** +** If there is no sub-select in pExpr, then return true if pExpr +** contains a TK_COLUMN node for a table that is (bUses==1) +** or is not (bUses==0) in pSrc. +** +** Said another way: +** +** bUses Return Meaning +** -------- ------ ------------------------------------------------ +** +** bUses==1 true pExpr contains either a sub-select or a +** TK_COLUMN referencing pSrc. +** +** bUses==1 false pExpr contains no sub-selects and all TK_COLUMN +** nodes reference tables not found in pSrc +** +** bUses==0 true pExpr contains either a sub-select or a TK_COLUMN +** that references a table not in pSrc. +** +** bUses==0 false pExpr contains no sub-selects and all TK_COLUMN +** nodes reference pSrc +*/ +static int exprUsesSrclist(SrcList *pSrc, Expr *pExpr, int bUses){ + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.eCode = bUses; + sWalker.u.pSrcList = pSrc; + sWalker.xExprCallback = exprUsesSrclistCb; + sWalker.xSelectCallback = exprUsesSrclistSelectCb; + return (sqlite3WalkExpr(&sWalker, pExpr)==WRC_Abort); +} + +/* +** Context object used by exprExistsToInIter() as it iterates through an +** expression tree. +*/ +struct ExistsToInCtx { + SrcList *pSrc; /* The tables in an EXISTS(SELECT ... FROM <here> ...) */ + Expr *pInLhs; /* OUT: Use this as the LHS of the IN operator */ + Expr *pEq; /* OUT: The == term that include pInLhs */ + Expr **ppAnd; /* OUT: The AND operator that includes pEq as a child */ + Expr **ppParent; /* The AND operator currently being examined */ +}; + +/* +** Iterate through all AND connected nodes in the expression tree +** headed by (*ppExpr), populating the structure passed as the first +** argument with the values required by exprAnalyzeExistsFindEq(). +** +** This function returns non-zero if the expression tree does not meet +** the two conditions described by the header comment for +** exprAnalyzeExistsFindEq(), or zero if it does. +*/ +static int exprExistsToInIter(struct ExistsToInCtx *p, Expr **ppExpr){ + Expr *pExpr = *ppExpr; + switch( pExpr->op ){ + case TK_AND: + p->ppParent = ppExpr; + if( exprExistsToInIter(p, &pExpr->pLeft) ) return 1; + p->ppParent = ppExpr; + if( exprExistsToInIter(p, &pExpr->pRight) ) return 1; + break; + case TK_EQ: { + int bLeft = exprUsesSrclist(p->pSrc, pExpr->pLeft, 0); + int bRight = exprUsesSrclist(p->pSrc, pExpr->pRight, 0); + if( bLeft || bRight ){ + if( (bLeft && bRight) || p->pInLhs ) return 1; + p->pInLhs = bLeft ? pExpr->pLeft : pExpr->pRight; + if( exprUsesSrclist(p->pSrc, p->pInLhs, 1) ) return 1; + p->pEq = pExpr; + p->ppAnd = p->ppParent; + } + break; + } + default: + if( exprUsesSrclist(p->pSrc, pExpr, 0) ){ + return 1; + } + break; + } + + return 0; +} + +/* +** This function is used by exprAnalyzeExists() when creating virtual IN(...) +** terms equivalent to user-supplied EXIST(...) clauses. It splits the WHERE +** clause of the Select object passed as the first argument into one or more +** expressions joined by AND operators, and then tests if the following are +** true: +** +** 1. Exactly one of the AND separated terms refers to the outer +** query, and it is an == (TK_EQ) expression. +** +** 2. Only one side of the == expression refers to the outer query, and +** it does not refer to any columns from the inner query. +** +** If both these conditions are true, then a pointer to the side of the == +** expression that refers to the outer query is returned. The caller will +** use this expression as the LHS of the IN(...) virtual term. Or, if one +** or both of the above conditions are not true, NULL is returned. +** +** If non-NULL is returned and ppEq is non-NULL, *ppEq is set to point +** to the == expression node before returning. If pppAnd is non-NULL and +** the == node is not the root of the WHERE clause, then *pppAnd is set +** to point to the pointer to the AND node that is the parent of the == +** node within the WHERE expression tree. +*/ +static Expr *exprAnalyzeExistsFindEq( + Select *pSel, /* The SELECT of the EXISTS */ + Expr **ppEq, /* OUT: == node from WHERE clause */ + Expr ***pppAnd /* OUT: Pointer to parent of ==, if any */ +){ + struct ExistsToInCtx ctx; + memset(&ctx, 0, sizeof(ctx)); + ctx.pSrc = pSel->pSrc; + if( exprExistsToInIter(&ctx, &pSel->pWhere) ){ + return 0; + } + if( ppEq ) *ppEq = ctx.pEq; + if( pppAnd ) *pppAnd = ctx.ppAnd; + return ctx.pInLhs; +} + +/* +** Term idxTerm of the WHERE clause passed as the second argument is an +** EXISTS expression with a correlated SELECT statement on the RHS. +** This function analyzes the SELECT statement, and if possible adds an +** equivalent "? IN(SELECT...)" virtual term to the WHERE clause. +** +** For an EXISTS term such as the following: +** +** EXISTS (SELECT ... FROM <srclist> WHERE <e1> = <e2> AND <e3>) +** +** The virtual IN() term added is: +** +** <e1> IN (SELECT <e2> FROM <srclist> WHERE <e3>) +** +** The virtual term is only added if the following conditions are met: +** +** 1. The sub-select must not be an aggregate or use window functions, +** +** 2. The sub-select must not be a compound SELECT, +** +** 3. Expression <e1> must refer to at least one column from the outer +** query, and must not refer to any column from the inner query +** (i.e. from <srclist>). +** +** 4. <e2> and <e3> must not refer to any values from the outer query. +** In other words, once <e1> has been removed, the inner query +** must not be correlated. +** +*/ +static void exprAnalyzeExists( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* the WHERE clause */ + int idxTerm /* Index of the term to be analyzed */ +){ + Parse *pParse = pWC->pWInfo->pParse; + WhereTerm *pTerm = &pWC->a[idxTerm]; + Expr *pExpr = pTerm->pExpr; + Select *pSel = pExpr->x.pSelect; + Expr *pDup = 0; + Expr *pEq = 0; + Expr *pRet = 0; + Expr *pInLhs = 0; + Expr **ppAnd = 0; + int idxNew; + sqlite3 *db = pParse->db; + + assert( pExpr->op==TK_EXISTS ); + assert( (pExpr->flags & EP_VarSelect) && (pExpr->flags & EP_xIsSelect) ); + + if( pSel->selFlags & SF_Aggregate ) return; +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSel->pWin ) return; +#endif + if( pSel->pPrior ) return; + if( pSel->pWhere==0 ) return; + if( pSel->pLimit ) return; + if( 0==exprAnalyzeExistsFindEq(pSel, 0, 0) ) return; + + pDup = sqlite3ExprDup(db, pExpr, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + return; + } + pSel = pDup->x.pSelect; + sqlite3ExprListDelete(db, pSel->pEList); + pSel->pEList = 0; + + pInLhs = exprAnalyzeExistsFindEq(pSel, &pEq, &ppAnd); + assert( pInLhs && pEq ); + assert( pEq==pSel->pWhere || ppAnd ); + if( pInLhs==pEq->pLeft ){ + pRet = pEq->pRight; + }else{ + CollSeq *p = sqlite3ExprCompareCollSeq(pParse, pEq); + pInLhs = sqlite3ExprAddCollateString(pParse, pInLhs, p?p->zName:"BINARY"); + pRet = pEq->pLeft; + } + + assert( pDup->pLeft==0 ); + pDup->op = TK_IN; + pDup->pLeft = pInLhs; + pDup->flags &= ~EP_VarSelect; + if( pRet->op==TK_VECTOR ){ + pSel->pEList = pRet->x.pList; + pRet->x.pList = 0; + sqlite3ExprDelete(db, pRet); + }else{ + pSel->pEList = sqlite3ExprListAppend(pParse, 0, pRet); + } + pEq->pLeft = 0; + pEq->pRight = 0; + if( ppAnd ){ + Expr *pAnd = *ppAnd; + Expr *pOther = (pAnd->pLeft==pEq) ? pAnd->pRight : pAnd->pLeft; + pAnd->pLeft = pAnd->pRight = 0; + sqlite3ExprDelete(db, pAnd); + *ppAnd = pOther; + }else{ + assert( pSel->pWhere==pEq ); + pSel->pWhere = 0; + } + sqlite3ExprDelete(db, pEq); + +#ifdef WHERETRACE_ENABLED /* 0x20 */ + if( sqlite3WhereTrace & 0x20 ){ + sqlite3DebugPrintf("Convert EXISTS:\n"); + sqlite3TreeViewExpr(0, pExpr, 0); + sqlite3DebugPrintf("into IN:\n"); + sqlite3TreeViewExpr(0, pDup, 0); + } +#endif + idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pWC, idxNew); + markTermAsChild(pWC, idxNew, idxTerm); + pWC->a[idxTerm].wtFlags |= TERM_COPIED; +} + +/* ** 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 ** subexpression and populate all the other fields of the WhereTerm @@ -145712,6 +147816,12 @@ static void exprAnalyze( pNew->prereqRight = prereqLeft | extraRight; pNew->prereqAll = prereqAll; pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; + }else if( op==TK_ISNULL && 0==sqlite3ExprCanBeNull(pLeft) ){ + pExpr->op = TK_TRUEFALSE; + pExpr->u.zToken = "false"; + ExprSetProperty(pExpr, EP_IsFalse); + pTerm->prereqAll = 0; + pTerm->eOperator = 0; } } @@ -145764,6 +147874,52 @@ static void exprAnalyze( } #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ + else if( pExpr->op==TK_EXISTS ){ + /* Perhaps treat an EXISTS operator as an IN operator */ + if( (pExpr->flags & EP_VarSelect)!=0 + && OptimizationEnabled(db, SQLITE_ExistsToIN) + ){ + exprAnalyzeExists(pSrc, pWC, idxTerm); + } + } + + /* 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 ** operator. @@ -145778,7 +147934,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 */ @@ -145848,52 +148005,6 @@ 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.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_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 @@ -145901,12 +148012,12 @@ static void exprAnalyze( ** ** 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) + 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; i<nLeft; i++){ @@ -145934,12 +148045,14 @@ static void exprAnalyze( ** 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->u.x.iField==0 + else if( pExpr->op==TK_IN + && pTerm->u.x.iField==0 && pExpr->pLeft->op==TK_VECTOR && pExpr->x.pSelect->pPrior==0 #ifndef SQLITE_OMIT_WINDOWFUNC && pExpr->x.pSelect->pWin==0 #endif + && pWC->op==TK_AND ){ int i; for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){ @@ -145951,44 +148064,51 @@ static void exprAnalyze( } } -#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.x.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->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.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. @@ -146148,7 +148268,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; @@ -146225,12 +148345,6 @@ struct HiddenIndexInfo { /* 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 */ @@ -146294,6 +148408,32 @@ SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ } /* +** 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. */ @@ -146862,7 +149002,7 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ */ static int termCanDriveIndex( WhereTerm *pTerm, /* WHERE clause term to check */ - struct SrcList_item *pSrc, /* Table we are trying to access */ + SrcItem *pSrc, /* Table we are trying to access */ Bitmask notReady /* Tables in outer loops of the join */ ){ char aff; @@ -146896,7 +149036,7 @@ static int termCanDriveIndex( static 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 */ + SrcItem *pSrc, /* The FROM clause term to get the next index */ Bitmask notReady, /* Mask of cursors that are not available */ WhereLevel *pLevel /* Write new index here */ ){ @@ -146920,7 +149060,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 */ @@ -147104,7 +149244,7 @@ static sqlite3_index_info *allocateIndexInfo( Parse *pParse, /* The parsing context */ 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 */ + SrcItem *pSrc, /* The FROM clause term that is the vtab */ ExprList *pOrderBy, /* The ORDER BY clause */ u16 *pmNoOmit /* Mask of terms not to omit */ ){ @@ -148002,7 +150142,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, @@ -148613,7 +150753,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) */ ){ @@ -148799,7 +150939,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))<pTerm->pWC->nTerm ); @@ -149104,7 +151244,7 @@ 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 */ @@ -149122,9 +151262,9 @@ static int whereLoopAddBtree( pWC = pBuilder->pWC; assert( !IsVirtual(pSrc->pTab) ); - if( pSrc->pIBIndex ){ + if( pSrc->fg.isIndexedBy ){ /* 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{ @@ -149160,7 +151300,7 @@ static int whereLoopAddBtree( 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 */ @@ -149210,7 +151350,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 @@ -149385,7 +151525,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 ); @@ -149577,7 +151717,7 @@ 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 */ @@ -149705,7 +151845,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; @@ -149821,8 +151961,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; @@ -149845,7 +151985,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ - struct SrcList_item *p; + SrcItem *p; for(p=&pItem[1]; p<pEnd; p++){ if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){ mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); @@ -150700,7 +152840,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; @@ -151159,7 +153299,7 @@ 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 || db->mallocFailed ){ goto whereBeginError; } #ifdef WHERETRACE_ENABLED @@ -151230,7 +153370,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( } for(i=pWInfo->nLevel-1; i>=1; i--){ WhereTerm *pTerm, *pEnd; - struct SrcList_item *pItem; + SrcItem *pItem; pLoop = pWInfo->a[i].pWLoop; pItem = &pWInfo->pTabList->a[pLoop->iTab]; if( (pItem->fg.jointype & JT_LEFT)==0 ) continue; @@ -151320,7 +153460,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){ Table *pTab; /* Table to open */ int iDb; /* Index of database containing table/index */ - struct SrcList_item *pTabItem; + SrcItem *pTabItem; pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; @@ -151657,7 +153797,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ int k, last; 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; @@ -151733,7 +153873,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ #endif pOp = sqlite3VdbeGetOp(v, k); pLastOp = pOp + (last - k); - assert( pOp<pLastOp ); + assert( pOp<pLastOp || (pParse->nErr>0 && pOp==pLastOp) ); do{ if( pOp->p1!=pLevel->iTabCur ){ /* no-op */ @@ -153101,15 +155241,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; } } @@ -153262,6 +155406,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); @@ -153858,6 +156003,7 @@ static void windowCodeRangeTest( int regString = ++pParse->nMem; /* Reg. for constant value '' */ int arith = OP_Add; /* OP_Add or OP_Subtract */ int addrGe; /* Jump destination */ + CollSeq *pColl; assert( op==OP_Ge || op==OP_Gt || op==OP_Le ); assert( pOrderBy && pOrderBy->nExpr==1 ); @@ -153948,6 +156094,8 @@ static void windowCodeRangeTest( ** 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); assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le ); @@ -154954,11 +157102,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 && @@ -154969,6 +157127,19 @@ static void updateDeleteLimitError( } } + /* 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 identifier. Use the ** new Expr to populate pOut. Set the span of pOut to be the identifier @@ -155144,90 +157315,92 @@ static void updateDeleteLimitError( #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_COLLATE 112 +#define TK_BITNOT 113 +#define TK_ON 114 +#define TK_INDEXED 115 +#define TK_STRING 116 +#define TK_JOIN_KW 117 +#define TK_CONSTRAINT 118 +#define TK_DEFAULT 119 +#define TK_NULL 120 +#define TK_PRIMARY 121 +#define TK_UNIQUE 122 +#define TK_CHECK 123 +#define TK_REFERENCES 124 +#define TK_AUTOINCR 125 +#define TK_INSERT 126 +#define TK_DELETE 127 +#define TK_UPDATE 128 +#define TK_SET 129 +#define TK_DEFERRABLE 130 +#define TK_FOREIGN 131 +#define TK_DROP 132 +#define TK_UNION 133 +#define TK_ALL 134 +#define TK_EXCEPT 135 +#define TK_INTERSECT 136 +#define TK_SELECT 137 +#define TK_VALUES 138 +#define TK_DISTINCT 139 +#define TK_DOT 140 +#define TK_FROM 141 +#define TK_JOIN 142 +#define TK_USING 143 +#define TK_ORDER 144 +#define TK_GROUP 145 +#define TK_HAVING 146 +#define TK_LIMIT 147 +#define TK_WHERE 148 +#define TK_RETURNING 149 +#define TK_INTO 150 +#define TK_NOTHING 151 +#define TK_FLOAT 152 +#define TK_BLOB 153 +#define TK_INTEGER 154 +#define TK_VARIABLE 155 +#define TK_CASE 156 +#define TK_WHEN 157 +#define TK_THEN 158 +#define TK_ELSE 159 +#define TK_INDEX 160 +#define TK_ALTER 161 +#define TK_ADD 162 +#define TK_WINDOW 163 +#define TK_OVER 164 +#define TK_FILTER 165 +#define TK_COLUMN 166 +#define TK_AGG_FUNCTION 167 +#define TK_AGG_COLUMN 168 +#define TK_TRUEFALSE 169 +#define TK_ISNOT 170 +#define TK_FUNCTION 171 +#define TK_UMINUS 172 +#define TK_UPLUS 173 +#define TK_TRUTH 174 +#define TK_REGISTER 175 +#define TK_VECTOR 176 +#define TK_SELECT_COLUMN 177 +#define TK_IF_NULL_ROW 178 +#define TK_ASTERISK 179 +#define TK_SPAN 180 +#define TK_SPACE 181 +#define TK_ILLEGAL 182 #endif /**************** End token definitions ***************************************/ @@ -155287,28 +157460,29 @@ static void updateDeleteLimitError( #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 310 +#define YYNOCODE 316 #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; + Window* yy19; + struct TrigEvent yy50; + int yy60; + struct FrameBound yy113; + Upsert* yy178; + With* yy195; + IdList* yy288; + SrcList* yy291; + Select* yy307; + ExprList* yy338; + TriggerStep* yy483; + const char* yy528; + u8 yy570; + Expr* yy602; + Cte* yy607; + struct {int value; int mask;} yy615; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -155324,18 +157498,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 570 +#define YYNRULE 398 +#define YYNRULE_WITH_ACTION 337 +#define YYNTOKEN 183 +#define YY_MAX_SHIFT 569 +#define YY_MIN_SHIFTREDUCE 825 +#define YY_MAX_SHIFTREDUCE 1222 +#define YY_ERROR_ACTION 1223 +#define YY_ACCEPT_ACTION 1224 +#define YY_NO_ACTION 1225 +#define YY_MIN_REDUCE 1226 +#define YY_MAX_REDUCE 1623 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -155402,586 +157576,600 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (1962) +#define YY_ACTTAB_COUNT (2020) 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 */ 563, 1295, 563, 1274, 168, 361, 115, 112, 218, 373, + /* 10 */ 563, 1295, 374, 563, 488, 563, 115, 112, 218, 406, + /* 20 */ 1300, 1300, 41, 41, 41, 41, 514, 1504, 520, 1298, + /* 30 */ 1298, 959, 41, 41, 1257, 71, 71, 51, 51, 960, + /* 40 */ 557, 557, 557, 122, 123, 113, 1200, 1200, 1035, 1038, + /* 50 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 414, 406, + /* 60 */ 273, 273, 273, 273, 115, 112, 218, 115, 112, 218, + /* 70 */ 197, 268, 545, 560, 515, 560, 1260, 563, 385, 248, + /* 80 */ 215, 521, 399, 122, 123, 113, 1200, 1200, 1035, 1038, + /* 90 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 540, 13, + /* 100 */ 13, 1259, 119, 119, 119, 119, 118, 118, 117, 117, + /* 110 */ 117, 116, 441, 1176, 419, 1531, 446, 137, 512, 1539, + /* 120 */ 1545, 372, 1547, 6, 371, 1176, 1148, 1584, 1148, 406, + /* 130 */ 1545, 534, 115, 112, 218, 1267, 99, 441, 121, 121, + /* 140 */ 121, 121, 119, 119, 119, 119, 118, 118, 117, 117, + /* 150 */ 117, 116, 441, 122, 123, 113, 1200, 1200, 1035, 1038, + /* 160 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 197, 1176, + /* 170 */ 1177, 1178, 241, 304, 554, 501, 498, 497, 473, 124, + /* 180 */ 394, 1176, 1177, 1178, 1176, 496, 119, 119, 119, 119, + /* 190 */ 118, 118, 117, 117, 117, 116, 441, 139, 540, 406, + /* 200 */ 121, 121, 121, 121, 114, 117, 117, 117, 116, 441, + /* 210 */ 541, 1532, 119, 119, 119, 119, 118, 118, 117, 117, + /* 220 */ 117, 116, 441, 122, 123, 113, 1200, 1200, 1035, 1038, + /* 230 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 406, 320, + /* 240 */ 1176, 1177, 1178, 81, 342, 1590, 396, 80, 119, 119, + /* 250 */ 119, 119, 118, 118, 117, 117, 117, 116, 441, 1176, + /* 260 */ 211, 450, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, + /* 270 */ 1028, 120, 120, 121, 121, 121, 121, 251, 450, 449, + /* 280 */ 273, 273, 119, 119, 119, 119, 118, 118, 117, 117, + /* 290 */ 117, 116, 441, 560, 1224, 1, 1, 569, 2, 1228, + /* 300 */ 317, 1176, 319, 1561, 305, 337, 140, 340, 406, 430, + /* 310 */ 469, 1533, 1197, 1308, 348, 1176, 1177, 1178, 168, 462, + /* 320 */ 330, 119, 119, 119, 119, 118, 118, 117, 117, 117, + /* 330 */ 116, 441, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, + /* 340 */ 1028, 120, 120, 121, 121, 121, 121, 273, 273, 563, + /* 350 */ 83, 450, 416, 1564, 569, 2, 1228, 1176, 1177, 1178, + /* 360 */ 560, 305, 471, 140, 944, 995, 860, 563, 467, 1197, + /* 370 */ 1308, 13, 13, 137, 229, 118, 118, 117, 117, 117, + /* 380 */ 116, 441, 96, 318, 946, 504, 424, 361, 562, 71, + /* 390 */ 71, 119, 119, 119, 119, 118, 118, 117, 117, 117, + /* 400 */ 116, 441, 427, 205, 273, 273, 445, 1015, 259, 276, + /* 410 */ 356, 507, 351, 506, 246, 406, 959, 560, 328, 344, + /* 420 */ 347, 315, 860, 1006, 960, 126, 545, 1005, 313, 304, + /* 430 */ 554, 229, 538, 1539, 148, 544, 281, 6, 203, 122, + /* 440 */ 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, + /* 450 */ 121, 121, 121, 121, 563, 217, 563, 12, 406, 1005, + /* 460 */ 1005, 1007, 502, 445, 119, 119, 119, 119, 118, 118, + /* 470 */ 117, 117, 117, 116, 441, 452, 71, 71, 70, 70, + /* 480 */ 944, 137, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, + /* 490 */ 1028, 120, 120, 121, 121, 121, 121, 1530, 119, 119, + /* 500 */ 119, 119, 118, 118, 117, 117, 117, 116, 441, 403, + /* 510 */ 402, 241, 1176, 545, 501, 498, 497, 1468, 1143, 451, + /* 520 */ 267, 267, 513, 1540, 496, 142, 1176, 6, 406, 530, + /* 530 */ 194, 1143, 864, 560, 1143, 461, 182, 304, 554, 32, + /* 540 */ 379, 119, 119, 119, 119, 118, 118, 117, 117, 117, + /* 550 */ 116, 441, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, + /* 560 */ 1028, 120, 120, 121, 121, 121, 121, 406, 1176, 1177, + /* 570 */ 1178, 857, 568, 1176, 1228, 925, 1176, 454, 361, 305, + /* 580 */ 189, 140, 1176, 1177, 1178, 519, 529, 404, 1308, 183, + /* 590 */ 1015, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, + /* 600 */ 120, 120, 121, 121, 121, 121, 1006, 16, 16, 370, + /* 610 */ 1005, 119, 119, 119, 119, 118, 118, 117, 117, 117, + /* 620 */ 116, 441, 273, 273, 1537, 150, 1176, 98, 6, 1176, + /* 630 */ 1177, 1178, 1176, 1177, 1178, 560, 380, 406, 376, 438, + /* 640 */ 437, 1161, 1005, 1005, 1007, 1025, 1025, 1036, 1039, 229, + /* 650 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116, + /* 660 */ 441, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, + /* 670 */ 120, 120, 121, 121, 121, 121, 406, 1143, 1619, 392, + /* 680 */ 1016, 445, 1176, 1177, 1178, 1207, 525, 1207, 1530, 995, + /* 690 */ 1143, 304, 554, 1143, 5, 563, 543, 3, 361, 216, + /* 700 */ 122, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, + /* 710 */ 120, 121, 121, 121, 121, 143, 563, 13, 13, 1029, + /* 720 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116, + /* 730 */ 441, 1176, 426, 563, 1176, 563, 274, 274, 13, 13, + /* 740 */ 1078, 1176, 328, 457, 316, 147, 406, 211, 361, 560, + /* 750 */ 1000, 213, 511, 293, 477, 55, 55, 71, 71, 119, + /* 760 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 441, + /* 770 */ 122, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, + /* 780 */ 120, 121, 121, 121, 121, 406, 455, 1176, 1177, 1178, + /* 790 */ 1176, 1177, 1178, 471, 526, 149, 404, 1176, 1177, 1178, + /* 800 */ 105, 270, 103, 563, 944, 563, 116, 441, 1530, 122, + /* 810 */ 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, + /* 820 */ 121, 121, 121, 121, 945, 13, 13, 13, 13, 119, + /* 830 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 441, + /* 840 */ 191, 563, 192, 563, 416, 439, 439, 439, 1083, 1083, + /* 850 */ 485, 561, 285, 914, 914, 406, 462, 330, 1530, 830, + /* 860 */ 831, 832, 206, 71, 71, 71, 71, 286, 119, 119, + /* 870 */ 119, 119, 118, 118, 117, 117, 117, 116, 441, 122, + /* 880 */ 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, + /* 890 */ 121, 121, 121, 121, 563, 217, 563, 1122, 1617, 406, + /* 900 */ 300, 1617, 301, 416, 1278, 1473, 244, 243, 242, 1249, + /* 910 */ 412, 556, 412, 282, 842, 279, 71, 71, 71, 71, + /* 920 */ 944, 1415, 1473, 1475, 101, 113, 1200, 1200, 1035, 1038, + /* 930 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 119, 119, + /* 940 */ 119, 119, 118, 118, 117, 117, 117, 116, 441, 273, + /* 950 */ 273, 1099, 563, 436, 1143, 440, 563, 1122, 1618, 357, + /* 960 */ 1558, 1618, 560, 546, 488, 197, 1100, 1143, 378, 290, + /* 970 */ 1143, 1306, 284, 460, 71, 71, 1120, 405, 13, 13, + /* 980 */ 145, 1101, 119, 119, 119, 119, 118, 118, 117, 117, + /* 990 */ 117, 116, 441, 542, 104, 1473, 509, 273, 273, 294, + /* 1000 */ 1514, 294, 900, 273, 273, 273, 273, 563, 1503, 563, + /* 1010 */ 560, 545, 901, 464, 406, 1058, 560, 852, 560, 198, + /* 1020 */ 547, 1080, 920, 404, 1400, 1080, 146, 919, 38, 56, + /* 1030 */ 56, 15, 15, 563, 406, 12, 1120, 471, 122, 123, + /* 1040 */ 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, 121, + /* 1050 */ 121, 121, 121, 1460, 406, 43, 43, 483, 122, 123, + /* 1060 */ 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, 121, + /* 1070 */ 121, 121, 121, 563, 852, 9, 471, 251, 122, 111, + /* 1080 */ 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, 121, + /* 1090 */ 121, 121, 121, 563, 421, 57, 57, 119, 119, 119, + /* 1100 */ 119, 118, 118, 117, 117, 117, 116, 441, 1176, 493, + /* 1110 */ 563, 289, 1197, 478, 1516, 44, 44, 119, 119, 119, + /* 1120 */ 119, 118, 118, 117, 117, 117, 116, 441, 880, 563, + /* 1130 */ 536, 563, 58, 58, 488, 1414, 245, 119, 119, 119, + /* 1140 */ 119, 118, 118, 117, 117, 117, 116, 441, 563, 535, + /* 1150 */ 291, 59, 59, 60, 60, 438, 437, 406, 1154, 505, + /* 1160 */ 304, 554, 477, 1204, 1176, 1177, 1178, 881, 1206, 1197, + /* 1170 */ 61, 61, 1246, 357, 1558, 1538, 1205, 563, 1467, 6, + /* 1180 */ 1176, 488, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, + /* 1190 */ 120, 120, 121, 121, 121, 121, 1400, 1143, 410, 62, + /* 1200 */ 62, 1207, 1099, 1207, 411, 447, 273, 273, 537, 1154, + /* 1210 */ 1143, 108, 555, 1143, 4, 391, 1220, 1100, 1512, 560, + /* 1220 */ 347, 516, 428, 548, 308, 1307, 1536, 1077, 558, 1077, + /* 1230 */ 6, 488, 1101, 1400, 488, 309, 1176, 1177, 1178, 563, + /* 1240 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116, + /* 1250 */ 441, 442, 278, 551, 563, 273, 273, 273, 273, 563, + /* 1260 */ 327, 45, 45, 552, 563, 528, 422, 563, 560, 1400, + /* 1270 */ 560, 108, 555, 137, 4, 1303, 46, 46, 335, 563, + /* 1280 */ 482, 47, 47, 477, 479, 307, 49, 49, 558, 50, + /* 1290 */ 50, 563, 1015, 563, 1221, 563, 1400, 563, 106, 106, + /* 1300 */ 8, 63, 63, 423, 563, 107, 312, 442, 565, 564, + /* 1310 */ 563, 442, 1005, 64, 64, 65, 65, 14, 14, 66, + /* 1320 */ 66, 391, 1121, 552, 1312, 1180, 128, 128, 563, 304, + /* 1330 */ 554, 563, 67, 67, 563, 359, 560, 532, 563, 484, + /* 1340 */ 563, 1196, 531, 222, 1005, 1005, 1007, 1008, 27, 522, + /* 1350 */ 52, 52, 1015, 68, 68, 563, 69, 69, 106, 106, + /* 1360 */ 53, 53, 156, 156, 563, 107, 434, 442, 565, 564, + /* 1370 */ 272, 215, 1005, 425, 563, 359, 563, 157, 157, 563, + /* 1380 */ 1535, 292, 1180, 98, 6, 1344, 76, 76, 1215, 475, + /* 1390 */ 413, 169, 226, 563, 245, 563, 54, 54, 72, 72, + /* 1400 */ 1221, 129, 129, 1343, 1005, 1005, 1007, 1008, 27, 1563, + /* 1410 */ 1165, 444, 456, 433, 277, 73, 73, 130, 130, 389, + /* 1420 */ 389, 388, 262, 386, 1165, 444, 839, 1519, 277, 108, + /* 1430 */ 555, 321, 4, 389, 389, 388, 262, 386, 563, 223, + /* 1440 */ 839, 311, 468, 84, 202, 523, 558, 1492, 303, 310, + /* 1450 */ 563, 110, 404, 223, 563, 311, 206, 30, 404, 277, + /* 1460 */ 131, 131, 411, 310, 389, 389, 388, 262, 386, 442, + /* 1470 */ 920, 839, 127, 127, 563, 919, 155, 155, 1491, 225, + /* 1480 */ 563, 552, 871, 563, 223, 476, 311, 161, 31, 563, + /* 1490 */ 135, 563, 480, 225, 310, 532, 154, 154, 332, 17, + /* 1500 */ 533, 161, 136, 136, 135, 134, 134, 224, 228, 355, + /* 1510 */ 1015, 132, 132, 133, 133, 1589, 106, 106, 889, 354, + /* 1520 */ 563, 224, 563, 107, 225, 442, 565, 564, 1117, 275, + /* 1530 */ 1005, 393, 161, 518, 563, 135, 108, 555, 417, 4, + /* 1540 */ 1340, 407, 75, 75, 77, 77, 304, 554, 867, 563, + /* 1550 */ 336, 563, 224, 558, 463, 407, 74, 74, 465, 1065, + /* 1560 */ 304, 554, 1005, 1005, 1007, 1008, 27, 962, 963, 543, + /* 1570 */ 448, 42, 42, 48, 48, 326, 442, 325, 98, 997, + /* 1580 */ 470, 287, 250, 250, 448, 1009, 407, 472, 552, 339, + /* 1590 */ 250, 304, 554, 879, 878, 331, 108, 555, 98, 4, + /* 1600 */ 1277, 494, 532, 345, 247, 867, 98, 531, 341, 886, + /* 1610 */ 887, 1126, 1076, 558, 1076, 448, 1065, 1015, 1061, 953, + /* 1620 */ 343, 247, 250, 106, 106, 1291, 917, 1276, 850, 110, + /* 1630 */ 107, 144, 442, 565, 564, 918, 442, 1005, 110, 1275, + /* 1640 */ 350, 360, 1009, 1331, 1352, 299, 1399, 1577, 552, 1327, + /* 1650 */ 1552, 550, 1338, 549, 1405, 1256, 1248, 1237, 1236, 1238, + /* 1660 */ 1571, 489, 265, 200, 1324, 363, 365, 367, 11, 1005, + /* 1670 */ 1005, 1007, 1008, 27, 390, 221, 1386, 1015, 280, 1391, + /* 1680 */ 1381, 208, 323, 106, 106, 924, 1374, 453, 283, 324, + /* 1690 */ 107, 474, 442, 565, 564, 1390, 499, 1005, 212, 288, + /* 1700 */ 1274, 397, 353, 108, 555, 195, 4, 1464, 369, 1463, + /* 1710 */ 1574, 1215, 1212, 329, 553, 171, 207, 383, 1511, 196, + /* 1720 */ 558, 254, 1509, 415, 100, 555, 83, 4, 204, 1005, + /* 1730 */ 1005, 1007, 1008, 27, 219, 79, 82, 1469, 180, 166, + /* 1740 */ 173, 558, 458, 442, 175, 176, 177, 178, 35, 1387, + /* 1750 */ 492, 459, 231, 1395, 96, 552, 1393, 1392, 395, 184, + /* 1760 */ 481, 466, 36, 235, 442, 89, 398, 266, 487, 1480, + /* 1770 */ 1458, 237, 188, 338, 508, 429, 552, 490, 400, 238, + /* 1780 */ 334, 1239, 239, 1294, 1015, 1293, 1292, 1285, 91, 871, + /* 1790 */ 106, 106, 213, 431, 1588, 432, 524, 107, 517, 442, + /* 1800 */ 565, 564, 401, 1264, 1005, 1015, 1263, 1587, 352, 1262, + /* 1810 */ 1557, 106, 106, 1586, 1284, 297, 298, 358, 107, 1335, + /* 1820 */ 442, 565, 564, 95, 362, 1005, 253, 252, 435, 125, + /* 1830 */ 543, 10, 1444, 1543, 377, 1542, 1005, 1005, 1007, 1008, + /* 1840 */ 27, 302, 102, 97, 527, 1336, 260, 1317, 364, 1245, + /* 1850 */ 1334, 34, 566, 1171, 366, 381, 375, 1005, 1005, 1007, + /* 1860 */ 1008, 27, 1333, 1359, 368, 1316, 199, 382, 261, 263, + /* 1870 */ 264, 1358, 158, 1496, 141, 1497, 1495, 567, 1234, 1229, + /* 1880 */ 1494, 295, 159, 209, 210, 78, 826, 443, 201, 306, + /* 1890 */ 220, 1075, 138, 1073, 160, 314, 162, 172, 1196, 174, + /* 1900 */ 903, 227, 230, 322, 1089, 179, 163, 164, 418, 85, + /* 1910 */ 420, 181, 170, 408, 409, 86, 87, 165, 88, 1092, + /* 1920 */ 232, 233, 1088, 151, 18, 234, 1081, 250, 333, 185, + /* 1930 */ 1209, 486, 236, 186, 37, 841, 491, 354, 240, 346, + /* 1940 */ 503, 187, 90, 167, 19, 495, 20, 869, 500, 349, + /* 1950 */ 92, 882, 296, 152, 93, 510, 1127, 1159, 153, 1041, + /* 1960 */ 214, 1128, 39, 94, 269, 271, 952, 190, 947, 110, + /* 1970 */ 1149, 1145, 1153, 249, 1133, 1147, 7, 33, 21, 193, + /* 1980 */ 22, 23, 24, 25, 1152, 539, 98, 1056, 26, 1042, + /* 1990 */ 1040, 1044, 1098, 1045, 1097, 256, 255, 28, 40, 387, + /* 2000 */ 1010, 851, 109, 29, 1167, 559, 384, 257, 913, 258, + /* 2010 */ 1166, 1579, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1578, }; 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, - /* 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, + /* 0 */ 191, 220, 191, 222, 191, 191, 271, 272, 273, 216, + /* 10 */ 191, 230, 216, 191, 191, 191, 271, 272, 273, 19, + /* 20 */ 232, 233, 213, 214, 213, 214, 202, 292, 202, 232, + /* 30 */ 233, 31, 213, 214, 213, 213, 214, 213, 214, 39, + /* 40 */ 207, 208, 209, 43, 44, 45, 46, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 235, 19, + /* 60 */ 236, 237, 236, 237, 271, 272, 273, 271, 272, 273, + /* 70 */ 191, 210, 250, 249, 250, 249, 213, 191, 199, 253, + /* 80 */ 254, 259, 203, 43, 44, 45, 46, 47, 48, 49, + /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 191, 213, + /* 100 */ 214, 213, 102, 103, 104, 105, 106, 107, 108, 109, + /* 110 */ 110, 111, 112, 59, 228, 301, 293, 81, 305, 306, + /* 120 */ 311, 312, 311, 310, 313, 59, 86, 212, 88, 19, + /* 130 */ 311, 312, 271, 272, 273, 220, 26, 112, 54, 55, + /* 140 */ 56, 57, 102, 103, 104, 105, 106, 107, 108, 109, + /* 150 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49, + /* 160 */ 50, 51, 52, 53, 54, 55, 56, 57, 191, 115, + /* 170 */ 116, 117, 118, 137, 138, 121, 122, 123, 191, 69, + /* 180 */ 203, 115, 116, 117, 59, 131, 102, 103, 104, 105, + /* 190 */ 106, 107, 108, 109, 110, 111, 112, 72, 191, 19, + /* 200 */ 54, 55, 56, 57, 58, 108, 109, 110, 111, 112, + /* 210 */ 303, 304, 102, 103, 104, 105, 106, 107, 108, 109, + /* 220 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49, + /* 230 */ 50, 51, 52, 53, 54, 55, 56, 57, 19, 16, + /* 240 */ 115, 116, 117, 24, 16, 227, 202, 67, 102, 103, + /* 250 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 59, + /* 260 */ 26, 191, 43, 44, 45, 46, 47, 48, 49, 50, + /* 270 */ 51, 52, 53, 54, 55, 56, 57, 24, 208, 209, + /* 280 */ 236, 237, 102, 103, 104, 105, 106, 107, 108, 109, + /* 290 */ 110, 111, 112, 249, 183, 184, 185, 186, 187, 188, + /* 300 */ 77, 59, 79, 191, 193, 77, 195, 79, 19, 19, + /* 310 */ 266, 304, 59, 202, 24, 115, 116, 117, 191, 127, + /* 320 */ 128, 102, 103, 104, 105, 106, 107, 108, 109, 110, + /* 330 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50, + /* 340 */ 51, 52, 53, 54, 55, 56, 57, 236, 237, 191, + /* 350 */ 150, 281, 191, 185, 186, 187, 188, 115, 116, 117, + /* 360 */ 249, 193, 191, 195, 26, 73, 59, 191, 114, 116, + /* 370 */ 202, 213, 214, 81, 263, 106, 107, 108, 109, 110, + /* 380 */ 111, 112, 148, 160, 142, 95, 228, 191, 191, 213, + /* 390 */ 214, 102, 103, 104, 105, 106, 107, 108, 109, 110, + /* 400 */ 111, 112, 112, 149, 236, 237, 295, 100, 118, 119, + /* 410 */ 120, 121, 122, 123, 124, 19, 31, 249, 126, 23, + /* 420 */ 130, 260, 115, 116, 39, 22, 250, 120, 191, 137, + /* 430 */ 138, 263, 305, 306, 238, 259, 265, 310, 149, 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, + /* 450 */ 54, 55, 56, 57, 191, 117, 191, 210, 19, 152, + /* 460 */ 153, 154, 23, 295, 102, 103, 104, 105, 106, 107, + /* 470 */ 108, 109, 110, 111, 112, 266, 213, 214, 213, 214, + /* 480 */ 142, 81, 43, 44, 45, 46, 47, 48, 49, 50, + /* 490 */ 51, 52, 53, 54, 55, 56, 57, 301, 102, 103, + /* 500 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 106, + /* 510 */ 107, 118, 59, 250, 121, 122, 123, 280, 76, 119, + /* 520 */ 236, 237, 259, 306, 131, 72, 59, 310, 19, 87, + /* 530 */ 283, 89, 23, 249, 92, 288, 22, 137, 138, 22, + /* 540 */ 275, 102, 103, 104, 105, 106, 107, 108, 109, 110, + /* 550 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50, + /* 560 */ 51, 52, 53, 54, 55, 56, 57, 19, 115, 116, + /* 570 */ 117, 23, 186, 59, 188, 108, 59, 241, 191, 193, + /* 580 */ 26, 195, 115, 116, 117, 191, 144, 251, 202, 22, + /* 590 */ 100, 43, 44, 45, 46, 47, 48, 49, 50, 51, + /* 600 */ 52, 53, 54, 55, 56, 57, 116, 213, 214, 191, + /* 610 */ 120, 102, 103, 104, 105, 106, 107, 108, 109, 110, + /* 620 */ 111, 112, 236, 237, 306, 238, 59, 26, 310, 115, + /* 630 */ 116, 117, 115, 116, 117, 249, 246, 19, 248, 106, + /* 640 */ 107, 23, 152, 153, 154, 46, 47, 48, 49, 263, + /* 650 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 660 */ 112, 43, 44, 45, 46, 47, 48, 49, 50, 51, + /* 670 */ 52, 53, 54, 55, 56, 57, 19, 76, 298, 299, + /* 680 */ 23, 295, 115, 116, 117, 152, 191, 154, 301, 73, + /* 690 */ 89, 137, 138, 92, 22, 191, 144, 22, 191, 191, + /* 700 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + /* 710 */ 53, 54, 55, 56, 57, 163, 191, 213, 214, 120, + /* 720 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 730 */ 112, 59, 228, 191, 59, 191, 236, 237, 213, 214, + /* 740 */ 11, 59, 126, 127, 128, 238, 19, 26, 191, 249, + /* 750 */ 23, 164, 165, 228, 191, 213, 214, 213, 214, 102, + /* 760 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 770 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + /* 780 */ 53, 54, 55, 56, 57, 19, 241, 115, 116, 117, + /* 790 */ 115, 116, 117, 191, 250, 238, 251, 115, 116, 117, + /* 800 */ 157, 23, 159, 191, 26, 191, 111, 112, 301, 43, + /* 810 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 820 */ 54, 55, 56, 57, 142, 213, 214, 213, 214, 102, + /* 830 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 840 */ 228, 191, 228, 191, 191, 207, 208, 209, 126, 127, + /* 850 */ 128, 133, 289, 135, 136, 19, 127, 128, 301, 7, + /* 860 */ 8, 9, 141, 213, 214, 213, 214, 265, 102, 103, + /* 870 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 43, + /* 880 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 890 */ 54, 55, 56, 57, 191, 117, 191, 22, 23, 19, + /* 900 */ 250, 26, 250, 191, 223, 191, 126, 127, 128, 205, + /* 910 */ 206, 205, 206, 260, 21, 202, 213, 214, 213, 214, + /* 920 */ 142, 270, 208, 209, 158, 45, 46, 47, 48, 49, + /* 930 */ 50, 51, 52, 53, 54, 55, 56, 57, 102, 103, + /* 940 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 236, + /* 950 */ 237, 12, 191, 250, 76, 250, 191, 22, 23, 308, + /* 960 */ 309, 26, 249, 202, 191, 191, 27, 89, 191, 202, + /* 970 */ 92, 202, 260, 80, 213, 214, 101, 203, 213, 214, + /* 980 */ 22, 42, 102, 103, 104, 105, 106, 107, 108, 109, + /* 990 */ 110, 111, 112, 228, 158, 281, 108, 236, 237, 225, + /* 1000 */ 191, 227, 63, 236, 237, 236, 237, 191, 235, 191, + /* 1010 */ 249, 250, 73, 241, 19, 122, 249, 59, 249, 24, + /* 1020 */ 259, 29, 134, 251, 191, 33, 22, 139, 24, 213, + /* 1030 */ 214, 213, 214, 191, 19, 210, 101, 191, 43, 44, + /* 1040 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + /* 1050 */ 55, 56, 57, 160, 19, 213, 214, 65, 43, 44, + /* 1060 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + /* 1070 */ 55, 56, 57, 191, 116, 22, 191, 24, 43, 44, + /* 1080 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + /* 1090 */ 55, 56, 57, 191, 261, 213, 214, 102, 103, 104, + /* 1100 */ 105, 106, 107, 108, 109, 110, 111, 112, 59, 19, + /* 1110 */ 191, 265, 59, 288, 191, 213, 214, 102, 103, 104, + /* 1120 */ 105, 106, 107, 108, 109, 110, 111, 112, 35, 191, + /* 1130 */ 66, 191, 213, 214, 191, 270, 46, 102, 103, 104, + /* 1140 */ 105, 106, 107, 108, 109, 110, 111, 112, 191, 85, + /* 1150 */ 265, 213, 214, 213, 214, 106, 107, 19, 94, 66, + /* 1160 */ 137, 138, 191, 114, 115, 116, 117, 74, 119, 116, + /* 1170 */ 213, 214, 202, 308, 309, 306, 127, 191, 235, 310, + /* 1180 */ 59, 191, 44, 45, 46, 47, 48, 49, 50, 51, + /* 1190 */ 52, 53, 54, 55, 56, 57, 191, 76, 196, 213, + /* 1200 */ 214, 152, 12, 154, 114, 191, 236, 237, 87, 145, + /* 1210 */ 89, 19, 20, 92, 22, 22, 23, 27, 191, 249, + /* 1220 */ 130, 202, 129, 202, 191, 235, 306, 152, 36, 154, + /* 1230 */ 310, 191, 42, 191, 191, 191, 115, 116, 117, 191, + /* 1240 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 1250 */ 112, 59, 99, 63, 191, 236, 237, 236, 237, 191, + /* 1260 */ 289, 213, 214, 71, 191, 144, 261, 191, 249, 191, + /* 1270 */ 249, 19, 20, 81, 22, 235, 213, 214, 235, 191, + /* 1280 */ 278, 213, 214, 191, 282, 132, 213, 214, 36, 213, + /* 1290 */ 214, 191, 100, 191, 101, 191, 191, 191, 106, 107, + /* 1300 */ 48, 213, 214, 261, 191, 113, 191, 115, 116, 117, + /* 1310 */ 191, 59, 120, 213, 214, 213, 214, 213, 214, 213, + /* 1320 */ 214, 22, 23, 71, 237, 59, 213, 214, 191, 137, + /* 1330 */ 138, 191, 213, 214, 191, 191, 249, 85, 191, 261, + /* 1340 */ 191, 26, 90, 15, 152, 153, 154, 155, 156, 19, + /* 1350 */ 213, 214, 100, 213, 214, 191, 213, 214, 106, 107, + /* 1360 */ 213, 214, 213, 214, 191, 113, 261, 115, 116, 117, + /* 1370 */ 253, 254, 120, 229, 191, 191, 191, 213, 214, 191, + /* 1380 */ 306, 289, 116, 26, 310, 191, 213, 214, 60, 19, + /* 1390 */ 296, 297, 24, 191, 46, 191, 213, 214, 213, 214, + /* 1400 */ 101, 213, 214, 191, 152, 153, 154, 155, 156, 0, + /* 1410 */ 1, 2, 191, 229, 5, 213, 214, 213, 214, 10, + /* 1420 */ 11, 12, 13, 14, 1, 2, 17, 191, 5, 19, + /* 1430 */ 20, 191, 22, 10, 11, 12, 13, 14, 191, 30, + /* 1440 */ 17, 32, 241, 148, 149, 115, 36, 191, 241, 40, + /* 1450 */ 191, 26, 251, 30, 191, 32, 141, 22, 251, 5, + /* 1460 */ 213, 214, 114, 40, 10, 11, 12, 13, 14, 59, + /* 1470 */ 134, 17, 213, 214, 191, 139, 213, 214, 191, 70, + /* 1480 */ 191, 71, 125, 191, 30, 115, 32, 78, 53, 191, + /* 1490 */ 81, 191, 191, 70, 40, 85, 213, 214, 191, 22, + /* 1500 */ 90, 78, 213, 214, 81, 213, 214, 98, 140, 120, + /* 1510 */ 100, 213, 214, 213, 214, 23, 106, 107, 26, 130, + /* 1520 */ 191, 98, 191, 113, 70, 115, 116, 117, 23, 22, + /* 1530 */ 120, 26, 78, 19, 191, 81, 19, 20, 61, 22, + /* 1540 */ 191, 132, 213, 214, 213, 214, 137, 138, 59, 191, + /* 1550 */ 191, 191, 98, 36, 128, 132, 213, 214, 128, 59, + /* 1560 */ 137, 138, 152, 153, 154, 155, 156, 83, 84, 144, + /* 1570 */ 161, 213, 214, 213, 214, 23, 59, 151, 26, 23, + /* 1580 */ 23, 151, 26, 26, 161, 59, 132, 23, 71, 191, + /* 1590 */ 26, 137, 138, 119, 120, 23, 19, 20, 26, 22, + /* 1600 */ 223, 23, 85, 23, 26, 116, 26, 90, 191, 7, + /* 1610 */ 8, 97, 152, 36, 154, 161, 116, 100, 23, 23, + /* 1620 */ 191, 26, 26, 106, 107, 191, 23, 223, 23, 26, + /* 1630 */ 113, 26, 115, 116, 117, 23, 59, 120, 26, 191, + /* 1640 */ 191, 191, 116, 255, 191, 252, 191, 140, 71, 191, + /* 1650 */ 315, 233, 191, 191, 191, 191, 191, 191, 191, 191, + /* 1660 */ 191, 285, 284, 239, 252, 252, 252, 252, 240, 152, + /* 1670 */ 153, 154, 155, 156, 189, 294, 268, 100, 242, 268, + /* 1680 */ 264, 211, 290, 106, 107, 108, 264, 256, 256, 243, + /* 1690 */ 113, 290, 115, 116, 117, 268, 217, 120, 226, 243, + /* 1700 */ 222, 268, 216, 19, 20, 246, 22, 216, 256, 216, + /* 1710 */ 194, 60, 38, 242, 277, 294, 240, 242, 198, 246, + /* 1720 */ 36, 140, 198, 198, 19, 20, 150, 22, 149, 152, + /* 1730 */ 153, 154, 155, 156, 294, 291, 291, 280, 22, 43, + /* 1740 */ 231, 36, 18, 59, 234, 234, 234, 234, 267, 269, + /* 1750 */ 18, 198, 197, 231, 148, 71, 269, 269, 243, 231, + /* 1760 */ 198, 243, 267, 197, 59, 157, 243, 198, 62, 287, + /* 1770 */ 243, 197, 22, 198, 114, 64, 71, 218, 218, 197, + /* 1780 */ 286, 198, 197, 215, 100, 215, 215, 224, 22, 125, + /* 1790 */ 106, 107, 164, 24, 221, 112, 143, 113, 302, 115, + /* 1800 */ 116, 117, 218, 215, 120, 100, 217, 221, 215, 215, + /* 1810 */ 309, 106, 107, 215, 224, 279, 279, 218, 113, 258, + /* 1820 */ 115, 116, 117, 114, 257, 120, 91, 198, 82, 147, + /* 1830 */ 144, 22, 274, 314, 198, 314, 152, 153, 154, 155, + /* 1840 */ 156, 276, 157, 146, 145, 258, 25, 247, 257, 201, + /* 1850 */ 258, 26, 200, 13, 257, 244, 246, 152, 153, 154, + /* 1860 */ 155, 156, 258, 262, 257, 247, 245, 243, 192, 192, + /* 1870 */ 6, 262, 204, 210, 219, 210, 210, 190, 190, 190, + /* 1880 */ 210, 219, 204, 211, 211, 210, 4, 3, 22, 162, + /* 1890 */ 15, 23, 16, 23, 204, 138, 129, 150, 26, 141, + /* 1900 */ 20, 24, 143, 16, 1, 141, 129, 129, 61, 53, + /* 1910 */ 37, 150, 297, 300, 300, 53, 53, 129, 53, 115, + /* 1920 */ 34, 140, 1, 5, 22, 114, 68, 26, 160, 68, + /* 1930 */ 75, 41, 140, 114, 24, 20, 19, 130, 124, 23, + /* 1940 */ 96, 22, 22, 37, 22, 67, 22, 59, 67, 24, + /* 1950 */ 22, 28, 67, 23, 148, 22, 97, 23, 23, 23, + /* 1960 */ 140, 23, 22, 26, 23, 23, 115, 22, 142, 26, + /* 1970 */ 75, 88, 75, 34, 23, 86, 44, 22, 34, 26, + /* 1980 */ 34, 34, 34, 34, 93, 24, 26, 23, 34, 23, + /* 1990 */ 23, 23, 23, 11, 23, 22, 26, 22, 22, 15, + /* 2000 */ 23, 23, 22, 22, 1, 26, 23, 140, 134, 140, + /* 2010 */ 1, 140, 316, 316, 316, 316, 316, 316, 316, 140, + /* 2020 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2030 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2040 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2050 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2060 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2070 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2080 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2090 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2100 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2110 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2120 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2130 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2140 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2150 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2160 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2170 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2180 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2190 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2200 */ 316, 316, 316, }; -#define YY_SHIFT_COUNT (552) +#define YY_SHIFT_COUNT (569) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (1951) +#define YY_SHIFT_MAX (2009) 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 */ 1423, 1409, 1454, 1192, 1192, 36, 1252, 1410, 1517, 1684, + /* 10 */ 1684, 1684, 292, 0, 0, 180, 1015, 1684, 1684, 1684, + /* 20 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, + /* 30 */ 1049, 1049, 1121, 1121, 54, 400, 36, 36, 36, 36, + /* 40 */ 36, 40, 110, 219, 289, 396, 439, 509, 548, 618, + /* 50 */ 657, 727, 766, 836, 995, 1015, 1015, 1015, 1015, 1015, + /* 60 */ 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, + /* 70 */ 1015, 1015, 1015, 1035, 1015, 1138, 880, 880, 1577, 1684, + /* 80 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, + /* 90 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, + /* 100 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, + /* 110 */ 1684, 1684, 1684, 1705, 1684, 1684, 1684, 1684, 1684, 1684, + /* 120 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 146, 84, 84, + /* 130 */ 84, 84, 84, 362, 269, 125, 97, 453, 66, 66, + /* 140 */ 893, 1090, 66, 66, 533, 533, 66, 554, 554, 554, + /* 150 */ 554, 192, 587, 587, 695, 25, 2020, 2020, 290, 290, + /* 160 */ 290, 200, 514, 514, 514, 514, 939, 939, 442, 875, + /* 170 */ 935, 66, 66, 66, 66, 66, 66, 66, 66, 66, + /* 180 */ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + /* 190 */ 66, 601, 601, 66, 729, 878, 878, 1266, 1266, 552, + /* 200 */ 1023, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 307, 490, + /* 210 */ 490, 567, 393, 517, 467, 672, 242, 682, 675, 66, + /* 220 */ 66, 66, 66, 66, 66, 66, 66, 66, 66, 616, + /* 230 */ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + /* 240 */ 66, 66, 1093, 1093, 1093, 66, 66, 66, 778, 66, + /* 250 */ 66, 66, 1053, 1064, 66, 66, 1190, 66, 66, 66, + /* 260 */ 66, 66, 66, 66, 66, 722, 992, 718, 253, 253, + /* 270 */ 253, 253, 338, 718, 718, 888, 403, 852, 1328, 254, + /* 280 */ 1295, 721, 1330, 1295, 1330, 1370, 234, 254, 254, 234, + /* 290 */ 254, 721, 1370, 1357, 1492, 1348, 385, 385, 385, 1330, + /* 300 */ 1425, 1425, 643, 1315, 1336, 1004, 1651, 1651, 1581, 1581, + /* 310 */ 1674, 1674, 1581, 1576, 1579, 1716, 1696, 1724, 1724, 1724, + /* 320 */ 1724, 1581, 1732, 1606, 1579, 1579, 1606, 1716, 1696, 1606, + /* 330 */ 1696, 1606, 1581, 1732, 1608, 1706, 1581, 1732, 1750, 1581, + /* 340 */ 1732, 1581, 1732, 1750, 1660, 1660, 1660, 1711, 1766, 1766, + /* 350 */ 1750, 1660, 1664, 1660, 1711, 1660, 1660, 1628, 1769, 1683, + /* 360 */ 1683, 1750, 1653, 1709, 1653, 1709, 1653, 1709, 1653, 1709, + /* 370 */ 1581, 1735, 1735, 1746, 1746, 1682, 1686, 1809, 1581, 1685, + /* 380 */ 1682, 1697, 1699, 1606, 1821, 1825, 1840, 1840, 1864, 1864, + /* 390 */ 1864, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, + /* 400 */ 2020, 2020, 2020, 2020, 2020, 2020, 599, 223, 1193, 1299, + /* 410 */ 228, 780, 958, 1505, 1153, 1435, 1368, 1426, 1430, 1552, + /* 420 */ 1477, 1556, 1557, 1564, 1572, 1578, 1580, 1489, 1474, 1602, + /* 430 */ 1389, 1514, 1500, 1595, 1596, 1484, 1603, 1075, 1460, 1605, + /* 440 */ 1612, 1526, 1507, 1882, 1884, 1866, 1727, 1875, 1876, 1868, + /* 450 */ 1870, 1757, 1747, 1767, 1872, 1872, 1877, 1758, 1880, 1759, + /* 460 */ 1887, 1903, 1764, 1777, 1872, 1778, 1847, 1873, 1872, 1761, + /* 470 */ 1856, 1862, 1863, 1865, 1788, 1804, 1886, 1781, 1921, 1918, + /* 480 */ 1902, 1811, 1768, 1858, 1901, 1861, 1855, 1890, 1792, 1819, + /* 490 */ 1910, 1915, 1917, 1807, 1814, 1919, 1878, 1920, 1922, 1916, + /* 500 */ 1924, 1881, 1888, 1925, 1844, 1923, 1928, 1885, 1906, 1930, + /* 510 */ 1806, 1933, 1934, 1935, 1936, 1937, 1938, 1940, 1859, 1820, + /* 520 */ 1941, 1942, 1851, 1939, 1945, 1826, 1943, 1944, 1946, 1947, + /* 530 */ 1948, 1883, 1895, 1889, 1932, 1897, 1891, 1949, 1951, 1955, + /* 540 */ 1961, 1953, 1960, 1954, 1964, 1943, 1966, 1967, 1968, 1969, + /* 550 */ 1970, 1971, 1973, 1982, 1975, 1976, 1977, 1978, 1980, 1981, + /* 560 */ 1979, 1874, 1867, 1869, 1871, 1879, 1983, 1984, 2003, 2009, }; -#define YY_REDUCE_COUNT (391) -#define YY_REDUCE_MIN (-262) -#define YY_REDUCE_MAX (1625) +#define YY_REDUCE_COUNT (405) +#define YY_REDUCE_MIN (-265) +#define YY_REDUCE_MAX (1690) 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 */ 111, 168, 386, 761, -176, -174, -191, -189, -181, -178, + /* 10 */ 176, 263, 44, -207, -204, -265, -139, -114, 158, 504, + /* 20 */ 525, 544, 612, 614, 650, 652, 765, 265, 703, 705, + /* 30 */ 70, 714, -187, 127, 774, 713, 767, 769, 970, 1019, + /* 40 */ 1021, -255, -255, -255, -255, -255, -255, -255, -255, -255, + /* 50 */ -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, + /* 60 */ -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, + /* 70 */ -255, -255, -255, -255, -255, -255, -255, -255, 394, 542, + /* 80 */ 816, 818, 842, 882, 902, 919, 938, 940, 957, 986, + /* 90 */ 1048, 1063, 1068, 1073, 1076, 1088, 1100, 1102, 1104, 1106, + /* 100 */ 1113, 1119, 1137, 1140, 1143, 1147, 1149, 1164, 1173, 1183, + /* 110 */ 1185, 1188, 1202, 1204, 1247, 1259, 1263, 1283, 1289, 1292, + /* 120 */ 1298, 1300, 1329, 1331, 1343, 1358, 1360, -255, -255, -255, + /* 130 */ -255, -255, -255, -255, -255, 196, -255, 387, -177, 507, + /* 140 */ 1002, -219, 557, -93, -167, 638, -121, 284, 500, 284, + /* 150 */ 500, 247, 651, 865, -255, -255, -255, -255, -85, -85, + /* 160 */ -85, 237, 171, 602, 846, 885, -212, -203, 217, 380, + /* 170 */ 380, -23, 161, 653, 712, 773, 943, 990, 1040, 563, + /* 180 */ 833, 971, 1005, 1042, 1092, 1078, 1043, 1144, 1184, -186, + /* 190 */ 1105, 318, 869, 7, 825, 920, 1074, 704, 706, 390, + /* 200 */ 1087, 1094, 336, 545, 772, 1201, 1117, 1207, -179, -137, + /* 210 */ -112, -13, 18, 112, 197, 418, 495, 508, 777, 809, + /* 220 */ 923, 1014, 1027, 1033, 1044, 1115, 1194, 1212, 1221, 209, + /* 230 */ 1236, 1240, 1256, 1287, 1301, 1307, 1349, 1359, 1398, 1417, + /* 240 */ 1429, 1434, 681, 1377, 1404, 1448, 1449, 1450, 1388, 1453, + /* 250 */ 1455, 1458, 1393, 1335, 1461, 1462, 1418, 1463, 197, 1464, + /* 260 */ 1465, 1466, 1467, 1468, 1469, 1376, 1378, 1424, 1412, 1413, + /* 270 */ 1414, 1415, 1388, 1424, 1424, 1428, 1470, 1485, 1381, 1408, + /* 280 */ 1416, 1436, 1431, 1422, 1432, 1392, 1446, 1411, 1427, 1456, + /* 290 */ 1433, 1471, 1401, 1479, 1472, 1478, 1486, 1491, 1493, 1452, + /* 300 */ 1459, 1473, 1437, 1475, 1476, 1516, 1421, 1440, 1520, 1524, + /* 310 */ 1444, 1445, 1525, 1457, 1480, 1481, 1509, 1510, 1511, 1512, + /* 320 */ 1513, 1553, 1555, 1515, 1487, 1488, 1518, 1495, 1522, 1523, + /* 330 */ 1528, 1527, 1562, 1566, 1482, 1494, 1569, 1574, 1559, 1575, + /* 340 */ 1582, 1583, 1585, 1560, 1568, 1570, 1571, 1563, 1573, 1586, + /* 350 */ 1584, 1588, 1589, 1593, 1590, 1594, 1598, 1501, 1496, 1536, + /* 360 */ 1537, 1599, 1561, 1567, 1587, 1591, 1592, 1597, 1604, 1607, + /* 370 */ 1629, 1519, 1521, 1601, 1609, 1600, 1610, 1558, 1636, 1565, + /* 380 */ 1618, 1621, 1611, 1624, 1648, 1652, 1676, 1677, 1687, 1688, + /* 390 */ 1689, 1613, 1614, 1615, 1668, 1663, 1665, 1666, 1670, 1678, + /* 400 */ 1655, 1662, 1672, 1673, 1675, 1690, }; 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 */ 1623, 1623, 1623, 1453, 1223, 1332, 1223, 1223, 1223, 1453, + /* 10 */ 1453, 1453, 1223, 1362, 1362, 1506, 1254, 1223, 1223, 1223, + /* 20 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1452, 1223, 1223, + /* 30 */ 1223, 1223, 1541, 1541, 1223, 1223, 1223, 1223, 1223, 1223, + /* 40 */ 1223, 1223, 1371, 1223, 1378, 1223, 1223, 1223, 1223, 1223, + /* 50 */ 1454, 1455, 1223, 1223, 1223, 1505, 1507, 1470, 1385, 1384, + /* 60 */ 1383, 1382, 1488, 1349, 1376, 1369, 1373, 1448, 1449, 1447, + /* 70 */ 1451, 1455, 1454, 1223, 1372, 1419, 1433, 1418, 1223, 1223, + /* 80 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 90 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 100 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 110 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 120 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1427, 1432, 1438, + /* 130 */ 1431, 1428, 1421, 1420, 1422, 1223, 1423, 1223, 1223, 1223, + /* 140 */ 1244, 1296, 1223, 1223, 1223, 1223, 1223, 1525, 1524, 1223, + /* 150 */ 1223, 1254, 1413, 1412, 1424, 1425, 1435, 1434, 1513, 1576, + /* 160 */ 1575, 1471, 1223, 1223, 1223, 1223, 1223, 1223, 1541, 1223, + /* 170 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 180 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 190 */ 1223, 1541, 1541, 1223, 1254, 1541, 1541, 1250, 1250, 1356, + /* 200 */ 1223, 1520, 1323, 1323, 1323, 1323, 1332, 1323, 1223, 1223, + /* 210 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 220 */ 1223, 1223, 1223, 1510, 1508, 1223, 1223, 1223, 1223, 1223, + /* 230 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 240 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 250 */ 1223, 1223, 1328, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 260 */ 1223, 1223, 1223, 1223, 1570, 1223, 1483, 1310, 1328, 1328, + /* 270 */ 1328, 1328, 1330, 1311, 1309, 1322, 1255, 1230, 1615, 1388, + /* 280 */ 1377, 1329, 1351, 1377, 1351, 1612, 1375, 1388, 1388, 1375, + /* 290 */ 1388, 1329, 1612, 1271, 1592, 1266, 1362, 1362, 1362, 1351, + /* 300 */ 1356, 1356, 1450, 1329, 1322, 1223, 1615, 1615, 1337, 1337, + /* 310 */ 1614, 1614, 1337, 1471, 1599, 1397, 1299, 1305, 1305, 1305, + /* 320 */ 1305, 1337, 1241, 1375, 1599, 1599, 1375, 1397, 1299, 1375, + /* 330 */ 1299, 1375, 1337, 1241, 1487, 1609, 1337, 1241, 1461, 1337, + /* 340 */ 1241, 1337, 1241, 1461, 1297, 1297, 1297, 1286, 1223, 1223, + /* 350 */ 1461, 1297, 1271, 1297, 1286, 1297, 1297, 1559, 1223, 1465, + /* 360 */ 1465, 1461, 1355, 1350, 1355, 1350, 1355, 1350, 1355, 1350, + /* 370 */ 1337, 1551, 1551, 1365, 1365, 1370, 1356, 1456, 1337, 1223, + /* 380 */ 1370, 1368, 1366, 1375, 1247, 1289, 1573, 1573, 1569, 1569, + /* 390 */ 1569, 1620, 1620, 1520, 1585, 1254, 1254, 1254, 1254, 1585, + /* 400 */ 1273, 1273, 1255, 1255, 1254, 1585, 1223, 1223, 1223, 1223, + /* 410 */ 1223, 1223, 1580, 1223, 1515, 1472, 1341, 1223, 1223, 1223, + /* 420 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 430 */ 1223, 1526, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 440 */ 1223, 1223, 1402, 1223, 1226, 1517, 1223, 1223, 1223, 1223, + /* 450 */ 1223, 1223, 1223, 1223, 1379, 1380, 1342, 1223, 1223, 1223, + /* 460 */ 1223, 1223, 1223, 1223, 1394, 1223, 1223, 1223, 1389, 1223, + /* 470 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1611, 1223, 1223, + /* 480 */ 1223, 1223, 1223, 1223, 1486, 1485, 1223, 1223, 1339, 1223, + /* 490 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 500 */ 1223, 1223, 1269, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 510 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 520 */ 1223, 1223, 1223, 1223, 1223, 1223, 1367, 1223, 1223, 1223, + /* 530 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 540 */ 1223, 1556, 1357, 1223, 1223, 1602, 1223, 1223, 1223, 1223, + /* 550 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 560 */ 1596, 1313, 1404, 1223, 1403, 1407, 1223, 1235, 1223, 1223, }; /********** End of lemon-generated parsing tables *****************************/ @@ -156098,6 +158286,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 */ @@ -156149,6 +158338,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 */ @@ -156367,219 +158557,225 @@ 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 */ "COLLATE", + /* 113 */ "BITNOT", + /* 114 */ "ON", + /* 115 */ "INDEXED", + /* 116 */ "STRING", + /* 117 */ "JOIN_KW", + /* 118 */ "CONSTRAINT", + /* 119 */ "DEFAULT", + /* 120 */ "NULL", + /* 121 */ "PRIMARY", + /* 122 */ "UNIQUE", + /* 123 */ "CHECK", + /* 124 */ "REFERENCES", + /* 125 */ "AUTOINCR", + /* 126 */ "INSERT", + /* 127 */ "DELETE", + /* 128 */ "UPDATE", + /* 129 */ "SET", + /* 130 */ "DEFERRABLE", + /* 131 */ "FOREIGN", + /* 132 */ "DROP", + /* 133 */ "UNION", + /* 134 */ "ALL", + /* 135 */ "EXCEPT", + /* 136 */ "INTERSECT", + /* 137 */ "SELECT", + /* 138 */ "VALUES", + /* 139 */ "DISTINCT", + /* 140 */ "DOT", + /* 141 */ "FROM", + /* 142 */ "JOIN", + /* 143 */ "USING", + /* 144 */ "ORDER", + /* 145 */ "GROUP", + /* 146 */ "HAVING", + /* 147 */ "LIMIT", + /* 148 */ "WHERE", + /* 149 */ "RETURNING", + /* 150 */ "INTO", + /* 151 */ "NOTHING", + /* 152 */ "FLOAT", + /* 153 */ "BLOB", + /* 154 */ "INTEGER", + /* 155 */ "VARIABLE", + /* 156 */ "CASE", + /* 157 */ "WHEN", + /* 158 */ "THEN", + /* 159 */ "ELSE", + /* 160 */ "INDEX", + /* 161 */ "ALTER", + /* 162 */ "ADD", + /* 163 */ "WINDOW", + /* 164 */ "OVER", + /* 165 */ "FILTER", + /* 166 */ "COLUMN", + /* 167 */ "AGG_FUNCTION", + /* 168 */ "AGG_COLUMN", + /* 169 */ "TRUEFALSE", + /* 170 */ "ISNOT", + /* 171 */ "FUNCTION", + /* 172 */ "UMINUS", + /* 173 */ "UPLUS", + /* 174 */ "TRUTH", + /* 175 */ "REGISTER", + /* 176 */ "VECTOR", + /* 177 */ "SELECT_COLUMN", + /* 178 */ "IF_NULL_ROW", + /* 179 */ "ASTERISK", + /* 180 */ "SPAN", + /* 181 */ "SPACE", + /* 182 */ "ILLEGAL", + /* 183 */ "input", + /* 184 */ "cmdlist", + /* 185 */ "ecmd", + /* 186 */ "cmdx", + /* 187 */ "explain", + /* 188 */ "cmd", + /* 189 */ "transtype", + /* 190 */ "trans_opt", + /* 191 */ "nm", + /* 192 */ "savepoint_opt", + /* 193 */ "create_table", + /* 194 */ "create_table_args", + /* 195 */ "createkw", + /* 196 */ "temp", + /* 197 */ "ifnotexists", + /* 198 */ "dbnm", + /* 199 */ "columnlist", + /* 200 */ "conslist_opt", + /* 201 */ "table_options", + /* 202 */ "select", + /* 203 */ "columnname", + /* 204 */ "carglist", + /* 205 */ "typetoken", + /* 206 */ "typename", + /* 207 */ "signed", + /* 208 */ "plus_num", + /* 209 */ "minus_num", + /* 210 */ "scanpt", + /* 211 */ "scantok", + /* 212 */ "ccons", + /* 213 */ "term", + /* 214 */ "expr", + /* 215 */ "onconf", + /* 216 */ "sortorder", + /* 217 */ "autoinc", + /* 218 */ "eidlist_opt", + /* 219 */ "refargs", + /* 220 */ "defer_subclause", + /* 221 */ "generated", + /* 222 */ "refarg", + /* 223 */ "refact", + /* 224 */ "init_deferred_pred_opt", + /* 225 */ "conslist", + /* 226 */ "tconscomma", + /* 227 */ "tcons", + /* 228 */ "sortlist", + /* 229 */ "eidlist", + /* 230 */ "defer_subclause_opt", + /* 231 */ "orconf", + /* 232 */ "resolvetype", + /* 233 */ "raisetype", + /* 234 */ "ifexists", + /* 235 */ "fullname", + /* 236 */ "selectnowith", + /* 237 */ "oneselect", + /* 238 */ "wqlist", + /* 239 */ "multiselect_op", + /* 240 */ "distinct", + /* 241 */ "selcollist", + /* 242 */ "from", + /* 243 */ "where_opt", + /* 244 */ "groupby_opt", + /* 245 */ "having_opt", + /* 246 */ "orderby_opt", + /* 247 */ "limit_opt", + /* 248 */ "window_clause", + /* 249 */ "values", + /* 250 */ "nexprlist", + /* 251 */ "sclp", + /* 252 */ "as", + /* 253 */ "seltablist", + /* 254 */ "stl_prefix", + /* 255 */ "joinop", + /* 256 */ "indexed_opt", + /* 257 */ "on_opt", + /* 258 */ "using_opt", + /* 259 */ "exprlist", + /* 260 */ "xfullname", + /* 261 */ "idlist", + /* 262 */ "nulls", + /* 263 */ "with", + /* 264 */ "where_opt_ret", + /* 265 */ "setlist", + /* 266 */ "insert_cmd", + /* 267 */ "idlist_opt", + /* 268 */ "upsert", + /* 269 */ "returning", + /* 270 */ "filter_over", + /* 271 */ "likeop", + /* 272 */ "between_op", + /* 273 */ "in_op", + /* 274 */ "paren_exprlist", + /* 275 */ "case_operand", + /* 276 */ "case_exprlist", + /* 277 */ "case_else", + /* 278 */ "uniqueflag", + /* 279 */ "collate", + /* 280 */ "vinto", + /* 281 */ "nmnum", + /* 282 */ "trigger_decl", + /* 283 */ "trigger_cmd_list", + /* 284 */ "trigger_time", + /* 285 */ "trigger_event", + /* 286 */ "foreach_clause", + /* 287 */ "when_clause", + /* 288 */ "trigger_cmd", + /* 289 */ "trnm", + /* 290 */ "tridxby", + /* 291 */ "database_kw_opt", + /* 292 */ "key_opt", + /* 293 */ "add_column_fullname", + /* 294 */ "kwcolumn_opt", + /* 295 */ "create_vtab", + /* 296 */ "vtabarglist", + /* 297 */ "vtabarg", + /* 298 */ "vtabargtoken", + /* 299 */ "lp", + /* 300 */ "anylist", + /* 301 */ "wqitem", + /* 302 */ "wqas", + /* 303 */ "windowdefn_list", + /* 304 */ "windowdefn", + /* 305 */ "window", + /* 306 */ "frame_opt", + /* 307 */ "part_opt", + /* 308 */ "filter_clause", + /* 309 */ "over_clause", + /* 310 */ "range_or_rows", + /* 311 */ "frame_bound", + /* 312 */ "frame_bound_s", + /* 313 */ "frame_bound_e", + /* 314 */ "frame_exclude_opt", + /* 315 */ "frame_exclude", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -156735,243 +158931,256 @@ static const char *const yyRuleName[] = { /* 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", + /* 148 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret", /* 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 ::=", + /* 151 */ "where_opt_ret ::=", + /* 152 */ "where_opt_ret ::= WHERE expr", + /* 153 */ "where_opt_ret ::= RETURNING selcollist", + /* 154 */ "where_opt_ret ::= WHERE expr RETURNING selcollist", + /* 155 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret", + /* 156 */ "setlist ::= setlist COMMA nm EQ expr", + /* 157 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", + /* 158 */ "setlist ::= nm EQ expr", + /* 159 */ "setlist ::= LP idlist RP EQ expr", + /* 160 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", + /* 161 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning", + /* 162 */ "upsert ::=", + /* 163 */ "upsert ::= RETURNING selcollist", + /* 164 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert", + /* 165 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert", + /* 166 */ "upsert ::= ON CONFLICT DO NOTHING returning", + /* 167 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning", + /* 168 */ "returning ::= RETURNING selcollist", + /* 169 */ "insert_cmd ::= INSERT orconf", + /* 170 */ "insert_cmd ::= REPLACE", + /* 171 */ "idlist_opt ::=", + /* 172 */ "idlist_opt ::= LP idlist RP", + /* 173 */ "idlist ::= idlist COMMA nm", + /* 174 */ "idlist ::= nm", + /* 175 */ "expr ::= LP expr RP", + /* 176 */ "expr ::= ID|INDEXED", + /* 177 */ "expr ::= JOIN_KW", + /* 178 */ "expr ::= nm DOT nm", + /* 179 */ "expr ::= nm DOT nm DOT nm", + /* 180 */ "term ::= NULL|FLOAT|BLOB", + /* 181 */ "term ::= STRING", + /* 182 */ "term ::= INTEGER", + /* 183 */ "expr ::= VARIABLE", + /* 184 */ "expr ::= expr COLLATE ID|STRING", + /* 185 */ "expr ::= CAST LP expr AS typetoken RP", + /* 186 */ "expr ::= ID|INDEXED LP distinct exprlist RP", + /* 187 */ "expr ::= ID|INDEXED LP STAR RP", + /* 188 */ "expr ::= ID|INDEXED LP distinct exprlist RP filter_over", + /* 189 */ "expr ::= ID|INDEXED LP STAR RP filter_over", + /* 190 */ "term ::= CTIME_KW", + /* 191 */ "expr ::= LP nexprlist COMMA expr RP", + /* 192 */ "expr ::= expr AND expr", + /* 193 */ "expr ::= expr OR expr", + /* 194 */ "expr ::= expr LT|GT|GE|LE expr", + /* 195 */ "expr ::= expr EQ|NE expr", + /* 196 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 197 */ "expr ::= expr PLUS|MINUS expr", + /* 198 */ "expr ::= expr STAR|SLASH|REM expr", + /* 199 */ "expr ::= expr CONCAT expr", + /* 200 */ "likeop ::= NOT LIKE_KW|MATCH", + /* 201 */ "expr ::= expr likeop expr", + /* 202 */ "expr ::= expr likeop expr ESCAPE expr", + /* 203 */ "expr ::= expr ISNULL|NOTNULL", + /* 204 */ "expr ::= expr NOT NULL", + /* 205 */ "expr ::= expr IS expr", + /* 206 */ "expr ::= expr IS NOT expr", + /* 207 */ "expr ::= NOT expr", + /* 208 */ "expr ::= BITNOT expr", + /* 209 */ "expr ::= PLUS|MINUS expr", + /* 210 */ "between_op ::= BETWEEN", + /* 211 */ "between_op ::= NOT BETWEEN", + /* 212 */ "expr ::= expr between_op expr AND expr", + /* 213 */ "in_op ::= IN", + /* 214 */ "in_op ::= NOT IN", + /* 215 */ "expr ::= expr in_op LP exprlist RP", + /* 216 */ "expr ::= LP select RP", + /* 217 */ "expr ::= expr in_op LP select RP", + /* 218 */ "expr ::= expr in_op nm dbnm paren_exprlist", + /* 219 */ "expr ::= EXISTS LP select RP", + /* 220 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 221 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 222 */ "case_exprlist ::= WHEN expr THEN expr", + /* 223 */ "case_else ::= ELSE expr", + /* 224 */ "case_else ::=", + /* 225 */ "case_operand ::= expr", + /* 226 */ "case_operand ::=", + /* 227 */ "exprlist ::=", + /* 228 */ "nexprlist ::= nexprlist COMMA expr", + /* 229 */ "nexprlist ::= expr", + /* 230 */ "paren_exprlist ::=", + /* 231 */ "paren_exprlist ::= LP exprlist RP", + /* 232 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", + /* 233 */ "uniqueflag ::= UNIQUE", + /* 234 */ "uniqueflag ::=", + /* 235 */ "eidlist_opt ::=", + /* 236 */ "eidlist_opt ::= LP eidlist RP", + /* 237 */ "eidlist ::= eidlist COMMA nm collate sortorder", + /* 238 */ "eidlist ::= nm collate sortorder", + /* 239 */ "collate ::=", + /* 240 */ "collate ::= COLLATE ID|STRING", + /* 241 */ "cmd ::= DROP INDEX ifexists fullname", + /* 242 */ "cmd ::= VACUUM vinto", + /* 243 */ "cmd ::= VACUUM nm vinto", + /* 244 */ "vinto ::= INTO expr", + /* 245 */ "vinto ::=", + /* 246 */ "cmd ::= PRAGMA nm dbnm", + /* 247 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 248 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 249 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 250 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 251 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 252 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 253 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 254 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 255 */ "trigger_time ::= BEFORE|AFTER", + /* 256 */ "trigger_time ::= INSTEAD OF", + /* 257 */ "trigger_time ::=", + /* 258 */ "trigger_event ::= DELETE|INSERT", + /* 259 */ "trigger_event ::= UPDATE", + /* 260 */ "trigger_event ::= UPDATE OF idlist", + /* 261 */ "when_clause ::=", + /* 262 */ "when_clause ::= WHEN expr", + /* 263 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 264 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 265 */ "trnm ::= nm DOT nm", + /* 266 */ "tridxby ::= INDEXED BY nm", + /* 267 */ "tridxby ::= NOT INDEXED", + /* 268 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", + /* 269 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", + /* 270 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", + /* 271 */ "trigger_cmd ::= scanpt select scanpt", + /* 272 */ "expr ::= RAISE LP IGNORE RP", + /* 273 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 274 */ "raisetype ::= ROLLBACK", + /* 275 */ "raisetype ::= ABORT", + /* 276 */ "raisetype ::= FAIL", + /* 277 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 278 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 279 */ "cmd ::= DETACH database_kw_opt expr", + /* 280 */ "key_opt ::=", + /* 281 */ "key_opt ::= KEY expr", + /* 282 */ "cmd ::= REINDEX", + /* 283 */ "cmd ::= REINDEX nm dbnm", + /* 284 */ "cmd ::= ANALYZE", + /* 285 */ "cmd ::= ANALYZE nm dbnm", + /* 286 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 287 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 288 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", + /* 289 */ "add_column_fullname ::= fullname", + /* 290 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 291 */ "cmd ::= create_vtab", + /* 292 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 293 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 294 */ "vtabarg ::=", + /* 295 */ "vtabargtoken ::= ANY", + /* 296 */ "vtabargtoken ::= lp anylist RP", + /* 297 */ "lp ::= LP", + /* 298 */ "with ::= WITH wqlist", + /* 299 */ "with ::= WITH RECURSIVE wqlist", + /* 300 */ "wqas ::= AS", + /* 301 */ "wqas ::= AS MATERIALIZED", + /* 302 */ "wqas ::= AS NOT MATERIALIZED", + /* 303 */ "wqitem ::= nm eidlist_opt wqas LP select RP", + /* 304 */ "wqlist ::= wqitem", + /* 305 */ "wqlist ::= wqlist COMMA wqitem", + /* 306 */ "windowdefn_list ::= windowdefn", + /* 307 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 308 */ "windowdefn ::= nm AS LP window RP", + /* 309 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", + /* 310 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", + /* 311 */ "window ::= ORDER BY sortlist frame_opt", + /* 312 */ "window ::= nm ORDER BY sortlist frame_opt", + /* 313 */ "window ::= frame_opt", + /* 314 */ "window ::= nm frame_opt", + /* 315 */ "frame_opt ::=", + /* 316 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", + /* 317 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", + /* 318 */ "range_or_rows ::= RANGE|ROWS|GROUPS", + /* 319 */ "frame_bound_s ::= frame_bound", + /* 320 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 321 */ "frame_bound_e ::= frame_bound", + /* 322 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 323 */ "frame_bound ::= expr PRECEDING|FOLLOWING", + /* 324 */ "frame_bound ::= CURRENT ROW", + /* 325 */ "frame_exclude_opt ::=", + /* 326 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", + /* 327 */ "frame_exclude ::= NO OTHERS", + /* 328 */ "frame_exclude ::= CURRENT ROW", + /* 329 */ "frame_exclude ::= GROUP|TIES", + /* 330 */ "window_clause ::= WINDOW windowdefn_list", + /* 331 */ "filter_over ::= filter_clause over_clause", + /* 332 */ "filter_over ::= over_clause", + /* 333 */ "filter_over ::= filter_clause", + /* 334 */ "over_clause ::= OVER LP window RP", + /* 335 */ "over_clause ::= OVER nm", + /* 336 */ "filter_clause ::= FILTER LP WHERE expr RP", + /* 337 */ "input ::= cmdlist", + /* 338 */ "cmdlist ::= cmdlist ecmd", + /* 339 */ "cmdlist ::= ecmd", + /* 340 */ "ecmd ::= SEMI", + /* 341 */ "ecmd ::= cmdx SEMI", + /* 342 */ "ecmd ::= explain cmdx SEMI", + /* 343 */ "trans_opt ::=", + /* 344 */ "trans_opt ::= TRANSACTION", + /* 345 */ "trans_opt ::= TRANSACTION nm", + /* 346 */ "savepoint_opt ::= SAVEPOINT", + /* 347 */ "savepoint_opt ::=", + /* 348 */ "cmd ::= create_table create_table_args", + /* 349 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 350 */ "columnlist ::= columnname carglist", + /* 351 */ "nm ::= ID|INDEXED", + /* 352 */ "nm ::= STRING", + /* 353 */ "nm ::= JOIN_KW", + /* 354 */ "typetoken ::= typename", + /* 355 */ "typename ::= ID|STRING", + /* 356 */ "signed ::= plus_num", + /* 357 */ "signed ::= minus_num", + /* 358 */ "carglist ::= carglist ccons", + /* 359 */ "carglist ::=", + /* 360 */ "ccons ::= NULL onconf", + /* 361 */ "ccons ::= GENERATED ALWAYS AS generated", + /* 362 */ "ccons ::= AS generated", + /* 363 */ "conslist_opt ::= COMMA conslist", + /* 364 */ "conslist ::= conslist tconscomma tcons", + /* 365 */ "conslist ::= tcons", + /* 366 */ "tconscomma ::=", + /* 367 */ "defer_subclause_opt ::= defer_subclause", + /* 368 */ "resolvetype ::= raisetype", + /* 369 */ "selectnowith ::= oneselect", + /* 370 */ "oneselect ::= values", + /* 371 */ "sclp ::= selcollist COMMA", + /* 372 */ "as ::= ID|STRING", + /* 373 */ "returning ::=", + /* 374 */ "expr ::= term", + /* 375 */ "likeop ::= LIKE_KW|MATCH", + /* 376 */ "exprlist ::= nexprlist", + /* 377 */ "nmnum ::= plus_num", + /* 378 */ "nmnum ::= nm", + /* 379 */ "nmnum ::= ON", + /* 380 */ "nmnum ::= DELETE", + /* 381 */ "nmnum ::= DEFAULT", + /* 382 */ "plus_num ::= INTEGER|FLOAT", + /* 383 */ "foreach_clause ::=", + /* 384 */ "foreach_clause ::= FOR EACH ROW", + /* 385 */ "trnm ::= nm", + /* 386 */ "tridxby ::=", + /* 387 */ "database_kw_opt ::= DATABASE", + /* 388 */ "database_kw_opt ::=", + /* 389 */ "kwcolumn_opt ::=", + /* 390 */ "kwcolumn_opt ::= COLUMNKW", + /* 391 */ "vtabarglist ::= vtabarg", + /* 392 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 393 */ "vtabarg ::= vtabarg vtabargtoken", + /* 394 */ "anylist ::=", + /* 395 */ "anylist ::= anylist LP anylist RP", + /* 396 */ "anylist ::= anylist ANY", + /* 397 */ "with ::=", }; #endif /* NDEBUG */ @@ -157097,98 +159306,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 202: /* select */ + case 236: /* selectnowith */ + case 237: /* oneselect */ + case 249: /* 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->yy307)); +} + break; + case 213: /* term */ + case 214: /* expr */ + case 243: /* where_opt */ + case 245: /* having_opt */ + case 257: /* on_opt */ + case 264: /* where_opt_ret */ + case 275: /* case_operand */ + case 277: /* case_else */ + case 280: /* vinto */ + case 287: /* when_clause */ + case 292: /* key_opt */ + case 308: /* 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->yy602)); +} + break; + case 218: /* eidlist_opt */ + case 228: /* sortlist */ + case 229: /* eidlist */ + case 241: /* selcollist */ + case 244: /* groupby_opt */ + case 246: /* orderby_opt */ + case 250: /* nexprlist */ + case 251: /* sclp */ + case 259: /* exprlist */ + case 265: /* setlist */ + case 274: /* paren_exprlist */ + case 276: /* case_exprlist */ + case 307: /* part_opt */ { -sqlite3ExprListDelete(pParse->db, (yypminor->yy242)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy338)); } break; - case 233: /* fullname */ - case 240: /* from */ - case 251: /* seltablist */ - case 252: /* stl_prefix */ - case 258: /* xfullname */ + case 235: /* fullname */ + case 242: /* from */ + case 253: /* seltablist */ + case 254: /* stl_prefix */ + case 260: /* xfullname */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy47)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy291)); } break; - case 236: /* wqlist */ + case 238: /* wqlist */ { -sqlite3WithDelete(pParse->db, (yypminor->yy131)); +sqlite3WithDelete(pParse->db, (yypminor->yy195)); } break; - case 246: /* window_clause */ - case 297: /* windowdefn_list */ + case 248: /* window_clause */ + case 303: /* windowdefn_list */ { -sqlite3WindowListDelete(pParse->db, (yypminor->yy303)); +sqlite3WindowListDelete(pParse->db, (yypminor->yy19)); } break; - case 256: /* using_opt */ - case 259: /* idlist */ - case 264: /* idlist_opt */ + case 258: /* using_opt */ + case 261: /* idlist */ + case 267: /* idlist_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy600)); +sqlite3IdListDelete(pParse->db, (yypminor->yy288)); } break; - case 266: /* filter_over */ - case 298: /* windowdefn */ - case 299: /* window */ - case 300: /* frame_opt */ - case 303: /* over_clause */ + case 270: /* filter_over */ + case 304: /* windowdefn */ + case 305: /* window */ + case 306: /* frame_opt */ + case 309: /* over_clause */ { -sqlite3WindowDelete(pParse->db, (yypminor->yy303)); +sqlite3WindowDelete(pParse->db, (yypminor->yy19)); } break; - case 279: /* trigger_cmd_list */ - case 284: /* trigger_cmd */ + case 283: /* trigger_cmd_list */ + case 288: /* trigger_cmd */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy447)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy483)); } break; - case 281: /* trigger_event */ + case 285: /* trigger_event */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy230).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy50).b); } break; - case 305: /* frame_bound */ - case 306: /* frame_bound_s */ - case 307: /* frame_bound_e */ + case 311: /* frame_bound */ + case 312: /* frame_bound_s */ + case 313: /* frame_bound_e */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy77).pExpr); +sqlite3ExprDelete(pParse->db, (yypminor->yy113).pExpr); } break; /********* End destructor definitions *****************************************/ @@ -157479,391 +159689,404 @@ 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 ::= */ + 187, /* (0) explain ::= EXPLAIN */ + 187, /* (1) explain ::= EXPLAIN QUERY PLAN */ + 186, /* (2) cmdx ::= cmd */ + 188, /* (3) cmd ::= BEGIN transtype trans_opt */ + 189, /* (4) transtype ::= */ + 189, /* (5) transtype ::= DEFERRED */ + 189, /* (6) transtype ::= IMMEDIATE */ + 189, /* (7) transtype ::= EXCLUSIVE */ + 188, /* (8) cmd ::= COMMIT|END trans_opt */ + 188, /* (9) cmd ::= ROLLBACK trans_opt */ + 188, /* (10) cmd ::= SAVEPOINT nm */ + 188, /* (11) cmd ::= RELEASE savepoint_opt nm */ + 188, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + 193, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + 195, /* (14) createkw ::= CREATE */ + 197, /* (15) ifnotexists ::= */ + 197, /* (16) ifnotexists ::= IF NOT EXISTS */ + 196, /* (17) temp ::= TEMP */ + 196, /* (18) temp ::= */ + 194, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */ + 194, /* (20) create_table_args ::= AS select */ + 201, /* (21) table_options ::= */ + 201, /* (22) table_options ::= WITHOUT nm */ + 203, /* (23) columnname ::= nm typetoken */ + 205, /* (24) typetoken ::= */ + 205, /* (25) typetoken ::= typename LP signed RP */ + 205, /* (26) typetoken ::= typename LP signed COMMA signed RP */ + 206, /* (27) typename ::= typename ID|STRING */ + 210, /* (28) scanpt ::= */ + 211, /* (29) scantok ::= */ + 212, /* (30) ccons ::= CONSTRAINT nm */ + 212, /* (31) ccons ::= DEFAULT scantok term */ + 212, /* (32) ccons ::= DEFAULT LP expr RP */ + 212, /* (33) ccons ::= DEFAULT PLUS scantok term */ + 212, /* (34) ccons ::= DEFAULT MINUS scantok term */ + 212, /* (35) ccons ::= DEFAULT scantok ID|INDEXED */ + 212, /* (36) ccons ::= NOT NULL onconf */ + 212, /* (37) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + 212, /* (38) ccons ::= UNIQUE onconf */ + 212, /* (39) ccons ::= CHECK LP expr RP */ + 212, /* (40) ccons ::= REFERENCES nm eidlist_opt refargs */ + 212, /* (41) ccons ::= defer_subclause */ + 212, /* (42) ccons ::= COLLATE ID|STRING */ + 221, /* (43) generated ::= LP expr RP */ + 221, /* (44) generated ::= LP expr RP ID */ + 217, /* (45) autoinc ::= */ + 217, /* (46) autoinc ::= AUTOINCR */ + 219, /* (47) refargs ::= */ + 219, /* (48) refargs ::= refargs refarg */ + 222, /* (49) refarg ::= MATCH nm */ + 222, /* (50) refarg ::= ON INSERT refact */ + 222, /* (51) refarg ::= ON DELETE refact */ + 222, /* (52) refarg ::= ON UPDATE refact */ + 223, /* (53) refact ::= SET NULL */ + 223, /* (54) refact ::= SET DEFAULT */ + 223, /* (55) refact ::= CASCADE */ + 223, /* (56) refact ::= RESTRICT */ + 223, /* (57) refact ::= NO ACTION */ + 220, /* (58) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + 220, /* (59) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 224, /* (60) init_deferred_pred_opt ::= */ + 224, /* (61) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + 224, /* (62) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 200, /* (63) conslist_opt ::= */ + 226, /* (64) tconscomma ::= COMMA */ + 227, /* (65) tcons ::= CONSTRAINT nm */ + 227, /* (66) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + 227, /* (67) tcons ::= UNIQUE LP sortlist RP onconf */ + 227, /* (68) tcons ::= CHECK LP expr RP onconf */ + 227, /* (69) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 230, /* (70) defer_subclause_opt ::= */ + 215, /* (71) onconf ::= */ + 215, /* (72) onconf ::= ON CONFLICT resolvetype */ + 231, /* (73) orconf ::= */ + 231, /* (74) orconf ::= OR resolvetype */ + 232, /* (75) resolvetype ::= IGNORE */ + 232, /* (76) resolvetype ::= REPLACE */ + 188, /* (77) cmd ::= DROP TABLE ifexists fullname */ + 234, /* (78) ifexists ::= IF EXISTS */ + 234, /* (79) ifexists ::= */ + 188, /* (80) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + 188, /* (81) cmd ::= DROP VIEW ifexists fullname */ + 188, /* (82) cmd ::= select */ + 202, /* (83) select ::= WITH wqlist selectnowith */ + 202, /* (84) select ::= WITH RECURSIVE wqlist selectnowith */ + 202, /* (85) select ::= selectnowith */ + 236, /* (86) selectnowith ::= selectnowith multiselect_op oneselect */ + 239, /* (87) multiselect_op ::= UNION */ + 239, /* (88) multiselect_op ::= UNION ALL */ + 239, /* (89) multiselect_op ::= EXCEPT|INTERSECT */ + 237, /* (90) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + 237, /* (91) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + 249, /* (92) values ::= VALUES LP nexprlist RP */ + 249, /* (93) values ::= values COMMA LP nexprlist RP */ + 240, /* (94) distinct ::= DISTINCT */ + 240, /* (95) distinct ::= ALL */ + 240, /* (96) distinct ::= */ + 251, /* (97) sclp ::= */ + 241, /* (98) selcollist ::= sclp scanpt expr scanpt as */ + 241, /* (99) selcollist ::= sclp scanpt STAR */ + 241, /* (100) selcollist ::= sclp scanpt nm DOT STAR */ + 252, /* (101) as ::= AS nm */ + 252, /* (102) as ::= */ + 242, /* (103) from ::= */ + 242, /* (104) from ::= FROM seltablist */ + 254, /* (105) stl_prefix ::= seltablist joinop */ + 254, /* (106) stl_prefix ::= */ + 253, /* (107) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ + 253, /* (108) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ + 253, /* (109) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ + 253, /* (110) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ + 198, /* (111) dbnm ::= */ + 198, /* (112) dbnm ::= DOT nm */ + 235, /* (113) fullname ::= nm */ + 235, /* (114) fullname ::= nm DOT nm */ + 260, /* (115) xfullname ::= nm */ + 260, /* (116) xfullname ::= nm DOT nm */ + 260, /* (117) xfullname ::= nm DOT nm AS nm */ + 260, /* (118) xfullname ::= nm AS nm */ + 255, /* (119) joinop ::= COMMA|JOIN */ + 255, /* (120) joinop ::= JOIN_KW JOIN */ + 255, /* (121) joinop ::= JOIN_KW nm JOIN */ + 255, /* (122) joinop ::= JOIN_KW nm nm JOIN */ + 257, /* (123) on_opt ::= ON expr */ + 257, /* (124) on_opt ::= */ + 256, /* (125) indexed_opt ::= */ + 256, /* (126) indexed_opt ::= INDEXED BY nm */ + 256, /* (127) indexed_opt ::= NOT INDEXED */ + 258, /* (128) using_opt ::= USING LP idlist RP */ + 258, /* (129) using_opt ::= */ + 246, /* (130) orderby_opt ::= */ + 246, /* (131) orderby_opt ::= ORDER BY sortlist */ + 228, /* (132) sortlist ::= sortlist COMMA expr sortorder nulls */ + 228, /* (133) sortlist ::= expr sortorder nulls */ + 216, /* (134) sortorder ::= ASC */ + 216, /* (135) sortorder ::= DESC */ + 216, /* (136) sortorder ::= */ + 262, /* (137) nulls ::= NULLS FIRST */ + 262, /* (138) nulls ::= NULLS LAST */ + 262, /* (139) nulls ::= */ + 244, /* (140) groupby_opt ::= */ + 244, /* (141) groupby_opt ::= GROUP BY nexprlist */ + 245, /* (142) having_opt ::= */ + 245, /* (143) having_opt ::= HAVING expr */ + 247, /* (144) limit_opt ::= */ + 247, /* (145) limit_opt ::= LIMIT expr */ + 247, /* (146) limit_opt ::= LIMIT expr OFFSET expr */ + 247, /* (147) limit_opt ::= LIMIT expr COMMA expr */ + 188, /* (148) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + 243, /* (149) where_opt ::= */ + 243, /* (150) where_opt ::= WHERE expr */ + 264, /* (151) where_opt_ret ::= */ + 264, /* (152) where_opt_ret ::= WHERE expr */ + 264, /* (153) where_opt_ret ::= RETURNING selcollist */ + 264, /* (154) where_opt_ret ::= WHERE expr RETURNING selcollist */ + 188, /* (155) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + 265, /* (156) setlist ::= setlist COMMA nm EQ expr */ + 265, /* (157) setlist ::= setlist COMMA LP idlist RP EQ expr */ + 265, /* (158) setlist ::= nm EQ expr */ + 265, /* (159) setlist ::= LP idlist RP EQ expr */ + 188, /* (160) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + 188, /* (161) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 268, /* (162) upsert ::= */ + 268, /* (163) upsert ::= RETURNING selcollist */ + 268, /* (164) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + 268, /* (165) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + 268, /* (166) upsert ::= ON CONFLICT DO NOTHING returning */ + 268, /* (167) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + 269, /* (168) returning ::= RETURNING selcollist */ + 266, /* (169) insert_cmd ::= INSERT orconf */ + 266, /* (170) insert_cmd ::= REPLACE */ + 267, /* (171) idlist_opt ::= */ + 267, /* (172) idlist_opt ::= LP idlist RP */ + 261, /* (173) idlist ::= idlist COMMA nm */ + 261, /* (174) idlist ::= nm */ + 214, /* (175) expr ::= LP expr RP */ + 214, /* (176) expr ::= ID|INDEXED */ + 214, /* (177) expr ::= JOIN_KW */ + 214, /* (178) expr ::= nm DOT nm */ + 214, /* (179) expr ::= nm DOT nm DOT nm */ + 213, /* (180) term ::= NULL|FLOAT|BLOB */ + 213, /* (181) term ::= STRING */ + 213, /* (182) term ::= INTEGER */ + 214, /* (183) expr ::= VARIABLE */ + 214, /* (184) expr ::= expr COLLATE ID|STRING */ + 214, /* (185) expr ::= CAST LP expr AS typetoken RP */ + 214, /* (186) expr ::= ID|INDEXED LP distinct exprlist RP */ + 214, /* (187) expr ::= ID|INDEXED LP STAR RP */ + 214, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + 214, /* (189) expr ::= ID|INDEXED LP STAR RP filter_over */ + 213, /* (190) term ::= CTIME_KW */ + 214, /* (191) expr ::= LP nexprlist COMMA expr RP */ + 214, /* (192) expr ::= expr AND expr */ + 214, /* (193) expr ::= expr OR expr */ + 214, /* (194) expr ::= expr LT|GT|GE|LE expr */ + 214, /* (195) expr ::= expr EQ|NE expr */ + 214, /* (196) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + 214, /* (197) expr ::= expr PLUS|MINUS expr */ + 214, /* (198) expr ::= expr STAR|SLASH|REM expr */ + 214, /* (199) expr ::= expr CONCAT expr */ + 271, /* (200) likeop ::= NOT LIKE_KW|MATCH */ + 214, /* (201) expr ::= expr likeop expr */ + 214, /* (202) expr ::= expr likeop expr ESCAPE expr */ + 214, /* (203) expr ::= expr ISNULL|NOTNULL */ + 214, /* (204) expr ::= expr NOT NULL */ + 214, /* (205) expr ::= expr IS expr */ + 214, /* (206) expr ::= expr IS NOT expr */ + 214, /* (207) expr ::= NOT expr */ + 214, /* (208) expr ::= BITNOT expr */ + 214, /* (209) expr ::= PLUS|MINUS expr */ + 272, /* (210) between_op ::= BETWEEN */ + 272, /* (211) between_op ::= NOT BETWEEN */ + 214, /* (212) expr ::= expr between_op expr AND expr */ + 273, /* (213) in_op ::= IN */ + 273, /* (214) in_op ::= NOT IN */ + 214, /* (215) expr ::= expr in_op LP exprlist RP */ + 214, /* (216) expr ::= LP select RP */ + 214, /* (217) expr ::= expr in_op LP select RP */ + 214, /* (218) expr ::= expr in_op nm dbnm paren_exprlist */ + 214, /* (219) expr ::= EXISTS LP select RP */ + 214, /* (220) expr ::= CASE case_operand case_exprlist case_else END */ + 276, /* (221) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + 276, /* (222) case_exprlist ::= WHEN expr THEN expr */ + 277, /* (223) case_else ::= ELSE expr */ + 277, /* (224) case_else ::= */ + 275, /* (225) case_operand ::= expr */ + 275, /* (226) case_operand ::= */ + 259, /* (227) exprlist ::= */ + 250, /* (228) nexprlist ::= nexprlist COMMA expr */ + 250, /* (229) nexprlist ::= expr */ + 274, /* (230) paren_exprlist ::= */ + 274, /* (231) paren_exprlist ::= LP exprlist RP */ + 188, /* (232) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + 278, /* (233) uniqueflag ::= UNIQUE */ + 278, /* (234) uniqueflag ::= */ + 218, /* (235) eidlist_opt ::= */ + 218, /* (236) eidlist_opt ::= LP eidlist RP */ + 229, /* (237) eidlist ::= eidlist COMMA nm collate sortorder */ + 229, /* (238) eidlist ::= nm collate sortorder */ + 279, /* (239) collate ::= */ + 279, /* (240) collate ::= COLLATE ID|STRING */ + 188, /* (241) cmd ::= DROP INDEX ifexists fullname */ + 188, /* (242) cmd ::= VACUUM vinto */ + 188, /* (243) cmd ::= VACUUM nm vinto */ + 280, /* (244) vinto ::= INTO expr */ + 280, /* (245) vinto ::= */ + 188, /* (246) cmd ::= PRAGMA nm dbnm */ + 188, /* (247) cmd ::= PRAGMA nm dbnm EQ nmnum */ + 188, /* (248) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + 188, /* (249) cmd ::= PRAGMA nm dbnm EQ minus_num */ + 188, /* (250) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + 208, /* (251) plus_num ::= PLUS INTEGER|FLOAT */ + 209, /* (252) minus_num ::= MINUS INTEGER|FLOAT */ + 188, /* (253) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + 282, /* (254) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + 284, /* (255) trigger_time ::= BEFORE|AFTER */ + 284, /* (256) trigger_time ::= INSTEAD OF */ + 284, /* (257) trigger_time ::= */ + 285, /* (258) trigger_event ::= DELETE|INSERT */ + 285, /* (259) trigger_event ::= UPDATE */ + 285, /* (260) trigger_event ::= UPDATE OF idlist */ + 287, /* (261) when_clause ::= */ + 287, /* (262) when_clause ::= WHEN expr */ + 283, /* (263) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 283, /* (264) trigger_cmd_list ::= trigger_cmd SEMI */ + 289, /* (265) trnm ::= nm DOT nm */ + 290, /* (266) tridxby ::= INDEXED BY nm */ + 290, /* (267) tridxby ::= NOT INDEXED */ + 288, /* (268) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + 288, /* (269) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + 288, /* (270) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + 288, /* (271) trigger_cmd ::= scanpt select scanpt */ + 214, /* (272) expr ::= RAISE LP IGNORE RP */ + 214, /* (273) expr ::= RAISE LP raisetype COMMA nm RP */ + 233, /* (274) raisetype ::= ROLLBACK */ + 233, /* (275) raisetype ::= ABORT */ + 233, /* (276) raisetype ::= FAIL */ + 188, /* (277) cmd ::= DROP TRIGGER ifexists fullname */ + 188, /* (278) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 188, /* (279) cmd ::= DETACH database_kw_opt expr */ + 292, /* (280) key_opt ::= */ + 292, /* (281) key_opt ::= KEY expr */ + 188, /* (282) cmd ::= REINDEX */ + 188, /* (283) cmd ::= REINDEX nm dbnm */ + 188, /* (284) cmd ::= ANALYZE */ + 188, /* (285) cmd ::= ANALYZE nm dbnm */ + 188, /* (286) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 188, /* (287) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + 188, /* (288) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + 293, /* (289) add_column_fullname ::= fullname */ + 188, /* (290) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 188, /* (291) cmd ::= create_vtab */ + 188, /* (292) cmd ::= create_vtab LP vtabarglist RP */ + 295, /* (293) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 297, /* (294) vtabarg ::= */ + 298, /* (295) vtabargtoken ::= ANY */ + 298, /* (296) vtabargtoken ::= lp anylist RP */ + 299, /* (297) lp ::= LP */ + 263, /* (298) with ::= WITH wqlist */ + 263, /* (299) with ::= WITH RECURSIVE wqlist */ + 302, /* (300) wqas ::= AS */ + 302, /* (301) wqas ::= AS MATERIALIZED */ + 302, /* (302) wqas ::= AS NOT MATERIALIZED */ + 301, /* (303) wqitem ::= nm eidlist_opt wqas LP select RP */ + 238, /* (304) wqlist ::= wqitem */ + 238, /* (305) wqlist ::= wqlist COMMA wqitem */ + 303, /* (306) windowdefn_list ::= windowdefn */ + 303, /* (307) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + 304, /* (308) windowdefn ::= nm AS LP window RP */ + 305, /* (309) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + 305, /* (310) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + 305, /* (311) window ::= ORDER BY sortlist frame_opt */ + 305, /* (312) window ::= nm ORDER BY sortlist frame_opt */ + 305, /* (313) window ::= frame_opt */ + 305, /* (314) window ::= nm frame_opt */ + 306, /* (315) frame_opt ::= */ + 306, /* (316) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + 306, /* (317) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + 310, /* (318) range_or_rows ::= RANGE|ROWS|GROUPS */ + 312, /* (319) frame_bound_s ::= frame_bound */ + 312, /* (320) frame_bound_s ::= UNBOUNDED PRECEDING */ + 313, /* (321) frame_bound_e ::= frame_bound */ + 313, /* (322) frame_bound_e ::= UNBOUNDED FOLLOWING */ + 311, /* (323) frame_bound ::= expr PRECEDING|FOLLOWING */ + 311, /* (324) frame_bound ::= CURRENT ROW */ + 314, /* (325) frame_exclude_opt ::= */ + 314, /* (326) frame_exclude_opt ::= EXCLUDE frame_exclude */ + 315, /* (327) frame_exclude ::= NO OTHERS */ + 315, /* (328) frame_exclude ::= CURRENT ROW */ + 315, /* (329) frame_exclude ::= GROUP|TIES */ + 248, /* (330) window_clause ::= WINDOW windowdefn_list */ + 270, /* (331) filter_over ::= filter_clause over_clause */ + 270, /* (332) filter_over ::= over_clause */ + 270, /* (333) filter_over ::= filter_clause */ + 309, /* (334) over_clause ::= OVER LP window RP */ + 309, /* (335) over_clause ::= OVER nm */ + 308, /* (336) filter_clause ::= FILTER LP WHERE expr RP */ + 183, /* (337) input ::= cmdlist */ + 184, /* (338) cmdlist ::= cmdlist ecmd */ + 184, /* (339) cmdlist ::= ecmd */ + 185, /* (340) ecmd ::= SEMI */ + 185, /* (341) ecmd ::= cmdx SEMI */ + 185, /* (342) ecmd ::= explain cmdx SEMI */ + 190, /* (343) trans_opt ::= */ + 190, /* (344) trans_opt ::= TRANSACTION */ + 190, /* (345) trans_opt ::= TRANSACTION nm */ + 192, /* (346) savepoint_opt ::= SAVEPOINT */ + 192, /* (347) savepoint_opt ::= */ + 188, /* (348) cmd ::= create_table create_table_args */ + 199, /* (349) columnlist ::= columnlist COMMA columnname carglist */ + 199, /* (350) columnlist ::= columnname carglist */ + 191, /* (351) nm ::= ID|INDEXED */ + 191, /* (352) nm ::= STRING */ + 191, /* (353) nm ::= JOIN_KW */ + 205, /* (354) typetoken ::= typename */ + 206, /* (355) typename ::= ID|STRING */ + 207, /* (356) signed ::= plus_num */ + 207, /* (357) signed ::= minus_num */ + 204, /* (358) carglist ::= carglist ccons */ + 204, /* (359) carglist ::= */ + 212, /* (360) ccons ::= NULL onconf */ + 212, /* (361) ccons ::= GENERATED ALWAYS AS generated */ + 212, /* (362) ccons ::= AS generated */ + 200, /* (363) conslist_opt ::= COMMA conslist */ + 225, /* (364) conslist ::= conslist tconscomma tcons */ + 225, /* (365) conslist ::= tcons */ + 226, /* (366) tconscomma ::= */ + 230, /* (367) defer_subclause_opt ::= defer_subclause */ + 232, /* (368) resolvetype ::= raisetype */ + 236, /* (369) selectnowith ::= oneselect */ + 237, /* (370) oneselect ::= values */ + 251, /* (371) sclp ::= selcollist COMMA */ + 252, /* (372) as ::= ID|STRING */ + 269, /* (373) returning ::= */ + 214, /* (374) expr ::= term */ + 271, /* (375) likeop ::= LIKE_KW|MATCH */ + 259, /* (376) exprlist ::= nexprlist */ + 281, /* (377) nmnum ::= plus_num */ + 281, /* (378) nmnum ::= nm */ + 281, /* (379) nmnum ::= ON */ + 281, /* (380) nmnum ::= DELETE */ + 281, /* (381) nmnum ::= DEFAULT */ + 208, /* (382) plus_num ::= INTEGER|FLOAT */ + 286, /* (383) foreach_clause ::= */ + 286, /* (384) foreach_clause ::= FOR EACH ROW */ + 289, /* (385) trnm ::= nm */ + 290, /* (386) tridxby ::= */ + 291, /* (387) database_kw_opt ::= DATABASE */ + 291, /* (388) database_kw_opt ::= */ + 294, /* (389) kwcolumn_opt ::= */ + 294, /* (390) kwcolumn_opt ::= COLUMNKW */ + 296, /* (391) vtabarglist ::= vtabarg */ + 296, /* (392) vtabarglist ::= vtabarglist COMMA vtabarg */ + 297, /* (393) vtabarg ::= vtabarg vtabargtoken */ + 300, /* (394) anylist ::= */ + 300, /* (395) anylist ::= anylist LP anylist RP */ + 300, /* (396) anylist ::= anylist ANY */ + 263, /* (397) with ::= */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -158017,243 +160240,256 @@ static const signed char yyRuleInfoNRhs[] = { -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 */ + -6, /* (148) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ 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, /* (151) where_opt_ret ::= */ + -2, /* (152) where_opt_ret ::= WHERE expr */ + -2, /* (153) where_opt_ret ::= RETURNING selcollist */ + -4, /* (154) where_opt_ret ::= WHERE expr RETURNING selcollist */ + -9, /* (155) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + -5, /* (156) setlist ::= setlist COMMA nm EQ expr */ + -7, /* (157) setlist ::= setlist COMMA LP idlist RP EQ expr */ + -3, /* (158) setlist ::= nm EQ expr */ + -5, /* (159) setlist ::= LP idlist RP EQ expr */ + -7, /* (160) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + -8, /* (161) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 0, /* (162) upsert ::= */ + -2, /* (163) upsert ::= RETURNING selcollist */ + -12, /* (164) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + -9, /* (165) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + -5, /* (166) upsert ::= ON CONFLICT DO NOTHING returning */ + -8, /* (167) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + -2, /* (168) returning ::= RETURNING selcollist */ + -2, /* (169) insert_cmd ::= INSERT orconf */ + -1, /* (170) insert_cmd ::= REPLACE */ + 0, /* (171) idlist_opt ::= */ + -3, /* (172) idlist_opt ::= LP idlist RP */ + -3, /* (173) idlist ::= idlist COMMA nm */ + -1, /* (174) idlist ::= nm */ + -3, /* (175) expr ::= LP expr RP */ + -1, /* (176) expr ::= ID|INDEXED */ + -1, /* (177) expr ::= JOIN_KW */ + -3, /* (178) expr ::= nm DOT nm */ + -5, /* (179) expr ::= nm DOT nm DOT nm */ + -1, /* (180) term ::= NULL|FLOAT|BLOB */ + -1, /* (181) term ::= STRING */ + -1, /* (182) term ::= INTEGER */ + -1, /* (183) expr ::= VARIABLE */ + -3, /* (184) expr ::= expr COLLATE ID|STRING */ + -6, /* (185) expr ::= CAST LP expr AS typetoken RP */ + -5, /* (186) expr ::= ID|INDEXED LP distinct exprlist RP */ + -4, /* (187) expr ::= ID|INDEXED LP STAR RP */ + -6, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + -5, /* (189) expr ::= ID|INDEXED LP STAR RP filter_over */ + -1, /* (190) term ::= CTIME_KW */ + -5, /* (191) expr ::= LP nexprlist COMMA expr RP */ + -3, /* (192) expr ::= expr AND expr */ + -3, /* (193) expr ::= expr OR expr */ + -3, /* (194) expr ::= expr LT|GT|GE|LE expr */ + -3, /* (195) expr ::= expr EQ|NE expr */ + -3, /* (196) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + -3, /* (197) expr ::= expr PLUS|MINUS expr */ + -3, /* (198) expr ::= expr STAR|SLASH|REM expr */ + -3, /* (199) expr ::= expr CONCAT expr */ + -2, /* (200) likeop ::= NOT LIKE_KW|MATCH */ + -3, /* (201) expr ::= expr likeop expr */ + -5, /* (202) expr ::= expr likeop expr ESCAPE expr */ + -2, /* (203) expr ::= expr ISNULL|NOTNULL */ + -3, /* (204) expr ::= expr NOT NULL */ + -3, /* (205) expr ::= expr IS expr */ + -4, /* (206) expr ::= expr IS NOT expr */ + -2, /* (207) expr ::= NOT expr */ + -2, /* (208) expr ::= BITNOT expr */ + -2, /* (209) expr ::= PLUS|MINUS expr */ + -1, /* (210) between_op ::= BETWEEN */ + -2, /* (211) between_op ::= NOT BETWEEN */ + -5, /* (212) expr ::= expr between_op expr AND expr */ + -1, /* (213) in_op ::= IN */ + -2, /* (214) in_op ::= NOT IN */ + -5, /* (215) expr ::= expr in_op LP exprlist RP */ + -3, /* (216) expr ::= LP select RP */ + -5, /* (217) expr ::= expr in_op LP select RP */ + -5, /* (218) expr ::= expr in_op nm dbnm paren_exprlist */ + -4, /* (219) expr ::= EXISTS LP select RP */ + -5, /* (220) expr ::= CASE case_operand case_exprlist case_else END */ + -5, /* (221) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + -4, /* (222) case_exprlist ::= WHEN expr THEN expr */ + -2, /* (223) case_else ::= ELSE expr */ + 0, /* (224) case_else ::= */ + -1, /* (225) case_operand ::= expr */ + 0, /* (226) case_operand ::= */ + 0, /* (227) exprlist ::= */ + -3, /* (228) nexprlist ::= nexprlist COMMA expr */ + -1, /* (229) nexprlist ::= expr */ + 0, /* (230) paren_exprlist ::= */ + -3, /* (231) paren_exprlist ::= LP exprlist RP */ + -12, /* (232) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + -1, /* (233) uniqueflag ::= UNIQUE */ + 0, /* (234) uniqueflag ::= */ + 0, /* (235) eidlist_opt ::= */ + -3, /* (236) eidlist_opt ::= LP eidlist RP */ + -5, /* (237) eidlist ::= eidlist COMMA nm collate sortorder */ + -3, /* (238) eidlist ::= nm collate sortorder */ + 0, /* (239) collate ::= */ + -2, /* (240) collate ::= COLLATE ID|STRING */ + -4, /* (241) cmd ::= DROP INDEX ifexists fullname */ + -2, /* (242) cmd ::= VACUUM vinto */ + -3, /* (243) cmd ::= VACUUM nm vinto */ + -2, /* (244) vinto ::= INTO expr */ + 0, /* (245) vinto ::= */ + -3, /* (246) cmd ::= PRAGMA nm dbnm */ + -5, /* (247) cmd ::= PRAGMA nm dbnm EQ nmnum */ + -6, /* (248) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + -5, /* (249) cmd ::= PRAGMA nm dbnm EQ minus_num */ + -6, /* (250) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + -2, /* (251) plus_num ::= PLUS INTEGER|FLOAT */ + -2, /* (252) minus_num ::= MINUS INTEGER|FLOAT */ + -5, /* (253) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + -11, /* (254) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + -1, /* (255) trigger_time ::= BEFORE|AFTER */ + -2, /* (256) trigger_time ::= INSTEAD OF */ + 0, /* (257) trigger_time ::= */ + -1, /* (258) trigger_event ::= DELETE|INSERT */ + -1, /* (259) trigger_event ::= UPDATE */ + -3, /* (260) trigger_event ::= UPDATE OF idlist */ + 0, /* (261) when_clause ::= */ + -2, /* (262) when_clause ::= WHEN expr */ + -3, /* (263) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (264) trigger_cmd_list ::= trigger_cmd SEMI */ + -3, /* (265) trnm ::= nm DOT nm */ + -3, /* (266) tridxby ::= INDEXED BY nm */ + -2, /* (267) tridxby ::= NOT INDEXED */ + -9, /* (268) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + -8, /* (269) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + -6, /* (270) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + -3, /* (271) trigger_cmd ::= scanpt select scanpt */ + -4, /* (272) expr ::= RAISE LP IGNORE RP */ + -6, /* (273) expr ::= RAISE LP raisetype COMMA nm RP */ + -1, /* (274) raisetype ::= ROLLBACK */ + -1, /* (275) raisetype ::= ABORT */ + -1, /* (276) raisetype ::= FAIL */ + -4, /* (277) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (278) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (279) cmd ::= DETACH database_kw_opt expr */ + 0, /* (280) key_opt ::= */ + -2, /* (281) key_opt ::= KEY expr */ + -1, /* (282) cmd ::= REINDEX */ + -3, /* (283) cmd ::= REINDEX nm dbnm */ + -1, /* (284) cmd ::= ANALYZE */ + -3, /* (285) cmd ::= ANALYZE nm dbnm */ + -6, /* (286) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -7, /* (287) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + -6, /* (288) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + -1, /* (289) add_column_fullname ::= fullname */ + -8, /* (290) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -1, /* (291) cmd ::= create_vtab */ + -4, /* (292) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (293) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (294) vtabarg ::= */ + -1, /* (295) vtabargtoken ::= ANY */ + -3, /* (296) vtabargtoken ::= lp anylist RP */ + -1, /* (297) lp ::= LP */ + -2, /* (298) with ::= WITH wqlist */ + -3, /* (299) with ::= WITH RECURSIVE wqlist */ + -1, /* (300) wqas ::= AS */ + -2, /* (301) wqas ::= AS MATERIALIZED */ + -3, /* (302) wqas ::= AS NOT MATERIALIZED */ + -6, /* (303) wqitem ::= nm eidlist_opt wqas LP select RP */ + -1, /* (304) wqlist ::= wqitem */ + -3, /* (305) wqlist ::= wqlist COMMA wqitem */ + -1, /* (306) windowdefn_list ::= windowdefn */ + -3, /* (307) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + -5, /* (308) windowdefn ::= nm AS LP window RP */ + -5, /* (309) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + -6, /* (310) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + -4, /* (311) window ::= ORDER BY sortlist frame_opt */ + -5, /* (312) window ::= nm ORDER BY sortlist frame_opt */ + -1, /* (313) window ::= frame_opt */ + -2, /* (314) window ::= nm frame_opt */ + 0, /* (315) frame_opt ::= */ + -3, /* (316) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + -6, /* (317) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + -1, /* (318) range_or_rows ::= RANGE|ROWS|GROUPS */ + -1, /* (319) frame_bound_s ::= frame_bound */ + -2, /* (320) frame_bound_s ::= UNBOUNDED PRECEDING */ + -1, /* (321) frame_bound_e ::= frame_bound */ + -2, /* (322) frame_bound_e ::= UNBOUNDED FOLLOWING */ + -2, /* (323) frame_bound ::= expr PRECEDING|FOLLOWING */ + -2, /* (324) frame_bound ::= CURRENT ROW */ + 0, /* (325) frame_exclude_opt ::= */ + -2, /* (326) frame_exclude_opt ::= EXCLUDE frame_exclude */ + -2, /* (327) frame_exclude ::= NO OTHERS */ + -2, /* (328) frame_exclude ::= CURRENT ROW */ + -1, /* (329) frame_exclude ::= GROUP|TIES */ + -2, /* (330) window_clause ::= WINDOW windowdefn_list */ + -2, /* (331) filter_over ::= filter_clause over_clause */ + -1, /* (332) filter_over ::= over_clause */ + -1, /* (333) filter_over ::= filter_clause */ + -4, /* (334) over_clause ::= OVER LP window RP */ + -2, /* (335) over_clause ::= OVER nm */ + -5, /* (336) filter_clause ::= FILTER LP WHERE expr RP */ + -1, /* (337) input ::= cmdlist */ + -2, /* (338) cmdlist ::= cmdlist ecmd */ + -1, /* (339) cmdlist ::= ecmd */ + -1, /* (340) ecmd ::= SEMI */ + -2, /* (341) ecmd ::= cmdx SEMI */ + -3, /* (342) ecmd ::= explain cmdx SEMI */ + 0, /* (343) trans_opt ::= */ + -1, /* (344) trans_opt ::= TRANSACTION */ + -2, /* (345) trans_opt ::= TRANSACTION nm */ + -1, /* (346) savepoint_opt ::= SAVEPOINT */ + 0, /* (347) savepoint_opt ::= */ + -2, /* (348) cmd ::= create_table create_table_args */ + -4, /* (349) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (350) columnlist ::= columnname carglist */ + -1, /* (351) nm ::= ID|INDEXED */ + -1, /* (352) nm ::= STRING */ + -1, /* (353) nm ::= JOIN_KW */ + -1, /* (354) typetoken ::= typename */ + -1, /* (355) typename ::= ID|STRING */ + -1, /* (356) signed ::= plus_num */ + -1, /* (357) signed ::= minus_num */ + -2, /* (358) carglist ::= carglist ccons */ + 0, /* (359) carglist ::= */ + -2, /* (360) ccons ::= NULL onconf */ + -4, /* (361) ccons ::= GENERATED ALWAYS AS generated */ + -2, /* (362) ccons ::= AS generated */ + -2, /* (363) conslist_opt ::= COMMA conslist */ + -3, /* (364) conslist ::= conslist tconscomma tcons */ + -1, /* (365) conslist ::= tcons */ + 0, /* (366) tconscomma ::= */ + -1, /* (367) defer_subclause_opt ::= defer_subclause */ + -1, /* (368) resolvetype ::= raisetype */ + -1, /* (369) selectnowith ::= oneselect */ + -1, /* (370) oneselect ::= values */ + -2, /* (371) sclp ::= selcollist COMMA */ + -1, /* (372) as ::= ID|STRING */ + 0, /* (373) returning ::= */ + -1, /* (374) expr ::= term */ + -1, /* (375) likeop ::= LIKE_KW|MATCH */ + -1, /* (376) exprlist ::= nexprlist */ + -1, /* (377) nmnum ::= plus_num */ + -1, /* (378) nmnum ::= nm */ + -1, /* (379) nmnum ::= ON */ + -1, /* (380) nmnum ::= DELETE */ + -1, /* (381) nmnum ::= DEFAULT */ + -1, /* (382) plus_num ::= INTEGER|FLOAT */ + 0, /* (383) foreach_clause ::= */ + -3, /* (384) foreach_clause ::= FOR EACH ROW */ + -1, /* (385) trnm ::= nm */ + 0, /* (386) tridxby ::= */ + -1, /* (387) database_kw_opt ::= DATABASE */ + 0, /* (388) database_kw_opt ::= */ + 0, /* (389) kwcolumn_opt ::= */ + -1, /* (390) kwcolumn_opt ::= COLUMNKW */ + -1, /* (391) vtabarglist ::= vtabarg */ + -3, /* (392) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (393) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (394) anylist ::= */ + -4, /* (395) anylist ::= anylist LP anylist RP */ + -2, /* (396) anylist ::= anylist ANY */ + 0, /* (397) with ::= */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -158283,55 +160519,6 @@ static YYACTIONTYPE yy_reduce( (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; - assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); -#ifndef NDEBUG - if( yyTraceFILE ){ - yysize = yyRuleInfoNRhs[yyruleno]; - if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", - yyTracePrompt, - yyruleno, yyRuleName[yyruleno], - yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action", - yymsp[yysize].stateno); - }else{ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", - yyTracePrompt, yyruleno, yyRuleName[yyruleno], - yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action"); - } - } -#endif /* NDEBUG */ - - /* Check that the stack is large enough to grow by a single entry - ** if the RHS of the rule is empty. This ensures that there is room - ** enough on the stack to push the LHS value */ - if( yyRuleInfoNRhs[yyruleno]==0 ){ -#ifdef YYTRACKMAXSTACKDEPTH - if( (int)(yypParser->yytos - 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 @@ -158354,16 +160541,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.yy60);} break; case 4: /* transtype ::= */ -{yymsp[1].minor.yy192 = TK_DEFERRED;} +{yymsp[1].minor.yy60 = 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 318: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==318); +{yymsp[0].minor.yy60 = yymsp[0].major; /*A-overwrites-X*/} break; case 8: /* cmd ::= COMMIT|END trans_opt */ case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); @@ -158386,7 +160573,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.yy60,0,0,yymsp[-2].minor.yy60); } break; case 14: /* createkw ::= CREATE */ @@ -158400,33 +160587,33 @@ static YYACTIONTYPE yy_reduce( 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 239: /* collate ::= */ yytestcase(yyruleno==239); +{yymsp[1].minor.yy60 = 0;} break; case 16: /* ifnotexists ::= IF NOT EXISTS */ -{yymsp[-2].minor.yy192 = 1;} +{yymsp[-2].minor.yy60 = 1;} break; case 17: /* temp ::= TEMP */ case 46: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==46); -{yymsp[0].minor.yy192 = 1;} +{yymsp[0].minor.yy60 = 1;} break; case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */ { - 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.yy60,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.yy307); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy307); } break; case 22: /* table_options ::= 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.yy60 = TF_WithoutRowid | TF_NoVisibleRowid; }else{ - yymsp[-1].minor.yy192 = 0; + yymsp[-1].minor.yy60 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } @@ -158455,7 +160642,7 @@ static YYACTIONTYPE yy_reduce( case 28: /* scanpt ::= */ { assert( yyLookahead!=YYNOCODE ); - yymsp[1].minor.yy436 = yyLookaheadToken.z; + yymsp[1].minor.yy528 = yyLookaheadToken.z; } break; case 29: /* scantok ::= */ @@ -158469,17 +160656,17 @@ static YYACTIONTYPE yy_reduce( {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]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy602,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);} +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy602,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]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy602,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; case 34: /* 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.yy602, 0); sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); } break; @@ -158494,176 +160681,158 @@ static YYACTIONTYPE yy_reduce( } break; case 36: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy192);} +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy60);} break; case 37: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy192,yymsp[0].minor.yy192,yymsp[-2].minor.yy192);} +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy60,yymsp[0].minor.yy60,yymsp[-2].minor.yy60);} break; case 38: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy192,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy60,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 39: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy202,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy602,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);} +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy338,yymsp[0].minor.yy60);} break; case 41: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy192);} +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy60);} break; case 42: /* ccons ::= COLLATE ID|STRING */ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; case 43: /* generated ::= LP expr RP */ -{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy202,0);} +{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy602,0);} break; case 44: /* generated ::= LP expr RP ID */ -{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy202,&yymsp[0].minor.yy0);} +{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy602,&yymsp[0].minor.yy0);} break; case 47: /* refargs ::= */ -{ yymsp[1].minor.yy192 = OE_None*0x0101; /* EV: R-19803-45884 */} +{ yymsp[1].minor.yy60 = OE_None*0x0101; /* EV: R-19803-45884 */} break; case 48: /* refargs ::= refargs refarg */ -{ yymsp[-1].minor.yy192 = (yymsp[-1].minor.yy192 & ~yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; } +{ yymsp[-1].minor.yy60 = (yymsp[-1].minor.yy60 & ~yymsp[0].minor.yy615.mask) | yymsp[0].minor.yy615.value; } break; case 49: /* refarg ::= MATCH nm */ -{ yymsp[-1].minor.yy207.value = 0; yymsp[-1].minor.yy207.mask = 0x000000; } +{ yymsp[-1].minor.yy615.value = 0; yymsp[-1].minor.yy615.mask = 0x000000; } break; case 50: /* refarg ::= ON INSERT refact */ -{ yymsp[-2].minor.yy207.value = 0; yymsp[-2].minor.yy207.mask = 0x000000; } +{ yymsp[-2].minor.yy615.value = 0; yymsp[-2].minor.yy615.mask = 0x000000; } break; case 51: /* refarg ::= ON DELETE refact */ -{ yymsp[-2].minor.yy207.value = yymsp[0].minor.yy192; yymsp[-2].minor.yy207.mask = 0x0000ff; } +{ yymsp[-2].minor.yy615.value = yymsp[0].minor.yy60; yymsp[-2].minor.yy615.mask = 0x0000ff; } break; case 52: /* refarg ::= ON UPDATE refact */ -{ yymsp[-2].minor.yy207.value = yymsp[0].minor.yy192<<8; yymsp[-2].minor.yy207.mask = 0x00ff00; } +{ yymsp[-2].minor.yy615.value = yymsp[0].minor.yy60<<8; yymsp[-2].minor.yy615.mask = 0x00ff00; } break; case 53: /* refact ::= SET NULL */ -{ yymsp[-1].minor.yy192 = OE_SetNull; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy60 = OE_SetNull; /* EV: R-33326-45252 */} break; case 54: /* refact ::= SET DEFAULT */ -{ yymsp[-1].minor.yy192 = OE_SetDflt; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy60 = OE_SetDflt; /* EV: R-33326-45252 */} break; case 55: /* refact ::= CASCADE */ -{ yymsp[0].minor.yy192 = OE_Cascade; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy60 = OE_Cascade; /* EV: R-33326-45252 */} break; case 56: /* refact ::= RESTRICT */ -{ yymsp[0].minor.yy192 = OE_Restrict; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy60 = OE_Restrict; /* EV: R-33326-45252 */} break; case 57: /* refact ::= NO ACTION */ -{ yymsp[-1].minor.yy192 = OE_None; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy60 = OE_None; /* EV: R-33326-45252 */} break; case 58: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -{yymsp[-2].minor.yy192 = 0;} +{yymsp[-2].minor.yy60 = 0;} 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 169: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==169); +{yymsp[-1].minor.yy60 = yymsp[0].minor.yy60;} 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 211: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==211); + case 214: /* in_op ::= NOT IN */ yytestcase(yyruleno==214); + case 240: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==240); +{yymsp[-1].minor.yy60 = 1;} break; case 62: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -{yymsp[-1].minor.yy192 = 0;} +{yymsp[-1].minor.yy60 = 0;} break; case 64: /* 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);} +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy338,yymsp[0].minor.yy60,yymsp[-2].minor.yy60,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, +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy338,yymsp[0].minor.yy60,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 68: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy202,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy602,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 */ { - 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.yy338, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy338, yymsp[-1].minor.yy60); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy60); } break; case 71: /* onconf ::= */ case 73: /* orconf ::= */ yytestcase(yyruleno==73); -{yymsp[1].minor.yy192 = OE_Default;} +{yymsp[1].minor.yy60 = OE_Default;} break; case 72: /* onconf ::= ON CONFLICT resolvetype */ -{yymsp[-2].minor.yy192 = yymsp[0].minor.yy192;} +{yymsp[-2].minor.yy60 = yymsp[0].minor.yy60;} break; case 75: /* resolvetype ::= IGNORE */ -{yymsp[0].minor.yy192 = OE_Ignore;} +{yymsp[0].minor.yy60 = OE_Ignore;} break; case 76: /* resolvetype ::= REPLACE */ - case 163: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==163); -{yymsp[0].minor.yy192 = OE_Replace;} + case 170: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==170); +{yymsp[0].minor.yy60 = OE_Replace;} break; case 77: /* cmd ::= DROP TABLE ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy47, 0, yymsp[-1].minor.yy192); + sqlite3DropTable(pParse, yymsp[0].minor.yy291, 0, yymsp[-1].minor.yy60); } break; case 80: /* 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.yy338, yymsp[0].minor.yy307, yymsp[-7].minor.yy60, yymsp[-5].minor.yy60); } break; case 81: /* cmd ::= DROP VIEW ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy47, 1, yymsp[-1].minor.yy192); + sqlite3DropTable(pParse, yymsp[0].minor.yy291, 1, yymsp[-1].minor.yy60); } break; case 82: /* 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.yy307, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy307); } 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; -} +{yymsp[-2].minor.yy307 = attachWithToSelect(pParse,yymsp[0].minor.yy307,yymsp[-1].minor.yy195);} 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; -} +{yymsp[-3].minor.yy307 = attachWithToSelect(pParse,yymsp[0].minor.yy307,yymsp[-1].minor.yy195);} break; case 85: /* select ::= selectnowith */ { - Select *p = yymsp[0].minor.yy539; + Select *p = yymsp[0].minor.yy307; if( p ){ parserDoubleLinkSelect(pParse, p); } - yymsp[0].minor.yy539 = p; /*A-overwrites-X*/ + yymsp[0].minor.yy307 = p; /*A-overwrites-X*/ } break; case 86: /* selectnowith ::= selectnowith multiselect_op oneselect */ { - Select *pRhs = yymsp[0].minor.yy539; - Select *pLhs = yymsp[-2].minor.yy539; + Select *pRhs = yymsp[0].minor.yy307; + Select *pLhs = yymsp[-2].minor.yy307; if( pRhs && pRhs->pPrior ){ SrcList *pFrom; Token x; @@ -158673,83 +160842,83 @@ 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.yy60; 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.yy60!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); } - yymsp[-2].minor.yy539 = pRhs; + yymsp[-2].minor.yy307 = 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*/} +{yymsp[0].minor.yy60 = yymsp[0].major; /*A-overwrites-OP*/} break; case 88: /* multiselect_op ::= UNION ALL */ -{yymsp[-1].minor.yy192 = TK_ALL;} +{yymsp[-1].minor.yy60 = TK_ALL;} break; case 90: /* 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.yy307 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy338,yymsp[-5].minor.yy291,yymsp[-4].minor.yy602,yymsp[-3].minor.yy338,yymsp[-2].minor.yy602,yymsp[-1].minor.yy338,yymsp[-7].minor.yy60,yymsp[0].minor.yy602); } break; case 91: /* 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.yy307 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy338,yymsp[-6].minor.yy291,yymsp[-5].minor.yy602,yymsp[-4].minor.yy338,yymsp[-3].minor.yy602,yymsp[-1].minor.yy338,yymsp[-8].minor.yy60,yymsp[0].minor.yy602); + if( yymsp[-9].minor.yy307 ){ + yymsp[-9].minor.yy307->pWinDefn = yymsp[-2].minor.yy19; }else{ - sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy303); + sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy19); } } break; case 92: /* 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.yy307 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy338,0,0,0,0,0,SF_Values,0); } break; case 93: /* 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.yy307; + pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy338,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.yy307 = pRight; }else{ - yymsp[-4].minor.yy539 = pLeft; + yymsp[-4].minor.yy307 = pLeft; } } break; case 94: /* distinct ::= DISTINCT */ -{yymsp[0].minor.yy192 = SF_Distinct;} +{yymsp[0].minor.yy60 = SF_Distinct;} break; case 95: /* distinct ::= ALL */ -{yymsp[0].minor.yy192 = SF_All;} +{yymsp[0].minor.yy60 = 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 227: /* exprlist ::= */ yytestcase(yyruleno==227); + case 230: /* paren_exprlist ::= */ yytestcase(yyruleno==230); + case 235: /* eidlist_opt ::= */ yytestcase(yyruleno==235); +{yymsp[1].minor.yy338 = 0;} break; case 98: /* 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.yy338 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy338, yymsp[-2].minor.yy602); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy338, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy338,yymsp[-3].minor.yy528,yymsp[-1].minor.yy528); } break; case 99: /* 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.yy338 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy338, p); } break; case 100: /* selcollist ::= sclp scanpt nm DOT STAR */ @@ -158757,56 +160926,56 @@ static YYACTIONTYPE yy_reduce( Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); - yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, pDot); + yymsp[-4].minor.yy338 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy338, 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 251: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==251); + case 252: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==252); {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} break; case 103: /* from ::= */ case 106: /* stl_prefix ::= */ yytestcase(yyruleno==106); -{yymsp[1].minor.yy47 = 0;} +{yymsp[1].minor.yy291 = 0;} break; case 104: /* from ::= FROM seltablist */ { - yymsp[-1].minor.yy47 = yymsp[0].minor.yy47; - sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy47); + yymsp[-1].minor.yy291 = yymsp[0].minor.yy291; + sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy291); } break; case 105: /* 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.yy291 && yymsp[-1].minor.yy291->nSrc>0) ) yymsp[-1].minor.yy291->a[yymsp[-1].minor.yy291->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy60; } break; case 107: /* 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.yy291 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy291,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy602,yymsp[0].minor.yy288); + sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy291, &yymsp[-2].minor.yy0); } break; case 108: /* 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.yy291 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy291,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy602,yymsp[0].minor.yy288); + sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy291, yymsp[-4].minor.yy338); } break; case 109: /* 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.yy291 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy291,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy307,yymsp[-1].minor.yy602,yymsp[0].minor.yy288); } break; case 110: /* 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.yy291==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy602==0 && yymsp[0].minor.yy288==0 ){ + yymsp[-6].minor.yy291 = yymsp[-4].minor.yy291; + }else if( yymsp[-4].minor.yy291->nSrc==1 ){ + yymsp[-6].minor.yy291 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy291,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy602,yymsp[0].minor.yy288); + if( yymsp[-6].minor.yy291 ){ + SrcItem *pNew = &yymsp[-6].minor.yy291->a[yymsp[-6].minor.yy291->nSrc-1]; + SrcItem *pOld = yymsp[-4].minor.yy291->a; pNew->zName = pOld->zName; pNew->zDatabase = pOld->zDatabase; pNew->pSelect = pOld->pSelect; @@ -158819,12 +160988,12 @@ 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.yy291); }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.yy291); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy291,0,0,0,0,SF_NestedFrom,0); + yymsp[-6].minor.yy291 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy291,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy602,yymsp[0].minor.yy288); } } break; @@ -158834,63 +161003,65 @@ static YYACTIONTYPE yy_reduce( break; case 113: /* 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.yy291 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); + if( IN_RENAME_OBJECT && yylhsminor.yy291 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy291->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy47 = yylhsminor.yy47; + yymsp[0].minor.yy291 = yylhsminor.yy291; break; case 114: /* 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.yy291 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + if( IN_RENAME_OBJECT && yylhsminor.yy291 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy291->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy47 = yylhsminor.yy47; + yymsp[-2].minor.yy291 = yylhsminor.yy291; break; case 115: /* xfullname ::= nm */ -{yymsp[0].minor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} +{yymsp[0].minor.yy291 = 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*/} +{yymsp[-2].minor.yy291 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} break; case 117: /* 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.yy291 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ + if( yymsp[-4].minor.yy291 ) yymsp[-4].minor.yy291->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; case 118: /* 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.yy291 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ + if( yymsp[-2].minor.yy291 ) yymsp[-2].minor.yy291->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; case 119: /* joinop ::= COMMA|JOIN */ -{ yymsp[0].minor.yy192 = JT_INNER; } +{ yymsp[0].minor.yy60 = JT_INNER; } break; case 120: /* joinop ::= JOIN_KW JOIN */ -{yymsp[-1].minor.yy192 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} +{yymsp[-1].minor.yy60 = 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*/} +{yymsp[-2].minor.yy60 = 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*/} +{yymsp[-3].minor.yy60 = 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 152: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==152); + case 223: /* case_else ::= ELSE expr */ yytestcase(yyruleno==223); + case 244: /* vinto ::= INTO expr */ yytestcase(yyruleno==244); +{yymsp[-1].minor.yy602 = yymsp[0].minor.yy602;} 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 151: /* where_opt_ret ::= */ yytestcase(yyruleno==151); + case 224: /* case_else ::= */ yytestcase(yyruleno==224); + case 226: /* case_operand ::= */ yytestcase(yyruleno==226); + case 245: /* vinto ::= */ yytestcase(yyruleno==245); +{yymsp[1].minor.yy602 = 0;} break; case 126: /* indexed_opt ::= INDEXED BY nm */ {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} @@ -158899,129 +161070,144 @@ static YYACTIONTYPE yy_reduce( {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;} +{yymsp[-3].minor.yy288 = yymsp[-1].minor.yy288;} break; case 129: /* using_opt ::= */ - case 164: /* idlist_opt ::= */ yytestcase(yyruleno==164); -{yymsp[1].minor.yy600 = 0;} + case 171: /* idlist_opt ::= */ yytestcase(yyruleno==171); +{yymsp[1].minor.yy288 = 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;} +{yymsp[-2].minor.yy338 = yymsp[0].minor.yy338;} break; case 132: /* 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.yy338 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy338,yymsp[-2].minor.yy602); + sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy338,yymsp[-1].minor.yy60,yymsp[0].minor.yy60); } break; case 133: /* 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.yy338 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy602); /*A-overwrites-Y*/ + sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy338,yymsp[-1].minor.yy60,yymsp[0].minor.yy60); } break; case 134: /* sortorder ::= ASC */ -{yymsp[0].minor.yy192 = SQLITE_SO_ASC;} +{yymsp[0].minor.yy60 = SQLITE_SO_ASC;} break; case 135: /* sortorder ::= DESC */ -{yymsp[0].minor.yy192 = SQLITE_SO_DESC;} +{yymsp[0].minor.yy60 = SQLITE_SO_DESC;} break; case 136: /* sortorder ::= */ case 139: /* nulls ::= */ yytestcase(yyruleno==139); -{yymsp[1].minor.yy192 = SQLITE_SO_UNDEFINED;} +{yymsp[1].minor.yy60 = SQLITE_SO_UNDEFINED;} break; case 137: /* nulls ::= NULLS FIRST */ -{yymsp[-1].minor.yy192 = SQLITE_SO_ASC;} +{yymsp[-1].minor.yy60 = SQLITE_SO_ASC;} break; case 138: /* nulls ::= NULLS LAST */ -{yymsp[-1].minor.yy192 = SQLITE_SO_DESC;} +{yymsp[-1].minor.yy60 = SQLITE_SO_DESC;} break; case 145: /* limit_opt ::= LIMIT expr */ -{yymsp[-1].minor.yy202 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy202,0);} +{yymsp[-1].minor.yy602 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy602,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);} +{yymsp[-3].minor.yy602 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy602,yymsp[0].minor.yy602);} 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);} +{yymsp[-3].minor.yy602 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy602,yymsp[-2].minor.yy602);} break; - case 148: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ + case 148: /* 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.yy291, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy291,yymsp[0].minor.yy602,0,0); } break; - case 151: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt */ + case 153: /* where_opt_ret ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy338); yymsp[-1].minor.yy602 = 0;} + break; + case 154: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy338); yymsp[-3].minor.yy602 = yymsp[-2].minor.yy602;} + break; + case 155: /* 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.yy291, &yymsp[-4].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy338,"set list"); + yymsp[-5].minor.yy291 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy291, yymsp[-1].minor.yy291); + sqlite3Update(pParse,yymsp[-5].minor.yy291,yymsp[-2].minor.yy338,yymsp[0].minor.yy602,yymsp[-6].minor.yy60,0,0,0); } break; - case 152: /* setlist ::= setlist COMMA nm EQ expr */ + case 156: /* 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.yy338 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy338, yymsp[0].minor.yy602); + sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy338, &yymsp[-2].minor.yy0, 1); } break; - case 153: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ + case 157: /* 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.yy338 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy338, yymsp[-3].minor.yy288, yymsp[0].minor.yy602); } break; - case 154: /* setlist ::= nm EQ expr */ + case 158: /* setlist ::= nm EQ expr */ { - yylhsminor.yy242 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy202); - sqlite3ExprListSetName(pParse, yylhsminor.yy242, &yymsp[-2].minor.yy0, 1); + yylhsminor.yy338 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy602); + sqlite3ExprListSetName(pParse, yylhsminor.yy338, &yymsp[-2].minor.yy0, 1); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy338 = yylhsminor.yy338; break; - case 155: /* setlist ::= LP idlist RP EQ expr */ + case 159: /* setlist ::= LP idlist RP EQ expr */ { - yymsp[-4].minor.yy242 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy600, yymsp[0].minor.yy202); + yymsp[-4].minor.yy338 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy288, yymsp[0].minor.yy602); } break; - case 156: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + case 160: /* 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.yy291, yymsp[-1].minor.yy307, yymsp[-2].minor.yy288, yymsp[-5].minor.yy60, yymsp[0].minor.yy178); } break; - case 157: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ + case 161: /* 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.yy291, 0, yymsp[-3].minor.yy288, yymsp[-6].minor.yy60, 0); } break; - case 158: /* upsert ::= */ -{ yymsp[1].minor.yy318 = 0; } + case 162: /* upsert ::= */ +{ yymsp[1].minor.yy178 = 0; } + break; + case 163: /* upsert ::= RETURNING selcollist */ +{ yymsp[-1].minor.yy178 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy338); } + break; + case 164: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ +{ yymsp[-11].minor.yy178 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy338,yymsp[-6].minor.yy602,yymsp[-2].minor.yy338,yymsp[-1].minor.yy602,yymsp[0].minor.yy178);} + break; + case 165: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ +{ yymsp[-8].minor.yy178 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy338,yymsp[-3].minor.yy602,0,0,yymsp[0].minor.yy178); } 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 166: /* upsert ::= ON CONFLICT DO NOTHING returning */ +{ yymsp[-4].minor.yy178 = 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 167: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ +{ yymsp[-7].minor.yy178 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy338,yymsp[-1].minor.yy602,0);} break; - case 161: /* upsert ::= ON CONFLICT DO NOTHING */ -{ yymsp[-3].minor.yy318 = sqlite3UpsertNew(pParse->db,0,0,0,0); } + case 168: /* returning ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy338);} break; - case 165: /* idlist_opt ::= LP idlist RP */ -{yymsp[-2].minor.yy600 = yymsp[-1].minor.yy600;} + case 172: /* idlist_opt ::= LP idlist RP */ +{yymsp[-2].minor.yy288 = yymsp[-1].minor.yy288;} break; - case 166: /* idlist ::= idlist COMMA nm */ -{yymsp[-2].minor.yy600 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy600,&yymsp[0].minor.yy0);} + case 173: /* idlist ::= idlist COMMA nm */ +{yymsp[-2].minor.yy288 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy288,&yymsp[0].minor.yy0);} break; - case 167: /* idlist ::= nm */ -{yymsp[0].minor.yy600 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} + case 174: /* idlist ::= nm */ +{yymsp[0].minor.yy288 = 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 175: /* expr ::= LP expr RP */ +{yymsp[-2].minor.yy602 = yymsp[-1].minor.yy602;} 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 176: /* expr ::= ID|INDEXED */ + case 177: /* expr ::= JOIN_KW */ yytestcase(yyruleno==177); +{yymsp[0].minor.yy602=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 171: /* expr ::= nm DOT nm */ + case 178: /* 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); @@ -159029,11 +161215,11 @@ static YYACTIONTYPE yy_reduce( sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0); sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0); } - yylhsminor.yy202 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); + yylhsminor.yy602 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } - yymsp[-2].minor.yy202 = yylhsminor.yy202; + yymsp[-2].minor.yy602 = yylhsminor.yy602; break; - case 172: /* expr ::= nm DOT nm DOT nm */ + case 179: /* 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); @@ -159043,26 +161229,26 @@ static YYACTIONTYPE yy_reduce( sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0); sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0); } - yylhsminor.yy202 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); + yylhsminor.yy602 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } - yymsp[-4].minor.yy202 = yylhsminor.yy202; + yymsp[-4].minor.yy602 = yylhsminor.yy602; 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 180: /* term ::= NULL|FLOAT|BLOB */ + case 181: /* term ::= STRING */ yytestcase(yyruleno==181); +{yymsp[0].minor.yy602=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 175: /* term ::= INTEGER */ + case 182: /* term ::= INTEGER */ { - yylhsminor.yy202 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); + yylhsminor.yy602 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); } - yymsp[0].minor.yy202 = yylhsminor.yy202; + yymsp[0].minor.yy602 = yylhsminor.yy602; break; - case 176: /* expr ::= VARIABLE */ + case 183: /* 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.yy602 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy602, 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 @@ -159071,159 +161257,159 @@ 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.yy602 = 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.yy602 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( yymsp[0].minor.yy602 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy602->iTable); } } } break; - case 177: /* expr ::= expr COLLATE ID|STRING */ + case 184: /* expr ::= expr COLLATE ID|STRING */ { - yymsp[-2].minor.yy202 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy202, &yymsp[0].minor.yy0, 1); + yymsp[-2].minor.yy602 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy602, &yymsp[0].minor.yy0, 1); } break; - case 178: /* expr ::= CAST LP expr AS typetoken RP */ + case 185: /* 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.yy602 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); + sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy602, yymsp[-3].minor.yy602, 0); } break; - case 179: /* expr ::= ID|INDEXED LP distinct exprlist RP */ + case 186: /* expr ::= ID|INDEXED LP distinct exprlist RP */ { - yylhsminor.yy202 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy242, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy192); + yylhsminor.yy602 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy338, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy60); } - yymsp[-4].minor.yy202 = yylhsminor.yy202; + yymsp[-4].minor.yy602 = yylhsminor.yy602; break; - case 180: /* expr ::= ID|INDEXED LP STAR RP */ + case 187: /* expr ::= ID|INDEXED LP STAR RP */ { - yylhsminor.yy202 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); + yylhsminor.yy602 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } - yymsp[-3].minor.yy202 = yylhsminor.yy202; + yymsp[-3].minor.yy602 = yylhsminor.yy602; break; - case 181: /* expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + case 188: /* 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.yy602 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy338, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy60); + sqlite3WindowAttach(pParse, yylhsminor.yy602, yymsp[0].minor.yy19); } - yymsp[-5].minor.yy202 = yylhsminor.yy202; + yymsp[-5].minor.yy602 = yylhsminor.yy602; break; - case 182: /* expr ::= ID|INDEXED LP STAR RP filter_over */ + case 189: /* 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.yy602 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); + sqlite3WindowAttach(pParse, yylhsminor.yy602, yymsp[0].minor.yy19); } - yymsp[-4].minor.yy202 = yylhsminor.yy202; + yymsp[-4].minor.yy602 = yylhsminor.yy602; break; - case 183: /* term ::= CTIME_KW */ + case 190: /* term ::= CTIME_KW */ { - yylhsminor.yy202 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); + yylhsminor.yy602 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } - yymsp[0].minor.yy202 = yylhsminor.yy202; + yymsp[0].minor.yy602 = yylhsminor.yy602; break; - case 184: /* expr ::= LP nexprlist COMMA expr RP */ + case 191: /* 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.yy338, yymsp[-1].minor.yy602); + yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( yymsp[-4].minor.yy602 ){ + yymsp[-4].minor.yy602->x.pList = pList; if( ALWAYS(pList->nExpr) ){ - yymsp[-4].minor.yy202->flags |= pList->a[0].pExpr->flags & EP_Propagate; + yymsp[-4].minor.yy602->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 192: /* expr ::= expr AND expr */ +{yymsp[-2].minor.yy602=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy602,yymsp[0].minor.yy602);} 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 193: /* expr ::= expr OR expr */ + case 194: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==194); + case 195: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==195); + case 196: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==196); + case 197: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==197); + case 198: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==198); + case 199: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==199); +{yymsp[-2].minor.yy602=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy602,yymsp[0].minor.yy602);} break; - case 193: /* likeop ::= NOT LIKE_KW|MATCH */ + case 200: /* 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 201: /* 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.yy602); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy602); + yymsp[-2].minor.yy602 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + if( bNot ) yymsp[-2].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy602, 0); + if( yymsp[-2].minor.yy602 ) yymsp[-2].minor.yy602->flags |= EP_InfixFunc; } break; - case 195: /* expr ::= expr likeop expr ESCAPE expr */ + case 202: /* 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.yy602); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy602); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy602); + yymsp[-4].minor.yy602 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); + if( bNot ) yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy602, 0); + if( yymsp[-4].minor.yy602 ) yymsp[-4].minor.yy602->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 203: /* expr ::= expr ISNULL|NOTNULL */ +{yymsp[-1].minor.yy602 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy602,0);} break; - case 197: /* expr ::= expr NOT NULL */ -{yymsp[-2].minor.yy202 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy202,0);} + case 204: /* expr ::= expr NOT NULL */ +{yymsp[-2].minor.yy602 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy602,0);} break; - case 198: /* expr ::= expr IS expr */ + case 205: /* 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.yy602 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy602,yymsp[0].minor.yy602); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy602, yymsp[-2].minor.yy602, TK_ISNULL); } break; - case 199: /* expr ::= expr IS NOT expr */ + case 206: /* 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.yy602 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy602,yymsp[0].minor.yy602); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy602, yymsp[-3].minor.yy602, 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 207: /* expr ::= NOT expr */ + case 208: /* expr ::= BITNOT expr */ yytestcase(yyruleno==208); +{yymsp[-1].minor.yy602 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy602, 0);/*A-overwrites-B*/} break; - case 202: /* expr ::= PLUS|MINUS expr */ + case 209: /* 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.yy602 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy602, 0); /*A-overwrites-B*/ } break; - case 203: /* between_op ::= BETWEEN */ - case 206: /* in_op ::= IN */ yytestcase(yyruleno==206); -{yymsp[0].minor.yy192 = 0;} + case 210: /* between_op ::= BETWEEN */ + case 213: /* in_op ::= IN */ yytestcase(yyruleno==213); +{yymsp[0].minor.yy60 = 0;} break; - case 205: /* expr ::= expr between_op expr AND expr */ + case 212: /* 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.yy602); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy602); + yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy602, 0); + if( yymsp[-4].minor.yy602 ){ + yymsp[-4].minor.yy602->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.yy60 ) yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy602, 0); } break; - case 208: /* expr ::= expr in_op LP exprlist RP */ + case 215: /* expr ::= expr in_op LP exprlist RP */ { - if( yymsp[-1].minor.yy242==0 ){ + if( yymsp[-1].minor.yy338==0 ){ /* Expressions of the form ** ** expr1 IN () @@ -159232,197 +161418,197 @@ 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); + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy602); + yymsp[-4].minor.yy602 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy60 ? "1" : "0"); + }else if( yymsp[-1].minor.yy338->nExpr==1 && sqlite3ExprIsConstant(yymsp[-1].minor.yy338->a[0].pExpr) ){ + Expr *pRHS = yymsp[-1].minor.yy338->a[0].pExpr; + yymsp[-1].minor.yy338->a[0].pExpr = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy338); 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); + yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy602, pRHS); + if( yymsp[-3].minor.yy60 ) yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy602, 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); + yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy602, 0); + if( yymsp[-4].minor.yy602 ){ + yymsp[-4].minor.yy602->x.pList = yymsp[-1].minor.yy338; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy602); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy242); + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy338); } - if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); + if( yymsp[-3].minor.yy60 ) yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy602, 0); } } break; - case 209: /* expr ::= LP select RP */ + case 216: /* 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.yy602 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy602, yymsp[-1].minor.yy307); } break; - case 210: /* expr ::= expr in_op LP select RP */ + case 217: /* 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.yy602 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy602, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy602, yymsp[-1].minor.yy307); + if( yymsp[-3].minor.yy60 ) yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy602, 0); } break; - case 211: /* expr ::= expr in_op nm dbnm paren_exprlist */ + case 218: /* 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.yy338 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy338); + yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy602, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy602, pSelect); + if( yymsp[-3].minor.yy60 ) yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy602, 0); } break; - case 212: /* expr ::= EXISTS LP select RP */ + case 219: /* 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.yy602 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy307); } break; - case 213: /* expr ::= CASE case_operand case_exprlist case_else END */ + case 220: /* 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.yy602 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy602, 0); + if( yymsp[-4].minor.yy602 ){ + yymsp[-4].minor.yy602->x.pList = yymsp[-1].minor.yy602 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy338,yymsp[-1].minor.yy602) : yymsp[-2].minor.yy338; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy602); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy242); - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy202); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy338); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy602); } } break; - case 214: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + case 221: /* 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.yy338 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy338, yymsp[-2].minor.yy602); + yymsp[-4].minor.yy338 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy338, yymsp[0].minor.yy602); } break; - case 215: /* case_exprlist ::= WHEN expr THEN expr */ + case 222: /* 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.yy338 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy602); + yymsp[-3].minor.yy338 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy338, yymsp[0].minor.yy602); } break; - case 218: /* case_operand ::= expr */ -{yymsp[0].minor.yy202 = yymsp[0].minor.yy202; /*A-overwrites-X*/} + case 225: /* case_operand ::= expr */ +{yymsp[0].minor.yy602 = yymsp[0].minor.yy602; /*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 228: /* nexprlist ::= nexprlist COMMA expr */ +{yymsp[-2].minor.yy338 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy338,yymsp[0].minor.yy602);} break; - case 222: /* nexprlist ::= expr */ -{yymsp[0].minor.yy242 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy202); /*A-overwrites-Y*/} + case 229: /* nexprlist ::= expr */ +{yymsp[0].minor.yy338 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy602); /*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 231: /* paren_exprlist ::= LP exprlist RP */ + case 236: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==236); +{yymsp[-2].minor.yy338 = yymsp[-1].minor.yy338;} break; - case 225: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + case 232: /* 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.yy338, yymsp[-10].minor.yy60, + &yymsp[-11].minor.yy0, yymsp[0].minor.yy602, SQLITE_SO_ASC, yymsp[-8].minor.yy60, 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 233: /* uniqueflag ::= UNIQUE */ + case 275: /* raisetype ::= ABORT */ yytestcase(yyruleno==275); +{yymsp[0].minor.yy60 = OE_Abort;} break; - case 227: /* uniqueflag ::= */ -{yymsp[1].minor.yy192 = OE_None;} + case 234: /* uniqueflag ::= */ +{yymsp[1].minor.yy60 = OE_None;} break; - case 230: /* eidlist ::= eidlist COMMA nm collate sortorder */ + case 237: /* 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.yy338 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy338, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy60, yymsp[0].minor.yy60); } break; - case 231: /* eidlist ::= nm collate sortorder */ + case 238: /* 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.yy338 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy60, yymsp[0].minor.yy60); /*A-overwrites-Y*/ } break; - case 234: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy47, yymsp[-1].minor.yy192);} + case 241: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy291, yymsp[-1].minor.yy60);} break; - case 235: /* cmd ::= VACUUM vinto */ -{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy202);} + case 242: /* cmd ::= VACUUM vinto */ +{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy602);} break; - case 236: /* cmd ::= VACUUM nm vinto */ -{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy202);} + case 243: /* cmd ::= VACUUM nm vinto */ +{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy602);} break; - case 239: /* cmd ::= PRAGMA nm dbnm */ + case 246: /* 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 247: /* 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 248: /* 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 249: /* 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 250: /* 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 253: /* 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.yy483, &all); } break; - case 247: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 254: /* 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.yy60, yymsp[-4].minor.yy50.a, yymsp[-4].minor.yy50.b, yymsp[-2].minor.yy291, yymsp[0].minor.yy602, yymsp[-10].minor.yy60, yymsp[-8].minor.yy60); 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 255: /* trigger_time ::= BEFORE|AFTER */ +{ yymsp[0].minor.yy60 = yymsp[0].major; /*A-overwrites-X*/ } break; - case 249: /* trigger_time ::= INSTEAD OF */ -{ yymsp[-1].minor.yy192 = TK_INSTEAD;} + case 256: /* trigger_time ::= INSTEAD OF */ +{ yymsp[-1].minor.yy60 = TK_INSTEAD;} break; - case 250: /* trigger_time ::= */ -{ yymsp[1].minor.yy192 = TK_BEFORE; } + case 257: /* trigger_time ::= */ +{ yymsp[1].minor.yy60 = 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 258: /* trigger_event ::= DELETE|INSERT */ + case 259: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==259); +{yymsp[0].minor.yy50.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy50.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 260: /* trigger_event ::= UPDATE OF idlist */ +{yymsp[-2].minor.yy50.a = TK_UPDATE; yymsp[-2].minor.yy50.b = yymsp[0].minor.yy288;} break; - case 254: /* when_clause ::= */ - case 273: /* key_opt ::= */ yytestcase(yyruleno==273); -{ yymsp[1].minor.yy202 = 0; } + case 261: /* when_clause ::= */ + case 280: /* key_opt ::= */ yytestcase(yyruleno==280); +{ yymsp[1].minor.yy602 = 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 262: /* when_clause ::= WHEN expr */ + case 281: /* key_opt ::= KEY expr */ yytestcase(yyruleno==281); +{ yymsp[-1].minor.yy602 = yymsp[0].minor.yy602; } break; - case 256: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 263: /* 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.yy483!=0 ); + yymsp[-2].minor.yy483->pLast->pNext = yymsp[-1].minor.yy483; + yymsp[-2].minor.yy483->pLast = yymsp[-1].minor.yy483; } break; - case 257: /* trigger_cmd_list ::= trigger_cmd SEMI */ + case 264: /* 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.yy483!=0 ); + yymsp[-1].minor.yy483->pLast = yymsp[-1].minor.yy483; } break; - case 258: /* trnm ::= nm DOT nm */ + case 265: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, @@ -159430,344 +161616,364 @@ static YYACTIONTYPE yy_reduce( "statements within triggers"); } break; - case 259: /* tridxby ::= INDEXED BY nm */ + case 266: /* 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 267: /* 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 268: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ +{yylhsminor.yy483 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy291, yymsp[-3].minor.yy338, yymsp[-1].minor.yy602, yymsp[-7].minor.yy60, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy528);} + yymsp[-8].minor.yy483 = yylhsminor.yy483; break; - case 262: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + case 269: /* 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.yy483 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy288,yymsp[-2].minor.yy307,yymsp[-6].minor.yy60,yymsp[-1].minor.yy178,yymsp[-7].minor.yy528,yymsp[0].minor.yy528);/*yylhsminor.yy483-overwrites-yymsp[-6].minor.yy60*/ } - yymsp[-7].minor.yy447 = yylhsminor.yy447; + yymsp[-7].minor.yy483 = yylhsminor.yy483; 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 270: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ +{yylhsminor.yy483 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy602, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy528);} + yymsp[-5].minor.yy483 = yylhsminor.yy483; 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 271: /* trigger_cmd ::= scanpt select scanpt */ +{yylhsminor.yy483 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy307, yymsp[-2].minor.yy528, yymsp[0].minor.yy528); /*yylhsminor.yy483-overwrites-yymsp[-1].minor.yy307*/} + yymsp[-2].minor.yy483 = yylhsminor.yy483; break; - case 265: /* expr ::= RAISE LP IGNORE RP */ + case 272: /* 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.yy602 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); + if( yymsp[-3].minor.yy602 ){ + yymsp[-3].minor.yy602->affExpr = OE_Ignore; } } break; - case 266: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 273: /* 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.yy602 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); + if( yymsp[-5].minor.yy602 ) { + yymsp[-5].minor.yy602->affExpr = (char)yymsp[-3].minor.yy60; } } break; - case 267: /* raisetype ::= ROLLBACK */ -{yymsp[0].minor.yy192 = OE_Rollback;} + case 274: /* raisetype ::= ROLLBACK */ +{yymsp[0].minor.yy60 = OE_Rollback;} break; - case 269: /* raisetype ::= FAIL */ -{yymsp[0].minor.yy192 = OE_Fail;} + case 276: /* raisetype ::= FAIL */ +{yymsp[0].minor.yy60 = OE_Fail;} break; - case 270: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 277: /* cmd ::= DROP TRIGGER ifexists fullname */ { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy192); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy291,yymsp[-1].minor.yy60); } break; - case 271: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 278: /* 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.yy602, yymsp[-1].minor.yy602, yymsp[0].minor.yy602); } break; - case 272: /* cmd ::= DETACH database_kw_opt expr */ + case 279: /* cmd ::= DETACH database_kw_opt expr */ { - sqlite3Detach(pParse, yymsp[0].minor.yy202); + sqlite3Detach(pParse, yymsp[0].minor.yy602); } break; - case 275: /* cmd ::= REINDEX */ + case 282: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 276: /* cmd ::= REINDEX nm dbnm */ + case 283: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 277: /* cmd ::= ANALYZE */ + case 284: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 278: /* cmd ::= ANALYZE nm dbnm */ + case 285: /* 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 286: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy47,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy291,&yymsp[0].minor.yy0); } break; - case 280: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + case 287: /* 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 288: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ +{ + sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy291, &yymsp[0].minor.yy0); +} + break; + case 289: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy47); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy291); } break; - case 282: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + case 290: /* 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.yy291, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 283: /* cmd ::= create_vtab */ + case 291: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 284: /* cmd ::= create_vtab LP vtabarglist RP */ + case 292: /* 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 293: /* 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.yy60); } break; - case 286: /* vtabarg ::= */ + case 294: /* 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 295: /* vtabargtoken ::= ANY */ + case 296: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==296); + case 297: /* lp ::= LP */ yytestcase(yyruleno==297); {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 298: /* with ::= WITH wqlist */ + case 299: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==299); +{ sqlite3WithPush(pParse, yymsp[0].minor.yy195, 1); } + break; + case 300: /* wqas ::= AS */ +{yymsp[0].minor.yy570 = M10d_Any;} + break; + case 301: /* wqas ::= AS MATERIALIZED */ +{yymsp[-1].minor.yy570 = M10d_Yes;} + break; + case 302: /* wqas ::= AS NOT MATERIALIZED */ +{yymsp[-2].minor.yy570 = M10d_No;} + break; + case 303: /* wqitem ::= nm eidlist_opt wqas LP select RP */ +{ + yymsp[-5].minor.yy607 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy338, yymsp[-1].minor.yy307, yymsp[-3].minor.yy570); /*A-overwrites-X*/ +} break; - case 292: /* wqlist ::= nm eidlist_opt AS LP select RP */ + case 304: /* 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.yy195 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy607); /*A-overwrites-X*/ } break; - case 293: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ + case 305: /* 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.yy195 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy195, yymsp[0].minor.yy607); } break; - case 294: /* windowdefn_list ::= windowdefn */ -{ yylhsminor.yy303 = yymsp[0].minor.yy303; } - yymsp[0].minor.yy303 = yylhsminor.yy303; + case 306: /* windowdefn_list ::= windowdefn */ +{ yylhsminor.yy19 = yymsp[0].minor.yy19; } + yymsp[0].minor.yy19 = yylhsminor.yy19; break; - case 295: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ + case 307: /* 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.yy19!=0 ); + sqlite3WindowChain(pParse, yymsp[0].minor.yy19, yymsp[-2].minor.yy19); + yymsp[0].minor.yy19->pNextWin = yymsp[-2].minor.yy19; + yylhsminor.yy19 = yymsp[0].minor.yy19; } - yymsp[-2].minor.yy303 = yylhsminor.yy303; + yymsp[-2].minor.yy19 = yylhsminor.yy19; break; - case 296: /* windowdefn ::= nm AS LP window RP */ + case 308: /* 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.yy19) ){ + yymsp[-1].minor.yy19->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); } - yylhsminor.yy303 = yymsp[-1].minor.yy303; + yylhsminor.yy19 = yymsp[-1].minor.yy19; } - yymsp[-4].minor.yy303 = yylhsminor.yy303; + yymsp[-4].minor.yy19 = yylhsminor.yy19; break; - case 297: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + case 309: /* 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.yy19 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy19, yymsp[-2].minor.yy338, yymsp[-1].minor.yy338, 0); } break; - case 298: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + case 310: /* 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.yy19 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy19, yymsp[-2].minor.yy338, yymsp[-1].minor.yy338, &yymsp[-5].minor.yy0); } - yymsp[-5].minor.yy303 = yylhsminor.yy303; + yymsp[-5].minor.yy19 = yylhsminor.yy19; break; - case 299: /* window ::= ORDER BY sortlist frame_opt */ + case 311: /* 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.yy19 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy19, 0, yymsp[-1].minor.yy338, 0); } break; - case 300: /* window ::= nm ORDER BY sortlist frame_opt */ + case 312: /* 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.yy19 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy19, 0, yymsp[-1].minor.yy338, &yymsp[-4].minor.yy0); } - yymsp[-4].minor.yy303 = yylhsminor.yy303; + yymsp[-4].minor.yy19 = yylhsminor.yy19; break; - case 301: /* window ::= frame_opt */ - case 320: /* filter_over ::= over_clause */ yytestcase(yyruleno==320); + case 313: /* window ::= frame_opt */ + case 332: /* filter_over ::= over_clause */ yytestcase(yyruleno==332); { - yylhsminor.yy303 = yymsp[0].minor.yy303; + yylhsminor.yy19 = yymsp[0].minor.yy19; } - yymsp[0].minor.yy303 = yylhsminor.yy303; + yymsp[0].minor.yy19 = yylhsminor.yy19; break; - case 302: /* window ::= nm frame_opt */ + case 314: /* window ::= nm frame_opt */ { - yylhsminor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, 0, 0, &yymsp[-1].minor.yy0); + yylhsminor.yy19 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy19, 0, 0, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy303 = yylhsminor.yy303; + yymsp[-1].minor.yy19 = yylhsminor.yy19; break; - case 303: /* frame_opt ::= */ + case 315: /* frame_opt ::= */ { - yymsp[1].minor.yy303 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); + yymsp[1].minor.yy19 = 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 316: /* 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.yy19 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy60, yymsp[-1].minor.yy113.eType, yymsp[-1].minor.yy113.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy570); } - yymsp[-2].minor.yy303 = yylhsminor.yy303; + yymsp[-2].minor.yy19 = yylhsminor.yy19; break; - case 305: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + case 317: /* 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.yy19 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy60, yymsp[-3].minor.yy113.eType, yymsp[-3].minor.yy113.pExpr, yymsp[-1].minor.yy113.eType, yymsp[-1].minor.yy113.pExpr, yymsp[0].minor.yy570); } - yymsp[-5].minor.yy303 = yylhsminor.yy303; + yymsp[-5].minor.yy19 = yylhsminor.yy19; 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 319: /* frame_bound_s ::= frame_bound */ + case 321: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==321); +{yylhsminor.yy113 = yymsp[0].minor.yy113;} + yymsp[0].minor.yy113 = yylhsminor.yy113; 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 320: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 322: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==322); + case 324: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==324); +{yylhsminor.yy113.eType = yymsp[-1].major; yylhsminor.yy113.pExpr = 0;} + yymsp[-1].minor.yy113 = yylhsminor.yy113; 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 323: /* frame_bound ::= expr PRECEDING|FOLLOWING */ +{yylhsminor.yy113.eType = yymsp[0].major; yylhsminor.yy113.pExpr = yymsp[-1].minor.yy602;} + yymsp[-1].minor.yy113 = yylhsminor.yy113; break; - case 313: /* frame_exclude_opt ::= */ -{yymsp[1].minor.yy58 = 0;} + case 325: /* frame_exclude_opt ::= */ +{yymsp[1].minor.yy570 = 0;} break; - case 314: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ -{yymsp[-1].minor.yy58 = yymsp[0].minor.yy58;} + case 326: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ +{yymsp[-1].minor.yy570 = yymsp[0].minor.yy570;} 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 327: /* frame_exclude ::= NO OTHERS */ + case 328: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==328); +{yymsp[-1].minor.yy570 = yymsp[-1].major; /*A-overwrites-X*/} break; - case 317: /* frame_exclude ::= GROUP|TIES */ -{yymsp[0].minor.yy58 = yymsp[0].major; /*A-overwrites-X*/} + case 329: /* frame_exclude ::= GROUP|TIES */ +{yymsp[0].minor.yy570 = yymsp[0].major; /*A-overwrites-X*/} break; - case 318: /* window_clause ::= WINDOW windowdefn_list */ -{ yymsp[-1].minor.yy303 = yymsp[0].minor.yy303; } + case 330: /* window_clause ::= WINDOW windowdefn_list */ +{ yymsp[-1].minor.yy19 = yymsp[0].minor.yy19; } break; - case 319: /* filter_over ::= filter_clause over_clause */ + case 331: /* filter_over ::= filter_clause over_clause */ { - yymsp[0].minor.yy303->pFilter = yymsp[-1].minor.yy202; - yylhsminor.yy303 = yymsp[0].minor.yy303; + yymsp[0].minor.yy19->pFilter = yymsp[-1].minor.yy602; + yylhsminor.yy19 = yymsp[0].minor.yy19; } - yymsp[-1].minor.yy303 = yylhsminor.yy303; + yymsp[-1].minor.yy19 = yylhsminor.yy19; break; - case 321: /* filter_over ::= filter_clause */ + case 333: /* 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.yy19 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yylhsminor.yy19 ){ + yylhsminor.yy19->eFrmType = TK_FILTER; + yylhsminor.yy19->pFilter = yymsp[0].minor.yy602; }else{ - sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy202); + sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy602); } } - yymsp[0].minor.yy303 = yylhsminor.yy303; + yymsp[0].minor.yy19 = yylhsminor.yy19; break; - case 322: /* over_clause ::= OVER LP window RP */ + case 334: /* over_clause ::= OVER LP window RP */ { - yymsp[-3].minor.yy303 = yymsp[-1].minor.yy303; - assert( yymsp[-3].minor.yy303!=0 ); + yymsp[-3].minor.yy19 = yymsp[-1].minor.yy19; + assert( yymsp[-3].minor.yy19!=0 ); } break; - case 323: /* over_clause ::= OVER nm */ + case 335: /* 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.yy19 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yymsp[-1].minor.yy19 ){ + yymsp[-1].minor.yy19->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 336: /* filter_clause ::= FILTER LP WHERE expr RP */ +{ yymsp[-4].minor.yy602 = yymsp[-1].minor.yy602; } 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); + /* (337) input ::= cmdlist */ yytestcase(yyruleno==337); + /* (338) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==338); + /* (339) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=339); + /* (340) ecmd ::= SEMI */ yytestcase(yyruleno==340); + /* (341) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==341); + /* (342) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=342); + /* (343) trans_opt ::= */ yytestcase(yyruleno==343); + /* (344) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==344); + /* (345) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==345); + /* (346) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==346); + /* (347) savepoint_opt ::= */ yytestcase(yyruleno==347); + /* (348) cmd ::= create_table create_table_args */ yytestcase(yyruleno==348); + /* (349) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==349); + /* (350) columnlist ::= columnname carglist */ yytestcase(yyruleno==350); + /* (351) nm ::= ID|INDEXED */ yytestcase(yyruleno==351); + /* (352) nm ::= STRING */ yytestcase(yyruleno==352); + /* (353) nm ::= JOIN_KW */ yytestcase(yyruleno==353); + /* (354) typetoken ::= typename */ yytestcase(yyruleno==354); + /* (355) typename ::= ID|STRING */ yytestcase(yyruleno==355); + /* (356) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=356); + /* (357) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=357); + /* (358) carglist ::= carglist ccons */ yytestcase(yyruleno==358); + /* (359) carglist ::= */ yytestcase(yyruleno==359); + /* (360) ccons ::= NULL onconf */ yytestcase(yyruleno==360); + /* (361) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==361); + /* (362) ccons ::= AS generated */ yytestcase(yyruleno==362); + /* (363) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==363); + /* (364) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==364); + /* (365) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=365); + /* (366) tconscomma ::= */ yytestcase(yyruleno==366); + /* (367) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=367); + /* (368) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=368); + /* (369) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=369); + /* (370) oneselect ::= values */ yytestcase(yyruleno==370); + /* (371) sclp ::= selcollist COMMA */ yytestcase(yyruleno==371); + /* (372) as ::= ID|STRING */ yytestcase(yyruleno==372); + /* (373) returning ::= */ yytestcase(yyruleno==373); + /* (374) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=374); + /* (375) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==375); + /* (376) exprlist ::= nexprlist */ yytestcase(yyruleno==376); + /* (377) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=377); + /* (378) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=378); + /* (379) nmnum ::= ON */ yytestcase(yyruleno==379); + /* (380) nmnum ::= DELETE */ yytestcase(yyruleno==380); + /* (381) nmnum ::= DEFAULT */ yytestcase(yyruleno==381); + /* (382) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==382); + /* (383) foreach_clause ::= */ yytestcase(yyruleno==383); + /* (384) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==384); + /* (385) trnm ::= nm */ yytestcase(yyruleno==385); + /* (386) tridxby ::= */ yytestcase(yyruleno==386); + /* (387) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==387); + /* (388) database_kw_opt ::= */ yytestcase(yyruleno==388); + /* (389) kwcolumn_opt ::= */ yytestcase(yyruleno==389); + /* (390) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==390); + /* (391) vtabarglist ::= vtabarg */ yytestcase(yyruleno==391); + /* (392) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==392); + /* (393) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==393); + /* (394) anylist ::= */ yytestcase(yyruleno==394); + /* (395) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==395); + /* (396) anylist ::= anylist ANY */ yytestcase(yyruleno==396); + /* (397) with ::= */ yytestcase(yyruleno==397); break; /********** End reduce actions ************************************************/ }; @@ -159919,12 +162125,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 */ + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); +#ifndef NDEBUG + if( yyTraceFILE ){ + int yysize = yyRuleInfoNRhs[yyruleno]; + if( yysize ){ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + yyTracePrompt, + yyruleno, yyRuleName[yyruleno], + yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action", + yypParser->yytos[yysize].stateno); + }else{ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", + yyTracePrompt, yyruleno, yyRuleName[yyruleno], + yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action"); + } + } +#endif /* NDEBUG */ + + /* Check that the stack is large enough to grow by a single entry + ** if the RHS of the rule is empty. This ensures that there is room + ** enough on the stack to push the LHS value */ + if( yyRuleInfoNRhs[yyruleno]==0 ){ +#ifdef YYTRACKMAXSTACKDEPTH + if( (int)(yypParser->yytos - 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 @@ -160037,7 +162287,7 @@ SQLITE_PRIVATE void sqlite3Parser( break; #endif } - }while( yypParser->yytos>yypParser->yystack ); + } #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; @@ -160098,8 +162348,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 */ @@ -160124,20 +162374,21 @@ 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 */ 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, +/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 28, 10, 28, 25, 28, /* 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, @@ -160149,22 +162400,22 @@ static const unsigned char aiClass[] = { #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 }; @@ -160229,20 +162480,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', @@ -160263,86 +162515,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, @@ -160360,18 +162613,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 @@ -160395,7 +162649,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: @@ -160491,7 +162745,7 @@ static const unsigned char aKWCode[145] = { ** 114: INTERSECT UNBOUNDED ** 115: ** 116: -** 117: ON +** 117: RETURNING ON ** 118: ** 119: WHERE ** 120: NO INNER @@ -160509,7 +162763,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]]; @@ -160614,63 +162868,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; } @@ -160682,7 +162938,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]; @@ -161051,7 +163307,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, @@ -161081,6 +163337,7 @@ 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; @@ -161263,19 +163520,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr if( !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; assert( nErr==0 || pParse->rc!=SQLITE_OK ); @@ -164182,7 +166427,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; @@ -164205,6 +166450,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; @@ -164253,7 +166500,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. ** @@ -164268,9 +166515,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; i<db->nDb && 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; @@ -165888,7 +168137,7 @@ 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; } @@ -166063,7 +168312,26 @@ SQLITE_API int sqlite3_test_control(int op, ...){ 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; + } } va_end(ap); #endif /* SQLITE_UNTESTABLE */ @@ -172948,9 +175216,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; } @@ -174884,6 +177152,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; @@ -182287,17 +184560,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; @@ -185785,6 +188061,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{ @@ -201540,22 +203817,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<<n) - 1) << ofst; } } } @@ -203342,6 +205621,7 @@ struct sqlite3_session { 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 */ sqlite3_value *pZeroBlob; /* Value containing X'' */ sqlite3_session *pNext; /* Next session object on same db. */ SessionTable *pTable; /* List of attached tables */ @@ -203384,6 +205664,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 */ @@ -203725,6 +206006,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 @@ -204192,13 +206493,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; @@ -204219,7 +206526,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ } } - sqlite3_free(pTab->apChange); + sessionFree(pSession, pTab->apChange); pTab->nChange = nNew; pTab->apChange = apNew; } @@ -204253,6 +206560,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 */ @@ -204307,7 +206615,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; } @@ -204350,7 +206658,7 @@ static int sessionTableInfo( *pabPK = 0; *pnCol = 0; if( pzTab ) *pzTab = 0; - sqlite3_free(azCol); + sessionFree(pSession, azCol); } sqlite3_finalize(pStmt); return rc; @@ -204372,7 +206680,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 ){ @@ -204463,7 +206771,7 @@ static void sessionPreupdateOneChange( } /* Grow the hash table if required */ - if( sessionGrowHash(0, pTab) ){ + if( sessionGrowHash(pSession, 0, pTab) ){ pSession->rc = SQLITE_NOMEM; return; } @@ -204530,7 +206838,7 @@ static void sessionPreupdateOneChange( } /* Allocate the change object */ - pChange = (SessionChange *)sqlite3_malloc64(nByte); + pChange = (SessionChange *)sessionMalloc64(pSession, nByte); if( !pChange ){ rc = SQLITE_NOMEM; goto error_out; @@ -204903,7 +207211,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; @@ -205001,7 +207309,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; @@ -205013,12 +207321,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); } } @@ -205046,9 +207354,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); } @@ -205095,7 +207405,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{ @@ -205692,7 +208003,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; } @@ -205868,6 +208179,13 @@ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession){ } /* +** Return the amount of heap memory in use. +*/ +SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession){ + return pSession->nMalloc; +} + +/* ** Do the work for either sqlite3changeset_start() or start_strm(). */ static int sessionChangesetStart( @@ -205876,7 +208194,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 */ @@ -205897,6 +208216,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; @@ -205911,7 +208231,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 */ @@ -205920,7 +208240,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); } /* @@ -205931,7 +208251,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 */ @@ -205940,7 +208260,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); } /* @@ -206066,11 +208386,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; i<nCol && rc==SQLITE_OK; i++){ int eType = 0; /* Type of value (SQLITE_NULL, TEXT etc.) */ if( abPK && abPK[i]==0 ) continue; @@ -206082,6 +208405,7 @@ static int sessionReadRecord( eType = pIn->aData[pIn->iNext++]; assert( apOut[i]==0 ); if( eType ){ + if( pbEmpty ) *pbEmpty = 0; apOut[i] = sqlite3ValueNew(0); if( !apOut[i] ) rc = SQLITE_NOMEM; } @@ -206261,31 +208585,27 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ } /* -** Advance the changeset iterator to the next change. +** Advance the changeset iterator to the next change. The differences between +** this function and sessionChangesetNext() are that ** -** 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. +** * 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; @@ -206358,13 +208678,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; } @@ -206392,6 +208712,37 @@ static int sessionChangesetNext( } /* +** 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 ** or SQLITE_CORRUPT. @@ -206663,9 +209014,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 @@ -206766,16 +209117,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 */ @@ -206785,6 +209145,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; ii<pIter->nCol; 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; ii<pIter->nCol; 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; ii<pIter->nCol; 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: @@ -206855,103 +209376,6 @@ static int sessionDeleteRow( } /* -** 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; i<p->nCol; 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; i<p->nCol; 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; i<p->nCol; 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: ** @@ -207032,17 +209456,6 @@ static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){ ); } 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 " "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END " @@ -207358,7 +209771,7 @@ static int sessionApplyOneOp( int nCol; int rc = SQLITE_OK; - assert( p->pDelete && p->pUpdate && p->pInsert && p->pSelect ); + assert( p->pDelete && p->pInsert && p->pSelect ); assert( p->azCol && p->abPK ); assert( !pbReplace || *pbReplace==0 ); @@ -207398,29 +209811,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 && i<nCol; i++){ sqlite3_value *pOld = sessionChangesetOld(pIter, i); sqlite3_value *pNew = sessionChangesetNew(pIter, i); - - sqlite3_bind_int(p->pUpdate, 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 @@ -207552,7 +209964,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*); @@ -207643,14 +210055,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; @@ -207678,7 +210089,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; @@ -207714,11 +210125,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; @@ -207777,9 +210187,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); @@ -207810,8 +210220,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 @@ -207869,7 +210279,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 @@ -208157,7 +210567,7 @@ static int sessionChangesetToHash( } } - if( sessionGrowHash(pIter->bPatchset, pTab) ){ + if( sessionGrowHash(0, pIter->bPatchset, pTab) ){ rc = SQLITE_NOMEM; break; } @@ -208343,7 +210753,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); } } @@ -208489,7 +210899,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 ){ @@ -208744,7 +211154,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); } } @@ -211206,55 +213616,6 @@ static fts5YYACTIONTYPE fts5yy_reduce( (void)fts5yyLookahead; (void)fts5yyLookaheadToken; fts5yymsp = fts5yypParser->fts5yytos; - assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ); -#ifndef NDEBUG - if( fts5yyTraceFILE ){ - fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno]; - if( fts5yysize ){ - fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", - fts5yyTracePrompt, - fts5yyruleno, fts5yyRuleName[fts5yyruleno], - fts5yyruleno<fts5YYNRULE_WITH_ACTION ? "" : " without external action", - fts5yymsp[fts5yysize].stateno); - }else{ - fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s.\n", - fts5yyTracePrompt, fts5yyruleno, fts5yyRuleName[fts5yyruleno], - fts5yyruleno<fts5YYNRULE_WITH_ACTION ? "" : " without external action"); - } - } -#endif /* NDEBUG */ - - /* Check that the stack is large enough to grow by a single entry - ** if the RHS of the rule is empty. This ensures that there is room - ** enough on the stack to push the LHS value */ - if( fts5yyRuleInfoNRhs[fts5yyruleno]==0 ){ -#ifdef fts5YYTRACKMAXSTACKDEPTH - if( (int)(fts5yypParser->fts5yytos - 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 @@ -211557,12 +213918,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 */ + assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ); +#ifndef NDEBUG + if( fts5yyTraceFILE ){ + int fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno]; + if( fts5yysize ){ + fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + fts5yyTracePrompt, + fts5yyruleno, fts5yyRuleName[fts5yyruleno], + fts5yyruleno<fts5YYNRULE_WITH_ACTION ? "" : " without external action", + fts5yypParser->fts5yytos[fts5yysize].stateno); + }else{ + fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s.\n", + fts5yyTracePrompt, fts5yyruleno, fts5yyRuleName[fts5yyruleno], + fts5yyruleno<fts5YYNRULE_WITH_ACTION ? "" : " without external action"); + } + } +#endif /* NDEBUG */ + + /* Check that the stack is large enough to grow by a single entry + ** if the RHS of the rule is empty. This ensures that there is room + ** enough on the stack to push the LHS value */ + if( fts5yyRuleInfoNRhs[fts5yyruleno]==0 ){ +#ifdef fts5YYTRACKMAXSTACKDEPTH + if( (int)(fts5yypParser->fts5yytos - 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 @@ -211675,7 +214080,7 @@ static void sqlite3Fts5Parser( break; #endif } - }while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ); + } #ifndef NDEBUG if( fts5yyTraceFILE ){ fts5yyStackEntry *i; @@ -215287,8 +217692,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; @@ -219473,14 +221878,10 @@ 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; @@ -220472,7 +222873,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 ){ @@ -220485,6 +222886,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)); @@ -220536,66 +222940,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( p<pEnd && *p!=0x01 ){ - while( *p++ & 0x80 ); - } - - return p - (*pa); -} - static void fts5IndexExtractColset( int *pRc, Fts5Colset *pColset, /* Colset to filter on */ const u8 *pPos, int nPos, /* Position list */ - Fts5Buffer *pBuf /* Output buffer */ + Fts5Iter *pIter ){ if( *pRc==SQLITE_OK ){ - int i; - fts5BufferZero(pBuf); - for(i=0; i<pColset->nCol; 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]<iCurrent ){ + i++; + if( i==pColset->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( p<pEnd && *p!=0x01 ){ + while( *p++ & 0x80 ); + } + + if( pColset->aiCol[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); } } } + } /* @@ -220715,16 +223125,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 @@ -222207,7 +224610,7 @@ static void fts5AppendPoslist( static void fts5DoclistIterNext(Fts5DoclistIter *pIter){ u8 *p = pIter->aPoslist + pIter->nSize + pIter->nPoslist; - assert( pIter->aPoslist ); + assert( pIter->aPoslist || (p==0 && pIter->aPoslist==0) ); if( p>=pIter->aEof ){ pIter->aPoslist = 0; }else{ @@ -222227,6 +224630,9 @@ static void fts5DoclistIterNext(Fts5DoclistIter *pIter){ } pIter->aPoslist = p; + if( &pIter->aPoslist[pIter->nPoslist]>pIter->aEof ){ + pIter->aPoslist = 0; + } } } @@ -222235,9 +224641,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 @@ -222291,16 +224699,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; @@ -222327,180 +224739,213 @@ 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; i<nBuf; i++){ + fts5DoclistIterInit(&aBuf[i], &aMerger[i].iter); + fts5PrefixMergerInsertByRowid(&pHead, &aMerger[i]); + nOut += aBuf[i].n; + } + if( nOut==0 ) return; + nOut += p1->n + 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.iRowid<i2.iRowid ){ - /* Copy entry from i1 */ - fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid); - fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.nPoslist+i1.nSize); - fts5DoclistIterNext(&i1); - if( i1.aPoslist==0 ) break; - assert( out.n<=((i1.aPoslist-p1->p) + (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 + FTS5_DATA_ZERO_PADDING - ); - if( p->rc ) break; + fts5BufferZero(&tmp); - sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - assert_nc( iPos1>=0 && iPos2>=0 ); + pThis = pHead; + pHead = pThis->pNext; + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos); + fts5PrefixMergerNextPosition(pThis); + fts5PrefixMergerInsertByPosition(&pHead, pThis); - if( iPos1<iPos2 ){ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); - sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - }else{ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); - sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - } - if( iPos1>=0 && iPos2>=0 ){ - while( 1 ){ - if( iPos1<iPos2 ){ - if( iPos1!=iPrev ){ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); - } - sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - if( iPos1<0 ) break; - }else{ - assert_nc( iPos2!=iPrev ); - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); - sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - if( iPos2<0 ) break; - } - } + while( pHead->pNext ){ + pThis = pHead; + if( pThis->iPos!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos); } + fts5PrefixMergerNextPosition(pThis); + pHead = pThis->pNext; + fts5PrefixMergerInsertByPosition(&pHead, pThis); + } - 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); - } + if( pHead->iPos!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pHead->iPos); + } + nTail = pHead->iter.nPoslist - pHead->iOff; - /* 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; + /* WRITEPOSLISTSIZE */ + assert( tmp.n+nTail<=nTmp ); + 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; i<nBuf+1; i++){ + PrefixMerger *pX = &aMerger[i]; + if( pX->iter.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) ); - - fts5BufferFree(p1); - fts5BufferFree(&tmp); - memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING); - *p1 = 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; } @@ -222520,6 +224965,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 */ ; @@ -222540,13 +225006,21 @@ static void fts5SetupPrefixIter( if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ - assert( i<nBuf ); - if( aBuf[i].n==0 ){ - fts5BufferSwap(&doclist, &aBuf[i]); - fts5BufferZero(&doclist); - }else{ - xMerge(p, &doclist, &aBuf[i]); - fts5BufferZero(&aBuf[i]); + int i1 = i*nMerge; + int iStore; + assert( i1+nMerge<=nBuf ); + for(iStore=i1; iStore<i1+nMerge; iStore++){ + if( aBuf[iStore].n==0 ){ + fts5BufferSwap(&doclist, &aBuf[iStore]); + fts5BufferZero(&doclist); + break; + } + } + if( iStore==i1+nMerge ){ + xMerge(p, &doclist, nMerge, &aBuf[i1]); + for(iStore=i1; iStore<i1+nMerge; iStore++){ + fts5BufferZero(&aBuf[iStore]); + } } } iLastRowid = 0; @@ -222556,11 +225030,15 @@ static void fts5SetupPrefixIter( iLastRowid = p1->base.iRowid; } - for(i=0; i<nBuf; i++){ + assert( (nBuf%nMerge)==0 ); + for(i=0; i<nBuf; i+=nMerge){ + int iFree; if( p->rc==SQLITE_OK ){ - xMerge(p, &doclist, &aBuf[i]); + xMerge(p, &doclist, nMerge, &aBuf[i]); + } + for(iFree=i; iFree<i+nMerge; iFree++){ + fts5BufferFree(&aBuf[iFree]); } - fts5BufferFree(&aBuf[i]); } fts5MultiIterFree(p1); @@ -222815,6 +225293,7 @@ static int sqlite3Fts5IndexQuery( if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ + int iPrefixIdx = 0; /* +1 prefix index */ if( nToken ) memcpy(&buf.p[1], pToken, nToken); /* Figure out which index to search and set iIdx accordingly. If this @@ -222836,7 +225315,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; } } @@ -222853,8 +225334,7 @@ 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); + fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet); assert( p->rc!=SQLITE_OK || pRet->pColset==0 ); fts5IterSetOutputCb(&p->rc, pRet); if( p->rc==SQLITE_OK ){ @@ -222927,8 +225407,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); } /* @@ -226214,7 +228695,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); @@ -226273,7 +228755,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); } @@ -226281,7 +228764,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 ){ @@ -226759,7 +229243,7 @@ static int sqlite3Fts5GetTokenizer( *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); }else{ rc = pMod->x.xCreate( - pMod->pUserData, &azArg[1], (nArg?nArg-1:0), &pConfig->pTok + pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok ); pConfig->pTokApi = &pMod->x; if( rc!=SQLITE_OK ){ @@ -226822,7 +229306,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2020-12-01 16:14:00 0000000000000000000000000000000000000000000000000000000000000000", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2021-04-19 18:32:05 1b256d97b553a9611efca188a3d995a2fff712759044ba480f9a0c9e98fae886", -1, SQLITE_TRANSIENT); } /* @@ -231748,9 +234232,9 @@ SQLITE_API int sqlite3_stmt_init( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ -#if __LINE__!=231751 +#if __LINE__!=234235 #undef SQLITE_SOURCE_ID -#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 b7738010bc8ef02ba84820368e557306390a33c38adaa5c7703154bae3edalt2" +#define SQLITE_SOURCE_ID "2021-04-19 18:32:05 1b256d97b553a9611efca188a3d995a2fff712759044ba480f9a0c9e98faalt2" #endif /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } diff --git a/chromium/third_party/sqlite/src/amalgamation_dev/sqlite3.h b/chromium/third_party/sqlite/src/amalgamation_dev/sqlite3.h index 44be7872663..19ee767fe86 100644 --- a/chromium/third_party/sqlite/src/amalgamation_dev/sqlite3.h +++ b/chromium/third_party/sqlite/src/amalgamation_dev/sqlite3.h @@ -123,9 +123,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.34.0" -#define SQLITE_VERSION_NUMBER 3034000 -#define SQLITE_SOURCE_ID "2020-12-01 16:14:00 b7738010bc8ef02ba84820368e557306390a33c38adaa5c7703154bae3edalt1" +#define SQLITE_VERSION "3.35.5" +#define SQLITE_VERSION_NUMBER 3035005 +#define SQLITE_SOURCE_ID "2021-04-19 18:32:05 1b256d97b553a9611efca188a3d995a2fff712759044ba480f9a0c9e98fae886" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -2115,7 +2115,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. </dd> +** which case the trigger setting is not reported back. +** +** <p>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.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] ** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt> @@ -2126,7 +2132,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. </dd> +** which case the view setting is not reported back. +** +** <p>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.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> @@ -3499,6 +3511,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** that uses dot-files in place of posix advisory locking. ** <tr><td> file:data.db?mode=readonly <td> ** An error. "readonly" is not a valid option for the "mode" parameter. +** Use "ro" instead: "file:data.db?mode=ro". ** </table> ** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and @@ -3697,7 +3710,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 @@ -7765,7 +7778,8 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 #define SQLITE_TESTCTRL_SEEK_COUNT 30 -#define SQLITE_TESTCTRL_LAST 30 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_TRACEFLAGS 31 +#define SQLITE_TESTCTRL_LAST 31 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -10439,6 +10453,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 ** @@ -10540,18 +10562,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/chromium/third_party/sqlite/src/autoconf/Makefile.msc b/chromium/third_party/sqlite/src/autoconf/Makefile.msc index 746162a00c0..1f177557a25 100644 --- a/chromium/third_party/sqlite/src/autoconf/Makefile.msc +++ b/chromium/third_party/sqlite/src/autoconf/Makefile.msc @@ -303,6 +303,9 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1 !ENDIF +# Always enable math functions on Windows +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MATH_FUNCTIONS + # Should the rbu extension be enabled? If so, add compilation options # to enable it. # diff --git a/chromium/third_party/sqlite/src/autoconf/configure.ac b/chromium/third_party/sqlite/src/autoconf/configure.ac index 167626d59ee..e050786bd71 100644 --- a/chromium/third_party/sqlite/src/autoconf/configure.ac +++ b/chromium/third_party/sqlite/src/autoconf/configure.ac @@ -87,7 +87,9 @@ AC_SUBST(READLINE_LIBS) AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING( [--enable-threadsafe], [build a thread-safe library [default=yes]])], [], [enable_threadsafe=yes]) -if test x"$enable_threadsafe" != "xno"; then +if test x"$enable_threadsafe" == "xno"; then + BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_THREADSAFE=0" +else BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1" AC_SEARCH_LIBS(pthread_create, pthread) AC_SEARCH_LIBS(pthread_mutexattr_init, pthread) @@ -110,13 +112,33 @@ AC_MSG_RESULT($enable_dynamic_extensions) #----------------------------------------------------------------------- #----------------------------------------------------------------------- +# --enable-math +# +AC_ARG_ENABLE(math, [AS_HELP_STRING( + [--enable-math], [SQL math functions [default=yes]])], + [], [enable_math=yes]) +AC_MSG_CHECKING([SQL math functions]) +if test x"$enable_math" = "xyes"; then + BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_MATH_FUNCTIONS" + AC_MSG_RESULT([enabled]) + AC_SEARCH_LIBS(ceil, m) +else + AC_MSG_RESULT([disabled]) +fi +#----------------------------------------------------------------------- + +#----------------------------------------------------------------------- # --enable-fts4 # AC_ARG_ENABLE(fts4, [AS_HELP_STRING( [--enable-fts4], [include fts4 support [default=yes]])], [], [enable_fts4=yes]) +AC_MSG_CHECKING([FTS4 extension]) if test x"$enable_fts4" = "xyes"; then BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4" + AC_MSG_RESULT([enabled]) +else + AC_MSG_RESULT([disabled]) fi #----------------------------------------------------------------------- @@ -126,8 +148,12 @@ fi AC_ARG_ENABLE(fts3, [AS_HELP_STRING( [--enable-fts3], [include fts3 support [default=no]])], [], []) +AC_MSG_CHECKING([FTS3 extension]) if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3" + AC_MSG_RESULT([enabled]) +else + AC_MSG_RESULT([disabled]) fi #----------------------------------------------------------------------- @@ -137,9 +163,13 @@ fi AC_ARG_ENABLE(fts5, [AS_HELP_STRING( [--enable-fts5], [include fts5 support [default=yes]])], [], [enable_fts5=yes]) +AC_MSG_CHECKING([FTS5 extension]) if test x"$enable_fts5" = "xyes"; then + AC_MSG_RESULT([enabled]) AC_SEARCH_LIBS(log, m) BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5" +else + AC_MSG_RESULT([disabled]) fi #----------------------------------------------------------------------- @@ -149,8 +179,12 @@ fi AC_ARG_ENABLE(json1, [AS_HELP_STRING( [--enable-json1], [include json1 support [default=yes]])], [],[enable_json1=yes]) +AC_MSG_CHECKING([JSON functions]) if test x"$enable_json1" = "xyes"; then BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1" + AC_MSG_RESULT([enabled]) +else + AC_MSG_RESULT([disabled]) fi #----------------------------------------------------------------------- @@ -160,8 +194,12 @@ fi AC_ARG_ENABLE(rtree, [AS_HELP_STRING( [--enable-rtree], [include rtree support [default=yes]])], [], [enable_rtree=yes]) +AC_MSG_CHECKING([RTREE extension]) if test x"$enable_rtree" = "xyes"; then BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY" + AC_MSG_RESULT([enabled]) +else + AC_MSG_RESULT([disabled]) fi #----------------------------------------------------------------------- @@ -171,8 +209,12 @@ fi AC_ARG_ENABLE(session, [AS_HELP_STRING( [--enable-session], [enable the session extension [default=no]])], [], []) +AC_MSG_CHECKING([Session extension]) if test x"$enable_session" = "xyes"; then BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK" + AC_MSG_RESULT([enabled]) +else + AC_MSG_RESULT([disabled]) fi #----------------------------------------------------------------------- @@ -182,9 +224,13 @@ fi AC_ARG_ENABLE(debug, [AS_HELP_STRING( [--enable-debug], [build with debugging features enabled [default=no]])], [], []) +AC_MSG_CHECKING([Build type]) if test x"$enable_debug" = "xyes"; then BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE" CFLAGS="-g -O0" + AC_MSG_RESULT([debug]) +else + AC_MSG_RESULT([release]) fi #----------------------------------------------------------------------- diff --git a/chromium/third_party/sqlite/src/configure b/chromium/third_party/sqlite/src/configure index a03d6fdb3ae..64ee8f7c164 100755 --- a/chromium/third_party/sqlite/src/configure +++ b/chromium/third_party/sqlite/src/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sqlite 3.34.0. +# Generated by GNU Autoconf 2.69 for sqlite 3.35.5. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -726,8 +726,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.34.0' -PACKAGE_STRING='sqlite 3.34.0' +PACKAGE_VERSION='3.35.5' +PACKAGE_STRING='sqlite 3.35.5' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -903,9 +903,10 @@ with_readline_inc enable_debug enable_amalgamation enable_load_extension +enable_math +enable_all enable_memsys5 enable_memsys3 -enable_all enable_fts3 enable_fts4 enable_fts5 @@ -1466,7 +1467,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.34.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.35.5 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1531,7 +1532,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.34.0:";; + short | recursive ) echo "Configuration of sqlite 3.35.5:";; esac cat <<\_ACEOF @@ -1557,9 +1558,10 @@ Optional Features: separately --disable-load-extension Disable loading of external extensions + --disable-math Disable math functions + --enable-all Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions --enable-memsys5 Enable MEMSYS5 --enable-memsys3 Enable MEMSYS3 - --enable-all Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions --enable-fts3 Enable the FTS3 extension --enable-fts4 Enable the FTS4 extension --enable-fts5 Enable the FTS5 extension @@ -1658,7 +1660,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.34.0 +sqlite configure 3.35.5 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2077,7 +2079,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.34.0, which was +It was created by sqlite $as_me 3.35.5, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3935,13 +3937,13 @@ if ${lt_cv_nm_interface+:} false; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3938: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3940: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3941: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3943: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3944: output\"" >&5) + (eval echo "\"\$as_me:3946: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5147,7 +5149,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5150 "configure"' > conftest.$ac_ext + echo '#line 5152 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6672,11 +6674,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6675: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6677: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6679: \$? = $ac_status" >&5 + echo "$as_me:6681: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7011,11 +7013,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7014: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7016: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7018: \$? = $ac_status" >&5 + echo "$as_me:7020: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7116,11 +7118,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7119: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7121: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7123: \$? = $ac_status" >&5 + echo "$as_me:7125: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7171,11 +7173,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7174: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7176: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7178: \$? = $ac_status" >&5 + echo "$as_me:7180: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9551,7 +9553,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9554 "configure" +#line 9556 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9647,7 +9649,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9650 "configure" +#line 9652 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10364,8 +10366,10 @@ fi if test "x${TCLLIBDIR+set}" != "xset" ; then TCLLIBDIR='$(libdir)' for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do - TCLLIBDIR=$i - break + if test -d $i ; then + TCLLIBDIR=$i + break + fi done TCLLIBDIR="${TCLLIBDIR}/sqlite3" fi @@ -11247,10 +11251,16 @@ if test "${enable_debug+set}" = set; then : enableval=$enable_debug; fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build type" >&5 +$as_echo_n "checking build type... " >&6; } if test "${enable_debug}" = "yes" ; then TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: debug" >&5 +$as_echo "debug" >&6; } else TARGET_DEBUG="-DNDEBUG" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: release" >&5 +$as_echo "release" >&6; } fi @@ -11412,6 +11422,91 @@ else fi ########## +# Do we want to support math functions +# +# Check whether --enable-math was given. +if test "${enable_math+set}" = set; then : + enableval=$enable_math; +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support math functions" >&5 +$as_echo_n "checking whether to support math functions... " >&6; } +if test "$enable_math" = "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ceil" >&5 +$as_echo_n "checking for library containing ceil... " >&6; } +if ${ac_cv_search_ceil+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ceil (); +int +main () +{ +return ceil (); + ; + return 0; +} +_ACEOF +for ac_lib in '' m; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_ceil=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_ceil+:} false; then : + break +fi +done +if ${ac_cv_search_ceil+:} false; then : + +else + ac_cv_search_ceil=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ceil" >&5 +$as_echo "$ac_cv_search_ceil" >&6; } +ac_res=$ac_cv_search_ceil +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + + +######## +# The --enable-all argument is short-hand to enable +# multiple extensions. +# Check whether --enable-all was given. +if test "${enable_all+set}" = set; then : + enableval=$enable_all; +fi + + +########## # Do we want to support memsys3 and/or memsys5 # # Check whether --enable-memsys5 was given. @@ -11445,15 +11540,6 @@ else $as_echo "no" >&6; } fi -######## -# The --enable-extensions argument is short-hand to enable -# multiple extensions. -# Check whether --enable-all was given. -if test "${enable_all+set}" = set; then : - enableval=$enable_all; -fi - - ######### # See whether we should enable Full Text Search extensions # Check whether --enable-fts3 was given. @@ -11461,15 +11547,26 @@ if test "${enable_fts3+set}" = set; then : enableval=$enable_fts3; fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS3" >&5 +$as_echo_n "checking whether to support FTS3... " >&6; } if test "${enable_fts3}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi # Check whether --enable-fts4 was given. if test "${enable_fts4+set}" = set; then : enableval=$enable_fts4; fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS4" >&5 +$as_echo_n "checking whether to support FTS4... " >&6; } if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5 $as_echo_n "checking for library containing log... " >&6; } @@ -11527,13 +11624,20 @@ if test "$ac_res" != no; then : fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi # Check whether --enable-fts5 was given. if test "${enable_fts5+set}" = set; then : enableval=$enable_fts5; fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS5" >&5 +$as_echo_n "checking whether to support FTS5... " >&6; } if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5 $as_echo_n "checking for library containing log... " >&6; } @@ -11591,6 +11695,9 @@ if test "$ac_res" != no; then : fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi ######### @@ -11600,8 +11707,15 @@ if test "${enable_json1+set}" = set; then : enableval=$enable_json1; fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support JSON" >&5 +$as_echo_n "checking whether to support JSON... " >&6; } if test "${enable_json1}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi ######### @@ -11612,8 +11726,15 @@ if test "${enable_update_limit+set}" = set; then : enableval=$enable_update_limit; fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support LIMIT on UPDATE and DELETE statements" >&5 +$as_echo_n "checking whether to support LIMIT on UPDATE and DELETE statements... " >&6; } if test "${enable_update_limit}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi ######### @@ -11625,9 +11746,16 @@ else enable_geopoly=no fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support GEOPOLY" >&5 +$as_echo_n "checking whether to support GEOPOLY... " >&6; } if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY" enable_rtree=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi ######### @@ -11637,8 +11765,15 @@ if test "${enable_rtree+set}" = set; then : enableval=$enable_rtree; fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support RTREE" >&5 +$as_echo_n "checking whether to support RTREE... " >&6; } if test "${enable_rtree}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi ######### @@ -11648,9 +11783,16 @@ if test "${enable_session+set}" = set; then : enableval=$enable_session; fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support SESSION" >&5 +$as_echo_n "checking whether to support SESSION... " >&6; } if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION" OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi ######### @@ -12236,7 +12378,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.34.0, which was +This file was extended by sqlite $as_me 3.35.5, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12302,7 +12444,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sqlite config.status 3.34.0 +sqlite config.status 3.35.5 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/chromium/third_party/sqlite/src/configure.ac b/chromium/third_party/sqlite/src/configure.ac index bb8f4bd5637..70664dd4110 100644 --- a/chromium/third_party/sqlite/src/configure.ac +++ b/chromium/third_party/sqlite/src/configure.ac @@ -134,8 +134,10 @@ AC_ARG_VAR([TCLLIBDIR], [Where to install tcl plugin]) if test "x${TCLLIBDIR+set}" != "xset" ; then TCLLIBDIR='$(libdir)' for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do - TCLLIBDIR=$i - break + if test -d $i ; then + TCLLIBDIR=$i + break + fi done TCLLIBDIR="${TCLLIBDIR}/sqlite3" fi @@ -553,10 +555,13 @@ AC_SEARCH_LIBS(fdatasync, [rt]) ######### # check for debug enabled AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],[enable debugging & verbose explain])) +AC_MSG_CHECKING([build type]) if test "${enable_debug}" = "yes" ; then TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0" + AC_MSG_RESULT([debug]) else TARGET_DEBUG="-DNDEBUG" + AC_MSG_RESULT([release]) fi AC_SUBST(TARGET_DEBUG) @@ -587,6 +592,27 @@ else fi ########## +# Do we want to support math functions +# +AC_ARG_ENABLE(math, +AC_HELP_STRING([--disable-math],[Disable math functions])) +AC_MSG_CHECKING([whether to support math functions]) +if test "$enable_math" = "no"; then + AC_MSG_RESULT([no]) +else + AC_MSG_RESULT([yes]) + OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS" + AC_SEARCH_LIBS(ceil, m) +fi + + +######## +# The --enable-all argument is short-hand to enable +# multiple extensions. +AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all], + [Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions])) + +########## # Do we want to support memsys3 and/or memsys5 # AC_ARG_ENABLE(memsys5, @@ -608,37 +634,47 @@ else AC_MSG_RESULT([no]) fi -######## -# The --enable-extensions argument is short-hand to enable -# multiple extensions. -AC_ARG_ENABLE(all, AC_HELP_STRING([--enable-all], - [Enable FTS4, FTS5, Geopoly, JSON, RTree, Sessions])) - ######### # See whether we should enable Full Text Search extensions AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3], [Enable the FTS3 extension])) +AC_MSG_CHECKING([whether to support FTS3]) if test "${enable_fts3}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) fi AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4], [Enable the FTS4 extension])) +AC_MSG_CHECKING([whether to support FTS4]) if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then + AC_MSG_RESULT([yes]) OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4" AC_SEARCH_LIBS([log],[m]) +else + AC_MSG_RESULT([no]) fi AC_ARG_ENABLE(fts5, AC_HELP_STRING([--enable-fts5], [Enable the FTS5 extension])) +AC_MSG_CHECKING([whether to support FTS5]) if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then + AC_MSG_RESULT([yes]) OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5" AC_SEARCH_LIBS([log],[m]) +else + AC_MSG_RESULT([no]) fi ######### # See whether we should enable JSON1 AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],[Enable the JSON1 extension])) +AC_MSG_CHECKING([whether to support JSON]) if test "${enable_json1}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) fi ######### @@ -646,8 +682,12 @@ fi # statements. AC_ARG_ENABLE(update-limit, AC_HELP_STRING([--enable-update-limit], [Enable the UPDATE/DELETE LIMIT clause])) +AC_MSG_CHECKING([whether to support LIMIT on UPDATE and DELETE statements]) if test "${enable_update_limit}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) fi ######### @@ -655,26 +695,38 @@ fi AC_ARG_ENABLE(geopoly, AC_HELP_STRING([--enable-geopoly], [Enable the GEOPOLY extension]), [enable_geopoly=yes],[enable_geopoly=no]) +AC_MSG_CHECKING([whether to support GEOPOLY]) if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY" enable_rtree=yes + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) fi ######### # See whether we should enable RTREE AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree], [Enable the RTREE extension])) +AC_MSG_CHECKING([whether to support RTREE]) if test "${enable_rtree}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) fi ######### # See whether we should enable the SESSION extension AC_ARG_ENABLE(session, AC_HELP_STRING([--enable-session], [Enable the SESSION extension])) +AC_MSG_CHECKING([whether to support SESSION]) if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION" OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK" + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) fi ######### diff --git a/chromium/third_party/sqlite/src/doc/lemon.html b/chromium/third_party/sqlite/src/doc/lemon.html index bd078c8ec71..457004627e4 100644 --- a/chromium/third_party/sqlite/src/doc/lemon.html +++ b/chromium/third_party/sqlite/src/doc/lemon.html @@ -1077,7 +1077,7 @@ can choose a different start symbol using the <a id='syntax_error'></a> <h4>4.4.19 The <tt>%syntax_error</tt> directive</h4> -<p>See <a href='#error_processing'>Error Processing</a>.</p> +<p>See <a href='#errors'>Error Processing</a>.</p> <a id='token_class'></a> <h4>4.4.20 The <tt>%token_class</tt> directive</h4> @@ -1176,7 +1176,7 @@ match any input token.</p> the wildcard token and some other token, the other token is always used. The wildcard token is only matched if there are no alternatives.</p> -<a id='error_processing'></a> +<a id='errors'></a> <h2>5.0 Error Processing</h2> <p>After extensive experimentation over several years, it has been diff --git a/chromium/third_party/sqlite/src/ext/expert/expert1.test b/chromium/third_party/sqlite/src/ext/expert/expert1.test index f49f1f5e5c0..0e6fc826049 100644 --- a/chromium/third_party/sqlite/src/ext/expert/expert1.test +++ b/chromium/third_party/sqlite/src/ext/expert/expert1.test @@ -28,6 +28,7 @@ if {[info commands sqlite3_expert_new]==""} { return } + set CLI [test_binary_name sqlite3] set CMD [test_binary_name sqlite3_expert] @@ -367,6 +368,29 @@ do_setup_rec_test $tn.17.5 { SEARCH TABLE example USING INDEX example_idx_0000cb3f (B=? AND A>?) } +do_setup_rec_test $tn.18.0 { + CREATE TABLE SomeObject ( + a INTEGER PRIMARY KEY, + x TEXT GENERATED ALWAYS AS(HEX(a)) VIRTUAL + ); +} { + SELECT x FROM SomeObject; +} { + (no new indexes) + SCAN TABLE SomeObject +} +do_setup_rec_test $tn.18.1 { + CREATE TABLE SomeObject ( + a INTEGER PRIMARY KEY, + x TEXT GENERATED ALWAYS AS(HEX(a)) VIRTUAL + ); +} { + SELECT * FROM SomeObject WHERE x=?; +} { + CREATE INDEX SomeObject_idx_00000078 ON SomeObject(x); + SEARCH TABLE SomeObject USING COVERING INDEX SomeObject_idx_00000078 (x=?) +} + } proc do_candidates_test {tn sql res} { @@ -430,5 +454,5 @@ do_execsql_test 5.3 { t2 t2_idx_0001295b {100 20 5} } - finish_test + diff --git a/chromium/third_party/sqlite/src/ext/expert/sqlite3expert.c b/chromium/third_party/sqlite/src/ext/expert/sqlite3expert.c index c2a6fe3ba9f..863c6a34098 100644 --- a/chromium/third_party/sqlite/src/ext/expert/sqlite3expert.c +++ b/chromium/third_party/sqlite/src/ext/expert/sqlite3expert.c @@ -687,7 +687,7 @@ static int idxGetTableInfo( char *pCsr = 0; int nPk = 0; - rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab); + rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_xinfo=%Q", zTab); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ const char *zCol = (const char*)sqlite3_column_text(p1, 1); nByte += 1 + STRLEN(zCol); @@ -1721,10 +1721,12 @@ static int idxPopulateStat1(sqlite3expert *p, char **pzErr){ idxFinalize(&rc, pIndexXInfo); idxFinalize(&rc, pWrite); - for(i=0; i<pCtx->nSlot; i++){ - sqlite3_free(pCtx->aSlot[i].z); + if( pCtx ){ + for(i=0; i<pCtx->nSlot; i++){ + sqlite3_free(pCtx->aSlot[i].z); + } + sqlite3_free(pCtx); } - sqlite3_free(pCtx); if( rc==SQLITE_OK ){ rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0); diff --git a/chromium/third_party/sqlite/src/ext/fts3/fts3.c b/chromium/third_party/sqlite/src/ext/fts3/fts3.c index 79dc5c88cea..50fa88db8ab 100644 --- a/chromium/third_party/sqlite/src/ext/fts3/fts3.c +++ b/chromium/third_party/sqlite/src/ext/fts3/fts3.c @@ -5212,9 +5212,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; } diff --git a/chromium/third_party/sqlite/src/ext/fts3/fts3_expr.c b/chromium/third_party/sqlite/src/ext/fts3/fts3_expr.c index e19137a03db..7a69a935f0c 100644 --- a/chromium/third_party/sqlite/src/ext/fts3/fts3_expr.c +++ b/chromium/third_party/sqlite/src/ext/fts3/fts3_expr.c @@ -493,6 +493,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; diff --git a/chromium/third_party/sqlite/src/ext/fts3/fts3_unicode.c b/chromium/third_party/sqlite/src/ext/fts3/fts3_unicode.c index b06d9921447..2fd4b39fb77 100644 --- a/chromium/third_party/sqlite/src/ext/fts3/fts3_unicode.c +++ b/chromium/third_party/sqlite/src/ext/fts3/fts3_unicode.c @@ -285,6 +285,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{ diff --git a/chromium/third_party/sqlite/src/ext/fts3/fts3_write.c b/chromium/third_party/sqlite/src/ext/fts3/fts3_write.c index 092cad9ac5f..bc42fc3d639 100644 --- a/chromium/third_party/sqlite/src/ext/fts3/fts3_write.c +++ b/chromium/third_party/sqlite/src/ext/fts3/fts3_write.c @@ -4335,17 +4335,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; diff --git a/chromium/third_party/sqlite/src/ext/fts5/fts5_expr.c b/chromium/third_party/sqlite/src/ext/fts5/fts5_expr.c index 392dde3ab49..088d8b8caec 100644 --- a/chromium/third_party/sqlite/src/ext/fts5/fts5_expr.c +++ b/chromium/third_party/sqlite/src/ext/fts5/fts5_expr.c @@ -1500,8 +1500,8 @@ int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){ } /* 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; diff --git a/chromium/third_party/sqlite/src/ext/fts5/fts5_index.c b/chromium/third_party/sqlite/src/ext/fts5/fts5_index.c index f83488e2f69..7a9ad5d713f 100644 --- a/chromium/third_party/sqlite/src/ext/fts5/fts5_index.c +++ b/chromium/third_party/sqlite/src/ext/fts5/fts5_index.c @@ -2070,14 +2070,10 @@ 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; @@ -3069,7 +3065,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 ){ @@ -3082,6 +3078,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)); @@ -3133,66 +3132,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( p<pEnd && *p!=0x01 ){ - while( *p++ & 0x80 ); - } - - return p - (*pa); -} - static void fts5IndexExtractColset( int *pRc, Fts5Colset *pColset, /* Colset to filter on */ const u8 *pPos, int nPos, /* Position list */ - Fts5Buffer *pBuf /* Output buffer */ + Fts5Iter *pIter ){ if( *pRc==SQLITE_OK ){ - int i; - fts5BufferZero(pBuf); - for(i=0; i<pColset->nCol; 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]<iCurrent ){ + i++; + if( i==pColset->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( p<pEnd && *p!=0x01 ){ + while( *p++ & 0x80 ); + } + + if( pColset->aiCol[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); } } } + } /* @@ -3312,16 +3317,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 @@ -4804,7 +4802,7 @@ static void fts5AppendPoslist( static void fts5DoclistIterNext(Fts5DoclistIter *pIter){ u8 *p = pIter->aPoslist + pIter->nSize + pIter->nPoslist; - assert( pIter->aPoslist ); + assert( pIter->aPoslist || (p==0 && pIter->aPoslist==0) ); if( p>=pIter->aEof ){ pIter->aPoslist = 0; }else{ @@ -4824,6 +4822,9 @@ static void fts5DoclistIterNext(Fts5DoclistIter *pIter){ } pIter->aPoslist = p; + if( &pIter->aPoslist[pIter->nPoslist]>pIter->aEof ){ + pIter->aPoslist = 0; + } } } @@ -4832,9 +4833,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 @@ -4888,16 +4891,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; @@ -4924,180 +4931,213 @@ 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 */ + int nBuf, /* Number of buffers in array aBuf[] */ + Fts5Buffer *aBuf /* Other lists to merge in */ ){ - 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); - - while( 1 ){ - if( i1.iRowid<i2.iRowid ){ - /* Copy entry from i1 */ - fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid); - fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.nPoslist+i1.nSize); - fts5DoclistIterNext(&i1); - if( i1.aPoslist==0 ) break; - assert( out.n<=((i1.aPoslist-p1->p) + (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) ); +#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; i<nBuf; i++){ + fts5DoclistIterInit(&aBuf[i], &aMerger[i].iter); + fts5PrefixMergerInsertByRowid(&pHead, &aMerger[i]); + nOut += aBuf[i].n; + } + if( nOut==0 ) return; + nOut += p1->n + 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; } - 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 + FTS5_DATA_ZERO_PADDING - ); - if( p->rc ) break; - sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - assert_nc( iPos1>=0 && iPos2>=0 ); + if( pHead==0 || pHead->pNext==0 ){ + p->rc = FTS5_CORRUPT; + break; + } - if( iPos1<iPos2 ){ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); - sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - }else{ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); - sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - } - if( iPos1>=0 && iPos2>=0 ){ - while( 1 ){ - if( iPos1<iPos2 ){ - if( iPos1!=iPrev ){ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); - } - sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - if( iPos1<0 ) break; - }else{ - assert_nc( iPos2!=iPrev ); - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); - sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - if( iPos2<0 ) break; - } - } + /* 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; + } + fts5BufferZero(&tmp); + + 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); + } - 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); - } + if( pHead->iPos!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pHead->iPos); + } + nTail = pHead->iter.nPoslist - pHead->iOff; - /* 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; + /* WRITEPOSLISTSIZE */ + assert( tmp.n+nTail<=nTmp ); + 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; i<nBuf+1; i++){ + PrefixMerger *pX = &aMerger[i]; + if( pX->iter.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) ); - - fts5BufferFree(p1); - fts5BufferFree(&tmp); - memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING); - *p1 = 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; } @@ -5117,6 +5157,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 */ ; @@ -5137,13 +5198,21 @@ static void fts5SetupPrefixIter( if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ - assert( i<nBuf ); - if( aBuf[i].n==0 ){ - fts5BufferSwap(&doclist, &aBuf[i]); - fts5BufferZero(&doclist); - }else{ - xMerge(p, &doclist, &aBuf[i]); - fts5BufferZero(&aBuf[i]); + int i1 = i*nMerge; + int iStore; + assert( i1+nMerge<=nBuf ); + for(iStore=i1; iStore<i1+nMerge; iStore++){ + if( aBuf[iStore].n==0 ){ + fts5BufferSwap(&doclist, &aBuf[iStore]); + fts5BufferZero(&doclist); + break; + } + } + if( iStore==i1+nMerge ){ + xMerge(p, &doclist, nMerge, &aBuf[i1]); + for(iStore=i1; iStore<i1+nMerge; iStore++){ + fts5BufferZero(&aBuf[iStore]); + } } } iLastRowid = 0; @@ -5153,11 +5222,15 @@ static void fts5SetupPrefixIter( iLastRowid = p1->base.iRowid; } - for(i=0; i<nBuf; i++){ + assert( (nBuf%nMerge)==0 ); + for(i=0; i<nBuf; i+=nMerge){ + int iFree; if( p->rc==SQLITE_OK ){ - xMerge(p, &doclist, &aBuf[i]); + xMerge(p, &doclist, nMerge, &aBuf[i]); + } + for(iFree=i; iFree<i+nMerge; iFree++){ + fts5BufferFree(&aBuf[iFree]); } - fts5BufferFree(&aBuf[i]); } fts5MultiIterFree(p1); @@ -5412,6 +5485,7 @@ int sqlite3Fts5IndexQuery( if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ + int iPrefixIdx = 0; /* +1 prefix index */ if( nToken ) memcpy(&buf.p[1], pToken, nToken); /* Figure out which index to search and set iIdx accordingly. If this @@ -5433,7 +5507,9 @@ 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; } } @@ -5450,8 +5526,7 @@ 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); + fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet); assert( p->rc!=SQLITE_OK || pRet->pColset==0 ); fts5IterSetOutputCb(&p->rc, pRet); if( p->rc==SQLITE_OK ){ @@ -5524,8 +5599,9 @@ int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ 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); } /* diff --git a/chromium/third_party/sqlite/src/ext/fts5/fts5_main.c b/chromium/third_party/sqlite/src/ext/fts5/fts5_main.c index 788821e6b82..8a7af1894a5 100644 --- a/chromium/third_party/sqlite/src/ext/fts5/fts5_main.c +++ b/chromium/third_party/sqlite/src/ext/fts5/fts5_main.c @@ -2177,7 +2177,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); @@ -2236,7 +2237,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); } @@ -2244,7 +2246,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 ){ @@ -2722,7 +2725,7 @@ int sqlite3Fts5GetTokenizer( *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); }else{ rc = pMod->x.xCreate( - pMod->pUserData, &azArg[1], (nArg?nArg-1:0), &pConfig->pTok + pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok ); pConfig->pTokApi = &pMod->x; if( rc!=SQLITE_OK ){ diff --git a/chromium/third_party/sqlite/src/ext/fts5/fts5_test_tok.c b/chromium/third_party/sqlite/src/ext/fts5/fts5_test_tok.c index b5d4162fa83..a5d839da66e 100644 --- a/chromium/third_party/sqlite/src/ext/fts5/fts5_test_tok.c +++ b/chromium/third_party/sqlite/src/ext/fts5/fts5_test_tok.c @@ -211,7 +211,7 @@ static int fts5tokConnectMethod( rc = pApi->xFindTokenizer(pApi, zModule, &pTokCtx, &pTab->tok); if( rc==SQLITE_OK ){ - const char **azArg = (const char **)&azDequote[1]; + const char **azArg = (nDequote>1 ? (const char **)&azDequote[1] : 0); int nArg = nDequote>0 ? nDequote-1 : 0; rc = pTab->tok.xCreate(pTokCtx, azArg, nArg, &pTab->pTok); } diff --git a/chromium/third_party/sqlite/src/ext/misc/appendvfs.c b/chromium/third_party/sqlite/src/ext/misc/appendvfs.c index 14260efb52c..4ea5b1c2cb4 100644 --- a/chromium/third_party/sqlite/src/ext/misc/appendvfs.c +++ b/chromium/third_party/sqlite/src/ext/misc/appendvfs.c @@ -14,24 +14,23 @@ ** appended onto the end of some other file, such as an executable. ** ** A special record must appear at the end of the file that identifies the -** file as an appended database and provides an offset to page 1. For -** best performance page 1 should be located at a disk page boundary, though -** that is not required. +** file as an appended database and provides the offset to the first page +** of the exposed content. (Or, it is the length of the content prefix.) +** For best performance page 1 should be located at a disk page boundary, +** though that is not required. ** ** When opening a database using this VFS, the connection might treat -** the file as an ordinary SQLite database, or it might treat is as a -** database appended onto some other file. Here are the rules: +** the file as an ordinary SQLite database, or it might treat it as a +** database appended onto some other file. The decision is made by +** applying the following rules in order: ** -** (1) When opening a new empty file, that file is treated as an ordinary -** database. +** (1) An empty file is an ordinary database. ** -** (2) When opening a file that begins with the standard SQLite prefix -** string "SQLite format 3", that file is treated as an ordinary -** database. +** (2) If the file ends with the appendvfs trailer string +** "Start-Of-SQLite3-NNNNNNNN" that file is an appended database. ** -** (3) When opening a file that ends with the appendvfs trailer string -** "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended -** database. +** (3) If the file begins with the standard SQLite prefix string +** "SQLite format 3", that file is an ordinary database. ** ** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is ** set, then a new database is appended to the already existing file. @@ -39,13 +38,13 @@ ** (5) Otherwise, SQLITE_CANTOPEN is returned. ** ** To avoid unnecessary complications with the PENDING_BYTE, the size of -** the file containing the database is limited to 1GB. This VFS will refuse -** to read or write past the 1GB mark. This restriction might be lifted in -** future versions. For now, if you need a large database, then keep the -** database in a separate file. +** the file containing the database is limited to 1GiB. (1073741824 bytes) +** This VFS will not read or write past the 1GiB mark. This restriction +** might be lifted in future versions. For now, if you need a larger +** database, then keep it in a separate file. ** -** If the file being opened is not an appended database, then this shim is -** a pass-through into the default underlying VFS. +** If the file being opened is a plain database (not an appended one), then +** this shim is a pass-through into the default underlying VFS. (rule 3) **/ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 @@ -58,17 +57,27 @@ SQLITE_EXTENSION_INIT1 ** 123456789 123456789 12345 ** ** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is -** the offset to page 1. +** the offset to page 1, and also the length of the prefix content. */ #define APND_MARK_PREFIX "Start-Of-SQLite3-" #define APND_MARK_PREFIX_SZ 17 -#define APND_MARK_SIZE 25 +#define APND_MARK_FOS_SZ 8 +#define APND_MARK_SIZE (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ) /* ** Maximum size of the combined prefix + database + append-mark. This ** must be less than 0x40000000 to avoid locking issues on Windows. */ -#define APND_MAX_SIZE (65536*15259) +#define APND_MAX_SIZE (0x40000000) + +/* +** Try to align the database to an even multiple of APND_ROUNDUP bytes. +*/ +#ifndef APND_ROUNDUP +#define APND_ROUNDUP 4096 +#endif +#define APND_ALIGN_MASK ((sqlite3_int64)(APND_ROUNDUP-1)) +#define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK) /* ** Forward declaration of objects used by this utility @@ -82,11 +91,45 @@ typedef struct ApndFile ApndFile; #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) #define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1)) -/* An open file */ +/* An open appendvfs file +** +** An instance of this structure describes the appended database file. +** A separate sqlite3_file object is always appended. The appended +** sqlite3_file object (which can be accessed using ORIGFILE()) describes +** the entire file, including the prefix, the database, and the +** append-mark. +** +** The structure of an AppendVFS database is like this: +** +** +-------------+---------+----------+-------------+ +** | prefix-file | padding | database | append-mark | +** +-------------+---------+----------+-------------+ +** ^ ^ +** | | +** iPgOne iMark +** +** +** "prefix file" - file onto which the database has been appended. +** "padding" - zero or more bytes inserted so that "database" +** starts on an APND_ROUNDUP boundary +** "database" - The SQLite database file +** "append-mark" - The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates +** the offset from the start of prefix-file to the start +** of "database". +** +** The size of the database is iMark - iPgOne. +** +** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value +** of iPgOne stored as a big-ending 64-bit integer. +** +** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE). +** Or, iMark is -1 to indicate that it has not yet been written. +*/ struct ApndFile { - sqlite3_file base; /* IO methods */ - sqlite3_int64 iPgOne; /* File offset to page 1 */ - sqlite3_int64 iMark; /* Start of the append-mark */ + sqlite3_file base; /* Subclass. MUST BE FIRST! */ + sqlite3_int64 iPgOne; /* Offset to the start of the database */ + sqlite3_int64 iMark; /* Offset of the append mark. -1 if unwritten */ + /* Always followed by another sqlite3_file that describes the whole file */ }; /* @@ -178,8 +221,6 @@ static const sqlite3_io_methods apnd_io_methods = { apndUnfetch /* xUnfetch */ }; - - /* ** Close an apnd-file. */ @@ -197,22 +238,37 @@ static int apndRead( int iAmt, sqlite_int64 iOfst ){ - ApndFile *p = (ApndFile *)pFile; + ApndFile *paf = (ApndFile *)pFile; pFile = ORIGFILE(pFile); - return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst+p->iPgOne); + return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst); } /* -** Add the append-mark onto the end of the file. +** Add the append-mark onto what should become the end of the file. +* If and only if this succeeds, internal ApndFile.iMark is updated. +* Parameter iWriteEnd is the appendvfs-relative offset of the new mark. */ -static int apndWriteMark(ApndFile *p, sqlite3_file *pFile){ - int i; +static int apndWriteMark( + ApndFile *paf, + sqlite3_file *pFile, + sqlite_int64 iWriteEnd +){ + sqlite_int64 iPgOne = paf->iPgOne; unsigned char a[APND_MARK_SIZE]; + int i = APND_MARK_FOS_SZ; + int rc; + assert(pFile == ORIGFILE(paf)); memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ); - for(i=0; i<8; i++){ - a[APND_MARK_PREFIX_SZ+i] = (p->iPgOne >> (56 - i*8)) & 0xff; + while( --i >= 0 ){ + a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff); + iPgOne >>= 8; + } + iWriteEnd += paf->iPgOne; + if( SQLITE_OK==(rc = pFile->pMethods->xWrite + (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){ + paf->iMark = iWriteEnd; } - return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark); + return rc; } /* @@ -224,38 +280,28 @@ static int apndWrite( int iAmt, sqlite_int64 iOfst ){ - int rc; - ApndFile *p = (ApndFile *)pFile; + ApndFile *paf = (ApndFile *)pFile; + sqlite_int64 iWriteEnd = iOfst + iAmt; + if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL; pFile = ORIGFILE(pFile); - if( iOfst+iAmt>=APND_MAX_SIZE ) return SQLITE_FULL; - rc = pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst+p->iPgOne); - if( rc==SQLITE_OK && iOfst + iAmt + p->iPgOne > p->iMark ){ - sqlite3_int64 sz = 0; - rc = pFile->pMethods->xFileSize(pFile, &sz); - if( rc==SQLITE_OK ){ - p->iMark = sz - APND_MARK_SIZE; - if( iOfst + iAmt + p->iPgOne > p->iMark ){ - p->iMark = p->iPgOne + iOfst + iAmt; - rc = apndWriteMark(p, pFile); - } - } + /* If append-mark is absent or will be overwritten, write it. */ + if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){ + int rc = apndWriteMark(paf, pFile, iWriteEnd); + if( SQLITE_OK!=rc ) return rc; } - return rc; + return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst); } /* ** Truncate an apnd-file. */ static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){ - int rc; - ApndFile *p = (ApndFile *)pFile; + ApndFile *paf = (ApndFile *)pFile; pFile = ORIGFILE(pFile); - rc = pFile->pMethods->xTruncate(pFile, size+p->iPgOne+APND_MARK_SIZE); - if( rc==SQLITE_OK ){ - p->iMark = p->iPgOne+size; - rc = apndWriteMark(p, pFile); - } - return rc; + /* The append mark goes out first so truncate failure does not lose it. */ + if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR; + /* Truncate underlying file just past append mark */ + return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE); } /* @@ -268,16 +314,12 @@ static int apndSync(sqlite3_file *pFile, int flags){ /* ** Return the current file-size of an apnd-file. +** If the append mark is not yet there, the file-size is 0. */ static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ - ApndFile *p = (ApndFile *)pFile; - int rc; - pFile = ORIGFILE(p); - rc = pFile->pMethods->xFileSize(pFile, pSize); - if( rc==SQLITE_OK && p->iPgOne ){ - *pSize -= p->iPgOne + APND_MARK_SIZE; - } - return rc; + ApndFile *paf = (ApndFile *)pFile; + *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0; + return SQLITE_OK; } /* @@ -308,12 +350,13 @@ static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){ ** File control method. For custom operations on an apnd-file. */ static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){ - ApndFile *p = (ApndFile *)pFile; + ApndFile *paf = (ApndFile *)pFile; int rc; pFile = ORIGFILE(pFile); + if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne; rc = pFile->pMethods->xFileControl(pFile, op, pArg); if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){ - *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", p->iPgOne, *(char**)pArg); + *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg); } return rc; } @@ -372,6 +415,9 @@ static int apndFetch( void **pp ){ ApndFile *p = (ApndFile *)pFile; + if( p->iMark < 0 || iOfst+iAmt > p->iMark ){ + return SQLITE_IOERR; /* Cannot read what is not yet there. */ + } pFile = ORIGFILE(pFile); return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp); } @@ -384,94 +430,152 @@ static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ } /* -** Check to see if the file is an ordinary SQLite database file. -*/ -static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){ - int rc; - char zHdr[16]; - static const char aSqliteHdr[] = "SQLite format 3"; - if( sz<512 ) return 0; - rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0); - if( rc ) return 0; - return memcmp(zHdr, aSqliteHdr, sizeof(zHdr))==0; -} - -/* ** Try to read the append-mark off the end of a file. Return the -** start of the appended database if the append-mark is present. If -** there is no append-mark, return -1; +** start of the appended database if the append-mark is present. +** If there is no valid append-mark, return -1; +** +** An append-mark is only valid if the NNNNNNNN start-of-database offset +** indicates that the appended database contains at least one page. The +** start-of-database value must be a multiple of 512. */ static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){ int rc, i; sqlite3_int64 iMark; + int msbs = 8 * (APND_MARK_FOS_SZ-1); unsigned char a[APND_MARK_SIZE]; - if( sz<=APND_MARK_SIZE ) return -1; + if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1; rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE); if( rc ) return -1; if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1; - iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ]&0x7f))<<56; - for(i=1; i<8; i++){ - iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<(56-8*i); + iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs; + for(i=1; i<8; i++){ + msbs -= 8; + iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs; } + if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1; + if( iMark & 0x1ff ) return -1; return iMark; } +static const char apvfsSqliteHdr[] = "SQLite format 3"; +/* +** Check to see if the file is an appendvfs SQLite database file. +** Return true iff it is such. Parameter sz is the file's size. +*/ +static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){ + int rc; + char zHdr[16]; + sqlite3_int64 iMark = apndReadMark(sz, pFile); + if( iMark>=0 ){ + /* If file has the correct end-marker, the expected odd size, and the + ** SQLite DB type marker where the end-marker puts it, then it + ** is an appendvfs database. + */ + rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark); + if( SQLITE_OK==rc + && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0 + && (sz & 0x1ff) == APND_MARK_SIZE + && sz>=512+APND_MARK_SIZE + ){ + return 1; /* It's an appendvfs database */ + } + } + return 0; +} + +/* +** Check to see if the file is an ordinary SQLite database file. +** Return true iff so. Parameter sz is the file's size. +*/ +static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){ + char zHdr[16]; + if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */ + || (sz & 0x1ff) != 0 + || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0) + || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0 + ){ + return 0; + }else{ + return 1; + } +} + /* ** Open an apnd file handle. */ static int apndOpen( - sqlite3_vfs *pVfs, + sqlite3_vfs *pApndVfs, const char *zName, sqlite3_file *pFile, int flags, int *pOutFlags ){ - ApndFile *p; - sqlite3_file *pSubFile; - sqlite3_vfs *pSubVfs; + ApndFile *pApndFile = (ApndFile*)pFile; + sqlite3_file *pBaseFile = ORIGFILE(pFile); + sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs); int rc; - sqlite3_int64 sz; - pSubVfs = ORIGVFS(pVfs); + sqlite3_int64 sz = 0; if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){ - return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags); + /* The appendvfs is not to be used for transient or temporary databases. + ** Just use the base VFS open to initialize the given file object and + ** open the underlying file. (Appendvfs is then unused for this file.) + */ + return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags); } - p = (ApndFile*)pFile; - memset(p, 0, sizeof(*p)); - pSubFile = ORIGFILE(pFile); + memset(pApndFile, 0, sizeof(ApndFile)); pFile->pMethods = &apnd_io_methods; - rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags); - if( rc ) goto apnd_open_done; - rc = pSubFile->pMethods->xFileSize(pSubFile, &sz); + pApndFile->iMark = -1; /* Append mark not yet written */ + + rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags); + if( rc==SQLITE_OK ){ + rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz); + } if( rc ){ - pSubFile->pMethods->xClose(pSubFile); - goto apnd_open_done; + pBaseFile->pMethods->xClose(pBaseFile); + pFile->pMethods = 0; + return rc; } - if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){ - memmove(pFile, pSubFile, pSubVfs->szOsFile); + if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){ + /* The file being opened appears to be just an ordinary DB. Copy + ** the base dispatch-table so this instance mimics the base VFS. + */ + memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile); return SQLITE_OK; } - p->iMark = 0; - p->iPgOne = apndReadMark(sz, pFile); - if( p->iPgOne>0 ){ + pApndFile->iPgOne = apndReadMark(sz, pFile); + if( pApndFile->iPgOne>=0 ){ + pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */ return SQLITE_OK; } if( (flags & SQLITE_OPEN_CREATE)==0 ){ - pSubFile->pMethods->xClose(pSubFile); + pBaseFile->pMethods->xClose(pBaseFile); rc = SQLITE_CANTOPEN; + pFile->pMethods = 0; + }else{ + /* Round newly added appendvfs location to #define'd page boundary. + ** Note that nothing has yet been written to the underlying file. + ** The append mark will be written along with first content write. + ** Until then, paf->iMark value indicates it is not yet written. + */ + pApndFile->iPgOne = APND_START_ROUNDUP(sz); } - p->iPgOne = (sz+0xfff) & ~(sqlite3_int64)0xfff; -apnd_open_done: - if( rc ) pFile->pMethods = 0; return rc; } /* -** All other VFS methods are pass-thrus. +** Delete an apnd file. +** For an appendvfs, this could mean delete the appendvfs portion, +** leaving the appendee as it was before it gained an appendvfs. +** For now, this code deletes the underlying file too. */ static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync); } + +/* +** All other VFS methods are pass-thrus. +*/ static int apndAccess( sqlite3_vfs *pVfs, const char *zPath, diff --git a/chromium/third_party/sqlite/src/ext/misc/cksumvfs.c b/chromium/third_party/sqlite/src/ext/misc/cksumvfs.c index a0888c0024d..0f6b00f4361 100644 --- a/chromium/third_party/sqlite/src/ext/misc/cksumvfs.c +++ b/chromium/third_party/sqlite/src/ext/misc/cksumvfs.c @@ -356,6 +356,41 @@ static void cksmVerifyFunc( sqlite3_result_int(context, memcmp(data+nByte-8,cksum,8)==0); } +#ifdef SQLITE_CKSUMVFS_INIT_FUNCNAME +/* +** SQL function: initialize_cksumvfs(SCHEMANAME) +** +** This SQL functions (whose name is actually determined at compile-time +** by the value of the SQLITE_CKSUMVFS_INIT_FUNCNAME macro) invokes: +** +** sqlite3_file_control(db, SCHEMANAME, SQLITE_FCNTL_RESERVE_BYTE, &n); +** +** In order to set the reserve bytes value to 8, so that cksumvfs will +** operation. This feature is provided (if and only if the +** SQLITE_CKSUMVFS_INIT_FUNCNAME compile-time option is set to a string +** which is the name of the SQL function) so as to provide the ability +** to invoke the file-control in programming languages that lack +** direct access to the sqlite3_file_control() interface (ex: Java). +** +** This interface is undocumented, apart from this comment. Usage +** example: +** +** 1. Compile with -DSQLITE_CKSUMVFS_INIT_FUNCNAME="ckvfs_init" +** 2. Run: "SELECT cksum_init('main'); VACUUM;" +*/ +static void cksmInitFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int nByte = 8; + const char *zSchemaName = (const char*)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3_file_control(db, zSchemaName, SQLITE_FCNTL_RESERVE_BYTES, &nByte); + /* Return NULL */ +} +#endif /* SQLITE_CKSUMBFS_INIT_FUNCNAME */ + /* ** Close a cksm-file. */ @@ -715,7 +750,17 @@ static int cksmGetLastError(sqlite3_vfs *pVfs, int a, char *b){ return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); } static int cksmCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ - return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); + sqlite3_vfs *pOrig = ORIGVFS(pVfs); + int rc; + assert( pOrig->iVersion>=2 ); + if( pOrig->xCurrentTimeInt64 ){ + rc = pOrig->xCurrentTimeInt64(pOrig, p); + }else{ + double r; + rc = pOrig->xCurrentTime(pOrig, &r); + *p = (sqlite3_int64)(r*86400000.0); + } + return rc; } static int cksmSetSystemCall( sqlite3_vfs *pVfs, @@ -746,6 +791,11 @@ static int cksmRegisterFunc( rc = sqlite3_create_function(db, "verify_checksum", 1, SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, 0, cksmVerifyFunc, 0, 0); +#ifdef SQLITE_CKSUMVFS_INIT_FUNCNAME + (void)sqlite3_create_function(db, SQLITE_CKSUMVFS_INIT_FUNCNAME, 1, + SQLITE_UTF8|SQLITE_DIRECTONLY, + 0, cksmInitFunc, 0, 0); +#endif return rc; } diff --git a/chromium/third_party/sqlite/src/ext/misc/ieee754.c b/chromium/third_party/sqlite/src/ext/misc/ieee754.c index 121eb43d66f..6cdd79a4d4e 100644 --- a/chromium/third_party/sqlite/src/ext/misc/ieee754.c +++ b/chromium/third_party/sqlite/src/ext/misc/ieee754.c @@ -167,6 +167,14 @@ static void ieee754func( int isNeg = 0; m = sqlite3_value_int64(argv[0]); e = sqlite3_value_int64(argv[1]); + + /* Limit the range of e. Ticket 22dea1cfdb9151e4 2021-03-02 */ + if( e>10000 ){ + e = 10000; + }else if( e<-10000 ){ + e = -10000; + } + if( m<0 ){ isNeg = 1; m = -m; diff --git a/chromium/third_party/sqlite/src/ext/misc/series.c b/chromium/third_party/sqlite/src/ext/misc/series.c index 092383e57e7..a4e92ace883 100644 --- a/chromium/third_party/sqlite/src/ext/misc/series.c +++ b/chromium/third_party/sqlite/src/ext/misc/series.c @@ -247,7 +247,8 @@ static int seriesEof(sqlite3_vtab_cursor *cur){ ** 4: step=VALUE ** ** Also, if bit 8 is set, that means that the series should be output -** in descending order rather than in ascending order. +** in descending order rather than in ascending order. If bit 16 is +** set, then output must appear in ascending order. ** ** This routine should initialize the cursor and position it so that it ** is pointing at the first row, or pointing off the end of the table @@ -273,7 +274,12 @@ static int seriesFilter( } if( idxNum & 4 ){ pCur->iStep = sqlite3_value_int64(argv[i++]); - if( pCur->iStep<1 ) pCur->iStep = 1; + if( pCur->iStep==0 ){ + pCur->iStep = 1; + }else if( pCur->iStep<0 ){ + pCur->iStep = -pCur->iStep; + if( (idxNum & 16)==0 ) idxNum |= 8; + } }else{ pCur->iStep = 1; } @@ -367,7 +373,11 @@ static int seriesBestIndex( pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0)); pIdxInfo->estimatedRows = 1000; if( pIdxInfo->nOrderBy==1 ){ - if( pIdxInfo->aOrderBy[0].desc ) idxNum |= 8; + if( pIdxInfo->aOrderBy[0].desc ){ + idxNum |= 8; + }else{ + idxNum |= 16; + } pIdxInfo->orderByConsumed = 1; } }else{ diff --git a/chromium/third_party/sqlite/src/ext/misc/shathree.c b/chromium/third_party/sqlite/src/ext/misc/shathree.c index 56eba564ce3..ef25cb56c6d 100644 --- a/chromium/third_party/sqlite/src/ext/misc/shathree.c +++ b/chromium/third_party/sqlite/src/ext/misc/shathree.c @@ -31,7 +31,10 @@ SQLITE_EXTENSION_INIT1 #include <assert.h> #include <string.h> #include <stdarg.h> + +#ifndef SQLITE_AMALGAMATION typedef sqlite3_uint64 u64; +#endif /* SQLITE_AMALGAMATION */ /****************************************************************************** ** The Hash Engine @@ -621,9 +624,11 @@ static void sha3QueryFunc( } nCol = sqlite3_column_count(pStmt); z = sqlite3_sql(pStmt); - n = (int)strlen(z); - hash_step_vformat(&cx,"S%d:",n); - SHA3Update(&cx,(unsigned char*)z,n); + if( z ){ + n = (int)strlen(z); + hash_step_vformat(&cx,"S%d:",n); + SHA3Update(&cx,(unsigned char*)z,n); + } /* Compute a hash over the result of the query */ while( SQLITE_ROW==sqlite3_step(pStmt) ){ diff --git a/chromium/third_party/sqlite/src/ext/misc/wholenumber.c b/chromium/third_party/sqlite/src/ext/misc/wholenumber.c index 5643f9cf7e7..03d6e6902e0 100644 --- a/chromium/third_party/sqlite/src/ext/misc/wholenumber.c +++ b/chromium/third_party/sqlite/src/ext/misc/wholenumber.c @@ -220,7 +220,7 @@ static int wholenumberBestIndex( pIdxInfo->orderByConsumed = 1; } if( (idxNum & 12)==0 ){ - pIdxInfo->estimatedCost = (double)100000000; + pIdxInfo->estimatedCost = 1e99; }else if( (idxNum & 3)==0 ){ pIdxInfo->estimatedCost = (double)5; }else{ diff --git a/chromium/third_party/sqlite/src/ext/rbu/rbu.c b/chromium/third_party/sqlite/src/ext/rbu/rbu.c index 02822c4a429..91773409cf8 100644 --- a/chromium/third_party/sqlite/src/ext/rbu/rbu.c +++ b/chromium/third_party/sqlite/src/ext/rbu/rbu.c @@ -183,6 +183,13 @@ int main(int argc, char **argv){ break; } + if( nStatStep>0 ){ + sqlite3_int64 nUsed; + sqlite3_int64 nHighwater; + sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &nUsed, &nHighwater, 0); + fprintf(stdout, "memory used=%lld highwater=%lld\n", nUsed, nHighwater); + } + sqlite3_free(zErrmsg); return (rc==SQLITE_OK || rc==SQLITE_DONE) ? 0 : 1; } diff --git a/chromium/third_party/sqlite/src/ext/rbu/rbudiff.test b/chromium/third_party/sqlite/src/ext/rbu/rbudiff.test index 965ce297e33..5c2bf9bee7b 100644 --- a/chromium/third_party/sqlite/src/ext/rbu/rbudiff.test +++ b/chromium/third_party/sqlite/src/ext/rbu/rbudiff.test @@ -268,6 +268,14 @@ tablE t1 USING FTs5(c); DELETE FROM t1 WHERE rowid = 1; INSERT INTO t1 VALUES('a b c'); } + 4 { + creAte virTUal tablE t1 USING FTs5(c); + INSERT INTO t1 VALUES('a b c'); + INSERT INTO t1 VALUES('a b c'); + } { + DELETE FROM t1 WHERE rowid = 1; + INSERT INTO t1 VALUES('a b c'); + } } { forcedelete test.db test.db2 diff --git a/chromium/third_party/sqlite/src/ext/rbu/sqlite3rbu.c b/chromium/third_party/sqlite/src/ext/rbu/sqlite3rbu.c index 12a0a466033..c5f809848d1 100644 --- a/chromium/third_party/sqlite/src/ext/rbu/sqlite3rbu.c +++ b/chromium/third_party/sqlite/src/ext/rbu/sqlite3rbu.c @@ -4828,22 +4828,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<<n) - 1) << ofst; } } } diff --git a/chromium/third_party/sqlite/src/ext/session/session2.test b/chromium/third_party/sqlite/src/ext/session/session2.test index cd8c2869e79..806687745e5 100644 --- a/chromium/third_party/sqlite/src/ext/session/session2.test +++ b/chromium/third_party/sqlite/src/ext/session/session2.test @@ -35,7 +35,7 @@ proc test_reset {} { test_reset do_execsql_test 1.0 { - CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t1(a INT PRIMARY KEY, b); INSERT INTO t1 VALUES('i', 'one'); } do_iterator_test 1.1 t1 { @@ -184,7 +184,7 @@ set set_of_tests { test_reset do_common_sql { - CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t1(a int PRIMARY KEY, b); CREATE TABLE t2(a, b INTEGER PRIMARY KEY); CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b)); CREATE TABLE t4(a, b, PRIMARY KEY(b, a)); @@ -206,17 +206,17 @@ sqlite3 db3 test.db3 do_test 3.0 { execsql { ATTACH 'test.db3' AS 'aux'; - CREATE TABLE t1(a, b PRIMARY KEY); + CREATE TABLE t1(a int, b PRIMARY KEY); CREATE TABLE t2(x, y, z); CREATE TABLE t3(a); - CREATE TABLE aux.t1(a PRIMARY KEY, b); + CREATE TABLE aux.t1(a int PRIMARY KEY, b); CREATE TABLE aux.t2(a, b INTEGER PRIMARY KEY); CREATE TABLE aux.t3(a, b, c, PRIMARY KEY(a, b)); CREATE TABLE aux.t4(a, b, PRIMARY KEY(b, a)); } execsql { - CREATE TABLE t1(a PRIMARY KEY, b); + CREATE TABLE t1(a int PRIMARY KEY, b); CREATE TABLE t2(a, b INTEGER PRIMARY KEY); CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b)); CREATE TABLE t4(a, b, PRIMARY KEY(b, a)); @@ -588,4 +588,52 @@ do_execsql_test 10.2 { } {0 0 1 1} S delete +#------------------------------------------------------------------------- +test_reset +do_common_sql { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d, e, f); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<32 + ) + INSERT INTO t1 SELECT NULL, 0, 0, 0, 0, 0 FROM s +} + +do_then_apply_sql { + UPDATE t1 SET f=f+1 WHERE a=1; + UPDATE t1 SET e=e+1 WHERE a=2; + UPDATE t1 SET e=e+1, f=f+1 WHERE a=3; + UPDATE t1 SET d=d+1 WHERE a=4; + UPDATE t1 SET d=d+1, f=f+1 WHERE a=5; + UPDATE t1 SET d=d+1, e=e+1 WHERE a=6; + UPDATE t1 SET d=d+1, e=e+1, f=f+1 WHERE a=7; + UPDATE t1 SET c=c+1 WHERE a=8; + UPDATE t1 SET c=c+1, f=f+1 WHERE a=9; + UPDATE t1 SET c=c+1, e=e+1 WHERE a=10; + UPDATE t1 SET c=c+1, e=e+1, f=f+1 WHERE a=11; + UPDATE t1 SET c=c+1, d=d+1 WHERE a=12; + UPDATE t1 SET c=c+1, d=d+1, f=f+1 WHERE a=13; + UPDATE t1 SET c=c+1, d=d+1, e=e+1 WHERE a=14; + UPDATE t1 SET c=c+1, d=d+1, e=e+1, f=f+1 WHERE a=15; + UPDATE t1 SET d=d+1 WHERE a=16; + UPDATE t1 SET d=d+1, f=f+1 WHERE a=17; + UPDATE t1 SET d=d+1, e=e+1 WHERE a=18; + UPDATE t1 SET d=d+1, e=e+1, f=f+1 WHERE a=19; + UPDATE t1 SET d=d+1, d=d+1 WHERE a=20; + UPDATE t1 SET d=d+1, d=d+1, f=f+1 WHERE a=21; + UPDATE t1 SET d=d+1, d=d+1, e=e+1 WHERE a=22; + UPDATE t1 SET d=d+1, d=d+1, e=e+1, f=f+1 WHERE a=23; + UPDATE t1 SET d=d+1, c=c+1 WHERE a=24; + UPDATE t1 SET d=d+1, c=c+1, f=f+1 WHERE a=25; + UPDATE t1 SET d=d+1, c=c+1, e=e+1 WHERE a=26; + UPDATE t1 SET d=d+1, c=c+1, e=e+1, f=f+1 WHERE a=27; + UPDATE t1 SET d=d+1, c=c+1, d=d+1 WHERE a=28; + UPDATE t1 SET d=d+1, c=c+1, d=d+1, f=f+1 WHERE a=29; + UPDATE t1 SET d=d+1, c=c+1, d=d+1, e=e+1 WHERE a=30; + UPDATE t1 SET d=d+1, c=c+1, d=d+1, e=e+1, f=f+1 WHERE a=31; +} + +do_test 11.0 { + compare_db db db2 +} {} + finish_test diff --git a/chromium/third_party/sqlite/src/ext/session/sessionmem.test b/chromium/third_party/sqlite/src/ext/session/sessionmem.test new file mode 100644 index 00000000000..75b48623d0f --- /dev/null +++ b/chromium/third_party/sqlite/src/ext/session/sessionmem.test @@ -0,0 +1,57 @@ +# 2020 December 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 regression tests for the SQLite sessions module +# Specifically, for the sqlite3session_memory_used() API. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionmem + +do_execsql_test 1.0 { + CREATE TABLE t1(i INTEGER PRIMARY KEY, x, y); + CREATE TABLE t2(i INTEGER, x, y, PRIMARY KEY(x, y)); +} + +do_test 1.1 { + sqlite3session S db main + S attach * +} {} + +foreach {tn sql eRes} { + 1 { INSERT INTO t1 VALUES(1, 2, 3) } 1 + 2 { UPDATE t1 SET x=5 } 0 + 3 { UPDATE t1 SET i=5 } 1 + 4 { DELETE FROM t1 } 0 + 5 { INSERT INTO t1 VALUES(1, 2, 3) } 0 + 6 { INSERT INTO t1 VALUES(5, 2, 3) } 0 + 7 { INSERT INTO t2 VALUES('a', 'b', 'c') } 1 + 8 { INSERT INTO t2 VALUES('d', 'e', 'f') } 1 + 9 { UPDATE t2 SET i='e' } 0 +} { + set mem1 [S memory_used] + do_test 1.2.$tn.(mu=$mem1) { + execsql $sql + set mem2 [S memory_used] + expr {$mem2 > $mem1} + } $eRes +} + +do_test 1.3 { + S delete +} {} + +finish_test diff --git a/chromium/third_party/sqlite/src/ext/session/sessionnoop.test b/chromium/third_party/sqlite/src/ext/session/sessionnoop.test new file mode 100644 index 00000000000..16c60b7abff --- /dev/null +++ b/chromium/third_party/sqlite/src/ext/session/sessionnoop.test @@ -0,0 +1,187 @@ +# 2021 Februar 20 +# +# 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 regression tests for SQLite library. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionnoop + +#------------------------------------------------------------------------- +# Test plan: +# +# 1.*: Test that concatenating changesets cannot produce a noop UPDATE. +# 2.*: Test that rebasing changesets cannot produce a noop UPDATE. +# 3.*: Test that sqlite3changeset_apply() ignores noop UPDATE changes. +# + +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b, c, d); + INSERT INTO t1 VALUES(1, 1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3, 3); +} + +proc do_concat_test {tn sql1 sql2 res} { + uplevel [list do_test $tn [subst -nocommands { + set C1 [changeset_from_sql {$sql1}] + set C2 [changeset_from_sql {$sql2}] + set C3 [sqlite3changeset_concat [set C1] [set C2]] + set got [list] + sqlite3session_foreach elem [set C3] { lappend got [set elem] } + set got + }] [list {*}$res]] +} + +do_concat_test 1.1 { + UPDATE t1 SET c=c+1; +} { + UPDATE t1 SET c=c-1; +} { +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE TABLE t1(a PRIMARY KEY, b, c); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); +} + +proc do_rebase_test {tn sql_local sql_remote conflict_res expected} { + proc xConflict {args} [list return $conflict_res] + + uplevel [list \ + do_test $tn [subst -nocommands { + execsql BEGIN + set c_remote [changeset_from_sql {$sql_remote}] + execsql ROLLBACK + + execsql BEGIN + set c_local [changeset_from_sql {$sql_local}] + set base [sqlite3changeset_apply_v2 db [set c_remote] xConflict] + execsql ROLLBACK + + sqlite3rebaser_create R + R config [set base] + set res [list] + sqlite3session_foreach elem [R rebase [set c_local]] { + lappend res [set elem] + } + R delete + set res + }] [list {*}$expected] + ] +} + +do_rebase_test 2.1 { + UPDATE t1 SET c=2 WHERE a=1; -- local +} { + UPDATE t1 SET c=3 WHERE a=1; -- remote +} OMIT { + {UPDATE t1 0 X.. {i 1 {} {} i 3} {{} {} {} {} i 2}} +} + +do_rebase_test 2.2 { + UPDATE t1 SET c=2 WHERE a=1; -- local +} { + UPDATE t1 SET c=3 WHERE a=1; -- remote +} REPLACE { +} + +do_rebase_test 2.3.1 { + UPDATE t1 SET c=4 WHERE a=1; -- local +} { + UPDATE t1 SET c=4 WHERE a=1 -- remote +} OMIT { + {UPDATE t1 0 X.. {i 1 {} {} i 4} {{} {} {} {} i 4}} +} + +do_rebase_test 2.3.2 { + UPDATE t1 SET c=5 WHERE a=1; -- local +} { + UPDATE t1 SET c=5 WHERE a=1 -- remote +} REPLACE { +} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 3.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + INSERT INTO t1 VALUES(1, 1, 1); + INSERT INTO t1 VALUES(2, 2, 2); + INSERT INTO t1 VALUES(3, 3, 3); + INSERT INTO t1 VALUES(4, 4, 4); +} + +# Arg $pkstr contains one character for each column in the table. An +# "X" for PK column, or a "." for a non-PK. +# +proc mk_tbl_header {name pkstr} { + set ret [binary format H2c 54 [string length $pkstr]] + foreach i [split $pkstr {}] { + if {$i=="X"} { + append ret [binary format H2 01] + } else { + if {$i!="."} {error "bad pkstr: $pkstr ($i)"} + append ret [binary format H2 00] + } + } + append ret $name + append ret [binary format H2 00] + set ret +} + +proc mk_update_change {args} { + set ret [binary format H2H2 17 00] + foreach a $args { + if {$a==""} { + append ret [binary format H2 00] + } else { + append ret [binary format H2W 01 $a] + } + } + set ret +} + +proc xConflict {args} { return "ABORT" } +do_test 3.1 { + set C [mk_tbl_header t1 X..] + append C [mk_update_change 1 {} 1 {} {} 500] + append C [mk_update_change 2 {} {} {} {} {}] + append C [mk_update_change 3 3 {} {} 600 {}] + append C [mk_update_change 4 {} {} {} {} {}] + + sqlite3changeset_apply_v2 db $C xConflict +} {} +do_execsql_test 3.2 { + SELECT * FROM t1 +} { + 1 1 500 + 2 2 2 + 3 600 3 + 4 4 4 +} + + + + + + +finish_test + diff --git a/chromium/third_party/sqlite/src/ext/session/sessionwor.test b/chromium/third_party/sqlite/src/ext/session/sessionwor.test index 0f0b429d7be..7d9e5c6a897 100644 --- a/chromium/third_party/sqlite/src/ext/session/sessionwor.test +++ b/chromium/third_party/sqlite/src/ext/session/sessionwor.test @@ -69,7 +69,9 @@ foreach {tn wo} { } { reset_db - do_execsql_test 2.$tn.0 "CREATE TABLE t1(a INTEGER PRIMARY KEY, b) $wo ;" + do_execsql_test 2.$tn.0.1 "CREATE TABLE t1(a INTEGER PRIMARY KEY, b) $wo ;" + do_execsql_test 2.$tn.0.2 "CREATE TABLE t2(a INTEGER PRIMARY KEY, b) $wo ;" + do_execsql_test 2.$tn.0.3 "CREATE TABLE t3(a INTEGER PRIMARY KEY, b) $wo ;" do_iterator_test 1.1 t1 { INSERT INTO t1 VALUES(1, 'two'); @@ -94,6 +96,27 @@ foreach {tn wo} { } { {DELETE t1 0 X. {i 1 t four} {}} } + + do_execsql_test 2.$tn.5 { + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); + } + + do_iterator_test 2.$tn.6 t2 { + INSERT INTO t2 SELECT a, b FROM t1 + } { + {INSERT t2 0 X. {} {i 1 t one}} + {INSERT t2 0 X. {} {i 2 t two}} + {INSERT t2 0 X. {} {i 3 t three}} + } + do_iterator_test 2.$tn.7 t3 { + INSERT INTO t3 SELECT * FROM t1 + } { + {INSERT t3 0 X. {} {i 1 t one}} + {INSERT t3 0 X. {} {i 2 t two}} + {INSERT t3 0 X. {} {i 3 t three}} + } } finish_test diff --git a/chromium/third_party/sqlite/src/ext/session/sqlite3session.c b/chromium/third_party/sqlite/src/ext/session/sqlite3session.c index dae26047194..8210056a890 100644 --- a/chromium/third_party/sqlite/src/ext/session/sqlite3session.c +++ b/chromium/third_party/sqlite/src/ext/session/sqlite3session.c @@ -48,6 +48,7 @@ struct sqlite3_session { 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 */ sqlite3_value *pZeroBlob; /* Value containing X'' */ sqlite3_session *pNext; /* Next session object on same db. */ SessionTable *pTable; /* List of attached tables */ @@ -90,6 +91,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 */ @@ -431,6 +433,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 @@ -898,13 +920,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; @@ -925,7 +953,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ } } - sqlite3_free(pTab->apChange); + sessionFree(pSession, pTab->apChange); pTab->nChange = nNew; pTab->apChange = apNew; } @@ -959,6 +987,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 */ @@ -1013,7 +1042,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; } @@ -1056,7 +1085,7 @@ static int sessionTableInfo( *pabPK = 0; *pnCol = 0; if( pzTab ) *pzTab = 0; - sqlite3_free(azCol); + sessionFree(pSession, azCol); } sqlite3_finalize(pStmt); return rc; @@ -1078,7 +1107,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 ){ @@ -1169,7 +1198,7 @@ static void sessionPreupdateOneChange( } /* Grow the hash table if required */ - if( sessionGrowHash(0, pTab) ){ + if( sessionGrowHash(pSession, 0, pTab) ){ pSession->rc = SQLITE_NOMEM; return; } @@ -1236,7 +1265,7 @@ static void sessionPreupdateOneChange( } /* Allocate the change object */ - pChange = (SessionChange *)sqlite3_malloc64(nByte); + pChange = (SessionChange *)sessionMalloc64(pSession, nByte); if( !pChange ){ rc = SQLITE_NOMEM; goto error_out; @@ -1609,7 +1638,7 @@ 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; @@ -1707,7 +1736,7 @@ 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; @@ -1719,12 +1748,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); } } @@ -1752,9 +1781,11 @@ 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); } @@ -1801,7 +1832,8 @@ 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{ @@ -2398,7 +2430,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; } @@ -2574,6 +2606,13 @@ int sqlite3session_isempty(sqlite3_session *pSession){ } /* +** Return the amount of heap memory in use. +*/ +sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession){ + return pSession->nMalloc; +} + +/* ** Do the work for either sqlite3changeset_start() or start_strm(). */ static int sessionChangesetStart( @@ -2582,7 +2621,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 */ @@ -2603,6 +2643,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; @@ -2617,7 +2658,7 @@ 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); } int sqlite3changeset_start_v2( sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ @@ -2626,7 +2667,7 @@ 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); } /* @@ -2637,7 +2678,7 @@ 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); } int sqlite3changeset_start_v2_strm( sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ @@ -2646,7 +2687,7 @@ 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); } /* @@ -2772,11 +2813,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; i<nCol && rc==SQLITE_OK; i++){ int eType = 0; /* Type of value (SQLITE_NULL, TEXT etc.) */ if( abPK && abPK[i]==0 ) continue; @@ -2788,6 +2832,7 @@ static int sessionReadRecord( eType = pIn->aData[pIn->iNext++]; assert( apOut[i]==0 ); if( eType ){ + if( pbEmpty ) *pbEmpty = 0; apOut[i] = sqlite3ValueNew(0); if( !apOut[i] ) rc = SQLITE_NOMEM; } @@ -2967,31 +3012,27 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ } /* -** Advance the changeset iterator to the next change. +** Advance the changeset iterator to the next change. The differences between +** this function and sessionChangesetNext() are that ** -** 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. +** * 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; @@ -3064,13 +3105,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; } @@ -3098,6 +3139,37 @@ static int sessionChangesetNext( } /* +** 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 ** or SQLITE_CORRUPT. @@ -3369,9 +3441,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 @@ -3472,16 +3544,25 @@ 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 */ @@ -3491,6 +3572,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; ii<pIter->nCol; 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; ii<pIter->nCol; 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; ii<pIter->nCol; 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: @@ -3561,103 +3803,6 @@ static int sessionDeleteRow( } /* -** 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; i<p->nCol; 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; i<p->nCol; 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; i<p->nCol; 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: ** @@ -3738,17 +3883,6 @@ static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){ ); } 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 " "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END " @@ -4064,7 +4198,7 @@ static int sessionApplyOneOp( int nCol; int rc = SQLITE_OK; - assert( p->pDelete && p->pUpdate && p->pInsert && p->pSelect ); + assert( p->pDelete && p->pInsert && p->pSelect ); assert( p->azCol && p->abPK ); assert( !pbReplace || *pbReplace==0 ); @@ -4104,29 +4238,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 && i<nCol; i++){ sqlite3_value *pOld = sessionChangesetOld(pIter, i); sqlite3_value *pNew = sessionChangesetNew(pIter, i); - - sqlite3_bind_int(p->pUpdate, 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 @@ -4258,7 +4391,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*); @@ -4349,14 +4482,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; @@ -4384,7 +4516,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; @@ -4420,11 +4552,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; @@ -4483,9 +4614,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); @@ -4516,8 +4647,8 @@ 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 @@ -4575,7 +4706,7 @@ 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 @@ -4863,7 +4994,7 @@ static int sessionChangesetToHash( } } - if( sessionGrowHash(pIter->bPatchset, pTab) ){ + if( sessionGrowHash(0, pIter->bPatchset, pTab) ){ rc = SQLITE_NOMEM; break; } @@ -5049,7 +5180,7 @@ int sqlite3changegroup_output_strm( */ void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ if( pGrp ){ - sessionDeleteTable(pGrp->pList); + sessionDeleteTable(0, pGrp->pList); sqlite3_free(pGrp); } } @@ -5195,7 +5326,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 ){ @@ -5450,7 +5581,7 @@ int sqlite3rebaser_rebase_strm( */ void sqlite3rebaser_delete(sqlite3_rebaser *p){ if( p ){ - sessionDeleteTable(p->grp.pList); + sessionDeleteTable(0, p->grp.pList); sqlite3_free(p); } } diff --git a/chromium/third_party/sqlite/src/ext/session/sqlite3session.h b/chromium/third_party/sqlite/src/ext/session/sqlite3session.h index 1ed3b550f43..9ebf360ea3e 100644 --- a/chromium/third_party/sqlite/src/ext/session/sqlite3session.h +++ b/chromium/third_party/sqlite/src/ext/session/sqlite3session.h @@ -441,6 +441,14 @@ int sqlite3session_patchset( 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. +*/ +sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession); + +/* ** CAPI3REF: Create An Iterator To Traverse A Changeset ** CONSTRUCTOR: sqlite3_changeset_iter ** @@ -542,18 +550,23 @@ 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/chromium/third_party/sqlite/src/ext/session/test_session.c b/chromium/third_party/sqlite/src/ext/session/test_session.c index 82f30979f51..c3898fd860e 100644 --- a/chromium/third_party/sqlite/src/ext/session/test_session.c +++ b/chromium/third_party/sqlite/src/ext/session/test_session.c @@ -146,7 +146,10 @@ static int SQLITE_TCLAPI test_sql_exec_changeset( static int test_tcl_integer(Tcl_Interp *interp, const char *zVar){ Tcl_Obj *pObj; int iVal = 0; - pObj = Tcl_ObjGetVar2(interp, Tcl_NewStringObj(zVar, -1), 0, TCL_GLOBAL_ONLY); + Tcl_Obj *pName = Tcl_NewStringObj(zVar, -1); + Tcl_IncrRefCount(pName); + pObj = Tcl_ObjGetVar2(interp, pName, 0, TCL_GLOBAL_ONLY); + Tcl_DecrRefCount(pName); if( pObj ) Tcl_GetIntFromObj(0, pObj, &iVal); return iVal; } @@ -242,6 +245,7 @@ static int SQLITE_TCLAPI test_session_cmd( { "table_filter", 1, "SCRIPT", }, /* 6 */ { "patchset", 0, "", }, /* 7 */ { "diff", 2, "FROMDB TBL", }, /* 8 */ + { "memory_used", 0, "", }, /* 9 */ { 0 } }; int iSub; @@ -347,6 +351,12 @@ static int SQLITE_TCLAPI test_session_cmd( } break; } + + case 9: { /* memory_used */ + sqlite3_int64 nMalloc = sqlite3session_memory_used(pSession); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nMalloc)); + break; + } } return TCL_OK; diff --git a/chromium/third_party/sqlite/src/main.mk b/chromium/third_party/sqlite/src/main.mk index e47e85fdfbf..733d51372a3 100644 --- a/chromium/third_party/sqlite/src/main.mk +++ b/chromium/third_party/sqlite/src/main.mk @@ -360,6 +360,7 @@ TESTSRC = \ # TESTSRC += \ $(TOP)/ext/misc/amatch.c \ + $(TOP)/ext/misc/appendvfs.c \ $(TOP)/ext/misc/carray.c \ $(TOP)/ext/misc/cksumvfs.c \ $(TOP)/ext/misc/closure.c \ @@ -550,13 +551,13 @@ ST_OPT = -DSQLITE_THREADSAFE=0 # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. # -all: sqlite3.h libsqlite3.a sqlite3$(EXE) +all: sqlite3.h sqlite3ext.h libsqlite3.a sqlite3$(EXE) -libsqlite3.a: $(LIBOBJ) +libsqlite3.a: sqlite3.h $(LIBOBJ) $(AR) libsqlite3.a $(LIBOBJ) $(RANLIB) libsqlite3.a -sqlite3$(EXE): shell.c libsqlite3.a sqlite3.h +sqlite3$(EXE): sqlite3.h libsqlite3.a shell.c $(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) $(SHELL_OPT) \ shell.c libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB) @@ -824,13 +825,13 @@ fts3_unicode2.o: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR) fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c -fts5.o: fts5.c +fts5.o: fts5.c sqlite3ext.h sqlite3.h $(TCCX) -DSQLITE_CORE -c fts5.c -json1.o: $(TOP)/ext/misc/json1.c +json1.o: $(TOP)/ext/misc/json1.c sqlite3ext.h sqlite3.h $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c -stmt.o: $(TOP)/ext/misc/stmt.c +stmt.o: $(TOP)/ext/misc/stmt.c sqlite3ext.h sqlite3.h $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c rtree.o: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR) @@ -954,7 +955,7 @@ fuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz- ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db - valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA) + valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M $(FUZZDATA) valgrind ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db # The veryquick.test TCL tests. diff --git a/chromium/third_party/sqlite/src/manifest b/chromium/third_party/sqlite/src/manifest index 6c9cbb5ed81..4007a5dd739 100644 --- a/chromium/third_party/sqlite/src/manifest +++ b/chromium/third_party/sqlite/src/manifest @@ -1,13 +1,13 @@ -C Version\s3.34.0 -D 2020-12-01T16:14:00.051 +C Version\s3.35.5 +D 2021-04-19T18:32:05.830 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 0e88f5d095213a9ccd45c5bbd871c8ead498f886dff4493471fbf48b1f867f9d +F Makefile.in fe6cc1db11e02b308f3ab0ec2504344697b9eaaa410fa73f48d16a143462e5d3 F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 -F Makefile.msc dd10dbf63b2f8ac3e2f0542963a21bc69058976ac4355165f212a31c83d17f44 +F Makefile.msc 6b5428cef2af1288e02faeb602dabe68fbf2de7bc8a8e29c7299778ee08cd35c F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a -F VERSION 4027b9aea92d64385570778ebd14388c0b23e92aafda15e7b89c45886c9b920a +F VERSION 0c32b05000702ccfdfb5fc72e16b0f965ed664d6cb4fec361196fd0d91eb52c9 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@ -15,10 +15,10 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am a8d1d24affe52ebf8d7ddcf91aa973fa0316618ab95bb68c87cabf8faf527dc8 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac -F autoconf/Makefile.msc e0f1dafc48d000fd6ddfdb01815271528db55cbc7299ca888df5b93367f0d5a4 +F autoconf/Makefile.msc ebe7e66edbb2f453593cbde186d1a0fa0dcd8cae9977febcae27aef1dab5678d F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 4f04b0819303aabaa35fff5f7b257fb0c1ef95f1 -F autoconf/configure.ac 3cd933b959fe514eebd1ca1717dfddbf2c9b825b6bc2c5f744deaf5d63af9288 +F autoconf/configure.ac a8ba2a9e61216f5093d44f3b7d2cb8fe1890d6b7dc330a02f802d8efaa1fdc79 F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 @@ -34,11 +34,11 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 -F configure e7df2824b6e60d482d919fb3e7d823faf08467093b096ad47a4fe2eec3f0ba99 x -F configure.ac 73545c21eebcef9398d85c982c7be260f07708256778221b541f83ae8c6f61eb +F configure 64b2ab5ac52a8657cfdf97a2a1589441d0deaa859e0d2bbad5ff401829f71676 x +F configure.ac 4e4b58b32f88c8da9914a2f2c3158f80e69907eccc019fcc7e3ba14ffd91c640 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd -F doc/lemon.html c5d8ba85ac1daef7be8c2d389899480eb62451ff5c09b0c28ff8157bb8770746 +F doc/lemon.html 1bb72ece6271df0d901d233551dd985f2c6ba30d09382cf2d321ed951ab57491 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 @@ -50,8 +50,8 @@ F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 -F ext/expert/expert1.test dba6e752cc701621771f925f3872b183fa688f7b4a9f4822631fc02bdbffc45a -F ext/expert/sqlite3expert.c 2778d9f06b3a8bfa859cb6b75b82f004477bf5dd78edd17d954319750ca963f3 +F ext/expert/expert1.test 63d778d964e55ef2d1a723043d91c59e7dc6ef1649d91c78c0bef00f9c6f1427 +F ext/expert/sqlite3expert.c de51b187c629a4c4264d5de0b77862641e11426f7a963a92abf2d4077085fc8c F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e @@ -84,11 +84,11 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 4809e0b05af4519ad8bfa13d684f7ad635d1390a758299d2302f7e85c48ec160 +F ext/fts3/fts3.c 7b449348226a91cc851fe969f5c1932d4f00c359a32fd17f2afea92bf875147b F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h 045179f538c478ced266ca14327269cde8ad8d573c5be902230a5ebaa5636c59 F ext/fts3/fts3_aux.c 96708c8b3a7d9b8ca1b68ea2b7e503e283f20e95f145becadedfad096dbd0f34 -F ext/fts3/fts3_expr.c f081e38da641724cd72c20e23b71db2bf4d0c9517c14637442f6910259f11a34 +F ext/fts3/fts3_expr.c 5853cd7a35a79d193614add9b4c461b2d56f465d90899ca4309f05d9d1536558 F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6bdb48b7 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116 @@ -100,9 +100,9 @@ F ext/fts3/fts3_tokenize_vtab.c 8d15b148e7d88a4280389a200b26e8d52abda4c4ec2e9a35 F ext/fts3/fts3_tokenizer.c 6d8fc150c48238955d5182bf661498db0dd473c8a2a80e00c16994a646fa96e7 F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 -F ext/fts3/fts3_unicode.c 4b9af6151c29b35ed09574937083cece7c31e911f69615e168a39677569b684d +F ext/fts3/fts3_unicode.c de426ff05c1c2e7bce161cf6b706638419c3a1d9c2667de9cb9dc0458c18e226 F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f -F ext/fts3/fts3_write.c 723ed1b11ed46ad1b3a23c0d69fa39e77986783a82d5711bf87a5ce29e0a3b52 +F ext/fts3/fts3_write.c a5159accfd88f85fd3fc2298286d7a9427a02d1ea9a52b7c79730cff7a0bc03f F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 @@ -117,14 +117,14 @@ F ext/fts5/fts5Int.h 26c74dd5776f798436fbf604a0bf0e8de263b35b5060b05c15f9085845d F ext/fts5/fts5_aux.c f558e1fb9f0f86a4f7489e258c162e1f947de5ff2709087fbb465fddb7092f98 F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70 F ext/fts5/fts5_config.c be54f44fca491e96c6923a4b9a736f2da2b13811600eb6e38d1bcc91c4ea2e61 -F ext/fts5/fts5_expr.c e527e3a7410393075598cec544e3831798a8c88b3e8878e2cfb7cb147113e925 +F ext/fts5/fts5_expr.c 016bd06030679bd31b0f07ef87d62c42031e5da25cb3174a84e5b0f6ef4b47b0 F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959 -F ext/fts5/fts5_index.c 9f152a596df3a2227ddd59adb82549c2b6858ab36bc1d26fd8933f43d3d63d36 -F ext/fts5/fts5_main.c b4e4931c7fcc9acfa0c3b8b5e5e80b5b424b8d9207aae3a22b674bd35ccf149d +F ext/fts5/fts5_index.c df5e18b705ac601e826576298a5ce23ef1e5d417fbfdb3feb5f702f89e5f6f41 +F ext/fts5/fts5_main.c d77648a52b8d73d13887306149912e420f7e0b2d7b3d7da2f54152bfa140ac02 F ext/fts5/fts5_storage.c 58ba71e6cd3d43a5735815e7956ee167babb4d2cbfe206905174792af4d09d75 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee -F ext/fts5/fts5_test_tok.c f96c6e193c466711d6d7828d5f190407fe7ab897062d371426dd3036f01258e7 +F ext/fts5/fts5_test_tok.c a2bed8edb25f6432e8cdb62aad5916935c19dba8dac2b8324950cfff397e25ff F ext/fts5/fts5_tokenize.c 5e251efb0f1af99a25ed50010ba6b1ad1250aca5921af1988fdcabe5ebc3cb43 F ext/fts5/fts5_unicode2.c eca63dbc797f8ff0572e97caf4631389c0ab900d6364861b915bdd4735973f00 F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80 @@ -160,9 +160,9 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0 F ext/fts5/test/fts5content.test 213506436fb2c87567b8e31f6d43ab30aab99354cec74ed679f22aad0cdbf283 F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f -F ext/fts5/test/fts5corrupt3.test dd5435659d5363fc3b3ac32175e2fc793fdc17980b47e3d598695d867eaa77a2 -F ext/fts5/test/fts5corrupt4.test ea805c4d7c68b5f185b9db5d2060a7ae5875339738dd48203c92162f41e7ca91 -F ext/fts5/test/fts5delete.test 4a15fb03b6c7eac62ac807a3a32b7f0dc74f0d479c410e3e3568ae96b9469290 +F ext/fts5/test/fts5corrupt3.test 1cad09897fc69084a904c921dee7f777e1c866964ee2ec2cc7a8a69cc3f1ab68 +F ext/fts5/test/fts5corrupt4.test f4c08e2182a48d8b70975fd869ee5391855c06d8a0ff87b6a2529e7c5a88a1d3 +F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11 F ext/fts5/test/fts5dlidx.test b90852c55881b29dbac6380b274de27beae623ac4b6d567c6c8fb9cdc315a86e @@ -204,6 +204,7 @@ F ext/fts5/test/fts5plan.test 79d35b5e83bbdcba48d946a7f008df161f6b0ede1a966892d0 F ext/fts5/test/fts5porter.test 8d08010c28527db66bc3feebd2b8767504aaeb9b101a986342fa7833d49d0d15 F ext/fts5/test/fts5porter2.test 0d251a673f02fa13ca7f011654873b3add20745f7402f108600a23e52d8c7457 F ext/fts5/test/fts5prefix.test a0fa67b06650f2deaa7bf27745899d94e0fb547ad9ecbd08bfad98c04912c056 +F ext/fts5/test/fts5prefix2.test 3847ce46f70b82d61c6095103a9d7c53f2952c40a4704157bc079c04d9c8b18b F ext/fts5/test/fts5query.test ac363b17a442620bb0780e93c24f16a5f963dfe2f23dc85647b869efcfada728 F ext/fts5/test/fts5rank.test c9fd4a1e36b4fa92d572ec13d846469b97da249d1c2f7fd3ee7e017ce46f2416 F ext/fts5/test/fts5rebuild.test 55d6f17715cddbf825680dd6551efbc72ed916d8cf1cde40a46fc5d785b451e7 @@ -285,12 +286,12 @@ F ext/lsm1/tool/mklsm1c.tcl f31561bbee5349f0a554d1ad7236ac1991fc09176626f529f607 F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f238c240 F ext/misc/amatch.c e3ad5532799cee9a97647f483f67f43b38796b84b5a8c60594fe782a4338f358 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb -F ext/misc/appendvfs.c 55121d311d408ba9c62c3cfa367408887638f02f9522dd9859891d0ee69a7eba +F ext/misc/appendvfs.c bdc9de0a0e61c21327e975da178b4fd6f57de9c46123044aa6ee3a20798c5db2 F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a F ext/misc/btreeinfo.c d28ce349b40054eaa9473e835837bad7a71deec33ba13e39f963d50933bfa0f9 F ext/misc/carray.c b75a0f207391038bf1540d3372f482a95c3613511c7c474db51ede1196321c7c F ext/misc/carray.h de74ac70b2338f416723f7d538026e8ec0b7f1d388319f8f140c9a4d7677f02e -F ext/misc/cksumvfs.c c4e7ebeae5aa578df98f23bddb63ecbcbe913ee3c32b8b769525af100d752061 +F ext/misc/cksumvfs.c 8dc4e1b718e374bed3a9b5c0a08da2922438002e33267311697768e06217b983 F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243 F ext/misc/completion.c 6dafd7f4348eecc7be9e920d4b419d1fb2af75d938cd9c59a20cfe8beb2f22b9 F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9 @@ -303,7 +304,7 @@ F ext/misc/explain.c 0086fab288d4352ea638cf40ac382aad3b0dc5e845a1ea829a694c015fd F ext/misc/fileio.c 9b69e25da3b51d4a1d905a464ccb96709792ad627a742ba09215bc0d1447e7bd F ext/misc/fossildelta.c 1240b2d3e52eab1d50c160c7fe1902a9bd210e052dc209200a750bbf885402d5 F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d -F ext/misc/ieee754.c 5c7ca326361c7368f95f5743972eade3b8b24f60359ed7cba4706668a5682896 +F ext/misc/ieee754.c cd6ab89f85fda8a020559b3f4d03001a8a62dd856beda5af3f558621d12be913 F ext/misc/json1.c f31e89171f932d1821c91f10d2cb4979fc0447030030a8bce70420cd43d074c0 F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b @@ -318,9 +319,9 @@ F ext/misc/regexp.c 246244c714267f303df76acf73dcf110cf2eaf076896aaaba8db6d6d21a1 F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 -F ext/misc/series.c fbb8e6be97b54d10d2f235e163fa2f53a8f4421c66ebd532a233fd1c69c3f522 +F ext/misc/series.c c6bd5d249e5199a1b55aeee4d0e6576ff3a68702fc475dbd64503a32903516c7 F ext/misc/sha1.c c8f2253c8792ffab9517695ea7d88c079f0395a5505eefef5c8198fe184ed5ac -F ext/misc/shathree.c 135b7c145db4a09b1650c3e7aff9cb538763a9a361e834c015dd1aaf8d5c9a00 +F ext/misc/shathree.c e984f31731de4cf302a0386be5fe664580f63d8204c47b9b41cc4b997745f9ec F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f F ext/misc/sqlar.c 0ace5d3c10fe736dc584bf1159a36b8e2e60fab309d310cd8a0eecd9036621b6 @@ -335,10 +336,10 @@ F ext/misc/vfslog.c 3b25c2f56ba60788db247287be6ab024b53c4afffd412b4876db563389be F ext/misc/vfsstat.c 389ea13983d3af926504c314f06a83cc858d5adc24b40af74aaed1fece00c118 F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd -F ext/misc/wholenumber.c 520f34c3099e5b7d546f13708607dc2fa173c46b68952eecf0d19cd675fec85e +F ext/misc/wholenumber.c a838d1bea913c514ff316c69695efbb49ea3b8cb37d22afc57f73b6b010b4546 F ext/misc/zipfile.c e35e035bc2765b1ccdcb15f9815c2112843fcbc8f36aa071f0e5935df7072228 F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64 -F ext/rbu/rbu.c 8681f6157db6adc82c34af24b14ea8a3be0146ad2a3b6c1d5da6cb8a5796c8ce +F ext/rbu/rbu.c b880ca5cb857d6d6f52e72eb7397813058ef48c78c5402cd04ff2b6b5437f622 F ext/rbu/rbu1.test 221d9c18a5e600ac9ac6b1810d99d9f99163a7909ba61597876ab6e4d4beb3d6 F ext/rbu/rbu10.test 0a201c32202143f23c81c0144503da339786fc20acb7a2fda11601b65659f314 F ext/rbu/rbu11.test 5c834cf491086b45e071eabf71f708febc143e86a384a92de69e0b1a4cace144 @@ -358,7 +359,7 @@ F ext/rbu/rbu_common.tcl 60d904133ff843fe72cc0514e9dd2486707181e6e0fbab20979da28 F ext/rbu/rbucollate.test cac528a9a46318cba42e61258bb42660bbbf4fdb9a8c863de5a54ad0c658d197 F ext/rbu/rbucrash.test 000981a1fe8a6e4d9a684232f6a129e66a3ef595f5ed74655e2f9c68ffa613b4 F ext/rbu/rbucrash2.test efa143cc94228eb0266d3f1abfbee60a5838a84cef7cc3fcb8c145b74d96fd41 -F ext/rbu/rbudiff.test 156957851136b63c143478518dc1bda6c832103cdbe8ac1d7cdd47edb3cbe0a3 +F ext/rbu/rbudiff.test abe895a8d479e4d33acb40e244e3d8e2cd25f55a18dfa8b9f83e13d00073f600 F ext/rbu/rbudor.test e3e8623926012f43eebe51fedf06a102df2640750d971596b052495f2536db20 F ext/rbu/rbuexpr.test 10d0420537c3bc7666e576d72adeffe7e86cfbb00dcc30aa9ce096c042415190 F ext/rbu/rbufault.test 2d7f567b79d558f6e093c58808cab4354f8a174e3802f69e7790a9689b3c09f8 @@ -378,7 +379,7 @@ F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697 F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10 -F ext/rbu/sqlite3rbu.c 05c457c27e9340c944f34e850871a915a6b5ee1d823f7a0bb2b482ac6b1e1464 +F ext/rbu/sqlite3rbu.c e6531884442b72f9e0ba47036fb5c4641ea817ff659a642b3984c10b8535b0fd F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812 F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -427,7 +428,7 @@ F ext/session/changeset.c 7a1e6a14c7e92d36ca177e92e88b5281acd709f3b726298dc34ec0 F ext/session/changesetfuzz.c 227076ab0ae4447d742c01ee88a564da6478bbf26b65108bf8fac9cd8b0b24aa F ext/session/changesetfuzz1.test 2e1b90d888fbf0eea5e1bd2f1e527a48cc85f8e0ff75df1ec4e320b21f580b3a F ext/session/session1.test 0b2f88995832ea040ae8e83a1ad4afa99c00b85c779d213da73a95ea4113233e -F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0 +F ext/session/session2.test 7f53d755d921e0baf815c4258348e0ed460dfd8a772351bca5ad3ccbb1dc786e F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479 F ext/session/session4.test 6778997065b44d99c51ff9cece047ff9244a32856b328735ae27ddef68979c40 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 @@ -449,19 +450,21 @@ F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8 F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7 F ext/session/sessionfault2.test dd593f80b6b4786f7adfe83c5939620bc505559770cc181332da26f29cddd7bb F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2c52219819bc105a25 +F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09 +F ext/session/sessionnoop.test a9366a36a95ef85f8a3687856ebef46983df399541174cb1ede2ee53b8011bc7 F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2f05e82363b9142810 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5 -F ext/session/sessionwor.test 67b5ab91d4f93ce65ff1f58240ac5ddf73f8670facc1ffa49cef56293d52818d -F ext/session/sqlite3session.c 2c76b8c3a5d6dab736686f8a48833b8bdac0871ecc6f447f9839d28bd4a63d6c -F ext/session/sqlite3session.h a2db5b72b938d12c727b4b4ec632254ca493670a9c0de597af3271a7f774fc57 -F ext/session/test_session.c 24286d958dc6f4ca4d7e710f09bc0fa9d50956a40dd99fd8223e7488024c71fe +F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc +F ext/session/sqlite3session.c a7c5ac1acfe21d94b37921b29b0458d64d022a66b282338eee4aafa9c018cb1c +F ext/session/sqlite3session.h f48662626e7a3176a188787a0bd360933dd46cccd98df01c208b02051c540fb7 +F ext/session/test_session.c 90ccf1c30c857bd2fb3f6c990163e8f389ddbdbdc7fa5baa2f6f5f287df41c08 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 57451ea5b3d5cd86e9c5324b10c9de184b12e8dcccc31c65d24fbcb55ccd9c53 +F main.mk c6afb1c8bcacc4c3e320ab10259879bc927f0747401e184b64e8f4b78f057ab2 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -473,37 +476,37 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c b6de60d59419e34f5b48ff2b21fe0f9bb66fc714e5545a6ac790ac7a0c46548c +F src/alter.c 68467416a491b1111d319f653efa4c32ea7dac02a75eb8d59679626fc880a62d F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c -F src/attach.c 0f497c15c4cfe3bdcb214f0dbdbbb6c5ed7e8a9308ac445c7959f5e5780437a9 -F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 +F src/attach.c 9cbe761e464025694df8e6f6ee4d9f41432c3a255ca9443ccbb4130eeb87cf72 +F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c ee14224322b9e4172d01e691e2f289f6c630ae39b7906f84b72dc780b9e42a76 -F src/btree.h dcdff4037d75b3f032a5de0d922fcfaf35d48589417f634fa8627362709315f9 -F src/btreeInt.h ffd66480520d9d70222171b3a026d78b80833b5cea49c89867949f3e023d5f43 -F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81 +F src/btree.c cfd2a37794532d765e235a2550ad2732924a6d06b07a3bc9f6a71750e3b3cca1 +F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5 +F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 +F src/build.c 066c44421bf7b73c6fa47f6fb0c0fcf1357c10552bcf8f3f94c6ebede581cd01 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c e98518d2d3d4029a13c805e07313fb60c877be56db76e90dd5f3af73085d0ce6 -F src/date.c dace306a10d9b02ee553d454c8e1cf8d3c9b932e137738a6b15b90253a9bfc10 +F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 +F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c -F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe -F src/expr.c 0d196ed5a2ebf96be7e8df88add4fabfad0dce16c0fed81a4b8f6a26e259797f +F src/delete.c 73f57a9a183532c344a3135cf8f2a5589376e39183e0b5f562d6b61b2af0f4d8 +F src/expr.c cfab1113f9eba24f1d6d11b710577c9fcc9cc8e29ed60bd7ac7906be7481dda4 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72 -F src/func.c 574f7e5a67e4b7a7855cf3478037717c8f44686c0cd727e1d7f7773414165c03 -F src/global.c 943256ac44f333039d35a9830c18d075a81fa6b6bf2af05771494a9acfb9a40b +F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 +F src/func.c 479f6929be027eb0210cbdde9d3529c012facf082d64a6b854a9415940761e5e +F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 7e081d33aab4a9d761c39dccf3c3872c35501565d2ed9db66301918d23bc7901 +F src/insert.c e36be69e3810902eaf7e171260c885bc9547b1d41616c868f1cc46e6a0a3b7fd F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067 -F src/main.c 54d61d1e94f225636053c862c930d7dd7b29162b93d3f3ecb00439910ccba02a +F src/main.c 2a7ece3a67c646e5fe9984ffe0277d6a76f80ce9715bf2faa591d8cb66b9d913 F src/malloc.c c1af4ac5a463648cd2953fd4ac679b3ba9022ce5ec794a60806150ad69dfd33a F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -511,7 +514,7 @@ F src/mem2.c b93b8762ab999a29ae7751532dadf0a1ac78040308a5fb1d17fcc365171d67eb F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6 F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 F src/memdb.c ab0632d42407e866d2b616bd19d4211ac0ad1b430f04c4e187d60005b8700b98 -F src/memjournal.c 90b2ca7e2f465d57c16b69d15a9f3e3294af61088eb4938f2f7664d5ac50f813 +F src/memjournal.c 431c70a111223a8a6e2e7e9f014afc6c88d818d357d866afc563195f2277d50e F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8 F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25 F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a @@ -519,37 +522,37 @@ F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 F src/mutex_unix.c dd2b3f1cc1863079bc1349ac0fec395a500090c4fe4e11ab775310a49f2f956d F src/mutex_w32.c caa50e1c0258ac4443f52e00fe8aaea73b6d0728bd8856bedfff822cae418541 F src/notify.c 89a97dc854c3aa62ad5f384ef50c5a4a11d70fcc69f86de3e991573421130ed6 -F src/os.c 80e4cf3e5da06be03ca641661e331ce60eeeeabf0d7354dbb1c0e166d0eedbbe +F src/os.c 2d6e646370b1aa78942c68d7edf124e518963adf4a90bce87f365a5a5495529a F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c adbbcea4c63d3b400d405f60a5da4c01433753ec4a12e2dc695beb2bbd671fe9 +F src/os_unix.c 7a9eab7b11f552ab91ead980086b312c7e3b871efdee8c0c072b682bbec6592e F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d +F src/pager.c 970691daea03f9f15e34de671bd8675c1e136232b529e21bfd36d4dba6d41753 F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f -F src/parse.y 9ce4dfb772608ed5bd3c32f33e943e021e3b06cfd2c01932d4280888fdd2ebed +F src/parse.y 2107aff88e361bbf8388fdede3fed20fda875f23ba7585ec83b20e3e16a95670 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 -F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a -F src/pragma.c 6daaaecc26a4b09481d21722525b079ce756751a43a79cc1d8f122d686806193 +F src/pcache1.c 388304fd2d91c39591080b5e0f3c62cfba87db20370e7e0554062bfb29740e9f +F src/pragma.c eb42cb9bec189cf18cef5d8fcae56e13bb73ef2b019b198fb48740ced81bce95 F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf -F src/prepare.c 270170a239c0f66bd3c228f373afe24447c2614a6829ae22080babc64f241931 -F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed +F src/prepare.c e21b54489b5c73b06ada15e6fc79b5c6f64b06701924a6ca98944ae59e06256f +F src/printf.c 2b03a80d7c11bb422115dca175a18bf430e9c9dbaa0eee63b758f0c022f8f34f F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c +F src/resolve.c fec151c9c33a6fa2e93d10b4e8cd4084a7c773df36fb3ec6788eb89ae493a1a4 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 847062694ac9a6add162d39182584b7ca53948ad821c52512a125cd845904e71 -F src/shell.c.in 55113760ae91a05c6ce4558714a1c8fc7a44bf266f735de6e71ea40f79e69830 -F src/sqlite.h.in 1dbae67057d999161c30b21c3c7fa45d51f665b510d397dd1b7d671287d772b0 +F src/select.c 734cf12e42f81f2fe461e41214e6552375e55b62a802784a4f0066ac592e7f4a +F src/shell.c.in aa28256887d049badaf93aa30ab5c76a2ec88143a674d685c0e739056702e5c3 +F src/sqlite.h.in 3426a080ea1f222a73e3bd91e7eacbd30570a0117c03d42c6dde606f33e5e318 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h c01115c8dd967f7d334a98ba37ac821eafb04144c8085a795daaf2185743d27a +F src/sqliteInt.h e56aa05ef78513cd596c30a56fda68cd9bba91d444ac40e135e919fed40cd875 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 986b6391f02cd9b53c1d688be55899f6ffddeb8e8014cd83c1b73ff912579a71 -F src/test1.c 465b7a35b7e231bf2833e47c1371b5dfc99bd803ebe73783862399d479d696a5 +F src/test1.c cff43d8e21be543b77651b4d2caf49bd6488fee220f8540ecd9f71d13169dbd1 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159 @@ -564,7 +567,7 @@ F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 F src/test_bestindex.c 78809f11026f18a93fcfd798d9479cba37e1201c830260bf1edc674b2fa9b857 F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 -F src/test_config.c 5ea19bf0972a9d91728518b4d30e91477acce80496003ecbef3a7fb18d0bd081 +F src/test_config.c 98698f5242be88af75eaac54adde573471d5ed2f6484e0dac034cb1e763a551a F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f F src/test_demovfs.c 86142ba864d4297d54c5b2e972e74f3141ae4b30f05b3a95824184ed2d3d7f91 F src/test_devsym.c aff2255ea290d7718da08af30cdf18e470ff7325a5eff63e0057b1496ed66593 @@ -603,34 +606,34 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9 F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 4dc01b267593537e2a0d0efe9f80dabe24c5b6f7627bc6971c487fa6a1dacbbf -F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda -F src/trigger.c 515e79206d40d1d4149129318582e79a6e9db590a7b74e226fdb5b2a6c7e1b10 -F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580 -F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78 +F src/tokenize.c 0b9c82fa628b5adce93e2bcaf935a24d43eb83344fb51551f7835526d0693fc4 +F src/treeview.c c6260e1fa5f41c361b2409edc9b0050bcaef5bc4d6abc467fbc45f0d7ccf3d84 +F src/trigger.c bce0908f714a5b89360c01e444521a648997425e2a91ff9b92b899cf8d53c20b +F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 +F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 -F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002 +F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c d24a43b6b1ed2dba893636a14f5e56001444ab3fd5465e3bca8ab01799840acd -F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1 -F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e -F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9 -F src/vdbeaux.c c76b7e96e189f5056d1de914d33d07bd03d3b88741f75375c8e18c9b11ffd379 +F src/vdbe.c 5001a0d3003d3664615dd7ac3cedab1d51e2391b5bdd0878f40a41fdcd942e13 +F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe +F src/vdbeInt.h 000d9ab1ea4cb55a80de15e28f3f595645b4fddef34bca4347fb3db8031d9041 +F src/vdbeapi.c 4a43e303ec3354c785f453e881521969378e85628278ab74ba4a9df790c0d93b +F src/vdbeaux.c 1b3eaa3a70d9d1877266e8ade0d0c3b2b4c6cf77d393d94dbcbd522b9bfefc15 F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a -F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 +F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c -F src/vtab.c 5f5fc793092f53bbdfde296c50f563fb7bda58cf48e9cf6a8bdfbc5abd409845 +F src/vtab.c 032a0165c147fda16927e6a3230e90c068d4af93f887ce94e26f678fe48e5e4c F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a -F src/walker.c 3df26a33dc4f54e8771600fb7fdebe1ece0896c2ad68c30ab40b017aa4395049 -F src/where.c ad738741bf45999188a3047f6277063e3f6843304d581e3ad5875419afdeb6b2 -F src/whereInt.h 59077fbd0b3d01bc8715e746c86a99ebf4c85bde8a57077ec04d2a23e59666ec -F src/wherecode.c a3a1aff30fe99a818d8e7c607980f033f40c68d890e03ed25838b9dbb7908bee -F src/whereexpr.c 3a463e156ea388083c501502229c2c7f4f5c6b5330ea59bdf40d6eb6e155a25f -F src/window.c edd6f5e25a1e8f2b6f5305b7f5f7da7bb35f07f0d432b255b1d4c2fcab4205aa +F src/walker.c d42d6c80ea363ef689a462e65eefcfe87deab924c50de5baa37ecb6af7d7ddaa +F src/where.c 10d06b16670a1d2a992d52a9f08e49426d38a08fb0a7ae5f7f62fd023d560e1e +F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 +F src/wherecode.c e57a8690311a75d06e723e8d379f9831de04aba300e07174d236e32a7f9c7a13 +F src/whereexpr.c d8cafcf6781cf871082f04d7540862cf0fe30cb381dd1b2145a380376364fe8e +F src/window.c 32b03808aff2e7263889cce0cbcb2a68efefc2a9d5187514ddb6a2a1046dc7f5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7 @@ -638,19 +641,23 @@ F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 2f65ec8132e0ca896de550b9908094d49ad65a99116a9d79deeb6017604ad4f6 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13 -F test/alter.test 25e109787dc5e631e117eb6e1c57f96a572bb51228db3b4f8b5f41d665e2ccaa +F test/alter.test f53d8a4ecd35f051c07e54a36beec5d0a30d30a9d98bc723f6cde6afbfb3c5ca F test/alter2.test a966ccfcddf9ce0a4e0e6ff1aca9e6e7948e0e242cd7e43fc091948521807687 F test/alter3.test e487958dec7932453e0b83baf21d6b1e71d5e7d9a55bc20eadfa62a51ddffc29 F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f08cf F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 -F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499 -F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf -F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b +F test/alterauth2.test 794ac5cef251819fe364b4fe20f12f86e9c5d68070513c7fd26c17cb244c89af +F test/altercol.test 3456f7cc4196ef8f7d82d245d6e91940eb12bc95c36c91ac4b512f6b5c9a4fa9 +F test/altercorrupt.test 584d707a80e106952d6382790c8919bcf9f0db678ed3a1c09fd98b7f9d1d3a10 +F test/alterdropcol.test 7c5199c930d3db8621672265db0cc05bfa87867bae1ee5362f3cf4eaf36c06ba +F test/alterdropcol2.test 527fce683b200d620f560f666c44ae33e22728e990a10a48a543280dfd4b4d41 +F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b -F test/altertab.test 6d7bbac2c4a6ef71b775094a3298fa3a92274d95034ee23157ffba92768e47e6 +F test/altermalloc3.test 2c7bbd8cf3e9c4a91e28675bb62bcc2ef70f227967fa74349f03d9f4642f0615 +F test/altertab.test 7691872aadfe00a94b459af9086504bcf399dd936336e486da1b182930744b77 F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b -F test/altertab3.test 1db384eb85b4a30b0b332842f5c596b0dc0126f7c61959be3f85ae8b1c271d9a +F test/altertab3.test 2b82fa2236a3a91553d53ae5555d8e723c7eec174c41f1fa62ff497355398479 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7 F test/analyze3.test fca2a9de0017becfdcc201647f03b1cfd5ba0e7b5b5c852936e4ec62780cde49 @@ -675,7 +682,7 @@ F test/atof1.test 10049623e77006691c4c2978c1dc8a3f75276377a53417811aa85bda7493f9 F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061 F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da F test/atrc.c c388fac43dbba05c804432a7135ae688b32e8f25818e9994ffba4b64cf60c27c -F test/attach.test d42862c72fef3d54367d962d41dcfb5363442a4a1bd898c22ae950cea1aa0dd3 +F test/attach.test 54f8e49e88d0de48f6428267a678465863d2b8f72320612f35bd5c02e240bc2f F test/attach2.test 256bd240da1835fb8408dd59fb7ef71f8358c7a756c46662434d11d07ba3a0ce F test/attach3.test c59d92791070c59272e00183b7353eeb94915976 F test/attach4.test aa05b1d8218b24eba5a7cccf4f224f514ba57ba705c9267f09d2bb63fed0eea1 @@ -692,10 +699,11 @@ F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf F test/autoindex5.test a5d72fe8c217cc0ea356dc6fa06a282a8a3fc53aa807709d79dba07a8f248102 F test/autovacuum.test 0831cd34e14695d297187f7f6519265e3121c5b0a1720e548e86829e796129e9 F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 +F test/avfs.test 0c3a38e03cccb0fc3127838462dc05dc3f4c1480d770c084b388304c25de3652 F test/avtrans.test b7dc25459ecbd86c6fa9c606ee3068f59d81e225118617dcf2bbb6ded2ade89e F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d F test/backup.test dd4a5ff756e3df3931dacb1791db0584d4bad989 -F test/backup2.test 1fd1ad8c5b3d2d5b9c0cce4143a4fc610d51ddc6ae16a7a122973d43e6b50bbd +F test/backup2.test 8facb54df1388419d34b362ab1f7e233310ff3a3af64e8ad5ec47ba3c2bbe5cf F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32 F test/backup5.test ee5da6d7fe5082f5b9b0bbfa31d016f52412a2e4 F test/backup_ioerr.test 4c3c7147cee85b024ecf6e150e090c32fdbb5135 @@ -764,6 +772,7 @@ F test/collateA.test b8218ab90d1fa5c59dcf156efabb1b2599c580d6 F test/collateB.test 1e68906951b846570f29f20102ed91d29e634854ee47454d725f2151ecac0b95 F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1 F test/colname.test 87ad5458bb8709312dac0d6755fd30e8e4ca83298d0a9ef6e5c24277a3c3390e +F test/columncount.test eff33d402a7b0fde0a52a1920d238af200ca573327021e0ce3b7e5688de41449 F test/conflict.test ac0667090f66130ac77d5fb764655558ca6600dd6d88f670ca9123b61c448337 F test/conflict2.test 5557909ce683b1073982f5d1b61dfb1d41e369533bfdaf003180c5bc87282dd1 F test/conflict3.test 81865d9599609aca394fb3b9cd5f561d4729ea5b176bece3644f6ecb540f88ac @@ -790,6 +799,7 @@ F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af F test/corruptL.test 22589f503602cc5984e80f27f46c4de2134f24f1515ba2440513c377cb692258 F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067 +F test/corruptN.test 781c5f26a2d8918f03d45ac4968a738031eeb113a4b153c7588756d9b09c7b04 F test/cost.test 1d156ce9858780a966c062694687afe0343a0ed12d081d071fb57027e726bafc F test/count.test e0699a15712bc2a4679d60e408921c2cce7f6365a30340e790c98e0f334a9c77 F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86 @@ -798,7 +808,7 @@ F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651 F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418 F test/crash4.test fe2821baf37168dc59dd733dcf7dba2a401487bc -F test/crash5.test f14ff37eddc41991be4eb63568f86caa306fd9962a0ae3750db8836777bb7aae +F test/crash5.test 4aa55e7ac3c4bc511873e457aa65d2827d52da9b51e061511899dadcfe22b1e8 F test/crash6.test 4c56f1e40d0291e1110790a99807aa875b1647ba F test/crash7.test 1a194c4900a255258cf94b7fcbfd29536db572df F test/crash8.test 64366e459c28dd62edfb7ad87253a409c7533b92d16fcc479a6a8131bdcc3100 @@ -812,12 +822,12 @@ F test/cursorhint.test 0175e4404181ace3ceca8b114eb0a98eae600d565aa4e2705abbe6614 F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8 F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373 -F test/date2.test 520a1708e4e14c682cf514560f3e9f2e5affa9d66560fbc2a6941ae291260daf +F test/date2.test 7e12ec14aaf4d5e6294b4ba140445b0eca06ea50062a9c3a69c4ee13d0b6f8b1 F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbfuzz001.test 55e1a3504f8dea84155e09912fe3b1c3ad77e0b1a938ec42ca03b8e51b321e30 F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee -F test/dbfuzz2.c 40cc4600947f30600f0ab365a2714ec76a899c9adb2c0ccd63ba583b2f71390e +F test/dbfuzz2.c db2a1710c0d30d38e1352ee1b52b717fcb224c8caacc6f10909ef540f73cc9e8 F test/dbpage.test 650234ba683b9d82b899c6c51439819787e7609f17a0cc40e0080a7b6443bc38 F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759 F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef @@ -845,7 +855,7 @@ F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 235c610f8bf8ec44513e222b9085c7e49fad65ad0c1975ac2577109dd06fd8fa F test/e_dropview.test 74e405df7fa0f762e0c9445b166fe03955856532e2bb234c372f7c51228d75e7 F test/e_expr.test 6ba7a51ece7b3e7fc145f14f924eed25ebb5a24e7b8596c78f3838d372cf0385 -F test/e_fkey.test 0b458b85f192cdb9e9933d5891848bb19bcc44d3f49faf111a375f2844a164d3 +F test/e_fkey.test a2907f749cccd0b2c30d8576b673002eebdcc1fc9964bae61e5117b1d54733e2 F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07 F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e F test/e_reindex.test 2b0e29344497d9a8a999453a003cb476b6b1d2eef2d6c120f83c2d3a429f3164 @@ -872,6 +882,8 @@ F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650 F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac +F test/exists2.test 47970f2ce98826519cc38ce502b718641755b30a93d9b89915019ba1e770f361 +F test/existsfault.test 74f7edc713f5a335e7ff47adf503067bf05c6f8630f88b2a19c24f0fa5486ab8 F test/expr.test 26cd01e8485bc48c8aa6a1add598e9ce1e706b4eb4f3f554e0b0223022e8c2cf F test/expr2.test c27327ae9c017a7ff6280123f67aff496f912da74d78c888926d68b46ec75fd8 F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9 @@ -957,9 +969,9 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f F test/fts3corrupt.test 79a32ffdcd5254e2f7fa121d9656e61949ad049c3c6554229911b7ceac37c9c6 F test/fts3corrupt2.test e318f0676e5e78d5a4b702637e2bb25265954c08a1b1e4aaf93c7880bb0c67d0 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f -F test/fts3corrupt4.test e4662d37f02248301d8b58778eac380663e09a17a38dd5d6bb5ea4c927b9a575 +F test/fts3corrupt4.test b71512ec391d39da96d60d01959e4e9f20d4237a964a94abcf5f5a2ad28378c1 F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5 -F test/fts3corrupt6.test b6c55218b704b0cef224b284c756f9c55d0afd0b3c3837618bffeaa8c31e0d8e +F test/fts3corrupt6.test d5896a8d389bd824457772dc1e2d2023cd5c5cf8e42733607b5d632103018d8b F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f F test/fts3defer.test f4c20e4c7153d20a98ee49ee5f3faef624fefc9a067f8d8d629db380c4d9f1de @@ -1014,9 +1026,9 @@ F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309 F test/fts4onepass.test d69ddc4ee3415e40b0c5d1d0408488a87614d4f63ba9c44f3e52db541d6b7cc7 F test/fts4opt.test 0fd0cc84000743ff2a883b9b84b4a5be07249f0ba790c8848a757164cdd46b2a F test/fts4record.test a48508f69a84c9287c8019d3a1ae712f5730d8335ffaf8e2101e691d078950bb -F test/fts4rename.test 15fd9985c2bce6dea20da2245b22029ec89bd4710ed317c4c53abbe3cfd0c880 +F test/fts4rename.test 2e0565ffd92b2c51f1a757df0b8f2ca30537197106fec09e943919801d173692 F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429 -F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95 +F test/fts4unicode.test 82a9c16b68ba2f358a856226bb2ee02f81583797bc4744061c54401bf1a0f4c9 F test/fts4upfrom.test 8df5acb6e10ad73f393d1add082b042ab1db72567888847d098152121e507b34 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d F test/func.test f673822636fb8ed618dd2b80230d16e495d19c8f2e2e7d6c22e93e2b3de097ad @@ -1025,6 +1037,7 @@ F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1 F test/func4.test 2285fb5792d593fef442358763f0fd9de806eda47dbc7a5934df57ffdc484c31 F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d82a F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c +F test/func7.test b9e2a1a30a8562b00841b4a21a5d2d81754fa3ab99275fd71fd5279287b44b1c F test/fuzz-oss1.test e58330d01cbbd8215ee636b17a03fe220b37dbfa F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1 F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 @@ -1032,7 +1045,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 -F test/fuzzcheck.c 5f81f2cc65f13068620245f2e2c6059657d3b26be476df379ae2da539f17676d +F test/fuzzcheck.c 772110a59c6f839f95e49a9fd3e5f855bd9cbb90e9d366a6ccd15cb3616fc631 F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1040,17 +1053,17 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2 -F test/fuzzdata8.db f8451a1fd38efbea8c1a7cdf5d02259c4702446a9fabf566becd306b64a50236 +F test/fuzzdata8.db c8325de6fbdd24d030cd3a01384a2ff325dda5d5e3ff5d531a26ada3d9d7e010 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 -F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 +F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c F test/gencol1.test b05e6c5edb9b10d48efb634ed07342441bddc89d225043e17095c36e567521a0 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 -F test/having.test ea5cb01cdf3d90fd1b516ef36b1fbde518dbbd61c50141f5eb830d8101844040 +F test/having.test a89236dd8d55aa50c4805f82ac9daf64d477a44d712d8209c118978d0ca21ec9 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 F test/hidden.test 23c1393a79e846d68fd902d72c85d5e5dcf98711 -F test/hook.test e97382e68e4379838e888756d653afd159f5f14780315ff97b70360d3d8485bc +F test/hook.test fa54fa8afc842ae375f10c1f9fc0014fa59789052fc30c9eae19811fa3afa009 F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8 F test/icu.test 716a6b89fbabe5cc63e0cd4c260befb08fd7b9d761f04d43669233292f0753b1 F test/ieee754.test b0945d12be7d255f3dfa18e2511b17ca37e0edd2b803231c52d05b86c04ab26e @@ -1058,7 +1071,7 @@ F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 F test/in.test 688ed2011d922d83141a45af431601738674a4c0bdde34b6351f688b82a169b3 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 -F test/in4.test 65460600d48933adba4283c6ebd089aae173d16136ab9d01f74c89089090c5a5 +F test/in4.test 64ac9c767ac5af562f066a40163d4202f8fa3be05d264ec65d6258e74606b30c F test/in5.test b32ce7f4a93f44c5dee94af16886d922cc16ebe33c8e1765c73d4049d0f4b40f F test/in6.test 8562d0945195cab3cc4ab3794e9118e72cb44c43f785c2b04d48a9d06ca6b4ec F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 @@ -1081,7 +1094,7 @@ F test/index6.test f172653b35b20233e59200e8b92a76db61bf7285437bf777b93b306ba26a4 F test/index7.test b8a0ba2110fd517bb48c4e76d26d60f1ab2ed9e257b18d71f820d7e71e9f8570 F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 -F test/indexedby.test f54aac21c06948872010a956fd02de5178c362c7785a9887cf0b8616be17883b +F test/indexedby.test a3ca11f0819a9279619099f36b624bcaa315f7a1ed65c3ed2219c2a944683d2c F test/indexexpr1.test 284e119999d132cc8bf37735a928c9859b28e8e295d02b7a6a4f93977c7f9ba5 F test/indexexpr2.test dba11dbb0a58fcba4cd694f46b4004976123b81b0501f525d43c9be59f0207b1 F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811 @@ -1129,10 +1142,10 @@ F test/kvtest.c feb4358fb022da8ebd098c45811f2f6507688bb6c43aa72b3e840df19026317b F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7 -F test/like.test 47b81d5de2ff19d996d49a65d50ec9754246aacbe0e950b48d186d9d8171eaf0 +F test/like.test 0b7b4765ca59d95a1f92dfab9e4d810c9fb8280b5edd6332a01340a20db9e0ed F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da F test/like3.test 03d1bdf848483b78d2cfd1db283d75c4ec2e37c8b8eccc006813f3978d78fbbd -F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e +F test/limit.test 350f5d03c29e7dff9a2cde016f84f8d368d40bcd02fa2b2a52fa10c4bf3cbfaf F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04 F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7 @@ -1212,6 +1225,8 @@ F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18 +F test/notnull2.test d5e27e7eb9ff80c587998088a3c40dcc9e4faa71c7ec27a41b4435b0f3b8fdc9 +F test/notnullfault.test 6126e31300632070ca6021698393c7fcf61ab4791bc2aa1d6d704242c0fcd4f8 F test/null.test b7ff206a1c60fe01aa2abd33ef9ea83c93727d993ca8a613de86e925c9f2bc6f F test/nulls1.test 82c5bc33148405f21205865abf13c786084438d573a4ac4e87e11b6091cde526 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 @@ -1248,7 +1263,7 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035c F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test 661a4325a5717957a77836910ee164ba26594a502d7a3df0e1ae7b9cba829c5d +F test/permutations.test 0a7cf0b6b1283cdd4f0d6e31cb7afbde81d20b1caef60b73914e85b6bf660b8a F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f F test/pragma.test 50b91bedea9324d3ab48e793f908ee7d2c7dcf84bfa2281e792838be59641ec8 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f @@ -1267,7 +1282,7 @@ F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 F test/quota.test bfb269ce81ea52f593f9648316cd5013d766dd2a F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8 -F test/quote.test 3f9238ab0e1db70dea89af9afa5859dbd759b0ce0a63da67d547553e2c316475 +F test/quote.test b8ddaba6b81dcf63bb31243219e28a2f96e04396adc50108cc7e5593019c3eb5 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736 @@ -1277,9 +1292,10 @@ F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d F test/releasetest.tcl fb76d8fcc95ac29d6356cd9e52b726ab9e43a24082897618dfbcb7c2b0049153 x -F test/releasetest_data.tcl b9cb30360759b80d92d4ea86b84ebfd8035b97f9078a482deb3cf9d0b2442655 +F test/releasetest_data.tcl 3d41ddb3f04f474ac9d925485da24ce6576ff0ebc4c7201c8a340bc09846c261 F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb +F test/returning1.test ce2192b40045cc94d53ac5ec5789a72a3ade233a6ea6e29666e296d151b59479 F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8d38bb6 F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a @@ -1287,7 +1303,7 @@ F test/round1.test 768018b04522ca420b1aba8a24bd76091d269f3bce3902af3ec6ebcee41ab F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test bfbd7b97d9267660be3c8f28507c4ed7f205196b8877c0db42df347c2e8845e3 -F test/rowvalue.test 8964f95b253d3b5cc8dc1cfd0cdb7529bce3ecc6b6259e23c5f829f80f4d51cd +F test/rowvalue.test 6795850abf6243e96f09ef041919d1ea61713332237b60d01371c0fee73f6379 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 F test/rowvalue4.test 02e35f7762371c2f57ebd856aa056eac56cb27ef7715a0bb31eac1895a745356 @@ -1317,10 +1333,10 @@ F test/schema6.test e4bd1f23d368695eb9e7b51ef6e02ca0642ea2ab4a52579959826b5e7dce F test/schemafault.test 1936bceca55ac82c5efbcc9fc91a1933e45c8d1e1d106b9a7e56c972a5a2a51e F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2ff09384 F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 -F test/select1.test 0ed936740777f52858b6607f39ffac4b2b63b8fc7edf3ab2ebad3c3553ceecee +F test/select1.test 3d23f66bf9ba77570acfe2ca5f1540ece17037cc64ab1a00efec9758ac29c268 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select3.test c49fbb758903f3718e2de5aa4655eda4838131cbea24a86db908f8b6889aa68c -F test/select4.test e8a2502e3623f3058871030599a48abb35789d2244d5b380ecf3696873fdd4a4 +F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b F test/select5.test df9ec0d218cedceb4fe7b63262025b547b50a55e59148c6f40b60ca25f1d4546 F test/select6.test 319d45e414cdd321bf17cfacedaf19e3935ad64dac357c53f1492338c6e9b801 F test/select7.test f659f231489349e8c5734e610803d7654207318f @@ -1328,7 +1344,7 @@ F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95 F test/selectA.test 68de52409e45a3313d00b8461b48bef4fb729faf36ade9067a994eae55cc86f4 F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25 -F test/selectC.test e25243f8ca503e06f252eb0218976d07cfeceac3 +F test/selectC.test fec14c9015ed4ec941508bbc144f30b42e40ac34a4bb33001450369865dd0b75 F test/selectD.test fc20452847a01775710090383cfb4423275d2f745fed61f34fbf37573ac0d214 F test/selectE.test a8730ca330fcf40ace158f134f4fe0eb00c7edbf F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3 @@ -1349,10 +1365,10 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 0ba53c72545de142e1b76fa793ee33293134aa02abb9b50b35398670481ea661 +F test/shell1.test 56a7358a2a05e850e9e4aa24629db9c8975e8038dbe8debd2d95be22a5f03612 F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell3.test ac8c2b744014c3e9a0e26bfd829ab65f00923dc1a91ffd044863e9423cc91494 -F test/shell4.test 1c6aef11daaa2d6830acaba3ac9cbec93fbc1c3d5530743a637f39b3987d08ce +F test/shell4.test 3ed6c4b42fd695efcbc25d69ef759dbb15855ca8e52ba6c5ee076f8b435f48be F test/shell5.test 84a30b55722a95a5b72989e691c469a999ca7591e7aa00b7fabc783ea5c9a6fe F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3 F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f @@ -1390,7 +1406,7 @@ F test/speed3.test 694affeb9100526007436334cf7d08f3d74b85ef F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c -F test/speedtest1.c 849dbcb0bded9f966e43f28e8ce824b2915cb5dd0031a2e85996f7e3de36c2b1 +F test/speedtest1.c 5e5b805f24cc939656058f6a498f5a2160f9142e4815c54faf758ec798d4cdad F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 @@ -1398,6 +1414,7 @@ F test/spellfix4.test 51c7c26514ade169855c66bcf130bd5acfb4d7fd090cc624645ab275ae F test/sqldiff1.test 28cd737cf1b0078b1ec1bbf425e674c47785835e F test/sqllimits1.test 264f4b0f941800ba139d25e33ee919c5d95fea06dfbe8ac291d6811a30984ca5 F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a +F test/startup.c 1beb5ca66fcc0fce95c3444db9d1674f90fc605499a574ae2434dcfc10d22805 F test/stat.test 15a3106eddedfc882f64bc09f237b4169be4b92dd57c93031b8ff8b13af3e7c5 F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 54ed2cc0764bf3e48a058331813c3dbd19fc1d0827c3d8369914a5d8f564ec75 @@ -1431,7 +1448,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc -F test/tester.tcl 754521f0db534d51ab504b2d14fe0bdca1f1c15de731ceb8ee5bfd78372a2a5f +F test/tester.tcl 19d2a19a6dd55a2b4e2b943963959a05a2c088495dd5f5274b04e0494ce86d66 F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1592,7 +1609,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7 F test/tpch01.test 7c4eb8cdd79c568f46d344b3e789c9fdb8a766d112871352704861f3fca32a2a F test/trace.test a659a9862957f4789e37a92b3bf6d2caf5c86b02cdeefc41e850ae53acf6992a F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983 -F test/trace3.test 1dff966888773ff1bfea01c080caf15417892b3f998408fe920c4791f7337144 +F test/trace3.test ae2004df24b585fed9046cc0bae4601762bc6fc4aa321d475f1350bba5047f31 F test/trans.test 45f6f9ab6f66a7b5744f1caac06b558f95da62501916906cf55586a896f9f439 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 @@ -1610,7 +1627,7 @@ F test/triggerA.test 837be862d8721f903dba3f3ceff05b32e0bee5214cf6ea3da5fadf12d36 F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe F test/triggerC.test 29f5a28d0fe39e6e2c01f6e1f53f08c0955170ae10a63ad023e33cb0a1682a51 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650 -F test/triggerE.test ede2e4bce4ba802337bd69d39447fa04a938e06d84a8bfc53c76850fc36ed86d +F test/triggerE.test 612969cb57a4ef792059ad6d01af0117e1ae862c283753ffcc9a6428642b22ee F test/triggerF.test 5d76f0a8c428ff87a4d5ed52da06f6096a2c787a1e21b846111dfac4123de3ad F test/triggerG.test 2b816093c91ba73c733cfa8aedcc210ad819d72a98b1da30768a3c56505233e9 F test/triggerupfrom.test d25961fa70a99b6736193da7b49a36d8c1d28d56188f0be6406d4366315cd6e4 @@ -1624,6 +1641,9 @@ F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a +F test/unionall.test 369dac51f4e7b94442b054d3d7f2e6755cd6994274718228878e3bd47c425f6d +F test/unionall2.test c9a62db63350bcbce3a7bec50dd8c5410f08be33f8af435473756286d4657215 +F test/unionallfault.test 652bfbb630e6c43135965dc1e8f0a9a791da83aec885d626a632fe1909c56f73 F test/unionvtab.test e1704ab1b4c1bb3ffc9da4681f8e85a0b909fd80b937984fc94b27415ac8e5a4 F test/unionvtabfault.test e8759f3d14fb938ce9657e2342db34aeac0fb9bc1692b0d1ebb0069630151d06 F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264 @@ -1641,6 +1661,7 @@ F test/upsert1.test 88f9e258c6a0eeeb85937b08831e8daad440ba41f125af48439e9d33f266 F test/upsert2.test 9c3cdbb1a890227f6504ce4b0e3de68f4cdfa16bb21d8641208a9239896c5a09 F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5 +F test/upsert5.test fff0dcfce73c649204543088d8e5bde01172676063ec9b8f8fc7f195abc386fe F test/upsertfault.test f21ca47740841fdb4d61acfa7b17646d773e67724fe8c185b71c018db8a94b35 F test/uri.test 3481026f00ade6dfe8adb7acb6e1e47b04369568 F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 @@ -1648,14 +1669,15 @@ F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 F test/utf16align.test 54cd35a27c005a9b6e7815d887718780b6a462ae F test/vacuum-into.test 48f4cec354fb6f27c98ef58d2fe49a11b71ff131af0cd9140efacc9858b9f670 F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d -F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b +F test/vacuum2.test 9fd45ce6ce29f5614c249e03938d3567c06a9e772d4f155949f8eafe2d8af520 F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum4.test 7ea76b769fffeb41f925303b04cbcf5a5bbeabe55e4c60ae754ff24eeeb7c010 F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2f48c +F test/vacuum6.test d3173a54edc81d13d99e4cf4972232b3cbb52f1d56ed48c3a939ef4e751c1ee8 F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 -F test/view.test fd48eddb32a35a98c3de70062ebac66ebf4a2bbfc75a1cc1109159ef8bfc47a9 +F test/view.test ea88361d5e9bc8eabf9f573185a16aea73a885be9b6c6a95ae84908913416a80 F test/vtab1.test c5d9e90ed02bcacd776dcbb7360199d290f7f53c26b484ddece543060c54319f F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e @@ -1678,7 +1700,7 @@ F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c37 F test/vtab_err.test dcc8b7b9cb67522b3fe7a272c73856829dae4ab7fdb30399aea1b6981bda2b65 F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad F test/vtabdrop.test 65d4cf6722972e5499bdaf0c0d70ee3b8133944a4e4bc31862563f32a7edca12 -F test/wal.test 16180bc4becda176428ad02eaea437b4b8f5ae099314de443a4e12b2dcc007a2 +F test/wal.test b7cc6984709f54afbf8441747ced1f646af120bf0c1b1d847bfa39306fbea089 F test/wal2.test 31f6e2c404b9f2cdf9ca19b105a1742fdc19653c2c936da39e3658c617524046 F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c @@ -1713,7 +1735,7 @@ F test/walsetlk.test 11f7fe792fdce54cf09874dab824e0627f2eedecfb9f7983e325606ec51 F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417 F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 -F test/walvfs.test a2913001a83b19c1d20220e556cee14d87d47ecb6949b5e0a2e9e2590abecf1e +F test/walvfs.test bccb3e0d235ef85e276f491d34db32c9ada1ea67be8d9f10aabe7b30319ec656 F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec F test/wapptest.tcl 899594e25684861d5b0c0880fb012364def50ef8097041b8ddf74be5ba7fa270 x F test/where.test e713c0c64e3e6b062235e39a2f7e5508c517df16b63d69fd786e26bc7330b1c6 @@ -1736,10 +1758,10 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test a2874062140ed4aba9ffae76e6190a3df6fc73d1373fdfa8fd632945082a5364 F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b -F test/whereL.test e05cedc9389c6f09ad55bd5999a3fddccebec90672fb989433c145dcdaf26996 +F test/whereL.test 1afe47227f093dc0547236491fb37529b7be9724b8575925a321001b80e6a23a F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3 -F test/wherelimit.test 592081800806d297dd7449b1030c863d2883d6d42901837ccd2e5a9bd962edb0 +F test/wherelimit.test afb46397c6d7e964e6e294ba3569864a0c570fe3807afc634236c2b752372f31 F test/wherelimit2.test 657a3f24aadee62d058c5091ea682dc4af4b95ffe32f137155be49799a58e721 F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2aeee74 F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972 @@ -1758,17 +1780,19 @@ F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d761 F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1ce2 F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b -F test/window9.test 4d8c875b73febdbac9b8f2b52ec132b98f48261cdafd6b08db62bc6d8ff913fc +F test/window9.test 349c71eab4288a1ffc19e2f65872ec2c37e6cf8a1dda2ad300364b7450ae4836 F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be -F test/windowB.test 7a983ea1cc1cf72be7f378e4b32f6cb2d73014c5cd8b25aaee825164cd4269e5 +F test/windowB.test 6e601f8178ba8ba28b2f19e74fe613815084bb4a8d2ad942defc7d42e191e521 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b -F test/windowfault.test 72375ae71031eabf96bc88d0af128c8628a091ddc99b5a394e848b3df5fc17ad +F test/windowfault.test d543d46571b32d19f198cb04b6505747fabf3cc369970daae47074ee793612be +F test/windowpushd.test 5b9c114e8173c3addacf58a0fcd941437b14649f2033700184479a13f188ad00 F test/with1.test 780be387f01e290e768bdfd1827280f9e37ba37223eb4736aba386864fac5a94 -F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab -F test/with3.test a261f0ea225c4af0ce6447f1157bb603959b2a665f14a03951c2883d2ef1c0f0 +F test/with2.test 000fb95f1f29dae868cea0f41505eb5126077d49eb967ff88f9ee46212ad8863 +F test/with3.test 2f1e05aef7aeef9a741cbf36deeb4be73003dc541921c3abc78becbbf5b7852d F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205 F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8 +F test/with6.test 3001b59179cbdc26a8c67ff8f46944e3141fdece9ab064c49bbf08459b67b207 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 F test/without_rowid1.test e4034c0849ccc2e8bb749c69f15bd69bb9fcf8fe77e8d17ce02369604242fe83 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1805,8 +1829,8 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5 F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c 70eedc31614a58fe31a71025c17ebd1502a6ce9cfef0ed5e33acb0b5b737b291 -F tool/lempar.c 0e1d5eeb9736108d3dba782a9dd56f4e7cb69006b6ee181308b7ebfb15313a12 +F tool/lemon.c d44ba4f03427c9bd34b601f315fe77c2b6d4bd215801a0259aeedbcc4c94a95c +F tool/lempar.c 1d3d075da18681c67ecc66c1f171e7094e18cd2cfba6a8a1bd4f3f639d6656e1 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1814,7 +1838,7 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8 F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3 -F tool/mkkeywordhash.c 11a3f3af8e787d0c5ca459ed66fe80fd09e661876506e7b978ec08c19477bdc2 +F tool/mkkeywordhash.c 08b6e4d7a482a7f37a9a0032e7ba968e26624a027b6b2e9ba589be6f5e3d8c2c F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 @@ -1851,7 +1875,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl 3efcd4240b738f6bb2b5af0aea7e1e0ef9bc1c61654f645076cec883030b710c -F tool/sqldiff.c 4151108387cb56c08906e5ac8d6a353dcfe8fc6014eeded0f0910e2230ea0f5b +F tool/sqldiff.c 21226ef092ec1e543b237c5d3d2d32d344a60f2437eadfea04f65b348fbd00e4 F tool/sqlite3_analyzer.c.in 7eeaae8b0d7577662acaabbb11107af0659d1b41bc1dfdd4d91422de27127968 F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 @@ -1886,10 +1910,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 23212b1a054f05773a9f69f9802035eea6a9d759a2a09e22f46d1046c058b417 -R 02db8b9bcb7f3c64353edbc1fa9fbf5b -T +bgcolor * #d0c0ff +P d917b70a35cce7d82a848b1ff5e8bea182217a2c6a4a3a3d6cc914cc26144ea6 +R eda62fe381e7f0ef5c89c883a9c1cd96 T +sym-release * -T +sym-version-3.34.0 * +T +sym-version-3.35.5 * U drh -Z b7b093d44b407c1b4e832f8c913357ae +Z d4483274bc32f4bc8681ec9b9f324b4a diff --git a/chromium/third_party/sqlite/src/manifest.uuid b/chromium/third_party/sqlite/src/manifest.uuid index cd09bbf164e..f85c5071b96 100644 --- a/chromium/third_party/sqlite/src/manifest.uuid +++ b/chromium/third_party/sqlite/src/manifest.uuid @@ -1 +1 @@ -0000000000000000000000000000000000000000000000000000000000000000 +1b256d97b553a9611efca188a3d995a2fff712759044ba480f9a0c9e98fae886
\ No newline at end of file diff --git a/chromium/third_party/sqlite/src/src/alter.c b/chromium/third_party/sqlite/src/src/alter.c index f4098863dda..175f8981cfe 100644 --- a/chromium/third_party/sqlite/src/src/alter.c +++ b/chromium/third_party/sqlite/src/src/alter.c @@ -49,15 +49,22 @@ 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 */ + const char *zDropColumn /* Name of column being dropped */ +){ + pParse->colNamesSet = 1; sqlite3NestedParse(pParse, "SELECT 1 " "FROM \"%w\"." DFLT_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, %Q)=NULL ", zDb, - zDb, bTemp + zDb, bTemp, zWhen, zDropColumn ); if( bTemp==0 ){ @@ -66,8 +73,8 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ "FROM temp." DFLT_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, %Q)=NULL ", + zDb, zWhen, zDropColumn ); } } @@ -76,12 +83,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); } } @@ -230,7 +237,7 @@ 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); @@ -249,8 +256,8 @@ 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); @@ -381,11 +388,14 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ *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: */ sqlite3NestedParse(pParse, "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " - "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " + "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->addColOffset, zCol, pNew->addColOffset, zTab ); sqlite3DbFree(db, zCol); @@ -409,7 +419,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ } /* Reload the table definition */ - renameReloadSchema(pParse, iDb); + renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); } /* @@ -509,7 +519,7 @@ exit_begin_add_column: ** 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 ){ @@ -522,15 +532,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 /* @@ -559,7 +570,7 @@ 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); @@ -613,8 +624,8 @@ void sqlite3AlterRenameColumn( ); /* 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", 0); exit_rename_column: sqlite3SrcListDelete(db, pSrc); @@ -866,23 +877,33 @@ 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, + void *pPtr +){ RenameToken **pp; assert( pPtr!=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; } /* @@ -953,7 +974,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 @@ -962,8 +983,8 @@ 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 = sqlite3_mprintf("error in %s %s%s%s: %s", + zT, zN, (zWhen[0] ? " " : ""), zWhen, pParse->zErrMsg ); sqlite3_result_error(pCtx, zErr, -1); @@ -1028,12 +1049,17 @@ static int renameParseSql( const char *zDb, /* Name of schema SQL belongs to */ sqlite3 *db, /* Database handle */ const char *zSql, /* SQL to parse */ - int bTemp /* True if SQL is from temp schema */ + int bTemp, /* True if SQL is from temp schema */ + const char *zDropColumn /* Name of column being dropped */ ){ int rc; char *zErr = 0; db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); + if( zDropColumn ){ + db->init.bDropColumn = 1; + db->init.azInit = (char**)&zDropColumn; + } /* 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 @@ -1042,7 +1068,7 @@ static int renameParseSql( p->eParseMode = PARSE_MODE_RENAME; p->db = db; p->nQueryLoop = 1; - rc = sqlite3RunParser(p, zSql, &zErr); + rc = zSql ? sqlite3RunParser(p, zSql, &zErr) : SQLITE_NOMEM; assert( p->zErrMsg==0 ); assert( rc!=SQLITE_OK || zErr==0 ); p->zErrMsg = zErr; @@ -1066,6 +1092,7 @@ static int renameParseSql( #endif db->init.iDb = 0; + db->init.bDropColumn = 0; return rc; } @@ -1195,7 +1222,7 @@ static int renameResolveTrigger(Parse *pParse){ if( pSrc ){ int i; for(i=0; i<pSrc->nSrc && rc==SQLITE_OK; i++){ - struct SrcList_item *p = &pSrc->a[i]; + SrcItem *p = &pSrc->a[i]; p->iCursor = pParse->nTab++; if( p->pSelect ){ sqlite3SelectPrep(pParse, p->pSelect, 0); @@ -1221,9 +1248,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; @@ -1368,7 +1394,7 @@ static void renameColumnFunc( #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = 0; #endif - rc = renameParseSql(&sParse, zDb, db, zSql, bTemp); + rc = renameParseSql(&sParse, zDb, db, zSql, bTemp, 0); /* Find tokens that need to be replaced. */ memset(&sWalker, 0, sizeof(Walker)); @@ -1410,12 +1436,12 @@ static void renameColumnFunc( for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){ sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } - } #ifndef SQLITE_OMIT_GENERATED_COLUMNS - for(i=0; i<sParse.pNewTable->nCol; i++){ - sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); - } + for(i=0; i<sParse.pNewTable->nCol; i++){ + sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); + } #endif + } for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ for(i=0; i<pFKey->nCol; i++){ @@ -1469,7 +1495,7 @@ static void renameColumnFunc( renameColumnFunc_done: if( rc!=SQLITE_OK ){ if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); } @@ -1507,7 +1533,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ return WRC_Abort; } for(i=0; i<pSrc->nSrc; i++){ - struct SrcList_item *pItem = &pSrc->a[i]; + SrcItem *pItem = &pSrc->a[i]; if( pItem->pTab==p->pTab ){ renameTokenFind(pWalker->pParse, p, pItem->zName); } @@ -1572,7 +1598,7 @@ static void renameTableFunc( sWalker.xSelectCallback = renameTableSelectCb; sWalker.u.pRename = &sCtx; - rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp, 0); if( rc==SQLITE_OK ){ int isLegacy = (db->flags & SQLITE_LegacyAlter); @@ -1658,7 +1684,7 @@ static void renameTableFunc( } if( rc!=SQLITE_OK ){ if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); } @@ -1687,6 +1713,8 @@ 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: Name of column being dropped, or NULL. ** ** Unless it finds an error, this function normally returns NULL. However, it ** returns integer value 1 if: @@ -1704,6 +1732,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]); + char const *zDropColumn = (const char*)sqlite3_value_text(argv[6]); #ifndef SQLITE_OMIT_AUTHORIZATION sqlite3_xauth xAuth = db->xAuth; @@ -1714,7 +1744,7 @@ static void renameTableTest( if( zDb && zInput ){ int rc; Parse sParse; - rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp, zDropColumn); if( rc==SQLITE_OK ){ if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){ NameContext sNC; @@ -1736,8 +1766,8 @@ static void renameTableTest( } } - if( rc!=SQLITE_OK ){ - renameColumnParseError(context, 1, argv[2], argv[3], &sParse); + if( rc!=SQLITE_OK && zWhen ){ + renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse); } renameParseCleanup(&sParse); } @@ -1748,13 +1778,216 @@ static void renameTableTest( } /* +** 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, 0); + 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].zName); + if( iCol<pTab->nCol-1 ){ + RenameToken *pEnd; + pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zName); + zEnd = (const char*)pEnd->t.z; + }else{ + zEnd = (const char*)&zSql[pTab->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. +*/ +void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, 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: \"%s\"", zCol); + 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; + renameTestSchema(pParse, zDb, iDb==1, "", 0); + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." DFLT_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", zCol); + + /* 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; i<pPk->nKeyCol; i++){ + sqlite3VdbeAddOp3(v, OP_Column, iCur, i, reg+i+1); + } + nField = pPk->nKeyCol; + } + regRec = ++pParse->nMem; + for(i=0; i<pTab->nCol; 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( iPos<pPk->nKeyCol ) 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++; + } + } + 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 */ 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), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); } diff --git a/chromium/third_party/sqlite/src/src/attach.c b/chromium/third_party/sqlite/src/src/attach.c index 3b5c57f0ccd..8eb4486e582 100644 --- a/chromium/third_party/sqlite/src/src/attach.c +++ b/chromium/third_party/sqlite/src/src/attach.c @@ -434,6 +434,62 @@ void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ #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; i<pList->nSrc; 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 WRC_Abort; + } + 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( sqlite3WalkExpr(&pFix->w, pList->a[i].pOn) ) return WRC_Abort; +#endif + } + if( pSelect->pWith ){ + for(i=0; i<pSelect->pWith->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. */ @@ -444,9 +500,7 @@ 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; @@ -454,6 +508,13 @@ 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 = 0; + pFix->w.walkerDepth = 0; + pFix->w.eCode = 0; + pFix->w.u.pFix = pFix; } /* @@ -474,115 +535,27 @@ 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; i<pList->nSrc; 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) 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; i<pSelect->pWith->nCte; i++){ - if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){ - return 1; - } - } - } - pSelect = pSelect->pPrior; - } - return 0; + return sqlite3WalkSelect(&pFix->w, pSelect); } 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; -} -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; i<pList->nExpr; i++, pItem++){ - if( sqlite3FixExpr(pFix, pItem->pExpr) ){ - return 1; - } - } - return 0; + return sqlite3WalkExpr(&pFix->w, pExpr); } #endif @@ -592,25 +565,20 @@ 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) + if( sqlite3WalkExprList(&pFix->w, pUp->pUpsertTarget) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertTargetWhere) + || sqlite3WalkExprList(&pFix->w, pUp->pUpsertSet) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertWhere) ){ return 1; } @@ -618,6 +586,7 @@ int sqlite3FixTriggerStep( #endif pStep = pStep->pNext; } + return 0; } #endif diff --git a/chromium/third_party/sqlite/src/src/auth.c b/chromium/third_party/sqlite/src/src/auth.c index 40673d5ea4f..33420f58394 100644 --- a/chromium/third_party/sqlite/src/src/auth.c +++ b/chromium/third_party/sqlite/src/src/auth.c @@ -143,7 +143,6 @@ 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 */ @@ -151,8 +150,8 @@ 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 @@ -164,7 +163,7 @@ void sqlite3AuthRead( pTab = pParse->pTriggerTab; }else{ assert( pTabList ); - for(iSrc=0; ALWAYS(iSrc<pTabList->nSrc); iSrc++){ + for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ pTab = pTabList->a[iSrc].pTab; break; @@ -172,7 +171,7 @@ void sqlite3AuthRead( } } iCol = pExpr->iColumn; - if( NEVER(pTab==0) ) return; + if( pTab==0 ) return; if( iCol>=0 ){ assert( iCol<pTab->nCol ); @@ -183,7 +182,7 @@ void sqlite3AuthRead( }else{ zCol = "ROWID"; } - assert( iDb>=0 && iDb<db->nDb ); + assert( iDb>=0 && iDb<pParse->db->nDb ); if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ pExpr->op = TK_NULL; } @@ -209,11 +208,7 @@ 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; } diff --git a/chromium/third_party/sqlite/src/src/btree.c b/chromium/third_party/sqlite/src/src/btree.c index 44fe37a4622..1623e01723f 100644 --- a/chromium/third_party/sqlite/src/src/btree.c +++ b/chromium/third_party/sqlite/src/src/btree.c @@ -1144,6 +1144,24 @@ static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow( } /* +** 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. ** @@ -2719,19 +2737,23 @@ static void freeTempSpace(BtShared *pBt){ */ 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 @@ -2883,6 +2905,7 @@ int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ ((pageSize-1)&pageSize)==0 ){ assert( (pageSize & 7)==0 ); assert( !pBt->pCursor ); + if( nReserve>32 && pageSize==512 ) pageSize = 1024; pBt->pageSize = (u32)pageSize; freeTempSpace(pBt); } @@ -4112,7 +4135,7 @@ 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); } @@ -4522,7 +4545,14 @@ 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; @@ -7956,6 +7986,9 @@ static int balance_nonroot( apOld[i] = 0; rc = sqlite3PagerWrite(pNew->pDbPage); nNew++; + if( sqlite3PagerPageRefcount(pNew->pDbPage)!=1+(i==(iParentIdx-nxDiv)) ){ + rc = SQLITE_CORRUPT_BKPT; + } if( rc ) goto balance_cleanup; }else{ assert( i>0 ); @@ -7992,7 +8025,7 @@ static int balance_nonroot( aPgOrder[i] = aPgno[i] = apNew[i]->pgno; aPgFlags[i] = apNew[i]->pDbPage->flags; for(j=0; j<i; j++){ - if( aPgno[j]==aPgno[i] ){ + if( NEVER(aPgno[j]==aPgno[i]) ){ /* This branch is taken if the set of sibling pages somehow contains ** duplicate entries. This can happen if the database is corrupt. ** It would be simpler to detect this as part of the loop below, but @@ -8660,7 +8693,8 @@ 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 ); @@ -8678,7 +8712,7 @@ 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. ** @@ -8788,7 +8822,7 @@ int sqlite3BtreeInsert( || 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 ){ @@ -8805,7 +8839,21 @@ 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) ); @@ -8913,6 +8961,114 @@ end_insert: } /* +** 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. +*/ +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 && nIn<pDest->pPage->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( nOut<pSrc->info.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 ){ + 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. ** ** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then @@ -9509,7 +9665,7 @@ 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]); } diff --git a/chromium/third_party/sqlite/src/src/btree.h b/chromium/third_party/sqlite/src/src/btree.h index 7a9ed2e3c61..b7afecc426e 100644 --- a/chromium/third_party/sqlite/src/src/btree.h +++ b/chromium/third_party/sqlite/src/src/btree.h @@ -262,6 +262,7 @@ 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. @@ -361,6 +362,8 @@ void sqlite3BtreeCursorList(Btree*); int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); #endif +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 diff --git a/chromium/third_party/sqlite/src/src/btreeInt.h b/chromium/third_party/sqlite/src/src/btreeInt.h index c09699fbb56..37c07fe93be 100644 --- a/chromium/third_party/sqlite/src/src/btreeInt.h +++ b/chromium/third_party/sqlite/src/src/btreeInt.h @@ -350,7 +350,7 @@ 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 @@ -455,6 +455,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() */ }; /* diff --git a/chromium/third_party/sqlite/src/src/build.c b/chromium/third_party/sqlite/src/src/build.c index 9779e93732b..b6faf080d53 100644 --- a/chromium/third_party/sqlite/src/src/build.c +++ b/chromium/third_party/sqlite/src/src/build.c @@ -143,10 +143,36 @@ void sqlite3FinishCoding(Parse *pParse){ /* 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; + + addrRewind = + sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); + VdbeCoverage(v); + reg = pReturning->iRetReg; + for(i=0; i<pReturning->nRetCol; 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 @@ -224,12 +250,16 @@ void sqlite3FinishCoding(Parse *pParse){ } } + if( pParse->bReturning ){ + Returning *pRet = pParse->u1.pReturning; + 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 ){ @@ -448,7 +478,7 @@ Table *sqlite3LocateTable( Table *sqlite3LocateTableItem( Parse *pParse, u32 flags, - struct SrcList_item *p + SrcItem *p ){ const char *zDb; assert( p->pSchema==0 || p->zDatabase==0 ); @@ -1206,7 +1236,8 @@ void sqlite3StartTable( }else #endif { - pParse->addrCrTab = + assert( !pParse->bReturning ); + pParse->u1.addrCrTab = sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); } sqlite3OpenSchemaTable(pParse, iDb); @@ -1233,12 +1264,85 @@ begin_table_error: void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ if( sqlite3_strnicmp(pCol->zName, "__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(). +*/ +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.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. @@ -1255,6 +1359,8 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ char *zType; Column *pCol; sqlite3 *db = pParse->db; + u8 hName; + if( (p = pParse->pNewTable)==0 ) return; if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); @@ -1266,8 +1372,9 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ memcpy(z, pName->z, pName->n); z[pName->n] = 0; sqlite3Dequote(z); + hName = sqlite3StrIHash(z); for(i=0; i<p->nCol; i++){ - if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){ + if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zName)==0 ){ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); sqlite3DbFree(db, z); return; @@ -1285,7 +1392,7 @@ void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); pCol->zName = z; - pCol->hName = sqlite3StrIHash(z); + pCol->hName = hName; sqlite3ColumnPropertiesFromName(p, pCol); if( pType->n==0 ){ @@ -2068,9 +2175,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 @@ -2534,7 +2642,7 @@ 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. @@ -2551,20 +2659,17 @@ 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( !pSelect && !p->pSelect ){ + assert( pCons && pEnd ); + if( pCons->z==0 ){ + pCons = pEnd; } -#endif + p->addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z); } +#endif } #ifndef SQLITE_OMIT_VIEW @@ -2755,6 +2860,7 @@ 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) ); @@ -4022,7 +4128,7 @@ 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); } @@ -4043,7 +4149,11 @@ 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 */ + 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 = &pTab->pIndex; Index *pThis; for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){ @@ -4057,6 +4167,16 @@ exit_create_index: } 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); @@ -4415,7 +4535,7 @@ 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 ); @@ -4456,7 +4576,7 @@ SrcList *sqlite3SrcListAppend( */ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; - struct SrcList_item *pItem; + SrcItem *pItem; assert(pList || pParse->db->mallocFailed ); if( pList ){ for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ @@ -4474,7 +4594,7 @@ void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ */ void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ int i; - struct SrcList_item *pItem; + SrcItem *pItem; if( pList==0 ) return; for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){ if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase); @@ -4516,7 +4636,7 @@ 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", @@ -4560,7 +4680,7 @@ SrcList *sqlite3SrcListAppendFromTerm( 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 ); @@ -4590,7 +4710,7 @@ SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){ 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); } } @@ -4603,7 +4723,7 @@ SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){ */ 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 ); @@ -4758,7 +4878,7 @@ int sqlite3OpenTempDatabase(Parse *pParse){ static void sqlite3CodeVerifySchemaAtToplevel(Parse *pToplevel, int iDb){ assert( iDb>=0 && iDb<pToplevel->db->nDb ); assert( pToplevel->db->aDb[iDb].pBt!=0 || iDb==1 ); - assert( iDb<SQLITE_MAX_ATTACHED+2 ); + assert( iDb<SQLITE_MAX_DB ); assert( sqlite3SchemaMutexHeld(pToplevel->db, iDb, 0) ); if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ DbMaskSet(pToplevel->cookieMask, iDb); @@ -5100,24 +5220,76 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ } #ifndef SQLITE_OMIT_CTE +/* +** Create a new CTE object +*/ +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. +*/ +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. */ 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; i<pWith->nCte; i++){ @@ -5136,16 +5308,11 @@ 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; @@ -5158,10 +5325,7 @@ void sqlite3WithDelete(sqlite3 *db, With *pWith){ if( pWith ){ int i; for(i=0; i<pWith->nCte; 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); } diff --git a/chromium/third_party/sqlite/src/src/ctime.c b/chromium/third_party/sqlite/src/src/ctime.c index e3e1e79a95e..7982f23aebc 100644 --- a/chromium/third_party/sqlite/src/src/ctime.c +++ b/chromium/third_party/sqlite/src/src/ctime.c @@ -259,6 +259,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ENABLE_LOCKING_STYLE "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), #endif +#if SQLITE_ENABLE_MATH_FUNCTIONS + "ENABLE_MATH_FUNCTIONS", +#endif #if SQLITE_ENABLE_MEMORY_MANAGEMENT "ENABLE_MEMORY_MANAGEMENT", #endif diff --git a/chromium/third_party/sqlite/src/src/date.c b/chromium/third_party/sqlite/src/src/date.c index 1db26b1c693..f88f544e3ac 100644 --- a/chromium/third_party/sqlite/src/src/date.c +++ b/chromium/third_party/sqlite/src/src/date.c @@ -881,6 +881,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 diff --git a/chromium/third_party/sqlite/src/src/delete.c b/chromium/third_party/sqlite/src/src/delete.c index 064ae7325a2..0c9c7bc8d0f 100644 --- a/chromium/third_party/sqlite/src/src/delete.c +++ b/chromium/third_party/sqlite/src/src/delete.c @@ -29,7 +29,7 @@ ** */ 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); @@ -37,9 +37,9 @@ 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; } @@ -207,9 +207,15 @@ 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 ){ + 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, @@ -387,6 +393,7 @@ void sqlite3DeleteFrom( if( (db->flags & SQLITE_CountRows)!=0 && !pParse->nested && !pParse->pTriggerTab + && !pParse->bReturning ){ memCnt = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); @@ -608,7 +615,7 @@ void sqlite3DeleteFrom( ** invoke the callback function. */ if( memCnt ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, memCnt, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); } diff --git a/chromium/third_party/sqlite/src/src/expr.c b/chromium/third_party/sqlite/src/src/expr.c index 685f041752f..6a58616d18f 100644 --- a/chromium/third_party/sqlite/src/src/expr.c +++ b/chromium/third_party/sqlite/src/src/expr.c @@ -95,7 +95,18 @@ Expr *sqlite3ExprAddCollateToken( const Token *pCollName, /* Name of collating sequence */ int dequote /* True to dequote pCollName */ ){ - if( pCollName->n>0 ){ + assert( pExpr!=0 || pParse->db->mallocFailed ); + if( pExpr==0 ) return 0; + if( pExpr->op==TK_VECTOR ){ + ExprList *pList = pExpr->x.pList; + if( ALWAYS(pList!=0) ){ + int i; + for(i=0; i<pList->nExpr; i++){ + pList->a[i].pExpr = sqlite3ExprAddCollateToken(pParse,pList->a[i].pExpr, + pCollName, dequote); + } + } + }else if( pCollName->n>0 ){ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); if( pNew ){ pNew->pLeft = pExpr; @@ -947,8 +958,8 @@ 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); @@ -1145,6 +1156,22 @@ 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. +*/ +void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ + pParse->pConstExpr = + sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr); +} + /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the ** expression. */ @@ -1519,8 +1546,8 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; i<p->nSrc; i++){ - struct SrcList_item *pNewItem = &pNew->a[i]; - struct SrcList_item *pOldItem = &p->a[i]; + SrcItem *pNewItem = &pNew->a[i]; + SrcItem *pOldItem = &p->a[i]; Table *pTab; pNewItem->pSchema = pOldItem->pSchema; pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); @@ -1533,7 +1560,10 @@ 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); @@ -2571,7 +2601,7 @@ int sqlite3FindInIndex( /* Code an OP_Transaction and OP_TableLock for <table>. */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iDb>=0 && iDb<SQLITE_MAX_ATTACHED ); + assert( iDb>=0 && iDb<SQLITE_MAX_DB ); sqlite3CodeVerifySchema(pParse, iDb); sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); @@ -5767,8 +5797,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{ @@ -5777,8 +5806,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); } } } @@ -5850,7 +5878,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; i<pSrcList->nSrc; i++, pItem++){ struct AggInfo_col *pCol; assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); diff --git a/chromium/third_party/sqlite/src/src/fkey.c b/chromium/third_party/sqlite/src/src/fkey.c index 959e994d170..9f622f40c6b 100644 --- a/chromium/third_party/sqlite/src/src/fkey.c +++ b/chromium/third_party/sqlite/src/src/fkey.c @@ -1024,7 +1024,7 @@ 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++; @@ -1112,7 +1112,9 @@ 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). ** @@ -1124,13 +1126,14 @@ int sqlite3FkRequired( int *aChange, /* Non-NULL for UPDATE operations */ int chngRowid /* True for UPDATE that affects rowid */ ){ - int eRet = 0; + int eRet = 1; /* Value to return if bHaveFK is true */ + int bHaveFK = 0; /* If FK processing is required */ if( pParse->db->flags&SQLITE_ForeignKeys ){ if( !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->pFKey); }else{ /* This is an UPDATE. Foreign key processing is only required if the ** operation modifies one or more child or parent key columns. */ @@ -1138,9 +1141,9 @@ int sqlite3FkRequired( /* 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; if( fkChildIsModified(pTab, p, aChange, chngRowid) ){ - eRet = 1; + if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) eRet = 2; + bHaveFK = 1; } } @@ -1148,12 +1151,12 @@ 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; } /* @@ -1352,7 +1355,7 @@ static Trigger *fkActionTrigger( switch( action ){ case OE_Restrict: - pStep->op = TK_SELECT; + pStep->op = TK_SELECT; break; case OE_Cascade: if( !pChanges ){ diff --git a/chromium/third_party/sqlite/src/src/func.c b/chromium/third_party/sqlite/src/src/func.c index 5d00c94a920..aedbda6f362 100644 --- a/chromium/third_party/sqlite/src/src/func.c +++ b/chromium/third_party/sqlite/src/src/func.c @@ -694,7 +694,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; } @@ -1865,7 +1866,9 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ 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 ); + if( !pExpr->x.pList ){ return 0; } assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); @@ -1904,6 +1907,203 @@ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ 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 2-argument SQL math functions: +** +** power(X,Y) - Compute X to the Y-th power +*/ +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 @@ -2022,6 +2222,43 @@ 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 ), }; diff --git a/chromium/third_party/sqlite/src/src/global.c b/chromium/third_party/sqlite/src/src/global.c index 8ef5a8b2d09..b5239ad81ac 100644 --- a/chromium/third_party/sqlite/src/src/global.c +++ b/chromium/third_party/sqlite/src/src/global.c @@ -301,9 +301,10 @@ int sqlite3PendingByte = 0x40000000; #endif /* -** Flags for select tracing and the ".selecttrace" macro of the CLI +** Tracing flags set by SQLITE_TESTCTRL_TRACEFLAGS. */ -u32 sqlite3_unsupported_selecttrace = 0; +u32 sqlite3SelectTrace = 0; +u32 sqlite3WhereTrace = 0; #include "opcodes.h" /* diff --git a/chromium/third_party/sqlite/src/src/insert.c b/chromium/third_party/sqlite/src/src/insert.c index 393cd528f1f..89b66baf07c 100644 --- a/chromium/third_party/sqlite/src/src/insert.c +++ b/chromium/third_party/sqlite/src/src/insert.c @@ -370,7 +370,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; @@ -928,19 +930,24 @@ 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; i<pTab->nCol; 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; i<pTab->nCol; 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, 0, pTab->nCol-nHidden, nColumn); + goto insert_cleanup; + } } if( pColumn!=0 && nColumn!=pColumn->nId ){ sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); @@ -952,6 +959,7 @@ void sqlite3Insert( if( (db->flags & SQLITE_CountRows)!=0 && !pParse->nested && !pParse->pTriggerTab + && !pParse->bReturning ){ regRowCount = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); @@ -975,6 +983,7 @@ void sqlite3Insert( } #ifndef SQLITE_OMIT_UPSERT if( pUpsert ){ + Upsert *pNx; if( IsVirtual(pTab) ){ sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"", pTab->zName); @@ -988,13 +997,19 @@ 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 @@ -1135,11 +1150,6 @@ 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); @@ -1294,7 +1304,9 @@ 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. @@ -1309,7 +1321,7 @@ insert_end: ** invoke the callback function. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); } @@ -1400,6 +1412,70 @@ int sqlite3ExprReferencesUpdatedColumn( } /* +** 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. ** @@ -1507,7 +1583,7 @@ 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 */ @@ -1515,11 +1591,11 @@ 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 @@ -1529,6 +1605,7 @@ 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; @@ -1726,19 +1803,63 @@ 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 ); } } @@ -1801,11 +1922,20 @@ 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); } } @@ -1815,7 +1945,7 @@ 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 */ ){ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; @@ -1912,7 +2042,9 @@ 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); } @@ -1925,7 +2057,10 @@ 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 */ @@ -1933,15 +2068,14 @@ 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; } @@ -2012,8 +2146,8 @@ 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 */ @@ -2051,7 +2185,7 @@ 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); @@ -2203,13 +2337,16 @@ 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 */ @@ -2276,6 +2413,32 @@ void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ #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. ** A consecutive range of registers starting at regNewData contains the @@ -2323,17 +2486,9 @@ void sqlite3CompleteInsertion( 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, @@ -2531,7 +2686,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 */ @@ -2748,6 +2903,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 ); @@ -2783,11 +2939,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); @@ -2795,16 +2953,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); @@ -2846,13 +3016,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); diff --git a/chromium/third_party/sqlite/src/src/main.c b/chromium/third_party/sqlite/src/src/main.c index cc1464f136c..328cb823bb8 100644 --- a/chromium/third_party/sqlite/src/src/main.c +++ b/chromium/third_party/sqlite/src/src/main.c @@ -2374,7 +2374,7 @@ 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; @@ -2397,6 +2397,8 @@ 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; @@ -2445,7 +2447,7 @@ 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. ** @@ -2460,9 +2462,11 @@ int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){ 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; i<db->nDb && 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; @@ -4080,7 +4084,7 @@ 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; } @@ -4255,7 +4259,26 @@ int sqlite3_test_control(int op, ...){ 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; + } } va_end(ap); #endif /* SQLITE_UNTESTABLE */ diff --git a/chromium/third_party/sqlite/src/src/memjournal.c b/chromium/third_party/sqlite/src/src/memjournal.c index 4811f2d8d41..660a842676c 100644 --- a/chromium/third_party/sqlite/src/src/memjournal.c +++ b/chromium/third_party/sqlite/src/src/memjournal.c @@ -70,7 +70,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() */ @@ -131,14 +130,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; } /* @@ -165,7 +163,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 ){ @@ -248,7 +246,6 @@ static int memjrnlWrite( nWrite -= iSpace; p->endpoint.iOffset += iSpace; } - p->nSize = iAmt + iOfst; } } @@ -256,22 +253,30 @@ 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; - p->readpoint.pChunk = 0; - p->readpoint.iOffset = 0; + FileChunk *pIter = 0; + + if( size==0 ){ + memjrnlFreeChunks(p->pFirst); + p->pFirst = 0; + }else{ + i64 iOff = p->nChunkSize; + for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){ + 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; return SQLITE_OK; } @@ -280,7 +285,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; } diff --git a/chromium/third_party/sqlite/src/src/os.c b/chromium/third_party/sqlite/src/src/os.c index a1a276f4337..693d78dc917 100644 --- a/chromium/third_party/sqlite/src/src/os.c +++ b/chromium/third_party/sqlite/src/src/os.c @@ -129,6 +129,8 @@ int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ #ifdef SQLITE_TEST if( op!=SQLITE_FCNTL_COMMIT_PHASETWO && op!=SQLITE_FCNTL_LOCK_TIMEOUT + && op!=SQLITE_FCNTL_CKPT_DONE + && op!=SQLITE_FCNTL_CKPT_START ){ /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite ** is using a regular VFS, it is called after the corresponding @@ -139,7 +141,12 @@ int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ ** The core must call OsFileControl() though, not OsFileControlHint(), ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably ** means the commit really has failed and an error should be returned - ** to the user. */ + ** to the user. + ** + ** The CKPT_DONE and CKPT_START file-controls are write-only signals + ** to the cksumvfs. Their return code is meaningless and is ignored + ** by the SQLite core, so there is no point in simulating OOMs for them. + */ DO_OS_MALLOC_TEST(id); } #endif diff --git a/chromium/third_party/sqlite/src/src/os_unix.c b/chromium/third_party/sqlite/src/src/os_unix.c index a688ed2706e..e3cfe35cd29 100644 --- a/chromium/third_party/sqlite/src/src/os_unix.c +++ b/chromium/third_party/sqlite/src/src/os_unix.c @@ -6361,7 +6361,8 @@ static int unixBackupDir(const char *z, int *pJ){ int j = *pJ; int i; if( j<=0 ) return 0; - for(i=j-1; ALWAYS(i>0) && z[i-1]!='/'; i--){} + 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; diff --git a/chromium/third_party/sqlite/src/src/pager.c b/chromium/third_party/sqlite/src/src/pager.c index a5510e7eb8d..cd9096ed1c7 100644 --- a/chromium/third_party/sqlite/src/src/pager.c +++ b/chromium/third_party/sqlite/src/src/pager.c @@ -435,6 +435,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 @@ -1070,6 +1071,9 @@ static int subjRequiresPage(PgHdr *pPg){ for(i=0; i<pPager->nSavepoint; i++){ p = &pPager->aSavepoint[i]; if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){ + for(i=i+1; i<pPager->nSavepoint; i++){ + pPager->aSavepoint[i].bTruncateOnRelease = 0; + } return 1; } } @@ -6848,6 +6852,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; } @@ -6929,13 +6934,15 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ /* If this is a release of the outermost savepoint, truncate ** the sub-journal to zero bytes in size. */ 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)*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. diff --git a/chromium/third_party/sqlite/src/src/parse.y b/chromium/third_party/sqlite/src/src/parse.y index d3ec2b3da65..b748e1917ac 100644 --- a/chromium/third_party/sqlite/src/src/parse.y +++ b/chromium/third_party/sqlite/src/src/parse.y @@ -250,6 +250,7 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);} %ifndef SQLITE_OMIT_GENERATED_COLUMNS GENERATED ALWAYS %endif + MATERIALIZED REINDEX RENAME CTIME_KW IF . %wildcard ANY. @@ -496,11 +497,21 @@ cmd ::= select(X). { 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 && @@ -510,29 +521,25 @@ cmd ::= select(X). { } } } -} -%ifndef SQLITE_OMIT_CTE -select(A) ::= WITH wqlist(W) selectnowith(X). { - Select *p = X; - if( p ){ - p->pWith = W; - parserDoubleLinkSelect(pParse, p); - }else{ - sqlite3WithDelete(pParse->db, W); - } - A = p; -} -select(A) ::= WITH RECURSIVE wqlist(W) selectnowith(X). { - Select *p = X; - if( p ){ - p->pWith = W; - parserDoubleLinkSelect(pParse, p); - }else{ - sqlite3WithDelete(pParse->db, W); + /* 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; } - A = p; } + +%ifndef SQLITE_OMIT_CTE +select(A) ::= WITH wqlist(W) selectnowith(X). {A = attachWithToSelect(pParse,X,W);} +select(A) ::= WITH RECURSIVE wqlist(W) selectnowith(X). + {A = attachWithToSelect(pParse,X,W);} %endif /* SQLITE_OMIT_CTE */ select(A) ::= selectnowith(X). { Select *p = X; @@ -699,8 +706,8 @@ seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP exprlist(E) RP as(Z) }else if( F->nSrc==1 ){ A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,0,N,U); if( A ){ - struct SrcList_item *pNew = &A->a[A->nSrc-1]; - struct SrcList_item *pOld = F->a; + SrcItem *pNew = &A->a[A->nSrc-1]; + SrcItem *pOld = F->a; pNew->zName = pOld->zName; pNew->zDatabase = pOld->zDatabase; pNew->pSelect = pOld->pSelect; @@ -868,7 +875,7 @@ limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). /////////////////////////// The DELETE statement ///////////////////////////// // %if SQLITE_ENABLE_UPDATE_DELETE_LIMIT || SQLITE_UDL_CAPABLE_PARSER -cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt(W) +cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt_ret(W) orderby_opt(O) limit_opt(L). { sqlite3SrcListIndexedBy(pParse, X, &I); #ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT @@ -881,7 +888,7 @@ cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt(W) sqlite3DeleteFrom(pParse,X,W,O,L); } %else -cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt(W). { +cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt_ret(W). { sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3DeleteFrom(pParse,X,W,0,0); } @@ -889,15 +896,23 @@ cmd ::= with DELETE FROM xfullname(X) indexed_opt(I) where_opt(W). { %type where_opt {Expr*} %destructor where_opt {sqlite3ExprDelete(pParse->db, $$);} +%type where_opt_ret {Expr*} +%destructor where_opt_ret {sqlite3ExprDelete(pParse->db, $$);} where_opt(A) ::= . {A = 0;} where_opt(A) ::= WHERE expr(X). {A = X;} +where_opt_ret(A) ::= . {A = 0;} +where_opt_ret(A) ::= WHERE expr(X). {A = X;} +where_opt_ret(A) ::= RETURNING selcollist(X). + {sqlite3AddReturning(pParse,X); A = 0;} +where_opt_ret(A) ::= WHERE expr(X) RETURNING selcollist(Y). + {sqlite3AddReturning(pParse,Y); A = X;} ////////////////////////// The UPDATE command //////////////////////////////// // %if SQLITE_ENABLE_UPDATE_DELETE_LIMIT || SQLITE_UDL_CAPABLE_PARSER cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F) - where_opt(W) orderby_opt(O) limit_opt(L). { + where_opt_ret(W) orderby_opt(O) limit_opt(L). { sqlite3SrcListIndexedBy(pParse, X, &I); X = sqlite3SrcListAppendList(pParse, X, F); sqlite3ExprListCheckLength(pParse,Y,"set list"); @@ -912,7 +927,7 @@ cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F) } %else cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F) - where_opt(W). { + where_opt_ret(W). { sqlite3SrcListIndexedBy(pParse, X, &I); sqlite3ExprListCheckLength(pParse,Y,"set list"); X = sqlite3SrcListAppendList(pParse, X, F); @@ -946,7 +961,7 @@ cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) select(S) upsert(U). { sqlite3Insert(pParse, X, S, F, R, U); } -cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) DEFAULT VALUES. +cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) DEFAULT VALUES returning. { sqlite3Insert(pParse, X, 0, F, R, 0); } @@ -959,13 +974,19 @@ cmd ::= with insert_cmd(R) INTO xfullname(X) idlist_opt(F) DEFAULT VALUES. // avoid unreachable code. //%destructor upsert {sqlite3UpsertDelete(pParse->db,$$);} upsert(A) ::= . { A = 0; } +upsert(A) ::= RETURNING selcollist(X). { A = 0; sqlite3AddReturning(pParse,X); } upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) - DO UPDATE SET setlist(Z) where_opt(W). - { A = sqlite3UpsertNew(pParse->db,T,TW,Z,W);} -upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) DO NOTHING. - { A = sqlite3UpsertNew(pParse->db,T,TW,0,0); } -upsert(A) ::= ON CONFLICT DO NOTHING. - { A = sqlite3UpsertNew(pParse->db,0,0,0,0); } + DO UPDATE SET setlist(Z) where_opt(W) upsert(N). + { A = sqlite3UpsertNew(pParse->db,T,TW,Z,W,N);} +upsert(A) ::= ON CONFLICT LP sortlist(T) RP where_opt(TW) DO NOTHING upsert(N). + { A = sqlite3UpsertNew(pParse->db,T,TW,0,0,N); } +upsert(A) ::= ON CONFLICT DO NOTHING returning. + { A = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } +upsert(A) ::= ON CONFLICT DO UPDATE SET setlist(Z) where_opt(W) returning. + { A = sqlite3UpsertNew(pParse->db,0,0,Z,W,0);} + +returning ::= RETURNING selcollist(X). {sqlite3AddReturning(pParse,X);} +returning ::= . %type insert_cmd {int} insert_cmd(A) ::= INSERT orconf(R). {A = R;} @@ -1607,6 +1628,10 @@ cmd ::= ALTER TABLE add_column_fullname Y.n = (int)(pParse->sLastToken.z-Y.z) + pParse->sLastToken.n; sqlite3AlterFinishAddColumn(pParse, &Y); } +cmd ::= ALTER TABLE fullname(X) DROP kwcolumn_opt nm(Y). { + sqlite3AlterDropColumn(pParse, X, &Y); +} + add_column_fullname ::= fullname(X). { disableLookaside(pParse); sqlite3AlterBeginAddColumn(pParse, X); @@ -1644,17 +1669,26 @@ anylist ::= anylist ANY. //////////////////////// COMMON TABLE EXPRESSIONS //////////////////////////// %type wqlist {With*} %destructor wqlist {sqlite3WithDelete(pParse->db, $$);} +%type wqitem {Cte*} +// %destructor wqitem {sqlite3CteDelete(pParse->db, $$);} // not reachable with ::= . %ifndef SQLITE_OMIT_CTE with ::= WITH wqlist(W). { sqlite3WithPush(pParse, W, 1); } with ::= WITH RECURSIVE wqlist(W). { sqlite3WithPush(pParse, W, 1); } -wqlist(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. { - A = sqlite3WithAdd(pParse, 0, &X, Y, Z); /*A-overwrites-X*/ +%type wqas {u8} +wqas(A) ::= AS. {A = M10d_Any;} +wqas(A) ::= AS MATERIALIZED. {A = M10d_Yes;} +wqas(A) ::= AS NOT MATERIALIZED. {A = M10d_No;} +wqitem(A) ::= nm(X) eidlist_opt(Y) wqas(M) LP select(Z) RP. { + A = sqlite3CteNew(pParse, &X, Y, Z, M); /*A-overwrites-X*/ +} +wqlist(A) ::= wqitem(X). { + A = sqlite3WithAdd(pParse, 0, X); /*A-overwrites-X*/ } -wqlist(A) ::= wqlist(A) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. { - A = sqlite3WithAdd(pParse, A, &X, Y, Z); +wqlist(A) ::= wqlist(A) COMMA wqitem(X). { + A = sqlite3WithAdd(pParse, A, X); } %endif SQLITE_OMIT_CTE diff --git a/chromium/third_party/sqlite/src/src/pragma.c b/chromium/third_party/sqlite/src/src/pragma.c index 7be0f7f2563..84f29c2fd51 100644 --- a/chromium/third_party/sqlite/src/src/pragma.c +++ b/chromium/third_party/sqlite/src/src/pragma.c @@ -1969,7 +1969,7 @@ 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 ){ diff --git a/chromium/third_party/sqlite/src/src/prepare.c b/chromium/third_party/sqlite/src/src/prepare.c index 13fd1d33b22..eb4627f0d2c 100644 --- a/chromium/third_party/sqlite/src/src/prepare.c +++ b/chromium/third_party/sqlite/src/src/prepare.c @@ -21,7 +21,7 @@ */ 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; @@ -29,14 +29,18 @@ 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_AlterRename|INITFLAG_AlterDrop) ){ + *pData->pzErrMsg = sqlite3MPrintf(db, + "error in %s %s after %s: %s", azObj[0], azObj[1], + (pData->mInitFlags & INITFLAG_AlterRename) ? "rename" : "drop column", + 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; @@ -94,19 +98,26 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ db->mDbFlags |= DBFLAG_EncodingFixed; pData->nInitRow++; if( db->mallocFailed ){ - corruptSchema(pData, argv[1], 0); + corruptSchema(pData, argv, 0); return 1; } assert( iDb>=0 && iDb<db->nDb ); 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; @@ -119,7 +130,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ || (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; @@ -138,13 +149,13 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ 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)); } } } 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 @@ -155,7 +166,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ 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 @@ -163,7 +174,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ || sqlite3IndexHasDuplicateRootPage(pIndex) ){ if( sqlite3Config.bExtraSchemaChecks ){ - corruptSchema(pData, argv[1], "invalid rootpage"); + corruptSchema(pData, argv, "invalid rootpage"); } } } @@ -544,27 +555,20 @@ int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ } /* -** 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 */ void sqlite3ParserReset(Parse *pParse){ sqlite3 *db = pParse->db; - AggInfo *pThis = pParse->pAggList; - while( pThis ){ - AggInfo *pNext = pThis->pNext; - agginfoFree(db, pThis); - pThis = pNext; + 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( pParse->pConstExpr ){ + sqlite3ExprListDelete(db, pParse->pConstExpr); + } if( db ){ assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; @@ -574,6 +578,55 @@ void sqlite3ParserReset(Parse *pParse){ } /* +** 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 +** sqlite3ParserReset(), 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); +*/ +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; +} + +/* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ static int sqlite3Prepare( @@ -671,12 +724,6 @@ static int sqlite3Prepare( } assert( 0==sParse.nQueryLoop ); - if( sParse.rc==SQLITE_DONE ){ - sParse.rc = SQLITE_OK; - } - if( sParse.checkSchema ){ - schemaIsValid(&sParse); - } if( pzTail ){ *pzTail = sParse.zTail; } @@ -687,20 +734,28 @@ static int sqlite3Prepare( if( db->mallocFailed ){ sParse.rc = SQLITE_NOMEM_BKPT; } - 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 ){ + schemaIsValid(&sParse); + } + if( sParse.pVdbe ){ + sqlite3VdbeFinalize(sParse.pVdbe); + } + assert( 0==(*ppStmt) ); + rc = sParse.rc; + if( zErrMsg ){ + sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); + sqlite3DbFree(db, zErrMsg); + }else{ + sqlite3Error(db, rc); + } }else{ + assert( 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 ){ diff --git a/chromium/third_party/sqlite/src/src/printf.c b/chromium/third_party/sqlite/src/src/printf.c index f78d3bbb178..9aab863ed2b 100644 --- a/chromium/third_party/sqlite/src/src/printf.c +++ b/chromium/third_party/sqlite/src/src/printf.c @@ -856,7 +856,7 @@ void sqlite3_str_vappendf( case etSRCLIST: { SrcList *pSrc; int k; - struct SrcList_item *pItem; + SrcItem *pItem; if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; pSrc = va_arg(ap, SrcList*); k = va_arg(ap, int); @@ -921,7 +921,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ }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 */ diff --git a/chromium/third_party/sqlite/src/src/resolve.c b/chromium/third_party/sqlite/src/src/resolve.c index b55bdc41871..5ddfa4df399 100644 --- a/chromium/third_party/sqlite/src/src/resolve.c +++ b/chromium/third_party/sqlite/src/src/resolve.c @@ -70,7 +70,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 */ @@ -83,7 +82,7 @@ static void resolveAlias( db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); if( pDup!=0 ){ - if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); + incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } @@ -112,7 +111,6 @@ static void resolveAlias( } sqlite3DbFree(db, pDup); } - ExprSetProperty(pExpr, EP_Alias); } @@ -247,8 +245,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 */ @@ -369,25 +367,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; @@ -415,6 +421,7 @@ static int lookupName( } if( iCol<pTab->nCol ){ cnt++; + pMatch = 0; #ifndef SQLITE_OMIT_UPSERT if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){ testcase( iCol==(-1) ); @@ -426,27 +433,32 @@ 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)<<iCol)); - }else{ - testcase( iCol==31 ); - testcase( iCol==32 ); - pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); - } pExpr->y.pTab = pTab; - pExpr->iColumn = (i16)iCol; - eNewExprOp = TK_TRIGGER; + if( pParse->bReturning ){ + eNewExprOp = TK_REGISTER; + 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)<<iCol)); + }else{ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); + } #endif /* SQLITE_OMIT_TRIGGER */ + } } } } @@ -516,7 +528,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 ); @@ -551,6 +563,7 @@ static int lookupName( assert( pExpr->op==TK_ID ); if( ExprHasProperty(pExpr,EP_DblQuoted) && areDoubleQuotedStringsEnabled(db, pTopNC) + && (db->init.bDropColumn==0 || sqlite3StrICmp(zCol, db->init.azInit[0])!=0) ){ /* If a double-quoted identifier does not match any known column name, ** then treat it as a string. @@ -565,6 +578,11 @@ static int lookupName( ** Someday, I hope to get rid of this hack. Unfortunately there is ** a huge amount of legacy SQL that uses it. So for now, we just ** issue a warning. + ** + ** 2021-03-15: ticket 1c24a659e6d7f3a1 + ** Do not do the ID-to-STRING conversion when doing the schema + ** sanity check following a DROP COLUMN if the identifer name matches + ** the name of the column being dropped. */ sqlite3_log(SQLITE_WARNING, "double-quoted string literal: \"%w\"", zCol); @@ -618,18 +636,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(;;){ @@ -651,7 +675,7 @@ lookupname_end: 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]; + SrcItem *pItem = &pSrc->a[iSrc]; Table *pTab = p->y.pTab = pItem->pTab; p->iTable = pItem->iCursor; if( p->y.pTab->iPKey==iCol ){ @@ -763,7 +787,7 @@ 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; @@ -774,6 +798,47 @@ 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 && i<ArraySize(anRef); p=p->pNext, i++){ + anRef[i] = p->nRef; + } + sqlite3WalkExpr(pWalker, pExpr->pLeft); + if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){ + 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 && i<ArraySize(anRef); p=p->pNext, 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 @@ -1001,6 +1066,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( 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); @@ -1075,7 +1141,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 || pRight->op==TK_TRUEFALSE) ){ + 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 ){ @@ -1391,8 +1457,7 @@ int sqlite3ResolveOrderGroupBy( resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); 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; @@ -1577,27 +1642,26 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Recursively resolve names in all subqueries */ for(i=0; i<p->pSrc->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; - 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); + } } } @@ -1639,7 +1703,7 @@ 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; @@ -1647,7 +1711,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Resolve names in table-valued-function arguments */ for(i=0; i<p->pSrc->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) ){ diff --git a/chromium/third_party/sqlite/src/src/select.c b/chromium/third_party/sqlite/src/src/select.c index b4f27267939..e2fa051e594 100644 --- a/chromium/third_party/sqlite/src/src/select.c +++ b/chromium/third_party/sqlite/src/src/select.c @@ -85,12 +85,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; @@ -262,7 +266,7 @@ int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ ** 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){ +int sqlite3ColumnIndex(Table *pTab, const char *zCol){ int i; u8 h = sqlite3StrIHash(zCol); Column *pCol; @@ -294,7 +298,7 @@ static int tableAndColumnIndex( assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=0; i<N; i++){ - iCol = columnIndex(pSrc->a[i].pTab, zCol); + iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol); if( iCol>=0 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) ){ @@ -347,7 +351,7 @@ static void addWhereTerm( ExprSetProperty(pEq, EP_FromJoin); assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(pEq, EP_NoReduce); - pEq->iRightJoinTable = (i16)pE2->iTable; + pEq->iRightJoinTable = pE2->iTable; } *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq); } @@ -383,7 +387,7 @@ 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; + p->iRightJoinTable = iTable; if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; i<p->x.pList->nExpr; i++){ @@ -407,6 +411,9 @@ static void unsetJoinExpr(Expr *p, int iTable){ && (iTable<0 || p->iRightJoinTable==iTable) ){ ExprClearProperty(p, EP_FromJoin); } + if( p->op==TK_COLUMN && p->iTable==iTable ){ + ExprClearProperty(p, EP_CanBeNull); + } if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; i<p->x.pList->nExpr; i++){ @@ -435,8 +442,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]; @@ -504,7 +511,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) ){ @@ -1383,7 +1390,7 @@ KeyInfo *sqlite3KeyInfoFromExprList( /* ** Name of the connection operator, used for error messages. */ -static const char *selectOpName(int id){ +const char *sqlite3SelectOpName(int id){ char *z; switch( id ){ case TK_ALL: z = "UNION ALL"; break; @@ -1979,7 +1986,7 @@ int sqlite3ColumnsFromExprList( 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; @@ -2086,6 +2093,7 @@ void sqlite3SelectAddColumnTypeAndCollation( for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ const char *zType; int 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 */ @@ -2601,12 +2609,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 */ @@ -2663,7 +2667,7 @@ static int multiSelect( pPrior->iOffset = p->iOffset; pPrior->pLimit = p->pLimit; rc = sqlite3Select(pParse, pPrior, &dest); - p->pLimit = 0; + pPrior->pLimit = 0; if( rc ){ goto multi_select_end; } @@ -2684,8 +2688,8 @@ static int multiSelect( 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); @@ -2749,7 +2753,7 @@ static int multiSelect( p->pLimit = 0; uniondest.eDest = op; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", - selectOpName(p->op))); + sqlite3SelectOpName(p->op))); rc = sqlite3Select(pParse, p, &uniondest); testcase( rc!=SQLITE_OK ); assert( p->pOrderBy==0 ); @@ -2825,7 +2829,7 @@ static int multiSelect( p->pLimit = 0; intersectdest.iSDParm = tab2; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", - selectOpName(p->op))); + sqlite3SelectOpName(p->op))); rc = sqlite3Select(pParse, p, &intersectdest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; @@ -2934,7 +2938,8 @@ 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)); } } @@ -3031,10 +3036,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; } @@ -3326,7 +3329,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. @@ -3596,7 +3599,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{ @@ -3626,7 +3629,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; @@ -3636,7 +3639,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; @@ -3651,6 +3654,89 @@ static void recomputeColumnsUsed( #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] = iNew; +** +** The array is guaranteed by the caller to be large enough for all +** existing cursor numbers in pSrc. +** +** 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; i<pSrc->nSrc; i++, pItem++){ + if( i!=iExcept ){ + Select *p; + pItem->iCursor = aCsrMap[pItem->iCursor] = pParse->nTab++; + for(p=pItem->pSelect; p; p=p->pPrior){ + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); + } + } + } +} + +/* +** Expression walker callback used by renumberCursors() to update +** Expr objects to match newly assigned cursor numbers. +*/ +static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ + int *aCsrMap = pWalker->u.aiCol; + int op = pExpr->op; + if( (op==TK_COLUMN || op==TK_IF_NULL_ROW) && aCsrMap[pExpr->iTable] ){ + pExpr->iTable = aCsrMap[pExpr->iTable]; + } + if( ExprHasProperty(pExpr, EP_FromJoin) && aCsrMap[pExpr->iRightJoinTable] ){ + pExpr->iRightJoinTable = aCsrMap[pExpr->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. ** This routine returns 1 if it makes changes and 0 if no flattening occurs. ** @@ -3743,9 +3829,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, @@ -3761,8 +3847,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. @@ -3778,9 +3864,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(). ** @@ -3822,9 +3907,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. */ @@ -3920,13 +4006,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) */ @@ -3947,15 +4034,15 @@ 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, pParse->nTab*sizeof(int)); + } + } /***** If we reach this point, flattening is permitted. *****/ SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n", @@ -3967,6 +4054,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: @@ -4005,18 +4103,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 && db->mallocFailed==0 ){ + renumberCursors(pParse, pNew, iFrom, aCsrMap); + } pNew->pPrior = pPrior; if( pPrior ) pPrior->pNext = pNew; pNew->pNext = p; @@ -4024,24 +4127,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 @@ -4054,8 +4146,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--; } @@ -4075,6 +4169,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; @@ -4083,16 +4178,10 @@ 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 ** query. If the subquery has more than one element in its FROM clause, ** then expand the outer query to make space for it to hold all elements @@ -4210,7 +4299,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); } @@ -4405,6 +4494,35 @@ static int propagateConstants( } #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 ** the WHERE clause of subquery. Example: @@ -4451,9 +4569,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. @@ -4467,13 +4600,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 @@ -4509,6 +4646,7 @@ static int pushDownWhereTerms( } if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ nChng++; + pSubq->selFlags |= SF_PushDown; while( pSubq ){ SubstContext x; pNew = sqlite3ExprDup(pParse->db, pWhere, 0); @@ -4519,6 +4657,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{ @@ -4557,7 +4703,11 @@ 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) ){ + if( pEList==0 + || pEList->nExpr!=1 + || ExprHasProperty(pFunc, EP_WinFunc) + || OptimizationDisabled(db, SQLITE_MinMaxOpt) + ){ return eRet; } zFunc = pFunc->u.zToken; @@ -4620,24 +4770,26 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ ** SQLITE_ERROR and leave an error in pParse. Otherwise, populate ** pFrom->pIndex and return SQLITE_OK. */ -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; +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; } + pFrom->u2.pIBIndex = pIdx; return SQLITE_OK; } + /* ** Detect compound SELECT statements that use an ORDER BY clause with ** an alternative collating sequence. @@ -4724,7 +4876,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; @@ -4745,19 +4897,19 @@ 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; i<p->nCte; 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; i<p->nCte; i++){ + if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ + *ppContext = p; + return &p->a[i]; } } } @@ -4775,46 +4927,54 @@ static struct Cte *searchWith( ** statement with which it is associated. */ void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ - assert( bFree==0 || (pParse->pWith==0 && pParse->pWithToFree==0) ); if( pWith ){ assert( pParse->pWith!=pWith ); pWith->pOuter = pParse->pWith; pParse->pWith = pWith; - if( bFree ) pParse->pWithToFree = pWith; + if( bFree ){ + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3WithDelete, + pWith); + testcase( pParse->earlyCleanup ); + } } } /* ** 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. -** -** 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. -** -** 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. +** 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 matches a CTE according to either of these two above, pFrom->pTab +** and other fields are populated accordingly. +** +** 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->nErr ){ - return SQLITE_ERROR; + if( pParse->pWith==0 ){ + /* There are no WITH clauses in the stack. No match is possible */ + 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; } - pCte = searchWith(pParse->pWith, pFrom, &pWith); if( pCte ){ + sqlite3 *db = pParse->db; Table *pTab; ExprList *pEList; Select *pSel; @@ -4823,6 +4983,7 @@ static int withExpand( 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 @@ -4830,21 +4991,39 @@ 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; assert( pFrom->pSelect ); + 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. */ pRecTerm = pSel = pFrom->pSelect; @@ -4854,7 +5033,7 @@ static int withExpand( SrcList *pSrc = pRecTerm->pSrc; assert( pRecTerm->pPrior!=0 ); for(i=0; i<pSrc->nSrc; 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) @@ -4866,7 +5045,7 @@ static int withExpand( sqlite3ErrorMsg(pParse, "multiple references to recursive table: %s", pCte->zName ); - return SQLITE_ERROR; + return 2; } pRecTerm->selFlags |= SF_Recursive; if( iRecTab<0 ) iRecTab = pParse->nTab++; @@ -4881,16 +5060,24 @@ static int withExpand( pSavedWith = pParse->pWith; pParse->pWith = pWith; 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; - sqlite3WalkSelect(pWalker, pRecTerm); + 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; @@ -4902,7 +5089,7 @@ static int withExpand( pCte->zName, pEList->nExpr, pCte->pCols->nExpr ); pParse->pWith = pSavedWith; - return SQLITE_ERROR; + return 2; } pEList = pCte->pCols; } @@ -4918,9 +5105,9 @@ static int withExpand( } pCte->zCteErr = 0; pParse->pWith = pSavedWith; + return 1; /* Success */ } - - return SQLITE_OK; + return 0; /* No match */ } #endif @@ -4954,7 +5141,7 @@ static void selectPopWith(Walker *pWalker, Select *p){ ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, ** SQLITE_NOMEM. */ -int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){ +int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ Select *pSel = pFrom->pSelect; Table *pTab; @@ -5002,10 +5189,10 @@ int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){ */ 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; @@ -5041,10 +5228,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; @@ -5054,6 +5237,12 @@ static int selectExpander(Walker *pWalker, Select *p){ 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 */ assert( pFrom->pTab==0 ); @@ -5075,7 +5264,10 @@ static int selectExpander(Walker *pWalker, Select *p){ u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); - if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){ + if( pTab->pSelect + && (db->flags & SQLITE_EnableView)==0 + && pTab->pSchema!=db->aDb[1].pSchema + ){ sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", pTab->zName); } @@ -5101,7 +5293,7 @@ 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; } } @@ -5344,7 +5536,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; @@ -5656,7 +5848,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); } @@ -5668,11 +5860,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; pItem<pThis; pItem++){ Select *pS1; if( pItem->pSelect==0 ) continue; @@ -5688,9 +5882,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; @@ -5700,6 +5892,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 @@ -5778,7 +5979,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); } @@ -5831,7 +6032,7 @@ int sqlite3Select( 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 @@ -5845,8 +6046,19 @@ int sqlite3Select( 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 */ - sqlite3ExprListDelete(db, p->pOrderBy); - p->pOrderBy = 0; + 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; } @@ -5856,7 +6068,7 @@ int sqlite3Select( } 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); } @@ -5867,9 +6079,9 @@ int sqlite3Select( ** 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]; + SrcItem *p0 = &p->pSrc->a[0]; for(i=1; i<p->pSrc->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", @@ -5891,7 +6103,7 @@ int sqlite3Select( 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); } @@ -5907,7 +6119,7 @@ int sqlite3Select( */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ - struct SrcList_item *pItem = &pTabList->a[i]; + SrcItem *pItem = &pTabList->a[i]; Select *pSub = pItem->pSelect; Table *pTab = pItem->pTab; @@ -5998,7 +6210,7 @@ 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 @@ -6017,7 +6229,7 @@ int sqlite3Select( && 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); } @@ -6041,7 +6253,8 @@ int sqlite3Select( ** (2) Generate code for all sub-queries */ for(i=0; i<pTabList->nSrc; 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) @@ -6101,16 +6314,18 @@ int sqlite3Select( ** inside the subquery. This can help the subquery to run more efficiently. */ if( OptimizationEnabled(db, SQLITE_PushDown) + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, (pItem->fg.jointype & JT_OUTER)!=0) ){ #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")); } @@ -6120,16 +6335,18 @@ 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. @@ -6149,16 +6366,32 @@ int sqlite3Select( sqlite3VdbeEndCoroutine(v, pItem->regReturn); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); + }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); + } + 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{ - /* 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 - */ + /* Materalize 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; @@ -6173,22 +6406,22 @@ int sqlite3Select( }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; - }else{ - sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); - ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); - sqlite3Select(pParse, pSub, &dest); - } + sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); + ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); + 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)); 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); @@ -6205,7 +6438,7 @@ 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); } @@ -6241,7 +6474,7 @@ 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); } @@ -6333,6 +6566,7 @@ 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 @@ -6371,6 +6605,7 @@ int sqlite3Select( /* End the database scan loop. */ + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); } }else{ @@ -6441,11 +6676,14 @@ 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; @@ -6489,10 +6727,14 @@ 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; ii<pAggInfo->nColumn; ii++){ sqlite3DebugPrintf("agg-column[%d] iMem=%d\n", ii, pAggInfo->aCol[ii].iMem); @@ -6560,6 +6802,7 @@ int sqlite3Select( WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 ); if( pWInfo==0 ) goto select_end; + 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 @@ -6608,6 +6851,7 @@ 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); @@ -6682,9 +6926,10 @@ int sqlite3Select( /* 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); } @@ -6794,7 +7039,6 @@ int sqlite3Select( explainSimpleCount(pParse, pTab, pBest); }else{ int regAcc = 0; /* "populate accumulators" flag */ - int addrSkip; /* If there are accumulator registers but no min() or max() functions ** without FILTER clauses, allocate register regAcc. Register regAcc @@ -6841,12 +7085,13 @@ int sqlite3Select( if( pWInfo==0 ){ goto select_end; } + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); updateAccumulator(pParse, regAcc, pAggInfo); 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); } @@ -6891,15 +7136,13 @@ select_end: if( pAggInfo && !db->mallocFailed ){ for(i=0; i<pAggInfo->nColumn; 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; i<pAggInfo->nFunc; 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 ); } @@ -6908,7 +7151,7 @@ select_end: #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 diff --git a/chromium/third_party/sqlite/src/src/shell.c.in b/chromium/third_party/sqlite/src/src/shell.c.in index 2d98d23c2db..2ec454ffbf9 100644 --- a/chromium/third_party/sqlite/src/src/shell.c.in +++ b/chromium/third_party/sqlite/src/src/shell.c.in @@ -1085,12 +1085,12 @@ struct ShellState { u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ u8 autoEQPtest; /* autoEQP is in test mode */ u8 autoEQPtrace; /* autoEQP is in trace mode */ - u8 statsOn; /* True to display memory stats before each finalize */ u8 scanstatsOn; /* True to display scan stats before each finalize */ u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */ u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */ u8 nEqpLevel; /* Depth of the EQP output graph */ u8 eTraceType; /* SHELL_TRACE_* value for type of trace */ + unsigned statsOn; /* True to display memory stats before each finalize */ unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */ int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ @@ -2027,6 +2027,7 @@ static int shell_callback( if( azArg==0 ) break; for(i=0; i<nArg; i++){ int w = aExplainWidth[i]; + if( i==nArg-1 ) w = 0; if( azArg[i] && strlenChar(azArg[i])>w ){ w = strlenChar(azArg[i]); } @@ -2591,7 +2592,7 @@ static int display_stats( if( pArg==0 || pArg->out==0 ) return 0; out = pArg->out; - if( pArg->pStmt && (pArg->statsOn & 2) ){ + if( pArg->pStmt && pArg->statsOn==2 ){ int nCol, i, x; sqlite3_stmt *pStmt = pArg->pStmt; char z[100]; @@ -2615,6 +2616,14 @@ static int display_stats( } } + if( pArg->statsOn==3 ){ + if( pArg->pStmt ){ + iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); + raw_printf(pArg->out, "VM-steps: %d\n", iCur); + } + return 0; + } + displayStatLine(pArg, "Memory Used:", "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); displayStatLine(pArg, "Number of Outstanding Allocations:", @@ -2881,31 +2890,18 @@ static void explain_data_delete(ShellState *p){ /* ** Disable and restore .wheretrace and .selecttrace settings. */ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) -extern unsigned int sqlite3_unsupported_selecttrace; -static int savedSelectTrace; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) -extern int sqlite3WhereTrace; -static int savedWhereTrace; -#endif +static unsigned int savedSelectTrace; +static unsigned int savedWhereTrace; static void disable_debug_trace_modes(void){ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - savedSelectTrace = sqlite3_unsupported_selecttrace; - sqlite3_unsupported_selecttrace = 0; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - savedWhereTrace = sqlite3WhereTrace; - sqlite3WhereTrace = 0; -#endif + unsigned int zero = 0; + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 0, &savedSelectTrace); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &zero); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 2, &savedWhereTrace); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &zero); } static void restore_debug_trace_modes(void){ -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) - sqlite3_unsupported_selecttrace = savedSelectTrace; -#endif -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) - sqlite3WhereTrace = savedWhereTrace; -#endif + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &savedSelectTrace); + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &savedWhereTrace); } /* Create the TEMP table used to store parameter bindings */ @@ -3067,6 +3063,7 @@ static void exec_prepared_stmt_columnar( if( rc!=SQLITE_ROW ) return; nColumn = sqlite3_column_count(pStmt); nAlloc = nColumn*4; + if( nAlloc<=0 ) nAlloc = 1; azData = sqlite3_malloc64( nAlloc*sizeof(char*) ); if( azData==0 ) shell_out_of_memory(); for(i=0; i<nColumn; i++){ @@ -3106,6 +3103,7 @@ static void exec_prepared_stmt_columnar( if( n>p->actualWidth[j] ) p->actualWidth[j] = n; } if( seenInterrupt ) goto columnar_end; + if( nColumn==0 ) goto columnar_end; switch( p->cMode ){ case MODE_Column: { colSep = " "; @@ -3895,13 +3893,13 @@ static const char *(azHelp[]) = { ".databases List names and files of attached databases", ".dbconfig ?op? ?val? List or change sqlite3_db_config() options", ".dbinfo ?DB? Show status information about the database", - ".dump ?TABLE? Render database content as SQL", + ".dump ?OBJECTS? Render database content as SQL", " Options:", " --data-only Output only INSERT statements", " --newlines Allow unescaped newline characters in output", " --nosys Omit system tables (ex: \"sqlite_stat1\")", " --preserve-rowids Include ROWID values in the output", - " TABLE is a LIKE pattern for the tables to dump", + " OBJECTS is a LIKE pattern for tables, indexes, triggers or views to dump", " Additional LIKE patterns can be given in subsequent arguments", ".echo on|off Turn command echo on or off", ".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN", @@ -4060,7 +4058,11 @@ static const char *(azHelp[]) = { ".shell CMD ARGS... Run CMD ARGS... in a system shell", #endif ".show Show the current values for various settings", - ".stats ?on|off? Show stats or turn stats on or off", + ".stats ?ARG? Show stats or turn stats on or off", + " off Turn off automatic stat display", + " on Turn on automatic stat display", + " stmt Show statement stats", + " vmstep Show the virtual machine step count only", #ifndef SQLITE_NOHAVE_SYSTEM ".system CMD ARGS... Run CMD ARGS... in a system shell", #endif @@ -7876,16 +7878,17 @@ static int do_meta_command(char *zLine, ShellState *p){ int ctrlCode; /* Integer code for that option */ const char *zUsage; /* Usage notes */ } aCtrl[] = { - { "size_limit", SQLITE_FCNTL_SIZE_LIMIT, "[LIMIT]" }, { "chunk_size", SQLITE_FCNTL_CHUNK_SIZE, "SIZE" }, - /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY, "COUNT DELAY" },*/ - { "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" }, - { "psow", SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]" }, - /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/ - { "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" }, + { "data_version", SQLITE_FCNTL_DATA_VERSION, "" }, { "has_moved", SQLITE_FCNTL_HAS_MOVED, "" }, { "lock_timeout", SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" }, + { "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" }, + /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/ + { "psow", SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]" }, { "reserve_bytes", SQLITE_FCNTL_RESERVE_BYTES, "[N]" }, + { "size_limit", SQLITE_FCNTL_SIZE_LIMIT, "[LIMIT]" }, + { "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" }, + /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY, "COUNT DELAY" },*/ }; int filectrl = -1; int iCtrl = -1; @@ -7972,6 +7975,7 @@ static int do_meta_command(char *zLine, ShellState *p){ isOk = 1; break; } + case SQLITE_FCNTL_DATA_VERSION: case SQLITE_FCNTL_HAS_MOVED: { int x; if( nArg!=2 ) break; @@ -8680,9 +8684,9 @@ static int do_meta_command(char *zLine, ShellState *p){ #endif /* SQLITE_DEBUG */ if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){ - char *zNewFilename; /* Name of the database file to open */ - int iName = 1; /* Index in azArg[] of the filename */ - int newFlag = 0; /* True to delete file before opening */ + char *zNewFilename = 0; /* Name of the database file to open */ + int iName = 1; /* Index in azArg[] of the filename */ + int newFlag = 0; /* True to delete file before opening */ /* Close the existing database */ session_close_all(p); close_db(p->db); @@ -8694,7 +8698,7 @@ static int do_meta_command(char *zLine, ShellState *p){ p->openFlags = 0; p->szMax = 0; /* Check for command-line arguments */ - for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){ + for(iName=1; iName<nArg; iName++){ const char *z = azArg[iName]; if( optionMatch(z,"new") ){ newFlag = 1; @@ -8720,10 +8724,15 @@ static int do_meta_command(char *zLine, ShellState *p){ utf8_printf(stderr, "unknown option: %s\n", z); rc = 1; goto meta_command_exit; + }else if( zNewFilename ){ + utf8_printf(stderr, "extra argument: \"%s\"\n", z); + rc = 1; + goto meta_command_exit; + }else{ + zNewFilename = sqlite3_mprintf("%s", z); } } /* If a filename is specified, try to open it first */ - zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0; if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){ if( newFlag ) shellDeleteFile(zNewFilename); p->zDbFilename = zNewFilename; @@ -8746,7 +8755,7 @@ static int do_meta_command(char *zLine, ShellState *p){ && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0)) || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0) ){ - const char *zFile = 0; + char *zFile = 0; int bTxtMode = 0; int i; int eMode = 0; @@ -8776,17 +8785,22 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; } - }else if( zFile==0 ){ - zFile = z; + }else if( zFile==0 && eMode!='e' && eMode!='x' ){ + zFile = sqlite3_mprintf("%s", z); + if( zFile[0]=='|' ){ + while( i+1<nArg ) zFile = sqlite3_mprintf("%z %s", zFile, azArg[++i]); + break; + } }else{ utf8_printf(p->out,"ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]); showHelp(p->out, azArg[0]); rc = 1; + sqlite3_free(zFile); goto meta_command_exit; } } - if( zFile==0 ) zFile = "stdout"; + if( zFile==0 ) zFile = sqlite3_mprintf("stdout"); if( bOnce ){ p->outCount = 2; }else{ @@ -8809,7 +8823,8 @@ static int do_meta_command(char *zLine, ShellState *p){ newTempFile(p, "txt"); bTxtMode = 1; } - zFile = p->zTempFile; + sqlite3_free(zFile); + zFile = sqlite3_mprintf("%s", p->zTempFile); } #endif /* SQLITE_NOHAVE_SYSTEM */ if( zFile[0]=='|' ){ @@ -8841,6 +8856,7 @@ static int do_meta_command(char *zLine, ShellState *p){ sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } } + sqlite3_free(zFile); }else if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){ @@ -9024,6 +9040,11 @@ static int do_meta_command(char *zLine, ShellState *p){ goto meta_command_exit; } if( azArg[1][0]=='|' ){ +#ifdef SQLITE_OMIT_POPEN + raw_printf(stderr, "Error: pipes are not supported in this OS\n"); + rc = 1; + p->out = stdout; +#else p->in = popen(azArg[1]+1, "r"); if( p->in==0 ){ utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]); @@ -9032,6 +9053,7 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = process_input(p); pclose(p->in); } +#endif }else if( notNormalFile(azArg[1]) || (p->in = fopen(azArg[1], "rb"))==0 ){ utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); rc = 1; @@ -9246,11 +9268,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE) if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ - sqlite3_unsupported_selecttrace = nArg>=2 ? (int)integerValue(azArg[1]) : 0xffff; + unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x); }else -#endif #if defined(SQLITE_ENABLE_SESSION) if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){ @@ -9731,6 +9752,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='s' && strncmp(azArg[0], "show", n)==0 ){ static const char *azBool[] = { "off", "on", "trigger", "full"}; + const char *zOut; int i; if( nArg!=1 ){ raw_printf(stderr, "Usage: .show\n"); @@ -9755,7 +9777,13 @@ static int do_meta_command(char *zLine, ShellState *p){ utf8_printf(p->out,"%12.12s: ", "rowseparator"); output_c_string(p->out, p->rowSeparator); raw_printf(p->out, "\n"); - utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]); + switch( p->statsOn ){ + case 0: zOut = "off"; break; + default: zOut = "on"; break; + case 2: zOut = "stmt"; break; + case 3: zOut = "vmstep"; break; + } + utf8_printf(p->out, "%12.12s: %s\n","stats", zOut); utf8_printf(p->out, "%12.12s: ", "width"); for (i=0;i<p->nWidth;i++) { raw_printf(p->out, "%d ", p->colWidth[i]); @@ -9767,11 +9795,17 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){ if( nArg==2 ){ - p->statsOn = (u8)booleanValue(azArg[1]); + if( strcmp(azArg[1],"stmt")==0 ){ + p->statsOn = 2; + }else if( strcmp(azArg[1],"vmstep")==0 ){ + p->statsOn = 3; + }else{ + p->statsOn = (u8)booleanValue(azArg[1]); + } }else if( nArg==1 ){ display_stats(p->db, p, 0); }else{ - raw_printf(stderr, "Usage: .stats ?on|off?\n"); + raw_printf(stderr, "Usage: .stats ?on|off|stmt|vmstep?\n"); rc = 1; } }else @@ -9976,7 +10010,7 @@ static int do_meta_command(char *zLine, ShellState *p){ /* sqlite3_test_control(int, db, int) */ case SQLITE_TESTCTRL_OPTIMIZATIONS: if( nArg==3 ){ - int opt = (int)strtol(azArg[2], 0, 0); + unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0); rc2 = sqlite3_test_control(testctrl, p->db, opt); isOk = 3; } @@ -10305,11 +10339,10 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else -#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){ - sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff; + unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x); }else -#endif if( c=='w' && strncmp(azArg[0], "width", n)==0 ){ int j; @@ -10798,7 +10831,8 @@ static char *cmdline_option_value(int argc, char **argv, int i){ } #ifndef SQLITE_SHELL_IS_UTF8 -# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER) +# if (defined(_WIN32) || defined(WIN32)) \ + && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__))) # define SQLITE_SHELL_IS_UTF8 (0) # else # define SQLITE_SHELL_IS_UTF8 (1) diff --git a/chromium/third_party/sqlite/src/src/sqlite.h.in b/chromium/third_party/sqlite/src/src/sqlite.h.in index 3ec8efeab0d..c018767d13a 100644 --- a/chromium/third_party/sqlite/src/src/sqlite.h.in +++ b/chromium/third_party/sqlite/src/src/sqlite.h.in @@ -2115,7 +2115,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. </dd> +** which case the trigger setting is not reported back. +** +** <p>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.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] ** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt> @@ -2126,7 +2132,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. </dd> +** which case the view setting is not reported back. +** +** <p>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.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> @@ -3499,6 +3511,7 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** that uses dot-files in place of posix advisory locking. ** <tr><td> file:data.db?mode=readonly <td> ** An error. "readonly" is not a valid option for the "mode" parameter. +** Use "ro" instead: "file:data.db?mode=ro". ** </table> ** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and @@ -3697,7 +3710,7 @@ 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 @@ -7765,7 +7778,8 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 #define SQLITE_TESTCTRL_SEEK_COUNT 30 -#define SQLITE_TESTCTRL_LAST 30 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_TRACEFLAGS 31 +#define SQLITE_TESTCTRL_LAST 31 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking diff --git a/chromium/third_party/sqlite/src/src/sqliteInt.h b/chromium/third_party/sqlite/src/src/sqliteInt.h index 245070d4f82..799ed6ab0b4 100644 --- a/chromium/third_party/sqlite/src/src/sqliteInt.h +++ b/chromium/third_party/sqlite/src/src/sqliteInt.h @@ -119,6 +119,18 @@ # define MSVC_VERSION 0 #endif +/* +** Some C99 functions in "math.h" are only present for MSVC when its version +** is associated with Visual Studio 2013 or higher. +*/ +#ifndef SQLITE_HAVE_C99_MATH_FUNCS +# if MSVC_VERSION==0 || MSVC_VERSION>=1800 +# define SQLITE_HAVE_C99_MATH_FUNCS (1) +# else +# define SQLITE_HAVE_C99_MATH_FUNCS (0) +# endif +#endif + /* Needed for various definitions... */ #if defined(__GNUC__) && !defined(_GNU_SOURCE) # define _GNU_SOURCE @@ -202,7 +214,8 @@ #ifndef __has_extension # define __has_extension(x) 0 /* compatibility with non-clang compilers */ #endif -#if GCC_VERSION>=4007000 || __has_extension(c_atomic) +#if GCC_VERSION>=4007000 || \ + (__has_extension(c_atomic) && __has_extension(c_atomic_store_n)) # define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED) # define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED) #else @@ -984,15 +997,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) +extern 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 @@ -1001,6 +1013,19 @@ typedef INT16_TYPE LogEst; #endif /* +** Macros for "wheretrace" +*/ +extern 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. ** @@ -1111,7 +1136,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; @@ -1129,14 +1157,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; @@ -1450,6 +1481,11 @@ 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. @@ -1470,7 +1506,7 @@ struct sqlite3 { int errCode; /* Most recent error code (SQLITE_*) */ 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 */ @@ -1497,7 +1533,10 @@ 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 */ + unsigned bDropColumn : 1; /* Doing schema check after DROP COLUMN */ char **azInit; /* "type", "name", and "tbl_name" columns */ + /* or if bDropColumn, then azInit[0] is the */ + /* name of the column being dropped */ } init; int nVdbeActive; /* Number of VDBEs currently running */ int nVdbeRead; /* Number of active VDBEs that read or write */ @@ -1677,24 +1716,26 @@ 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_ExistsToIN 0x00020000 /* The EXISTS-to-IN optimization */ +#define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. @@ -1850,6 +1891,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 @@ -1885,6 +1929,9 @@ struct FuncDestructor { #define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } +#define MFUNCTION(zName, nArg, xPtr, xFunc) \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ + xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } @@ -1979,7 +2026,12 @@ struct Column { u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */ }; -/* Allowed values for Column.colFlags: +/* 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 */ @@ -2155,7 +2207,6 @@ struct Table { #endif Trigger *pTrigger; /* List of triggers stored in pSchema */ Schema *pSchema; /* Schema that contains this table */ - Table *pNextZombie; /* Next on the Parse.pZombieTab list */ }; /* @@ -2169,11 +2220,12 @@ struct Table { ** ** Constraints: ** -** TF_HasVirtual == COLFLAG_Virtual -** TF_HasStored == COLFLAG_Stored +** TF_HasVirtual == COLFLAG_VIRTUAL +** TF_HasStored == COLFLAG_STORED +** TF_HasHidden == COLFLAG_HIDDEN */ #define TF_Readonly 0x0001 /* Read-only system table */ -#define TF_Ephemeral 0x0002 /* An ephemeral table */ +#define TF_HasHidden 0x0002 /* Has one or more hidden columns */ #define TF_HasPrimaryKey 0x0004 /* Table has a primary key */ #define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */ #define TF_HasStat1 0x0010 /* nRowLogEst set from sqlite_stat1 */ @@ -2188,6 +2240,7 @@ struct Table { #define TF_HasNotNull 0x0800 /* Contains NOT NULL constraints */ #define TF_Shadow 0x1000 /* True for a shadow table */ #define TF_HasStat4 0x2000 /* STAT4 info available for this table */ +#define TF_Ephemeral 0x4000 /* An ephemeral table */ /* ** Test to see whether or not a table is a virtual table. This is @@ -2284,16 +2337,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 */ @@ -2550,7 +2609,6 @@ struct AggInfo { } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ - AggInfo *pNext; /* Next in list of them all */ }; /* @@ -2679,7 +2737,7 @@ 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 */ + int iRightJoinTable; /* If EP_FromJoin, the right table of the join */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ union { Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL @@ -2721,7 +2779,7 @@ struct Expr { #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 */ @@ -2870,6 +2928,45 @@ struct IdList { }; /* +** The SrcItem object represents a single term in the FROM clause of a query. +** The SrcList object is mostly an array of SrcItems. +*/ +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 */ + } 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<<N) set if column N of pTab is used */ + union { + char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" 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 ** the SrcList.a[] array. @@ -2891,36 +2988,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<<N) set if column N of pTab is used */ - union { - char *zIndexedBy; /* Identifier from "INDEXED BY <zIndex>" 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 */ }; /* @@ -2996,6 +3064,7 @@ 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 */ @@ -3024,6 +3093,7 @@ struct NameContext { #define NC_UEList 0x00080 /* True if uNC.pEList is used */ #define NC_UAggInfo 0x00100 /* True if uNC.pAggInfo is used */ #define NC_UUpsert 0x00200 /* True if uNC.pUpsert is used */ +#define NC_UBaseReg 0x00400 /* True if uNC.iBaseReg is used */ #define NC_MinMaxAgg 0x01000 /* min/max aggregates seen. See note above */ #define NC_Complex 0x02000 /* True if a function or subquery seen */ #define NC_AllowWin 0x04000 /* Window functions are allowed here */ @@ -3047,15 +3117,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 */ @@ -3135,6 +3211,8 @@ struct Select { #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_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ +#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ /* ** The results of a SELECT can be distributed in several ways, as defined @@ -3306,6 +3384,17 @@ struct TriggerPrg { #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 ** carry around information that is global to the entire parse. @@ -3336,6 +3425,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 */ @@ -3363,12 +3455,15 @@ struct Parse { 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 */ + 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 */ @@ -3414,10 +3509,9 @@ 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 */ + ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */ #ifndef SQLITE_OMIT_ALTERTABLE RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */ #endif @@ -3497,6 +3591,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 @@ -3518,6 +3613,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 <column-list> trigger, the <column-list> is stored here */ @@ -3576,14 +3672,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 */ @@ -3592,18 +3689,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 */ }; /* @@ -3643,7 +3738,8 @@ typedef struct { /* ** Allowed values for mInitFlags */ -#define INITFLAG_AlterTable 0x0001 /* This is a reparse after ALTER TABLE */ +#define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */ +#define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */ /* ** Structure containing global configuration data for the SQLite library. @@ -3755,10 +3851,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 */ int sqlite3WalkExpr(Walker*, Expr*); int sqlite3WalkExprList(Walker*, ExprList*); @@ -3784,20 +3896,55 @@ 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 */ + 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 @@ -4143,6 +4290,7 @@ Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); void sqlite3ExprFunctionUsable(Parse*,Expr*,FuncDef*); void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); +void sqlite3ExprDeferredDelete(Parse*, Expr*); void sqlite3ExprUnmapAndDelete(Parse*, Expr*); ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); @@ -4191,6 +4339,7 @@ void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*); void sqlite3AddCollateType(Parse*, Token*); void sqlite3AddGenerated(Parse*,Expr*,Token*); void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); +void sqlite3AddReturning(Parse*,ExprList*); int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); #define sqlite3CodecQueryParameters(A,B,C) 0 @@ -4256,7 +4405,7 @@ SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, Token*, Select*, Expr*, IdList*); void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); -int sqlite3IndexedByLookup(Parse *, struct SrcList_item *); +int sqlite3IndexedByLookup(Parse *, SrcItem *); void sqlite3SrcListShiftJoinType(SrcList*); void sqlite3SrcListAssignCursors(Parse*, SrcList*); void sqlite3IdListDelete(sqlite3*, IdList*); @@ -4284,6 +4433,7 @@ LogEst sqlite3WhereOutputRowCount(WhereInfo*); int sqlite3WhereIsDistinct(WhereInfo*); int sqlite3WhereIsOrdered(WhereInfo*); int sqlite3WhereOrderByLimitOptLabel(WhereInfo*); +void sqlite3WhereMinMaxOptEarlyOut(Vdbe*,WhereInfo*); int sqlite3WhereIsSorted(WhereInfo*); int sqlite3WhereContinueLabel(WhereInfo*); int sqlite3WhereBreakLabel(WhereInfo*); @@ -4317,7 +4467,7 @@ Table *sqlite3FindTable(sqlite3*,const char*, const char*); #define LOCATE_VIEW 0x01 #define LOCATE_NOERR 0x02 Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); -Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); +Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *); Index *sqlite3FindIndex(sqlite3*,const char*, const char*); void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); @@ -4445,6 +4595,7 @@ void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); #endif int sqlite3JoinType(Parse*, Token*, Token*, Token*); +int sqlite3ColumnIndex(Table *pTab, const char *zCol); void sqlite3SetJoinExpr(Expr*,int); void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); void sqlite3DeferForeignKey(Parse*, int); @@ -4467,7 +4618,6 @@ void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); int sqlite3FixSrcList(DbFixer*, SrcList*); int sqlite3FixSelect(DbFixer*, Select*); int sqlite3FixExpr(DbFixer*, Expr*); -int sqlite3FixExprList(DbFixer*, ExprList*); int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); int sqlite3RealSameAsInt(double,sqlite3_int64); void sqlite3Int64ToText(i64,char*); @@ -4530,6 +4680,7 @@ int sqlite3Atoi64(const char*, i64*, int, u8); int sqlite3DecOrHexToI64(const char*, i64*); void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); void sqlite3Error(sqlite3*,int); +void sqlite3ErrorClear(sqlite3*); void sqlite3SystemError(sqlite3*,int); void *sqlite3HexToBlob(sqlite3*, const char *z, int n); u8 sqlite3HexToInt(int h); @@ -4593,7 +4744,6 @@ extern const unsigned char sqlite3UpperToLower[]; extern const unsigned char sqlite3CtypeMap[]; extern SQLITE_WSD struct Sqlite3Config sqlite3Config; extern FuncDefHash sqlite3BuiltinFunctions; -extern u32 sqlite3_unsupported_selecttrace; #ifndef SQLITE_OMIT_WSD extern int sqlite3PendingByte; #endif @@ -4612,7 +4762,7 @@ void sqlite3ExpirePreparedStatements(sqlite3*, int); void sqlite3CodeRhsOfIN(Parse*, Expr*, int); int sqlite3CodeSubselect(Parse*, Expr*); void sqlite3SelectPrep(Parse*, Select*, NameContext*); -int sqlite3ExpandSubquery(Parse*, struct SrcList_item*); +int sqlite3ExpandSubquery(Parse*, SrcItem*); void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); int sqlite3MatchEName( const struct ExprList_item*, @@ -4630,6 +4780,7 @@ int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); void sqlite3ColumnDefault(Vdbe *, Table *, int, int); void sqlite3AlterFinishAddColumn(Parse *, Token *); void sqlite3AlterBeginAddColumn(Parse *, SrcList *); +void sqlite3AlterDropColumn(Parse*, SrcList*, Token*); void *sqlite3RenameTokenMap(Parse*, void*, Token*); void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); void sqlite3RenameExprUnmap(Parse*, Expr*); @@ -4653,6 +4804,7 @@ void sqlite3KeyInfoUnref(KeyInfo*); KeyInfo *sqlite3KeyInfoRef(KeyInfo*); KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); +const char *sqlite3SelectOpName(int); int sqlite3HasExplicitNulls(Parse*, ExprList*); #ifdef SQLITE_DEBUG @@ -4783,6 +4935,7 @@ sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); void sqlite3ParserReset(Parse*); +void *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*); #ifdef SQLITE_ENABLE_NORMALIZE char *sqlite3Normalize(Vdbe*, const char*); #endif @@ -4797,23 +4950,32 @@ const char *sqlite3JournalModename(int); int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif #ifndef SQLITE_OMIT_CTE - With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*); + Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8); + void sqlite3CteDelete(sqlite3*,Cte*); + With *sqlite3WithAdd(Parse*,With*,Cte*); void sqlite3WithDelete(sqlite3*,With*); void 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) #endif #ifndef SQLITE_OMIT_UPSERT - Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*); + Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*); void sqlite3UpsertDelete(sqlite3*,Upsert*); Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*); void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); + Upsert *sqlite3UpsertOfIndex(Upsert*,Index*); + 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 diff --git a/chromium/third_party/sqlite/src/src/test1.c b/chromium/third_party/sqlite/src/src/test1.c index 49461ea5fc5..27c638f4ee5 100644 --- a/chromium/third_party/sqlite/src/src/test1.c +++ b/chromium/third_party/sqlite/src/src/test1.c @@ -6648,7 +6648,7 @@ static int SQLITE_TCLAPI prng_seed( Tcl_WrongNumArgs(interp, 1, objv, "SEED ?DB?"); return TCL_ERROR; } - if( Tcl_GetIntFromObj(interp,objv[0],&i) ) return TCL_ERROR; + if( Tcl_GetIntFromObj(interp,objv[1],&i) ) return TCL_ERROR; if( objc==3 && getDbPointer(interp, Tcl_GetString(objv[2]), &db) ){ return TCL_ERROR; } @@ -7494,6 +7494,7 @@ static int SQLITE_TCLAPI tclLoadStaticExtensionCmd( Tcl_Obj *CONST objv[] ){ extern int sqlite3_amatch_init(sqlite3*,char**,const sqlite3_api_routines*); + extern int sqlite3_appendvfs_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_carray_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*); extern int sqlite3_csv_init(sqlite3*,char**,const sqlite3_api_routines*); @@ -7523,6 +7524,7 @@ static int SQLITE_TCLAPI tclLoadStaticExtensionCmd( int (*pInit)(sqlite3*,char**,const sqlite3_api_routines*); } aExtension[] = { { "amatch", sqlite3_amatch_init }, + { "appendvfs", sqlite3_appendvfs_init }, { "carray", sqlite3_carray_init }, { "closure", sqlite3_closure_init }, { "csv", sqlite3_csv_init }, @@ -7571,7 +7573,7 @@ static int SQLITE_TCLAPI tclLoadStaticExtensionCmd( }else{ rc = SQLITE_OK; } - if( rc!=SQLITE_OK || zErrMsg ){ + if( (rc!=SQLITE_OK && rc!=SQLITE_OK_LOAD_PERMANENTLY) || zErrMsg ){ Tcl_AppendResult(interp, "initialization of ", zName, " failed: ", zErrMsg, (char*)0); sqlite3_free(zErrMsg); @@ -8512,7 +8514,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ extern LONG volatile sqlite3_os_type; #endif #ifdef SQLITE_DEBUG - extern int sqlite3WhereTrace; + extern u32 sqlite3WhereTrace; extern int sqlite3OSTrace; extern int sqlite3WalTrace; #endif @@ -8521,9 +8523,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ extern int sqlite3_fts3_enable_parentheses; #endif #endif -#if defined(SQLITE_ENABLE_SELECTTRACE) - extern u32 sqlite3_unsupported_selecttrace; -#endif for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); @@ -8611,7 +8610,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ (char*)&sqlite3_fullsync_count, TCL_LINK_INT); #if defined(SQLITE_ENABLE_SELECTTRACE) Tcl_LinkVar(interp, "sqlite3_unsupported_selecttrace", - (char*)&sqlite3_unsupported_selecttrace, TCL_LINK_INT); + (char*)&sqlite3SelectTrace, TCL_LINK_INT); #endif #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST) Tcl_LinkVar(interp, "sqlite_fts3_enable_parentheses", diff --git a/chromium/third_party/sqlite/src/src/test_config.c b/chromium/third_party/sqlite/src/src/test_config.c index 362e92aa9ac..8c4fba71db9 100644 --- a/chromium/third_party/sqlite/src/src/test_config.c +++ b/chromium/third_party/sqlite/src/src/test_config.c @@ -154,6 +154,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "deserialize", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS + Tcl_SetVar2(interp, "sqlite_options", "mathlib", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "mathlib", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_ENABLE_MEMSYS3 Tcl_SetVar2(interp, "sqlite_options", "mem3", "1", TCL_GLOBAL_ONLY); #else diff --git a/chromium/third_party/sqlite/src/src/tokenize.c b/chromium/third_party/sqlite/src/src/tokenize.c index 70f0c636782..5e01de2b903 100644 --- a/chromium/third_party/sqlite/src/src/tokenize.c +++ b/chromium/third_party/sqlite/src/src/tokenize.c @@ -27,8 +27,8 @@ ** 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 */ @@ -53,20 +53,21 @@ #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 */ 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, +/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 28, 10, 28, 25, 28, /* 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, @@ -78,22 +79,22 @@ static const unsigned char aiClass[] = { #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 }; @@ -499,7 +500,7 @@ 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, @@ -529,6 +530,7 @@ 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; @@ -711,19 +713,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ if( !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; assert( nErr==0 || pParse->rc!=SQLITE_OK ); diff --git a/chromium/third_party/sqlite/src/src/treeview.c b/chromium/third_party/sqlite/src/src/treeview.c index 187f1a07d1c..b696d764e02 100644 --- a/chromium/third_party/sqlite/src/src/treeview.c +++ b/chromium/third_party/sqlite/src/src/treeview.c @@ -111,7 +111,10 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ } 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, i<pWith->nCte-1); sqlite3TreeViewSelect(pView, pCte->pSelect, 0); @@ -127,7 +130,7 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ int i; for(i=0; i<pSrc->nSrc; 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); @@ -150,6 +153,9 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ 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, i<pSrc->nSrc-1); if( pItem->pSelect ){ diff --git a/chromium/third_party/sqlite/src/src/trigger.c b/chromium/third_party/sqlite/src/src/trigger.c index dd4ed8c2e8b..4c7cb54880e 100644 --- a/chromium/third_party/sqlite/src/src/trigger.c +++ b/chromium/third_party/sqlite/src/src/trigger.c @@ -48,28 +48,39 @@ void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){ ** pTab as well as the triggers lised in pTab->pTrigger. */ 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; } - + pTmpSchema = pParse->db->aDb[1].pSchema; + p = sqliteHashFirst(&pTmpSchema->trigHash); + if( p==0 ){ + return pTab->pTrigger; + } + pList = pTab->pTrigger; if( pTmpSchema!=pTab->pSchema ){ - HashElem *p; - assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) ); - for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){ + while( p ){ Trigger *pTrig = (Trigger *)sqliteHashData(p); if( pTrig->pTabSchema==pTab->pSchema - && 0==sqlite3StrICmp(pTrig->table, pTab->zName) + && 0==sqlite3StrICmp(pTrig->table, pTab->zName) ){ - pTrig->pNext = (pList ? pList : pTab->pTrigger); + pTrig->pNext = pList; pList = pTrig; - } + }else if( pTrig->op==TK_RETURNING ){ + 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); + return pList; } /* @@ -345,7 +356,7 @@ void sqlite3FinishTrigger( 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 ){ @@ -558,7 +569,7 @@ TriggerStep *sqlite3TriggerDeleteStep( ** Recursively delete a Trigger structure */ 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); @@ -723,15 +734,53 @@ 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; } @@ -775,6 +824,131 @@ SrcList *sqlite3TriggerStepSrc( } /* +** 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; i<pList->nExpr; i++){ + Expr *pOldExpr = pList->a[i].pExpr; + if( NEVER(pOldExpr==0) ) continue; + if( isAsteriskTerm(pParse, pOldExpr) ){ + int jj; + for(jj=0; jj<pTab->nCol; jj++){ + Expr *pNewExpr; + if( IsHiddenColumn(pTab->aCol+jj) ) continue; + pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zName); + pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); + if( !db->mallocFailed ){ + struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; + pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zName); + pItem->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; + } + } + } + if( !db->mallocFailed ){ + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + sqlite3VdbeSetNumCols(v, pNew->nExpr); + for(i=0; i<pNew->nExpr; i++){ + sqlite3VdbeSetColName(v, i, COLNAME_NAME, pNew->a[i].zEName, + SQLITE_TRANSIENT); + } + } + 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; + ExprList *pNew; + Returning *pReturning; + + assert( v!=0 ); + assert( pParse->bReturning ); + pReturning = pParse->u1.pReturning; + assert( pTrigger == &(pReturning->retTrig) ); + pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); + if( pNew ){ + 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 ){ + int i; + int nCol = pNew->nExpr; + int reg = pParse->nMem+1; + pParse->nMem += nCol+2; + pReturning->iRetReg = reg; + for(i=0; i<nCol; i++){ + sqlite3ExprCodeFactorable(pParse, pNew->a[i].pExpr, 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(pParse->db, pNew); + pParse->eTriggerOp = 0; + pParse->pTriggerTab = 0; + } +} + + + +/* ** Generate VDBE code for the statements inside the body of a single ** trigger. */ @@ -823,6 +997,7 @@ static int codeTriggerProgram( sqlite3ExprDup(db, pStep->pWhere, 0), pParse->eOrconf, 0, 0, 0 ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } case TK_INSERT: { @@ -833,6 +1008,7 @@ static int codeTriggerProgram( pParse->eOrconf, sqlite3UpsertDup(db, pStep->pUpsert) ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } case TK_DELETE: { @@ -840,6 +1016,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 ); { @@ -851,9 +1028,6 @@ static int codeTriggerProgram( break; } } - if( pStep->op!=TK_SELECT ){ - sqlite3VdbeAddOp0(v, OP_ResetCount); - } } return 0; @@ -1000,7 +1174,6 @@ static TriggerPrg *codeRowTrigger( sqlite3VdbeDelete(v); } - assert( !pSubParse->pAinc && !pSubParse->pZombieTab ); assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); sqlite3ParserReset(pSubParse); sqlite3StackFree(db, pSubParse); @@ -1102,7 +1275,7 @@ 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 ** @@ -1147,12 +1320,20 @@ 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); + } } } } @@ -1197,13 +1378,18 @@ 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]; + } } } } diff --git a/chromium/third_party/sqlite/src/src/update.c b/chromium/third_party/sqlite/src/src/update.c index f8cb2afedb6..b360766b68a 100644 --- a/chromium/third_party/sqlite/src/src/update.c +++ b/chromium/third_party/sqlite/src/src/update.c @@ -643,6 +643,7 @@ void sqlite3Update( if( (db->flags&SQLITE_CountRows)!=0 && !pParse->pTriggerTab && !pParse->nested + && !pParse->bReturning && pUpsert==0 ){ regRowCount = ++pParse->nMem; @@ -1106,7 +1107,7 @@ void sqlite3Update( ** that information. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); } diff --git a/chromium/third_party/sqlite/src/src/upsert.c b/chromium/third_party/sqlite/src/src/upsert.c index 9a33f75d0ac..982dc7dbc1a 100644 --- a/chromium/third_party/sqlite/src/src/upsert.c +++ b/chromium/third_party/sqlite/src/src/upsert.c @@ -18,15 +18,22 @@ /* ** Free a list of Upsert objects */ -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 ); } +void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){ + if( p ) upsertDelete(db, p); +} + /* ** Duplicate an Upsert object. @@ -37,7 +44,8 @@ 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) ); } @@ -49,22 +57,25 @@ 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; } @@ -89,6 +100,7 @@ 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 ); @@ -102,87 +114,131 @@ 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; - - /* 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; - } - - /* 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; - } + 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 ); + continue; } - nn = pIdx->nKeyCol; - for(ii=0; ii<nn; ii++){ - Expr *pExpr; - sCol[0].u.zToken = (char*)pIdx->azColl[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]; + + /* 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; } - }else{ - sCol[0].pLeft = &sCol[1]; - sCol[1].iColumn = pIdx->aiColumn[ii]; - pExpr = &sCol[0]; } - for(jj=0; jj<nn; jj++){ - if( sqlite3ExprCompare(pParse, pTarget->a[jj].pExpr, pExpr,iCursor)<2 ){ - break; /* Column ii of the index matches column jj of target */ + nn = pIdx->nKeyCol; + for(ii=0; ii<nn; ii++){ + Expr *pExpr; + sCol[0].u.zToken = (char*)pIdx->azColl[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]; + } + for(jj=0; jj<nn; jj++){ + if( sqlite3ExprCompare(pParse,pTarget->a[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( ii<nn ){ + /* Column ii of the index did not match any term of the conflict target. + ** Continue the search with the next index. */ + continue; } + pUpsert->pUpsertIdx = pIdx; + break; } - if( ii<nn ){ - /* Column ii of the index did not match any term of the conflict target. - ** Continue the search with the next index. */ - continue; + if( pUpsert->pUpsertIdx==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. +*/ +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. +*/ +Upsert *sqlite3UpsertOfIndex(Upsert *pUpsert, Index *pIdx){ + while( + pUpsert + && pUpsert->pUpsertTarget!=0 + && pUpsert->pUpsertIdx!=pIdx + ){ + pUpsert = pUpsert->pNextUpsert; + } + return pUpsert; } /* @@ -206,11 +262,13 @@ 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); @@ -240,19 +298,17 @@ 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; i<pTab->nCol; 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")); } diff --git a/chromium/third_party/sqlite/src/src/util.c b/chromium/third_party/sqlite/src/src/util.c index fb86d7d118d..fc0c2042bdd 100644 --- a/chromium/third_party/sqlite/src/src/util.c +++ b/chromium/third_party/sqlite/src/src/util.c @@ -115,6 +115,16 @@ void sqlite3Error(sqlite3 *db, int err_code){ } /* +** The equivalent of sqlite3Error(db, SQLITE_OK). Clear the error state +** and error message. +*/ +void sqlite3ErrorClear(sqlite3 *db){ + assert( db!=0 ); + db->errCode = SQLITE_OK; + if( db->pErr ) sqlite3ValueSetNull(db->pErr); +} + +/* ** Load the sqlite3.iSysErrno field if that is an appropriate thing ** to do based on the SQLite error code in rc. */ diff --git a/chromium/third_party/sqlite/src/src/vdbe.c b/chromium/third_party/sqlite/src/src/vdbe.c index 1507fb31819..080c7eaf83d 100644 --- a/chromium/third_party/sqlite/src/src/vdbe.c +++ b/chromium/third_party/sqlite/src/src/vdbe.c @@ -272,11 +272,6 @@ static VdbeCursor *allocateCursor( assert( iCur>=0 && iCur<p->nCursor ); 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; } @@ -685,7 +680,7 @@ 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 ){ @@ -1445,6 +1440,26 @@ case OP_IntCopy: { /* out2 */ break; } +/* Opcode: ChngCntRow P1 P2 * * * +** Synopsis: output=r[P1] +** +** Output value in register P1 as the chance count for a DML statement, +** due to the "PRAGMA count_changes=ON" setting. Or, if there was a +** foreign key error in the statement, trigger the error now. +** +** This opcode is a variant of OP_ResultRow that checks the foreign key +** immediate constraint count and throws an error if the count is +** non-zero. The P2 opcode must be 1. +*/ +case OP_ChngCntRow: { + assert( pOp->p2==1 ); + if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){ + goto abort_due_to_error; + } + /* Fall through to the next case, OP_ResultRow */ + /* no break */ deliberate_fall_through +} + /* Opcode: ResultRow P1 P2 * * * ** Synopsis: output=r[P1@P2] ** @@ -1461,34 +1476,6 @@ case OP_ResultRow: { assert( pOp->p1>0 ); 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; @@ -3881,7 +3868,7 @@ 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); if( pCx==0 ) goto no_mem; @@ -3891,7 +3878,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->pBtx = pOrig->pBtx; + pCx->hasBeenDuped = 1; + pOrig->hasBeenDuped = 1; + rc = sqlite3BtreeCursor(pCx->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 @@ -3957,9 +3947,10 @@ case OP_OpenEphemeral: { 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 ){ + /* 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; @@ -3973,33 +3964,36 @@ case OP_OpenEphemeral: { 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); + 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); + } + pCx->isTable = 0; + }else{ + pCx->pgnoRoot = SCHEMA_ROOT; + rc = sqlite3BtreeCursor(pCx->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->pBtx); } } - pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); } if( rc ) goto abort_due_to_error; pCx->nullRow = 1; @@ -4433,13 +4427,13 @@ seek_not_found: ** ** There are three possible outcomes from this opcode:<ol> ** -** <li> If after This.P1 steps, the cursor is still point to a place that -** is earlier in the btree than the target row, -** then fall through into the subsquence OP_SeekGE opcode. +** <li> 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. ** ** <li> 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 opcode that follows the OP_SeekGE. +** past the OP_IdxGT or OP_IdxGE opcode that follows the OP_SeekGE. ** ** <li> 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. @@ -4456,7 +4450,8 @@ case OP_SeekScan: { /* 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 ); + 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 ); @@ -4909,8 +4904,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; @@ -5126,7 +5123,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; @@ -5143,6 +5141,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. @@ -5798,7 +5823,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 ); @@ -5809,7 +5834,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 ); @@ -5882,7 +5907,7 @@ case OP_IdxDelete: { rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); if( rc ) goto abort_due_to_error; }else if( pOp->p5 ){ - rc = SQLITE_CORRUPT_INDEX; + rc = sqlite3ReportError(SQLITE_CORRUPT_INDEX, __LINE__, "index corruption"); goto abort_due_to_error; } assert( pC->deferredMoveto==0 ); @@ -5961,6 +5986,8 @@ case OP_IdxRowid: { /* out2 */ pTabCur->deferredMoveto = 1; assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); pTabCur->aAltMap = pOp->p4.ai; + assert( !pC->isEphemeral ); + assert( !pTabCur->isEphemeral ); pTabCur->pAltCursor = pC; }else{ pOut = out2Prerelease(p, pOp); @@ -6308,7 +6335,7 @@ case OP_ParseSchema: { 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 diff --git a/chromium/third_party/sqlite/src/src/vdbe.h b/chromium/third_party/sqlite/src/src/vdbe.h index 17f11fdd773..3257ff68a17 100644 --- a/chromium/third_party/sqlite/src/src/vdbe.h +++ b/chromium/third_party/sqlite/src/src/vdbe.h @@ -223,7 +223,7 @@ VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno); #else # define sqlite3ExplainBreakpoint(A,B) /*no-op*/ #endif -void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); +void sqlite3VdbeAddParseSchemaOp(Vdbe*, int, char*, u16); void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8); void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1); void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); diff --git a/chromium/third_party/sqlite/src/src/vdbeInt.h b/chromium/third_party/sqlite/src/src/vdbeInt.h index 7d22cb8093b..cb423f20a1a 100644 --- a/chromium/third_party/sqlite/src/src/vdbeInt.h +++ b/chromium/third_party/sqlite/src/src/vdbeInt.h @@ -86,6 +86,7 @@ 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 hasBeenDuped:1; /* This cursor was source or target of OP_OpenDup */ u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ Btree *pBtx; /* Separate file holding temporary table */ i64 seqCount; /* Sequence counter */ @@ -381,7 +382,7 @@ 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 */ diff --git a/chromium/third_party/sqlite/src/src/vdbeapi.c b/chromium/third_party/sqlite/src/src/vdbeapi.c index a9cbf92fc3b..ba3bdf6a5f5 100644 --- a/chromium/third_party/sqlite/src/src/vdbeapi.c +++ b/chromium/third_party/sqlite/src/src/vdbeapi.c @@ -617,7 +617,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 @@ -1333,7 +1333,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, @@ -1687,7 +1687,7 @@ int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ */ 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; } /* diff --git a/chromium/third_party/sqlite/src/src/vdbeaux.c b/chromium/third_party/sqlite/src/src/vdbeaux.c index dfd259d7188..38315e9f487 100644 --- a/chromium/third_party/sqlite/src/src/vdbeaux.c +++ b/chromium/third_party/sqlite/src/src/vdbeaux.c @@ -35,7 +35,7 @@ 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 ); @@ -236,7 +236,7 @@ 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); @@ -471,9 +471,10 @@ void sqlite3VdbeExplainPop(Parse *pParse){ ** The zWhere string must have been obtained from sqlite3_malloc(). ** This routine will take ownership of the allocated memory. */ -void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){ +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; j<p->db->nDb; j++) sqlite3VdbeUsesBtree(p, j); sqlite3MayAbort(p->pParse); } @@ -565,7 +566,7 @@ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ 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 @@ -890,7 +891,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ ** Return the address of the next instruction to be inserted. */ int sqlite3VdbeCurrentAddr(Vdbe *p){ - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); return p->nOp; } @@ -975,7 +976,7 @@ 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; } @@ -1299,7 +1300,7 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ 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); @@ -1428,7 +1429,7 @@ 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; } @@ -2113,7 +2114,7 @@ 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 @@ -2293,14 +2294,14 @@ 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; i<p->nMem; i++){ @@ -2356,8 +2357,10 @@ 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; @@ -2442,8 +2445,6 @@ void sqlite3VdbeMakeReady( } } - p->pVList = pParse->pVList; - pParse->pVList = 0; if( db->mallocFailed ){ p->nVar = 0; p->nCursor = 0; @@ -2471,20 +2472,15 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ return; } assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE ); + assert( pCx->pBtx==0 || pCx->isEphemeral ); switch( pCx->eCurType ){ case CURTYPE_SORTER: { sqlite3VdbeSorterClose(p->db, pCx); 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 @@ -3041,7 +3037,7 @@ 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 ){ @@ -3199,7 +3195,7 @@ 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; @@ -3372,7 +3368,7 @@ int sqlite3VdbeReset(Vdbe *p){ } } #endif - p->magic = VDBE_MAGIC_RESET; + p->iVdbeMagic = VDBE_MAGIC_RESET; return p->rc & db->errMask; } @@ -3382,7 +3378,7 @@ int sqlite3VdbeReset(Vdbe *p){ */ 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 ); } @@ -3443,7 +3439,7 @@ 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); @@ -3491,7 +3487,7 @@ 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); } @@ -3568,6 +3564,7 @@ int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){ assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); if( p->deferredMoveto ){ u32 iMap; + assert( !p->isEphemeral ); if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 && !p->nullRow ){ *pp = p->pAltCursor; *piCol = iMap - 1; diff --git a/chromium/third_party/sqlite/src/src/vdbetrace.c b/chromium/third_party/sqlite/src/src/vdbetrace.c index 32c66af2281..1095e7f589c 100644 --- a/chromium/third_party/sqlite/src/src/vdbetrace.c +++ b/chromium/third_party/sqlite/src/src/vdbetrace.c @@ -125,7 +125,7 @@ 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 ){ diff --git a/chromium/third_party/sqlite/src/src/vtab.c b/chromium/third_party/sqlite/src/src/vtab.c index b2c01f2fadc..ded12c13bb3 100644 --- a/chromium/third_party/sqlite/src/src/vtab.c +++ b/chromium/third_party/sqlite/src/src/vtab.c @@ -489,7 +489,7 @@ 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; @@ -660,6 +660,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; @@ -828,7 +829,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ Table *pNew = sParse.pNewTable; Index *pIdx; pTab->aCol = pNew->aCol; - pTab->nCol = pNew->nCol; + pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); pNew->nCol = 0; pNew->aCol = 0; diff --git a/chromium/third_party/sqlite/src/src/walker.c b/chromium/third_party/sqlite/src/src/walker.c index 7649036f562..927f7e52d73 100644 --- a/chromium/third_party/sqlite/src/src/walker.c +++ b/chromium/third_party/sqlite/src/src/walker.c @@ -22,7 +22,7 @@ ** 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; @@ -41,6 +41,7 @@ static int walkWindowList(Walker *pWalker, Window *pList){ if( NEVER(rc) ) return WRC_Abort; rc = sqlite3WalkExpr(pWalker, pWin->pEnd); if( NEVER(rc) ) return WRC_Abort; + if( bOneOnly ) break; } return WRC_Continue; } @@ -88,7 +89,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 } @@ -135,7 +136,7 @@ int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ if( pParse && IN_RENAME_OBJECT ){ /* 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; } } @@ -153,7 +154,7 @@ int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ SrcList *pSrc; int i; - struct SrcList_item *pItem; + SrcItem *pItem; pSrc = p->pSrc; if( pSrc ){ diff --git a/chromium/third_party/sqlite/src/src/where.c b/chromium/third_party/sqlite/src/src/where.c index 2b97114e6b6..75b3ceff87a 100644 --- a/chromium/third_party/sqlite/src/src/where.c +++ b/chromium/third_party/sqlite/src/src/where.c @@ -37,12 +37,6 @@ struct HiddenIndexInfo { /* 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 */ @@ -106,6 +100,32 @@ int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ } /* +** 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. +*/ +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. */ @@ -674,7 +694,7 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ */ static int termCanDriveIndex( WhereTerm *pTerm, /* WHERE clause term to check */ - struct SrcList_item *pSrc, /* Table we are trying to access */ + SrcItem *pSrc, /* Table we are trying to access */ Bitmask notReady /* Tables in outer loops of the join */ ){ char aff; @@ -708,7 +728,7 @@ static int termCanDriveIndex( static 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 */ + SrcItem *pSrc, /* The FROM clause term to get the next index */ Bitmask notReady, /* Mask of cursors that are not available */ WhereLevel *pLevel /* Write new index here */ ){ @@ -732,7 +752,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 */ @@ -916,7 +936,7 @@ static sqlite3_index_info *allocateIndexInfo( Parse *pParse, /* The parsing context */ 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 */ + SrcItem *pSrc, /* The FROM clause term that is the vtab */ ExprList *pOrderBy, /* The ORDER BY clause */ u16 *pmNoOmit /* Mask of terms not to omit */ ){ @@ -1814,7 +1834,7 @@ void sqlite3WhereClausePrint(WhereClause *pWC){ 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, @@ -2425,7 +2445,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) */ ){ @@ -2611,7 +2631,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))<pTerm->pWC->nTerm ); @@ -2916,7 +2936,7 @@ 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 */ @@ -2934,9 +2954,9 @@ static int whereLoopAddBtree( pWC = pBuilder->pWC; assert( !IsVirtual(pSrc->pTab) ); - if( pSrc->pIBIndex ){ + if( pSrc->fg.isIndexedBy ){ /* 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{ @@ -2972,7 +2992,7 @@ static int whereLoopAddBtree( 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 */ @@ -3022,7 +3042,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 @@ -3197,7 +3217,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 ); @@ -3389,7 +3409,7 @@ 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 */ @@ -3517,7 +3537,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; @@ -3633,8 +3653,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; @@ -3657,7 +3677,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ - struct SrcList_item *p; + SrcItem *p; for(p=&pItem[1]; p<pEnd; p++){ if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){ mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); @@ -4512,7 +4532,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; @@ -4971,7 +4991,7 @@ WhereInfo *sqlite3WhereBegin( if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ pWInfo->revMask = ALLBITS; } - if( pParse->nErr || NEVER(db->mallocFailed) ){ + if( pParse->nErr || db->mallocFailed ){ goto whereBeginError; } #ifdef WHERETRACE_ENABLED @@ -5042,7 +5062,7 @@ WhereInfo *sqlite3WhereBegin( } for(i=pWInfo->nLevel-1; i>=1; i--){ WhereTerm *pTerm, *pEnd; - struct SrcList_item *pItem; + SrcItem *pItem; pLoop = pWInfo->a[i].pWLoop; pItem = &pWInfo->pTabList->a[pLoop->iTab]; if( (pItem->fg.jointype & JT_LEFT)==0 ) continue; @@ -5132,7 +5152,7 @@ WhereInfo *sqlite3WhereBegin( for(ii=0, pLevel=pWInfo->a; ii<nTabList; ii++, pLevel++){ Table *pTab; /* Table to open */ int iDb; /* Index of database containing table/index */ - struct SrcList_item *pTabItem; + SrcItem *pTabItem; pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; @@ -5469,7 +5489,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ int k, last; 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; @@ -5545,7 +5565,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ #endif pOp = sqlite3VdbeGetOp(v, k); pLastOp = pOp + (last - k); - assert( pOp<pLastOp ); + assert( pOp<pLastOp || (pParse->nErr>0 && pOp==pLastOp) ); do{ if( pOp->p1!=pLevel->iTabCur ){ /* no-op */ diff --git a/chromium/third_party/sqlite/src/src/whereInt.h b/chromium/third_party/sqlite/src/src/whereInt.h index 6c969af9c2c..8896da0271f 100644 --- a/chromium/third_party/sqlite/src/src/whereInt.h +++ b/chromium/third_party/sqlite/src/src/whereInt.h @@ -17,19 +17,6 @@ #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 */ @@ -283,11 +270,7 @@ struct WhereTerm { #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_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 */ @@ -557,7 +540,7 @@ Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*); Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*); Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); void sqlite3WhereExprAnalyze(SrcList*, WhereClause*); -void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); +void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); diff --git a/chromium/third_party/sqlite/src/src/wherecode.c b/chromium/third_party/sqlite/src/src/wherecode.c index 4afe0ac9c90..a7a76fb7043 100644 --- a/chromium/third_party/sqlite/src/src/wherecode.c +++ b/chromium/third_party/sqlite/src/src/wherecode.c @@ -129,7 +129,7 @@ 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. */ @@ -922,7 +922,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 */ @@ -1297,7 +1297,7 @@ 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 */ @@ -1743,6 +1743,12 @@ Bitmask sqlite3WhereCodeOneLoopStart( 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. @@ -2079,7 +2085,7 @@ 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])); diff --git a/chromium/third_party/sqlite/src/src/whereexpr.c b/chromium/third_party/sqlite/src/src/whereexpr.c index a77eb36106c..1807fbb000c 100644 --- a/chromium/third_party/sqlite/src/src/whereexpr.c +++ b/chromium/third_party/sqlite/src/src/whereexpr.c @@ -511,6 +511,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 @@ -1008,6 +1009,277 @@ static int exprMightBeIndexed( } /* +** Expression callback for exprUsesSrclist(). +*/ +static int exprUsesSrclistCb(Walker *p, Expr *pExpr){ + if( pExpr->op==TK_COLUMN ){ + SrcList *pSrc = p->u.pSrcList; + int iCsr = pExpr->iTable; + int ii; + for(ii=0; ii<pSrc->nSrc; ii++){ + if( pSrc->a[ii].iCursor==iCsr ){ + return p->eCode ? WRC_Abort : WRC_Continue; + } + } + return p->eCode ? WRC_Continue : WRC_Abort; + } + return WRC_Continue; +} + +/* +** Select callback for exprUsesSrclist(). +*/ +static int exprUsesSrclistSelectCb(Walker *NotUsed1, Select *NotUsed2){ + UNUSED_PARAMETER(NotUsed1); + UNUSED_PARAMETER(NotUsed2); + return WRC_Abort; +} + +/* +** This function always returns true if expression pExpr contains +** a sub-select. +** +** If there is no sub-select in pExpr, then return true if pExpr +** contains a TK_COLUMN node for a table that is (bUses==1) +** or is not (bUses==0) in pSrc. +** +** Said another way: +** +** bUses Return Meaning +** -------- ------ ------------------------------------------------ +** +** bUses==1 true pExpr contains either a sub-select or a +** TK_COLUMN referencing pSrc. +** +** bUses==1 false pExpr contains no sub-selects and all TK_COLUMN +** nodes reference tables not found in pSrc +** +** bUses==0 true pExpr contains either a sub-select or a TK_COLUMN +** that references a table not in pSrc. +** +** bUses==0 false pExpr contains no sub-selects and all TK_COLUMN +** nodes reference pSrc +*/ +static int exprUsesSrclist(SrcList *pSrc, Expr *pExpr, int bUses){ + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.eCode = bUses; + sWalker.u.pSrcList = pSrc; + sWalker.xExprCallback = exprUsesSrclistCb; + sWalker.xSelectCallback = exprUsesSrclistSelectCb; + return (sqlite3WalkExpr(&sWalker, pExpr)==WRC_Abort); +} + +/* +** Context object used by exprExistsToInIter() as it iterates through an +** expression tree. +*/ +struct ExistsToInCtx { + SrcList *pSrc; /* The tables in an EXISTS(SELECT ... FROM <here> ...) */ + Expr *pInLhs; /* OUT: Use this as the LHS of the IN operator */ + Expr *pEq; /* OUT: The == term that include pInLhs */ + Expr **ppAnd; /* OUT: The AND operator that includes pEq as a child */ + Expr **ppParent; /* The AND operator currently being examined */ +}; + +/* +** Iterate through all AND connected nodes in the expression tree +** headed by (*ppExpr), populating the structure passed as the first +** argument with the values required by exprAnalyzeExistsFindEq(). +** +** This function returns non-zero if the expression tree does not meet +** the two conditions described by the header comment for +** exprAnalyzeExistsFindEq(), or zero if it does. +*/ +static int exprExistsToInIter(struct ExistsToInCtx *p, Expr **ppExpr){ + Expr *pExpr = *ppExpr; + switch( pExpr->op ){ + case TK_AND: + p->ppParent = ppExpr; + if( exprExistsToInIter(p, &pExpr->pLeft) ) return 1; + p->ppParent = ppExpr; + if( exprExistsToInIter(p, &pExpr->pRight) ) return 1; + break; + case TK_EQ: { + int bLeft = exprUsesSrclist(p->pSrc, pExpr->pLeft, 0); + int bRight = exprUsesSrclist(p->pSrc, pExpr->pRight, 0); + if( bLeft || bRight ){ + if( (bLeft && bRight) || p->pInLhs ) return 1; + p->pInLhs = bLeft ? pExpr->pLeft : pExpr->pRight; + if( exprUsesSrclist(p->pSrc, p->pInLhs, 1) ) return 1; + p->pEq = pExpr; + p->ppAnd = p->ppParent; + } + break; + } + default: + if( exprUsesSrclist(p->pSrc, pExpr, 0) ){ + return 1; + } + break; + } + + return 0; +} + +/* +** This function is used by exprAnalyzeExists() when creating virtual IN(...) +** terms equivalent to user-supplied EXIST(...) clauses. It splits the WHERE +** clause of the Select object passed as the first argument into one or more +** expressions joined by AND operators, and then tests if the following are +** true: +** +** 1. Exactly one of the AND separated terms refers to the outer +** query, and it is an == (TK_EQ) expression. +** +** 2. Only one side of the == expression refers to the outer query, and +** it does not refer to any columns from the inner query. +** +** If both these conditions are true, then a pointer to the side of the == +** expression that refers to the outer query is returned. The caller will +** use this expression as the LHS of the IN(...) virtual term. Or, if one +** or both of the above conditions are not true, NULL is returned. +** +** If non-NULL is returned and ppEq is non-NULL, *ppEq is set to point +** to the == expression node before returning. If pppAnd is non-NULL and +** the == node is not the root of the WHERE clause, then *pppAnd is set +** to point to the pointer to the AND node that is the parent of the == +** node within the WHERE expression tree. +*/ +static Expr *exprAnalyzeExistsFindEq( + Select *pSel, /* The SELECT of the EXISTS */ + Expr **ppEq, /* OUT: == node from WHERE clause */ + Expr ***pppAnd /* OUT: Pointer to parent of ==, if any */ +){ + struct ExistsToInCtx ctx; + memset(&ctx, 0, sizeof(ctx)); + ctx.pSrc = pSel->pSrc; + if( exprExistsToInIter(&ctx, &pSel->pWhere) ){ + return 0; + } + if( ppEq ) *ppEq = ctx.pEq; + if( pppAnd ) *pppAnd = ctx.ppAnd; + return ctx.pInLhs; +} + +/* +** Term idxTerm of the WHERE clause passed as the second argument is an +** EXISTS expression with a correlated SELECT statement on the RHS. +** This function analyzes the SELECT statement, and if possible adds an +** equivalent "? IN(SELECT...)" virtual term to the WHERE clause. +** +** For an EXISTS term such as the following: +** +** EXISTS (SELECT ... FROM <srclist> WHERE <e1> = <e2> AND <e3>) +** +** The virtual IN() term added is: +** +** <e1> IN (SELECT <e2> FROM <srclist> WHERE <e3>) +** +** The virtual term is only added if the following conditions are met: +** +** 1. The sub-select must not be an aggregate or use window functions, +** +** 2. The sub-select must not be a compound SELECT, +** +** 3. Expression <e1> must refer to at least one column from the outer +** query, and must not refer to any column from the inner query +** (i.e. from <srclist>). +** +** 4. <e2> and <e3> must not refer to any values from the outer query. +** In other words, once <e1> has been removed, the inner query +** must not be correlated. +** +*/ +static void exprAnalyzeExists( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* the WHERE clause */ + int idxTerm /* Index of the term to be analyzed */ +){ + Parse *pParse = pWC->pWInfo->pParse; + WhereTerm *pTerm = &pWC->a[idxTerm]; + Expr *pExpr = pTerm->pExpr; + Select *pSel = pExpr->x.pSelect; + Expr *pDup = 0; + Expr *pEq = 0; + Expr *pRet = 0; + Expr *pInLhs = 0; + Expr **ppAnd = 0; + int idxNew; + sqlite3 *db = pParse->db; + + assert( pExpr->op==TK_EXISTS ); + assert( (pExpr->flags & EP_VarSelect) && (pExpr->flags & EP_xIsSelect) ); + + if( pSel->selFlags & SF_Aggregate ) return; +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSel->pWin ) return; +#endif + if( pSel->pPrior ) return; + if( pSel->pWhere==0 ) return; + if( pSel->pLimit ) return; + if( 0==exprAnalyzeExistsFindEq(pSel, 0, 0) ) return; + + pDup = sqlite3ExprDup(db, pExpr, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + return; + } + pSel = pDup->x.pSelect; + sqlite3ExprListDelete(db, pSel->pEList); + pSel->pEList = 0; + + pInLhs = exprAnalyzeExistsFindEq(pSel, &pEq, &ppAnd); + assert( pInLhs && pEq ); + assert( pEq==pSel->pWhere || ppAnd ); + if( pInLhs==pEq->pLeft ){ + pRet = pEq->pRight; + }else{ + CollSeq *p = sqlite3ExprCompareCollSeq(pParse, pEq); + pInLhs = sqlite3ExprAddCollateString(pParse, pInLhs, p?p->zName:"BINARY"); + pRet = pEq->pLeft; + } + + assert( pDup->pLeft==0 ); + pDup->op = TK_IN; + pDup->pLeft = pInLhs; + pDup->flags &= ~EP_VarSelect; + if( pRet->op==TK_VECTOR ){ + pSel->pEList = pRet->x.pList; + pRet->x.pList = 0; + sqlite3ExprDelete(db, pRet); + }else{ + pSel->pEList = sqlite3ExprListAppend(pParse, 0, pRet); + } + pEq->pLeft = 0; + pEq->pRight = 0; + if( ppAnd ){ + Expr *pAnd = *ppAnd; + Expr *pOther = (pAnd->pLeft==pEq) ? pAnd->pRight : pAnd->pLeft; + pAnd->pLeft = pAnd->pRight = 0; + sqlite3ExprDelete(db, pAnd); + *ppAnd = pOther; + }else{ + assert( pSel->pWhere==pEq ); + pSel->pWhere = 0; + } + sqlite3ExprDelete(db, pEq); + +#ifdef WHERETRACE_ENABLED /* 0x20 */ + if( sqlite3WhereTrace & 0x20 ){ + sqlite3DebugPrintf("Convert EXISTS:\n"); + sqlite3TreeViewExpr(0, pExpr, 0); + sqlite3DebugPrintf("into IN:\n"); + sqlite3TreeViewExpr(0, pDup, 0); + } +#endif + idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pWC, idxNew); + markTermAsChild(pWC, idxNew, idxTerm); + pWC->a[idxTerm].wtFlags |= TERM_COPIED; +} + +/* ** 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 ** subexpression and populate all the other fields of the WhereTerm @@ -1140,6 +1412,12 @@ static void exprAnalyze( pNew->prereqRight = prereqLeft | extraRight; pNew->prereqAll = prereqAll; pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; + }else if( op==TK_ISNULL && 0==sqlite3ExprCanBeNull(pLeft) ){ + pExpr->op = TK_TRUEFALSE; + pExpr->u.zToken = "false"; + ExprSetProperty(pExpr, EP_IsFalse); + pTerm->prereqAll = 0; + pTerm->eOperator = 0; } } @@ -1192,6 +1470,52 @@ static void exprAnalyze( } #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ + else if( pExpr->op==TK_EXISTS ){ + /* Perhaps treat an EXISTS operator as an IN operator */ + if( (pExpr->flags & EP_VarSelect)!=0 + && OptimizationEnabled(db, SQLITE_ExistsToIN) + ){ + exprAnalyzeExists(pSrc, pWC, idxTerm); + } + } + + /* 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 ** operator. @@ -1206,7 +1530,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 */ @@ -1276,52 +1601,6 @@ 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.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_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 @@ -1329,12 +1608,12 @@ static void exprAnalyze( ** ** 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) + 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; i<nLeft; i++){ @@ -1362,12 +1641,14 @@ static void exprAnalyze( ** 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->u.x.iField==0 + else if( pExpr->op==TK_IN + && pTerm->u.x.iField==0 && pExpr->pLeft->op==TK_VECTOR && pExpr->x.pSelect->pPrior==0 #ifndef SQLITE_OMIT_WINDOWFUNC && pExpr->x.pSelect->pWin==0 #endif + && pWC->op==TK_AND ){ int i; for(i=0; i<sqlite3ExprVectorSize(pExpr->pLeft); i++){ @@ -1379,44 +1660,51 @@ static void exprAnalyze( } } -#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.x.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->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.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. @@ -1576,7 +1864,7 @@ void sqlite3WhereExprAnalyze( */ 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; diff --git a/chromium/third_party/sqlite/src/src/window.c b/chromium/third_party/sqlite/src/src/window.c index 88ff7d314de..33e905e53fb 100644 --- a/chromium/third_party/sqlite/src/src/window.c +++ b/chromium/third_party/sqlite/src/src/window.c @@ -1304,15 +1304,19 @@ void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ ** SELECT, or (b) the windows already linked use a compatible window frame. */ 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; } } @@ -1465,6 +1469,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); @@ -2061,6 +2066,7 @@ static void windowCodeRangeTest( int regString = ++pParse->nMem; /* Reg. for constant value '' */ int arith = OP_Add; /* OP_Add or OP_Subtract */ int addrGe; /* Jump destination */ + CollSeq *pColl; assert( op==OP_Ge || op==OP_Gt || op==OP_Le ); assert( pOrderBy && pOrderBy->nExpr==1 ); @@ -2151,6 +2157,8 @@ static void windowCodeRangeTest( ** 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); assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le ); diff --git a/chromium/third_party/sqlite/src/tool/lemon.c b/chromium/third_party/sqlite/src/tool/lemon.c index 54c8946a0df..06ba1be2bd6 100644 --- a/chromium/third_party/sqlite/src/tool/lemon.c +++ b/chromium/third_party/sqlite/src/tool/lemon.c @@ -401,7 +401,7 @@ struct lemon { struct symbol *errsym; /* The error symbol */ struct symbol *wildcard; /* Token that matches anything */ char *name; /* Name of the generated parser */ - char *arg; /* Declaration of the 3th argument to parser */ + char *arg; /* Declaration of the 3rd argument to parser */ char *ctx; /* Declaration of 2nd argument to constructor */ char *tokentype; /* Type of terminal symbols in the parser stack */ char *vartype; /* The default type of non-terminal symbols */ @@ -1027,7 +1027,7 @@ PRIVATE void buildshifts(struct lemon *lemp, struct state *stp) struct symbol *bsp; /* Symbol following the dot in configuration "bcfp" */ struct state *newstp; /* A pointer to a successor state */ - /* Each configuration becomes complete after it contibutes to a successor + /* Each configuration becomes complete after it contributes to a successor ** state. Initially, all configurations are incomplete */ for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE; @@ -1887,7 +1887,7 @@ static char *merge( ** ** Return Value: ** A pointer to the head of a sorted list containing the elements -** orginally in list. +** originally in list. ** ** Side effects: ** The "next" pointers for elements in list are changed. @@ -3513,7 +3513,7 @@ void ReportOutput(struct lemon *lemp) } /* Search for the file "name" which is in the same directory as -** the exacutable */ +** the executable */ PRIVATE char *pathsearch(char *argv0, char *name, int modemask) { const char *pathlist; @@ -3868,7 +3868,7 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ lhsdirect = 1; }else if( rp->rhsalias[0]==0 ){ /* The left-most RHS symbol has no value. LHS direct is ok. But - ** we have to call the distructor on the RHS symbol first. */ + ** we have to call the destructor on the RHS symbol first. */ lhsdirect = 1; if( has_destructor(rp->rhs[0],lemp) ){ append_str(0,0,0,0); @@ -4849,7 +4849,7 @@ void ReportTable( ** yyRuleInfoNRhs[]. ** ** Note: This code depends on the fact that rules are number - ** sequentually beginning with 0. + ** sequentially beginning with 0. */ for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){ fprintf(out," %4d, /* (%d) ", rp->lhs->index, i); diff --git a/chromium/third_party/sqlite/src/tool/lempar.c b/chromium/third_party/sqlite/src/tool/lempar.c index 71a51cf4487..35c3768bb9d 100644 --- a/chromium/third_party/sqlite/src/tool/lempar.c +++ b/chromium/third_party/sqlite/src/tool/lempar.c @@ -718,55 +718,6 @@ static YYACTIONTYPE yy_reduce( (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; - assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); -#ifndef NDEBUG - if( yyTraceFILE ){ - yysize = yyRuleInfoNRhs[yyruleno]; - if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", - yyTracePrompt, - yyruleno, yyRuleName[yyruleno], - yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action", - yymsp[yysize].stateno); - }else{ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", - yyTracePrompt, yyruleno, yyRuleName[yyruleno], - yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action"); - } - } -#endif /* NDEBUG */ - - /* Check that the stack is large enough to grow by a single entry - ** if the RHS of the rule is empty. This ensures that there is room - ** enough on the stack to push the LHS value */ - if( yyRuleInfoNRhs[yyruleno]==0 ){ -#ifdef YYTRACKMAXSTACKDEPTH - if( (int)(yypParser->yytos - 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 @@ -925,12 +876,56 @@ void Parse( } #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 ParseCTX_PARAM); + unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */ + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); +#ifndef NDEBUG + if( yyTraceFILE ){ + int yysize = yyRuleInfoNRhs[yyruleno]; + if( yysize ){ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + yyTracePrompt, + yyruleno, yyRuleName[yyruleno], + yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action", + yypParser->yytos[yysize].stateno); + }else{ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", + yyTracePrompt, yyruleno, yyRuleName[yyruleno], + yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action"); + } + } +#endif /* NDEBUG */ + + /* Check that the stack is large enough to grow by a single entry + ** if the RHS of the rule is empty. This ensures that there is room + ** enough on the stack to push the LHS value */ + if( yyRuleInfoNRhs[yyruleno]==0 ){ +#ifdef YYTRACKMAXSTACKDEPTH + if( (int)(yypParser->yytos - 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 ParseCTX_PARAM); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); #ifndef YYNOERRORRECOVERY @@ -1043,7 +1038,7 @@ void Parse( break; #endif } - }while( yypParser->yytos>yypParser->yystack ); + } #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; diff --git a/chromium/third_party/sqlite/src/tool/mkkeywordhash.c b/chromium/third_party/sqlite/src/tool/mkkeywordhash.c index 83ec179ba08..bbb0ccf2932 100644 --- a/chromium/third_party/sqlite/src/tool/mkkeywordhash.c +++ b/chromium/third_party/sqlite/src/tool/mkkeywordhash.c @@ -155,10 +155,16 @@ struct Keyword { # define WINDOWFUNC 0x00100000 #endif #ifdef SQLITE_OMIT_GENERATED_COLUMNS -# define GENCOL 0 +# define GENCOL 0 #else -# define GENCOL 0x00200000 +# define GENCOL 0x00200000 #endif +#ifdef SQLITE_OMIT_RETURNING +# define RETURNING 0 +#else +# define RETURNING 0x00400000 +#endif + /* ** These are the keywords @@ -223,7 +229,7 @@ static Keyword aKeywordTable[] = { { "FOREIGN", "TK_FOREIGN", FKEY, 1 }, { "FROM", "TK_FROM", ALWAYS, 10 }, { "FULL", "TK_JOIN_KW", ALWAYS, 3 }, - { "GENERATED", "TK_GENERATED", GENCOL, 1 }, + { "GENERATED", "TK_GENERATED", ALWAYS, 1 }, { "GLOB", "TK_LIKE_KW", ALWAYS, 3 }, { "GROUP", "TK_GROUP", ALWAYS, 5 }, { "GROUPS", "TK_GROUPS", WINDOWFUNC, 2 }, @@ -249,6 +255,7 @@ static Keyword aKeywordTable[] = { { "LIKE", "TK_LIKE_KW", ALWAYS, 5 }, { "LIMIT", "TK_LIMIT", ALWAYS, 3 }, { "MATCH", "TK_MATCH", ALWAYS, 2 }, + { "MATERIALIZED", "TK_MATERIALIZED", CTE, 12 }, { "NATURAL", "TK_JOIN_KW", ALWAYS, 3 }, { "NO", "TK_NO", FKEY|WINDOWFUNC, 2 }, { "NOT", "TK_NOT", ALWAYS, 10 }, @@ -280,6 +287,7 @@ static Keyword aKeywordTable[] = { { "RENAME", "TK_RENAME", ALTER, 1 }, { "REPLACE", "TK_REPLACE", CONFLICT, 10 }, { "RESTRICT", "TK_RESTRICT", FKEY, 1 }, + { "RETURNING", "TK_RETURNING", RETURNING, 10 }, { "RIGHT", "TK_JOIN_KW", ALWAYS, 0 }, { "ROLLBACK", "TK_ROLLBACK", ALWAYS, 1 }, { "ROW", "TK_ROW", TRIGGER, 1 }, @@ -381,6 +389,14 @@ static void reorder(int *pFrom){ reorder(&aKeywordTable[i].iNext); } +/* Parameter to the hash function +*/ +#define HASH_OP ^ +#define HASH_CC '^' +#define HASH_C0 4 +#define HASH_C1 3 +#define HASH_C2 1 + /* ** This routine does the work. The generated code is printed on standard ** output. @@ -411,8 +427,9 @@ int main(int argc, char **argv){ assert( p->len<sizeof(p->zOrigName) ); memcpy(p->zOrigName, p->zName, p->len+1); totalLen += p->len; - p->hash = (charMap(p->zName[0])*4) ^ - (charMap(p->zName[p->len-1])*3) ^ (p->len*1); + p->hash = (charMap(p->zName[0])*HASH_C0) HASH_OP + (charMap(p->zName[p->len-1])*HASH_C1) HASH_OP + (p->len*HASH_C2); p->id = i+1; } @@ -648,8 +665,9 @@ int main(int argc, char **argv){ printf(" int i, j;\n"); printf(" const char *zKW;\n"); printf(" if( n>=2 ){\n"); - printf(" i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) %% %d;\n", - bestSize); + printf(" i = ((charMap(z[0])*%d) %c", HASH_C0, HASH_CC); + printf(" (charMap(z[n-1])*%d) %c", HASH_C1, HASH_CC); + printf(" n*%d) %% %d;\n", HASH_C2, bestSize); printf(" for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){\n"); printf(" if( aKWLen[i]!=n ) continue;\n"); printf(" zKW = &zKWText[aKWOffset[i]];\n"); diff --git a/chromium/third_party/sqlite/src/tool/sqldiff.c b/chromium/third_party/sqlite/src/tool/sqldiff.c index 123d5b49b78..9844cbadf0f 100644 --- a/chromium/third_party/sqlite/src/tool/sqldiff.c +++ b/chromium/third_party/sqlite/src/tool/sqldiff.c @@ -1713,19 +1713,27 @@ end_changeset_one_table: } /* +** Return true if the ascii character passed as the only argument is a +** whitespace character. Otherwise return false. +*/ +static int is_whitespace(char x){ + return (x==' ' || x=='\t' || x=='\n' || x=='\r'); +} + +/* ** Extract the next SQL keyword or quoted string from buffer zIn and copy it ** (or a prefix of it if it will not fit) into buffer zBuf, size nBuf bytes. ** Return a pointer to the character within zIn immediately following ** the token or quoted string just extracted. */ -const char *gobble_token(const char *zIn, char *zBuf, int nBuf){ +static const char *gobble_token(const char *zIn, char *zBuf, int nBuf){ const char *p = zIn; char *pOut = zBuf; char *pEnd = &pOut[nBuf-1]; char q = 0; /* quote character, if any */ if( p==0 ) return 0; - while( *p==' ' ) p++; + while( is_whitespace(*p) ) p++; switch( *p ){ case '"': q = '"'; break; case '\'': q = '\''; break; @@ -1744,7 +1752,7 @@ const char *gobble_token(const char *zIn, char *zBuf, int nBuf){ p++; } }else{ - while( *p && *p!=' ' && *p!='(' ){ + while( *p && !is_whitespace(*p) && *p!='(' ){ if( pOut<pEnd ) *pOut++ = *p; p++; } diff --git a/chromium/third_party/usrsctp/README.chromium b/chromium/third_party/usrsctp/README.chromium index e30db200cd0..418ba943461 100644 --- a/chromium/third_party/usrsctp/README.chromium +++ b/chromium/third_party/usrsctp/README.chromium @@ -19,3 +19,6 @@ as well as updates and enhancements from the following Internet Drafts: draft-stewart-prsctp-00.txt draft-stewart-tsvwg-sctpipv6-00.txt draft-iyengar-sctp-cacc-00.txt + +Local modifications: +* Cherry picked 0f8d58300b1fdcd943b4a9dd3fbd830825390d4d diff --git a/chromium/third_party/usrsctp/usrsctplib/usrsctplib/netinet/sctp_input.c b/chromium/third_party/usrsctp/usrsctplib/usrsctplib/netinet/sctp_input.c index f3c3644855f..62f663f5dd6 100755 --- a/chromium/third_party/usrsctp/usrsctplib/usrsctplib/netinet/sctp_input.c +++ b/chromium/third_party/usrsctp/usrsctplib/usrsctplib/netinet/sctp_input.c @@ -2005,11 +2005,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, /* temp code */ if (how_indx < sizeof(asoc->cookie_how)) asoc->cookie_how[how_indx] = 12; - sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net, - SCTP_FROM_SCTP_INPUT + SCTP_LOC_16); - sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, - SCTP_FROM_SCTP_INPUT + SCTP_LOC_17); - + sctp_stop_association_timers(stcb, false); /* notify upper layer */ *notification = SCTP_NOTIFY_ASSOC_RESTART; atomic_add_int(&stcb->asoc.refcnt, 1); @@ -2042,6 +2038,10 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, asoc->str_reset_seq_in = asoc->init_seq_number; asoc->advanced_peer_ack_point = asoc->last_acked_seq; asoc->send_sack = 1; + asoc->data_pkts_seen = 0; + asoc->last_data_chunk_from = NULL; + asoc->last_control_chunk_from = NULL; + asoc->last_net_cmt_send_started = NULL; if (asoc->mapping_array) { memset(asoc->mapping_array, 0, asoc->mapping_array_size); @@ -2106,6 +2106,9 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk); SCTP_DECR_CHK_COUNT(); } + asoc->ctrl_queue_cnt = 0; + asoc->str_reset = NULL; + asoc->stream_reset_outstanding = 0; TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) { TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next); if (chk->data) { @@ -2176,12 +2179,13 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, return (NULL); } /* respond with a COOKIE-ACK */ - sctp_stop_all_cookie_timers(stcb); - sctp_toss_old_cookies(stcb, asoc); sctp_send_cookie_ack(stcb); if (how_indx < sizeof(asoc->cookie_how)) asoc->cookie_how[how_indx] = 15; - + if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE) && + (asoc->sctp_autoclose_ticks > 0)) { + sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL); + } return (stcb); } if (how_indx < sizeof(asoc->cookie_how)) diff --git a/chromium/ui/views/controls/menu/menu_controller.cc b/chromium/ui/views/controls/menu/menu_controller.cc index 3beb5516e12..a4b1058975e 100644 --- a/chromium/ui/views/controls/menu/menu_controller.cc +++ b/chromium/ui/views/controls/menu/menu_controller.cc @@ -3034,9 +3034,6 @@ void MenuController::ExitMenu() { bool nested = delegate_stack_.size() > 1; // ExitTopMostMenu unwinds nested delegates internal::MenuControllerDelegate* delegate = delegate_; - // MenuController may have been deleted when releasing ViewsDelegate ref. - // However as |delegate| can outlive this, it must still be notified of the - // menu closing so that it can perform teardown. int accept_event_flags = accept_event_flags_; base::WeakPtr<MenuController> this_ref = AsWeakPtr(); MenuItemView* result = ExitTopMostMenu(); @@ -3048,15 +3045,12 @@ void MenuController::ExitMenu() { } MenuItemView* MenuController::ExitTopMostMenu() { - base::WeakPtr<MenuController> this_ref = AsWeakPtr(); - // Release the lock which prevents Chrome from shutting down while the menu is // showing. - ViewsDelegate::GetInstance()->ReleaseRef(); - - // Releasing the lock can result in Chrome shutting down, deleting this. - if (!this_ref) - return nullptr; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&ViewsDelegate::ReleaseRef, + base::Unretained(ViewsDelegate::GetInstance()))); // Close any open menus. SetSelection(nullptr, SELECTION_UPDATE_IMMEDIATELY | SELECTION_EXIT); diff --git a/chromium/ui/views/controls/menu/menu_runner_unittest.cc b/chromium/ui/views/controls/menu/menu_runner_unittest.cc index 24bef47ff5d..a39371910fa 100644 --- a/chromium/ui/views/controls/menu/menu_runner_unittest.cc +++ b/chromium/ui/views/controls/menu/menu_runner_unittest.cc @@ -12,6 +12,7 @@ #include "base/callback_helpers.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/bind.h" #include "base/test/simple_test_tick_clock.h" #include "build/build_config.h" #include "ui/base/ui_base_types.h" @@ -576,9 +577,12 @@ TEST_F(MenuRunnerDestructionTest, MenuRunnerDestroyedDuringReleaseRef) { menu_runner->RunMenuAt(owner(), nullptr, gfx::Rect(), MenuAnchorPosition::kTopLeft, 0); - test_views_delegate()->set_release_ref_callback(base::BindRepeating( - [](internal::MenuRunnerImpl* menu_runner) { menu_runner->Release(); }, - base::Unretained(menu_runner))); + base::RunLoop run_loop; + test_views_delegate()->set_release_ref_callback( + base::BindLambdaForTesting([&]() { + run_loop.Quit(); + menu_runner->Release(); + })); base::WeakPtr<internal::MenuRunnerImpl> ref(MenuRunnerAsWeakPtr(menu_runner)); MenuControllerTestApi menu_controller; @@ -586,8 +590,9 @@ TEST_F(MenuRunnerDestructionTest, MenuRunnerDestroyedDuringReleaseRef) { // |menu_runner| simulating device shutdown. menu_controller.controller()->Cancel(MenuController::ExitType::kAll); // Both the |menu_runner| and |menu_controller| should have been deleted. - EXPECT_EQ(nullptr, ref); EXPECT_EQ(nullptr, menu_controller.controller()); + run_loop.Run(); + EXPECT_EQ(nullptr, ref); } TEST_F(MenuRunnerImplTest, FocusOnMenuClose) { diff --git a/chromium/v8/include/v8-version.h b/chromium/v8/include/v8-version.h index c03274c9f94..7edf5052f71 100644 --- a/chromium/v8/include/v8-version.h +++ b/chromium/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 9 #define V8_MINOR_VERSION 0 #define V8_BUILD_NUMBER 257 -#define V8_PATCH_LEVEL 29 +#define V8_PATCH_LEVEL 32 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/chromium/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc b/chromium/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc index 8bcb609f1ba..b07c85a1903 100644 --- a/chromium/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc +++ b/chromium/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc @@ -50,7 +50,6 @@ class OptimizingCompileDispatcher::CompileTask : public CancelableTask { worker_thread_runtime_call_stats_( isolate->counters()->worker_thread_runtime_call_stats()), dispatcher_(dispatcher) { - base::MutexGuard lock_guard(&dispatcher_->ref_count_mutex_); ++dispatcher_->ref_count_; } @@ -98,12 +97,7 @@ class OptimizingCompileDispatcher::CompileTask : public CancelableTask { }; OptimizingCompileDispatcher::~OptimizingCompileDispatcher() { -#ifdef DEBUG - { - base::MutexGuard lock_guard(&ref_count_mutex_); - DCHECK_EQ(0, ref_count_); - } -#endif + DCHECK_EQ(0, ref_count_); DCHECK_EQ(0, input_queue_length_); DeleteArray(input_queue_); } @@ -234,6 +228,14 @@ void OptimizingCompileDispatcher::InstallOptimizedFunctions() { } } +bool OptimizingCompileDispatcher::HasJobs() { + DCHECK_EQ(ThreadId::Current(), isolate_->thread_id()); + // Note: This relies on {output_queue_} being mutated by a background thread + // only when {ref_count_} is not zero. Also, {ref_count_} is never incremented + // by a background thread. + return !(ref_count_ == 0 && output_queue_.empty()); +} + void OptimizingCompileDispatcher::QueueForOptimization( OptimizedCompilationJob* job) { DCHECK(IsQueueAvailable()); diff --git a/chromium/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.h b/chromium/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.h index 36f285d1631..7d7a5bebb74 100644 --- a/chromium/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.h +++ b/chromium/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.h @@ -53,6 +53,9 @@ class V8_EXPORT_PRIVATE OptimizingCompileDispatcher { static bool Enabled() { return FLAG_concurrent_recompilation; } + // This method must be called on the main thread. + bool HasJobs(); + private: class CompileTask; @@ -90,7 +93,7 @@ class V8_EXPORT_PRIVATE OptimizingCompileDispatcher { int blocked_jobs_; - int ref_count_; + std::atomic<int> ref_count_; base::Mutex ref_count_mutex_; base::ConditionVariable ref_count_zero_; diff --git a/chromium/v8/src/compiler/access-info.cc b/chromium/v8/src/compiler/access-info.cc index 06806feb420..ee82d7d1792 100644 --- a/chromium/v8/src/compiler/access-info.cc +++ b/chromium/v8/src/compiler/access-info.cc @@ -894,7 +894,7 @@ PropertyAccessInfo AccessInfoFactory::LookupTransition( // Transitioning stores *may* store to const fields. The resulting // DataConstant access infos can be distinguished from later, i.e. redundant, // stores to the same constant field by the presence of a transition map. - switch (details.constness()) { + switch (dependencies()->DependOnFieldConstness(transition_map_ref, number)) { case PropertyConstness::kMutable: return PropertyAccessInfo::DataField( zone(), map, std::move(unrecorded_dependencies), field_index, diff --git a/chromium/v8/src/heap/heap.cc b/chromium/v8/src/heap/heap.cc index 23b84296be1..a38080108b2 100644 --- a/chromium/v8/src/heap/heap.cc +++ b/chromium/v8/src/heap/heap.cc @@ -22,6 +22,7 @@ #include "src/codegen/compilation-cache.h" #include "src/common/assert-scope.h" #include "src/common/globals.h" +#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" #include "src/debug/debug.h" #include "src/deoptimizer/deoptimizer.h" #include "src/execution/isolate-utils-inl.h" @@ -3006,6 +3007,12 @@ bool Heap::CanMoveObjectStart(HeapObject object) { if (IsLargeObject(object)) return false; + // Compilation jobs may have references to the object. + if (isolate()->concurrent_recompilation_enabled() && + isolate()->optimizing_compile_dispatcher()->HasJobs()) { + return false; + } + // We can move the object start if the page was already swept. return Page::FromHeapObject(object)->SweepingDone(); } diff --git a/chromium/v8/src/inspector/v8-debugger-agent-impl.cc b/chromium/v8/src/inspector/v8-debugger-agent-impl.cc index 4e0b83952e2..1ea1c6fab3f 100644 --- a/chromium/v8/src/inspector/v8-debugger-agent-impl.cc +++ b/chromium/v8/src/inspector/v8-debugger-agent-impl.cc @@ -499,6 +499,8 @@ Response V8DebuggerAgentImpl::setBreakpointByUrl( Maybe<int> optionalColumnNumber, Maybe<String16> optionalCondition, String16* outBreakpointId, std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations) { + if (!enabled()) return Response::ServerError(kDebuggerNotEnabled); + *locations = std::make_unique<Array<protocol::Debugger::Location>>(); int specified = (optionalURL.isJust() ? 1 : 0) + @@ -587,6 +589,8 @@ Response V8DebuggerAgentImpl::setBreakpoint( String16 breakpointId = generateBreakpointId( BreakpointType::kByScriptId, location->getScriptId(), location->getLineNumber(), location->getColumnNumber(0)); + if (!enabled()) return Response::ServerError(kDebuggerNotEnabled); + if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) != m_breakpointIdToDebuggerBreakpointIds.end()) { return Response::ServerError( @@ -605,6 +609,8 @@ Response V8DebuggerAgentImpl::setBreakpoint( Response V8DebuggerAgentImpl::setBreakpointOnFunctionCall( const String16& functionObjectId, Maybe<String16> optionalCondition, String16* outBreakpointId) { + if (!enabled()) return Response::ServerError(kDebuggerNotEnabled); + InjectedScript::ObjectScope scope(m_session, functionObjectId); Response response = scope.initialize(); if (!response.IsSuccess()) return response; diff --git a/chromium/v8/src/objects/objects.cc b/chromium/v8/src/objects/objects.cc index d9cb7486be8..338254bd5cf 100644 --- a/chromium/v8/src/objects/objects.cc +++ b/chromium/v8/src/objects/objects.cc @@ -2520,9 +2520,21 @@ Maybe<bool> Object::SetPropertyInternal(LookupIterator* it, if ((maybe_attributes.FromJust() & READ_ONLY) != 0) { return WriteToReadOnlyProperty(it, value, should_throw); } - if (maybe_attributes.FromJust() == ABSENT) break; - *found = false; - return Nothing<bool>(); + // At this point we might have called interceptor's query or getter + // callback. Assuming that the callbacks have side effects, we use + // Object::SetSuperProperty() which works properly regardless on + // whether the property was present on the receiver or not when + // storing to the receiver. + if (maybe_attributes.FromJust() == ABSENT) { + // Proceed lookup from the next state. + it->Next(); + } else { + // Finish lookup in order to make Object::SetSuperProperty() store + // property to the receiver. + it->NotFound(); + } + return Object::SetSuperProperty(it, value, store_origin, + should_throw); } break; } @@ -2597,6 +2609,8 @@ Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value, if (found) return result; } + // TODO(ishell): refactor this: both SetProperty and and SetSuperProperty have + // this piece of code. // If the receiver is the JSGlobalObject, the store was contextual. In case // the property did not exist yet on the global object itself, we have to // throw a reference error in strict mode. In sloppy mode, we continue. @@ -2640,6 +2654,8 @@ Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value, } Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(it->GetReceiver()); + // Note, the callers rely on the fact that this code is redoing the full own + // lookup from scratch. LookupIterator::Configuration c = LookupIterator::OWN; LookupIterator own_lookup = it->IsElement() ? LookupIterator(isolate, receiver, it->index(), c) @@ -2702,6 +2718,25 @@ Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value, } } + // TODO(ishell): refactor this: both SetProperty and and SetSuperProperty have + // this piece of code. + // If the receiver is the JSGlobalObject, the store was contextual. In case + // the property did not exist yet on the global object itself, we have to + // throw a reference error in strict mode. In sloppy mode, we continue. + if (receiver->IsJSGlobalObject() && + (GetShouldThrow(isolate, should_throw) == ShouldThrow::kThrowOnError)) { + if (own_lookup.state() == LookupIterator::TRANSITION) { + // The property cell that we have created is garbage because we are going + // to throw now instead of putting it into the global dictionary. However, + // the cell might already have been stored into the feedback vector, so + // we must invalidate it nevertheless. + own_lookup.transition_cell()->ClearAndInvalidate(ReadOnlyRoots(isolate)); + } + isolate->Throw(*isolate->factory()->NewReferenceError( + MessageTemplate::kNotDefined, own_lookup.GetName())); + return Nothing<bool>(); + } + return AddDataProperty(&own_lookup, value, NONE, should_throw, store_origin); } |