Warning: msi_ros.diff needs to be updated with new sql.tab.c and sql.tab.h before performing any future autosyncs!
Log:
22 hours ago Mike McCormack msi: Use MSI_QueryGetRecord in ACTION_AppSearchReg.
22 hours ago Mike McCormack msi: Use MSI_QueryGetRecord in ACTION_AppSearchComponents.
22 hours ago Mike McCormack msi: Use MSI_QueryGetRecord in ACTION_AppSearchGetSigna ...
22 hours ago Mike McCormack msi: Use MSI_IterateRecords when cloning properties.
22 hours ago Francois Gouget msi: Add a Portuguese translation (contributed by Ameri ...
4 days ago Francois Gouget Replace SUBLANG_DEFAULT with the specific SUBLANG_XXX ...
6 days ago Mike McCormack msi: Treat the SourceDir folder the same as TargetDir.
6 days ago Mike McCormack msi: Load all folders in one query, rather one per ...
6 days ago Mike McCormack msi: Only wait for custom actions that don't have msidb ...
6 days ago Mike McCormack msi: Split process_action_return_value into two differe ...
6 days ago Mike McCormack msi: Remove an unused parameter. tree | commitdiff
6 days ago Mike McCormack msi: Fix use of integer fields in MsiFormatRecord.
6 days ago Mike McCormack msi: Test MsiRecordGetString on an integer record field ...
6 days ago Mike McCormack msi: Add a test for formatting records with strings.
6 days ago Mike McCormack msi: Don't access the list of controls after the dialog ...
6 days ago Mike McCormack msi: Create a function to free control data.
7 days ago Mike McCormack msi: Fix an access after freeing memory.
8 days ago Mike McCormack msi: Split msi_set_sourcedir_props into a separate ...
8 days ago Mike McCormack msi: Spelling fixes.
8 days ago Mike McCormack msi: Add another test for the SourceDir property.
8 days ago Mike McCormack msi: Clean up parameters of msi_media_get_disk_info().
8 days ago Mike McCormack msi: Fix some memory leaks.
8 days ago Mike McCormack msi: Don't leak row handles.
11 days ago Mike McCormack msi: Fix a memory leak in load_folder().
11 days ago Mike McCormack msi: Remove unnecessary includes.
11 days ago Mike McCormack msi: Remove a level of indent in resolve_folder().
11 days ago Mike McCormack msi: Add a test showing the _Properties table is a ...
11 days ago Mike McCormack msi: Add a test showing which tables are special.
11 days ago Mike McCormack msi: Remove some redundant else statements.
2006-11-14 Mike McCormack msi: Split MSI_CreatePackage into two functions.
2006-11-14 Mike McCormack msi: Delete the tempfile created by GetTempFileName.
2006-11-14 Mike McCormack msi: Defer package deletion until after the database ...
2006-11-14 Mike McCormack msi: Remove track_tempfile()'s unused 2nd parameter.
2006-11-14 Mike McCormack msi: Always delete temp files after creating them.
2006-11-14 Mike McCormack msi: Print a message if we fail to delete a file.
2006-11-14 James Hawkins msi: Notify the external UI handler when changing media.
2006-11-13 Mike McCormack msi: Only free a string in one place.
2006-11-13 Mike McCormack msi: Fix error handling.
2006-11-13 Mike McCormack msi: Track temp files as soon as they are created.
2006-11-13 Mike McCormack msi: Fail if we can't write out a temporary file.
2006-11-13 Mike McCormack msi: Fix an uninitialized variable in the test cases.
2006-11-13 Mike McCormack msi: Clean upstore_binary_to_temp.
2006-11-13 Francois Gouget Assorted spelling fixes.
2006-11-13 Francois Gouget msi: assert.h is not a local header (spotted by winapi ...
2006-11-13 Paul Vriens msi: Fix typo's (Coverity).
2006-11-13 James Hawkins msi: Fix a heap corruption bug by resizing the src ...
2006-11-10 Mike McCormack msi: Only log the Action, as it's the same as ActionReq ...
2006-11-10 Mike McCormack msi: Check whether the component is enabled first.
2006-11-10 Mike McCormack msi: Component attributes are bitmasks.
2006-11-09 Eric Pouech msi: Fixed bogus A -> W conversion.
2006-11-09 Eric Pouech msi: Don't call PropVariantClear on uninitialized variants.
2006-11-09 James Hawkins msi: Add support for continuous cabinets.
2006-11-09 James Hawkins msi: Extract cabinets in ACTION_InstallFiles. ready ...
2006-11-09 James Hawkins msi: Move the file sequence check out of ready_media ...
2006-11-09 James Hawkins msi: Factor out load_media_info from ready_media_for ...
2006-11-09 James Hawkins msi: Use disk_prompt from the media_info structure ...
2006-11-09 James Hawkins msi: Only add text to the scroll control if text is ...
2006-11-08 Stefan Leichter msi: Added stub for MsiGetFeatureValidStatesA/W.
2006-11-08 James Hawkins msi: Factor out download_remote_cabinet and reuse extra ...
2006-11-08 James Hawkins msi: Store the base URL of the MSI package if it is ...
2006-11-08 James Hawkins msi: Factor copy_install_file out of ACTION_InstallFiles.
2006-11-08 James Hawkins msi: Factor schedule_install_files out of ACTION_Instal ...
2006-11-08 James Hawkins msi: Model the media_info structure members after the ...
2006-11-08 James Hawkins msi: Use msi_alloc_zero instead of a helper function ...
2006-11-08 James Hawkins msi: Use the file's component instead of passing an ...
2006-11-08 James Hawkins msi: Use the media_info structure instead of passing ...
2006-11-08 James Hawkins msi: Add more tests for installing from cabinets.
2006-11-08 Mike McCormack msi: Fix a memory leak.
2006-11-07 Francois Gouget Assorted spelling fixes.
2006-11-07 Mike McCormack msi: By default, install components locally.
2006-11-07 Mike McCormack msi: Fix WHERE IS (NOT) NULL queries.
2006-11-07 Mike McCormack msi: Fix regression tests failing on Windows.
2006-11-07 Mike McCormack msi: Split ACTION_CostFinalize into two functions.
2006-11-06 Alexandre Julliard msi: Fixed definition of the MSIITERHANDLE type.
2006-11-02 Mike McCormack msi: Avoid a memory leak by freeing actions scripts ...
2006-11-02 Mike McCormack msi: Fix a memory leak.
2006-11-02 Mike McCormack msi: Fix a handle leak in the tests.
2006-11-01 Mike McCormack msi: Fix a typo.
2006-11-01 Mike McCormack msi: Don't print traces for addref and release.
2006-11-01 Mike McCormack msi: Search the patch package for source cabinet files.
2006-10-31 Mike McCormack msi: Add a test showing a join doesn't need a WHERE ...
2006-10-31 Mike McCormack msi: Use a simpler algorithm for joins.
2006-10-31 Mike McCormack msi: Test the data returned by join queries in one ...
2006-10-31 Mike McCormack msi: Remove tokens that aren't valid for MSI SQL.
2006-10-31 Mike McCormack msi: Fix a trace.
2006-10-31 Mike McCormack msi: Fix the ALTER and FREE keywords in the tokenizer.
2006-10-31 Mike McCormack msi: Mark components with missing or outdated files ...
2006-10-30 Mike McCormack msi: Split ACTION_UpdateInstallStates into two separate ...
2006-10-27 James Hawkins msi: Extract cabinets based on DiskId, not LastSequence.
2006-10-27 James Hawkins msi: Test the order in which cab files are handled ...
2006-10-27 James Hawkins msi: Implement handling for the ErrorDialog and use ...
2006-10-27 Mike McCormack msi: Avoid crashing if writeout_cabinet_stream fails.
2006-10-27 Mike McCormack msi: Remove redundant null checks before MSI_EvaluateCo ...
2006-10-26 Mike McCormack msi: Fix the join algorithm.
2006-10-26 Mike McCormack msi: Allow UPDATE queries without a condition.
2006-10-26 Mike McCormack msi: Update tables using records, not integer by integer.
2006-10-26 Mike McCormack msi: Remove some unused functions.
2006-10-26 Mike McCormack msi: Fixed the UPDATE query to work with explicit values.
2006-10-26 Mike McCormack msi: Use msi_feature_set_state and msi_component_set ...
2006-10-26 Mike McCormack msi: Create macro functions to set feature and componen ...
2006-10-26 James Hawkins msi: Add tests for the UPDATE sql command.
2006-10-25 Alexandre Julliard msi: Properly handle negative coordinates for mouse ...
2006-10-24 Mikołaj Zalewski resources: Change Dutch sublanguage code to SUBLANG ...
2006-10-24 Mikołaj Zalewski resources: Change German sublanguage code to SUBLANG ...
2006-10-24 Mike McCormack msi: Split code to get a file's verion into a separate ...
2006-10-24 James Hawkins msi: Add tests for installing from continuous cabinets.
2006-10-24 James Hawkins msi: Allow more customization of install test files.
2006-10-24 James Hawkins msi: Remove unused function pointer and definitions.
2006-10-24 James Hawkins msi: Remove two unnecessary install tables. tree | commitdiff
2006-10-24 James Hawkins msi: Add support for localizable strings in MsiDatabase ...
svn path=/trunk/; revision=24909
return ret;
}
+static UINT msi_check_transform_applicable( MSIPACKAGE *package, IStorage *patch )
+{
+ WCHAR szProductCode[] = { 'P','r','o','d','u','c','t','C','o','d','e',0 };
+ LPWSTR prod_code, patch_product;
+ UINT ret;
+
+ prod_code = msi_dup_property( package, szProductCode );
+ patch_product = msi_get_suminfo_product( patch );
+
+ TRACE("db = %s patch = %s\n", debugstr_w(prod_code), debugstr_w(patch_product));
+
+ if ( strstrW( patch_product, prod_code ) )
+ ret = ERROR_SUCCESS;
+ else
+ ret = ERROR_FUNCTION_FAILED;
+
+ msi_free( patch_product );
+ msi_free( prod_code );
+
+ return ret;
+}
+
static UINT msi_apply_substorage_transform( MSIPACKAGE *package,
MSIDATABASE *patch_db, LPCWSTR name )
{
r = IStorage_OpenStorage( patch_db->storage, name, NULL, STGM_SHARE_EXCLUSIVE, NULL, 0, &stg );
if (SUCCEEDED(r))
{
- ret = msi_table_apply_transform( package->db, stg );
+ ret = msi_check_transform_applicable( package, stg );
+ if (ret == ERROR_SUCCESS)
+ msi_table_apply_transform( package->db, stg );
+ else
+ TRACE("substorage transform %s wasn't applicable\n", debugstr_w(name));
IStorage_Release( stg );
- ret = ERROR_SUCCESS;
}
else
ERR("failed to open substorage %s\n", debugstr_w(name));
- return ret;
+ return ERROR_SUCCESS;
}
static UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si )
LPWSTR str, *substorage;
UINT i, r = ERROR_SUCCESS;
- si = MSI_GetSummaryInformationW( patch_db, 0 );
+ si = MSI_GetSummaryInformationW( patch_db->storage, 0 );
if (!si)
return ERROR_FUNCTION_FAILED;
}
msi_parse_patch_summary( package, patch_db );
+
+ /*
+ * There might be a CAB file in the patch package,
+ * so append it to the list of storage to search for streams.
+ */
+ append_storage_to_db( package->db, patch_db->storage );
+
msiobj_release( &patch_db->hdr );
return ERROR_SUCCESS;
check = msi_dup_property( package, cszSourceDir );
if (!check)
MSI_SetPropertyW(package, cszSourceDir, path);
+ msi_free(check);
check = msi_dup_property( package, cszSOURCEDIR );
if (!check)
/* check conditions */
cond = MSI_RecordGetString(row,2);
- if (cond)
- {
- /* this is a hack to skip errors in the condition code */
- if (MSI_EvaluateConditionW(package, cond) == MSICONDITION_FALSE)
- goto end;
- }
+
+ /* this is a hack to skip errors in the condition code */
+ if (MSI_EvaluateConditionW(package, cond) == MSICONDITION_FALSE)
+ goto end;
action = MSI_RecordGetString(row,1);
if (!action)
if (!action)
{
ERR("Error is retrieving action name\n");
- return ERROR_FUNCTION_FAILED;
+ return ERROR_FUNCTION_FAILED;
}
/* check conditions */
cond = MSI_RecordGetString(row,2);
- if (cond)
+
+ /* this is a hack to skip errors in the condition code */
+ if (MSI_EvaluateConditionW(iap->package, cond) == MSICONDITION_FALSE)
{
- /* this is a hack to skip errors in the condition code */
- if (MSI_EvaluateConditionW(iap->package, cond) == MSICONDITION_FALSE)
- {
- TRACE("Skipping action: %s (condition is false)\n",
- debugstr_w(action));
- return ERROR_SUCCESS;
- }
+ TRACE("Skipping action: %s (condition is false)\n", debugstr_w(action));
+ return ERROR_SUCCESS;
}
if (iap->UI)
comp->KeyPath = msi_dup_record_field( row, 6 );
comp->Installed = INSTALLSTATE_UNKNOWN;
- comp->Action = INSTALLSTATE_UNKNOWN;
- comp->ActionRequest = INSTALLSTATE_UNKNOWN;
+ msi_component_set_state( comp, INSTALLSTATE_UNKNOWN );
return ERROR_SUCCESS;
}
feature->Attributes = MSI_RecordGetInteger(row,8);
feature->Installed = INSTALLSTATE_UNKNOWN;
- feature->Action = INSTALLSTATE_UNKNOWN;
- feature->ActionRequest = INSTALLSTATE_UNKNOWN;
+ msi_feature_set_state( feature, INSTALLSTATE_UNKNOWN );
list_add_tail( &package->features, &feature->entry );
ui_actionstart(package, action);
TRACE("Executing Action (%s)\n",debugstr_w(action));
rc = ACTION_PerformAction(package, action, TRUE);
- msi_free(package->script->Actions[script][i]);
if (rc != ERROR_SUCCESS)
break;
}
- msi_free(package->script->Actions[script]);
-
- package->script->ActionCount[script] = 0;
- package->script->Actions[script] = NULL;
+ msi_free_action_script(package, script);
return rc;
}
return folder;
}
-/* scan for and update current install states */
-static void ACTION_UpdateInstallStates(MSIPACKAGE *package)
+static void ACTION_GetComponentInstallStates(MSIPACKAGE *package)
{
MSICOMPONENT *comp;
- MSIFEATURE *feature;
- /* FIXME: component's installed state should be determined
- * by the component's registration
- */
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{
INSTALLSTATE res;
if (!comp->ComponentId)
continue;
- res = MsiGetComponentPathW( package->ProductCode,
+ res = MsiGetComponentPathW( package->ProductCode,
comp->ComponentId, NULL, NULL);
if (res < 0)
res = INSTALLSTATE_ABSENT;
comp->Installed = res;
}
+}
+
+/* scan for and update current install states */
+static void ACTION_UpdateFeatureInstallStates(MSIPACKAGE *package)
+{
+ MSICOMPONENT *comp;
+ MSIFEATURE *feature;
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
override = msi_dup_property( package, property );
if (!override)
return FALSE;
-
+
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
if (strcmpiW(override,all)==0)
- {
- feature->ActionRequest= state;
- feature->Action = state;
- }
+ msi_feature_set_state( feature, state );
else
{
LPWSTR ptr = override;
if ((ptr2 && strncmpW(ptr,feature->Feature, ptr2-ptr)==0)
|| (!ptr2 && strcmpW(ptr,feature->Feature)==0))
{
- feature->ActionRequest= state;
- feature->Action = state;
+ msi_feature_set_state( feature, state );
break;
}
if (ptr2)
break;
}
}
- }
+ }
msi_free(override);
return TRUE;
* 11) FILEADDDEFAULT
* I have confirmed that if ADDLOCAL is stated then the INSTALLLEVEL is
* ignored for all the features. seems strange, especially since it is not
- * documented anywhere, but it is how it works.
+ * documented anywhere, but it is how it works.
*
* I am still ignoring a lot of these. But that is ok for now, ADDLOCAL and
* REMOVE are the big ones, since we don't handle administrative installs
if ((feature_state) && (feature->Action == INSTALLSTATE_UNKNOWN))
{
if (feature->Attributes & msidbFeatureAttributesFavorSource)
- {
- feature->ActionRequest = INSTALLSTATE_SOURCE;
- feature->Action = INSTALLSTATE_SOURCE;
- }
+ msi_feature_set_state( feature, INSTALLSTATE_SOURCE );
else if (feature->Attributes & msidbFeatureAttributesFavorAdvertise)
- {
- feature->ActionRequest = INSTALLSTATE_ADVERTISED;
- feature->Action = INSTALLSTATE_ADVERTISED;
- }
+ msi_feature_set_state( feature, INSTALLSTATE_ADVERTISED );
else
- {
- feature->ActionRequest = INSTALLSTATE_LOCAL;
- feature->Action = INSTALLSTATE_LOCAL;
- }
+ msi_feature_set_state( feature, INSTALLSTATE_LOCAL );
}
}
continue;
LIST_FOR_EACH_ENTRY( fl, &feature->Children, FeatureList, entry )
- {
- fl->feature->ActionRequest = INSTALLSTATE_UNKNOWN;
- fl->feature->Action = INSTALLSTATE_UNKNOWN;
- }
+ msi_feature_set_state( fl->feature, INSTALLSTATE_UNKNOWN );
}
}
else
}
/*
- * now we want to enable or disable components base on feature
- */
+ * now we want to enable or disable components base on feature
+ */
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
ComponentList *cl;
- TRACE("Examining Feature %s (Installed %i, Action %i, Request %i)\n",
- debugstr_w(feature->Feature), feature->Installed, feature->Action,
- feature->ActionRequest);
+ TRACE("Examining Feature %s (Installed %i, Action %i)\n",
+ debugstr_w(feature->Feature), feature->Installed, feature->Action);
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
{
component = cl->component;
- switch (component->Attributes)
+ if (!component->Enabled)
+ continue;
+
+ if (component->Attributes & msidbComponentAttributesOptional)
+ msi_component_set_state( component, INSTALLSTATE_DEFAULT );
+ else
{
- case msidbComponentAttributesLocalOnly:
- component->Action = INSTALLSTATE_LOCAL;
- component->ActionRequest = INSTALLSTATE_LOCAL;
- break;
- case msidbComponentAttributesSourceOnly:
- component->Action = INSTALLSTATE_SOURCE;
- component->ActionRequest = INSTALLSTATE_SOURCE;
- break;
- case msidbComponentAttributesOptional:
- component->Action = INSTALLSTATE_DEFAULT;
- component->ActionRequest = INSTALLSTATE_DEFAULT;
- break;
- default:
- component->Action = INSTALLSTATE_LOCAL;
- component->ActionRequest = INSTALLSTATE_LOCAL;
+ if (component->Attributes & msidbComponentAttributesSourceOnly)
+ msi_component_set_state( component, INSTALLSTATE_SOURCE );
+ else
+ msi_component_set_state( component, INSTALLSTATE_LOCAL );
}
if (component->ForceLocalState)
+ msi_component_set_state( component, INSTALLSTATE_LOCAL );
+
+ if (feature->Attributes == msidbFeatureAttributesFavorLocal)
{
- component->Action = INSTALLSTATE_LOCAL;
- component->ActionRequest = INSTALLSTATE_LOCAL;
+ if (!(component->Attributes & msidbComponentAttributesSourceOnly))
+ msi_component_set_state( component, INSTALLSTATE_LOCAL );
}
-
- if (!component->Enabled)
+ else if (feature->Attributes == msidbFeatureAttributesFavorSource)
{
- component->Action = INSTALLSTATE_UNKNOWN;
- component->ActionRequest = INSTALLSTATE_UNKNOWN;
+ if ((component->Action == INSTALLSTATE_UNKNOWN) ||
+ (component->Action == INSTALLSTATE_ABSENT) ||
+ (component->Action == INSTALLSTATE_ADVERTISED) ||
+ (component->Action == INSTALLSTATE_DEFAULT))
+ msi_component_set_state( component, INSTALLSTATE_SOURCE );
}
- else
+ else if (feature->ActionRequest == INSTALLSTATE_ADVERTISED)
{
- if (feature->Attributes == msidbFeatureAttributesFavorLocal)
- {
- if (!(component->Attributes & msidbComponentAttributesSourceOnly))
- {
- component->Action = INSTALLSTATE_LOCAL;
- component->ActionRequest = INSTALLSTATE_LOCAL;
- }
- }
- else if (feature->Attributes == msidbFeatureAttributesFavorSource)
- {
- if ((component->Action == INSTALLSTATE_UNKNOWN) ||
- (component->Action == INSTALLSTATE_ABSENT) ||
- (component->Action == INSTALLSTATE_ADVERTISED) ||
- (component->Action == INSTALLSTATE_DEFAULT))
-
- {
- component->Action = INSTALLSTATE_SOURCE;
- component->ActionRequest = INSTALLSTATE_SOURCE;
- }
- }
- else if (feature->ActionRequest == INSTALLSTATE_ADVERTISED)
- {
- if ((component->Action == INSTALLSTATE_UNKNOWN) ||
- (component->Action == INSTALLSTATE_ABSENT))
-
- {
- component->Action = INSTALLSTATE_ADVERTISED;
- component->ActionRequest = INSTALLSTATE_ADVERTISED;
- }
- }
- else if (feature->ActionRequest == INSTALLSTATE_ABSENT)
- {
- if (component->Action == INSTALLSTATE_UNKNOWN)
- {
- component->Action = INSTALLSTATE_ABSENT;
- component->ActionRequest = INSTALLSTATE_ABSENT;
- }
- }
- else if (feature->ActionRequest == INSTALLSTATE_UNKNOWN)
- {
- component->Action = INSTALLSTATE_UNKNOWN;
- component->ActionRequest = INSTALLSTATE_UNKNOWN;
- }
+ if ((component->Action == INSTALLSTATE_UNKNOWN) ||
+ (component->Action == INSTALLSTATE_ABSENT))
+ msi_component_set_state( component, INSTALLSTATE_ADVERTISED );
}
-
- if (component->ForceLocalState && feature->Action == INSTALLSTATE_SOURCE)
+ else if (feature->ActionRequest == INSTALLSTATE_ABSENT)
{
- feature->Action = INSTALLSTATE_LOCAL;
- feature->ActionRequest = INSTALLSTATE_LOCAL;
+ if (component->Action == INSTALLSTATE_UNKNOWN)
+ msi_component_set_state( component, INSTALLSTATE_ABSENT );
}
+ else if (feature->ActionRequest == INSTALLSTATE_UNKNOWN)
+ msi_component_set_state( component, INSTALLSTATE_UNKNOWN );
+
+ if (component->ForceLocalState && feature->Action == INSTALLSTATE_SOURCE)
+ msi_feature_set_state( feature, INSTALLSTATE_LOCAL );
}
- }
+ }
LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry )
{
- TRACE("Result: Component %s (Installed %i, Action %i, Request %i)\n",
- debugstr_w(component->Component), component->Installed,
- component->Action, component->ActionRequest);
+ if (component->Action == INSTALLSTATE_DEFAULT)
+ {
+ TRACE("%s was default, setting to local\n", debugstr_w(component->Component));
+ msi_component_set_state( component, INSTALLSTATE_LOCAL );
+ }
+
+ TRACE("Result: Component %s (Installed %i, Action %i)\n",
+ debugstr_w(component->Component), component->Installed, component->Action);
}
return ERROR_SUCCESS;
}
-/*
- * A lot is done in this function aside from just the costing.
- * The costing needs to be implemented at some point but for now I am going
- * to focus on the directory building
- *
- */
-static UINT ACTION_CostFinalize(MSIPACKAGE *package)
+LPWSTR msi_get_disk_file_version( LPCWSTR filename )
{
- static const WCHAR ExecSeqQuery[] =
- {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','D','i','r','e','c','t','o','r','y','`',0};
- static const WCHAR ConditionQuery[] =
- {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- '`','C','o','n','d','i','t','i','o','n','`',0};
- static const WCHAR szCosting[] =
- {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 };
- static const WCHAR szlevel[] =
- {'I','N','S','T','A','L','L','L','E','V','E','L',0};
- static const WCHAR szOne[] = { '1', 0 };
- MSICOMPONENT *comp;
- MSIFILE *file;
- UINT rc;
- MSIQUERY * view;
- LPWSTR level;
+ static const WCHAR name_fmt[] =
+ {'%','u','.','%','u','.','%','u','.','%','u',0};
+ static WCHAR name[] = {'\\',0};
+ VS_FIXEDFILEINFO *lpVer;
+ WCHAR filever[0x100];
+ LPVOID version;
+ DWORD versize;
+ DWORD handle;
+ UINT sz;
+
+ TRACE("%s\n", debugstr_w(filename));
+
+ versize = GetFileVersionInfoSizeW( filename, &handle );
+ if (!versize)
+ return NULL;
- if ( 1 == msi_get_property_int( package, szCosting, 0 ) )
- return ERROR_SUCCESS;
-
- TRACE("Building Directory properties\n");
+ version = msi_alloc( versize );
+ GetFileVersionInfoW( filename, 0, versize, version );
- rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
- if (rc == ERROR_SUCCESS)
- {
- rc = MSI_IterateRecords(view, NULL, ITERATE_CostFinalizeDirectories,
- package);
- msiobj_release(&view->hdr);
- }
+ VerQueryValueW( version, name, (LPVOID*)&lpVer, &sz );
+ msi_free( version );
- TRACE("File calculations\n");
+ sprintfW( filever, name_fmt,
+ HIWORD(lpVer->dwFileVersionMS),
+ LOWORD(lpVer->dwFileVersionMS),
+ HIWORD(lpVer->dwFileVersionLS),
+ LOWORD(lpVer->dwFileVersionLS));
+
+ return strdupW( filever );
+}
+
+static UINT msi_check_file_install_states( MSIPACKAGE *package )
+{
+ LPWSTR file_version;
+ MSIFILE *file;
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
{
msi_free(file->TargetPath);
TRACE("file %s is named %s\n",
- debugstr_w(file->File),debugstr_w(file->FileName));
+ debugstr_w(file->File), debugstr_w(file->FileName));
file->TargetPath = build_directory_name(2, p, file->FileName);
msi_free(p);
TRACE("file %s resolves to %s\n",
- debugstr_w(file->File),debugstr_w(file->TargetPath));
+ debugstr_w(file->File), debugstr_w(file->TargetPath));
+
+ /* don't check files of components that aren't installed */
+ if (comp->Installed == INSTALLSTATE_UNKNOWN ||
+ comp->Installed == INSTALLSTATE_ABSENT)
+ {
+ file->state = msifs_missing; /* assume files are missing */
+ continue;
+ }
if (GetFileAttributesW(file->TargetPath) == INVALID_FILE_ATTRIBUTES)
{
file->state = msifs_missing;
comp->Cost += file->FileSize;
+ comp->Installed = INSTALLSTATE_INCOMPLETE;
continue;
}
- if (file->Version)
+ if (file->Version &&
+ (file_version = msi_get_disk_file_version( file->TargetPath )))
{
- DWORD handle;
- DWORD versize;
- UINT sz;
- LPVOID version;
- static WCHAR name[] = {'\\',0};
- static const WCHAR name_fmt[] =
- {'%','u','.','%','u','.','%','u','.','%','u',0};
- WCHAR filever[0x100];
- VS_FIXEDFILEINFO *lpVer;
-
- TRACE("Version comparison..\n");
- versize = GetFileVersionInfoSizeW(file->TargetPath,&handle);
- version = msi_alloc(versize);
- GetFileVersionInfoW(file->TargetPath, 0, versize, version);
-
- VerQueryValueW(version, name, (LPVOID*)&lpVer, &sz);
-
- sprintfW(filever,name_fmt,
- HIWORD(lpVer->dwFileVersionMS),
- LOWORD(lpVer->dwFileVersionMS),
- HIWORD(lpVer->dwFileVersionLS),
- LOWORD(lpVer->dwFileVersionLS));
-
TRACE("new %s old %s\n", debugstr_w(file->Version),
- debugstr_w(filever));
- if (strcmpiW(filever,file->Version)<0)
+ debugstr_w(file_version));
+ /* FIXME: seems like a bad way to compare version numbers */
+ if (lstrcmpiW(file_version, file->Version)<0)
{
file->state = msifs_overwrite;
- /* FIXME: cost should be diff in size */
comp->Cost += file->FileSize;
+ comp->Installed = INSTALLSTATE_INCOMPLETE;
}
else
file->state = msifs_present;
- msi_free(version);
+ msi_free( file_version );
}
else
file->state = msifs_present;
}
+ return ERROR_SUCCESS;
+}
+
+/*
+ * A lot is done in this function aside from just the costing.
+ * The costing needs to be implemented at some point but for now I am going
+ * to focus on the directory building
+ *
+ */
+static UINT ACTION_CostFinalize(MSIPACKAGE *package)
+{
+ static const WCHAR ExecSeqQuery[] =
+ {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+ '`','D','i','r','e','c','t','o','r','y','`',0};
+ static const WCHAR ConditionQuery[] =
+ {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+ '`','C','o','n','d','i','t','i','o','n','`',0};
+ static const WCHAR szCosting[] =
+ {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 };
+ static const WCHAR szlevel[] =
+ {'I','N','S','T','A','L','L','L','E','V','E','L',0};
+ static const WCHAR szOne[] = { '1', 0 };
+ MSICOMPONENT *comp;
+ UINT rc;
+ MSIQUERY * view;
+ LPWSTR level;
+
+ if ( 1 == msi_get_property_int( package, szCosting, 0 ) )
+ return ERROR_SUCCESS;
+
+ TRACE("Building Directory properties\n");
+
+ rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
+ if (rc == ERROR_SUCCESS)
+ {
+ rc = MSI_IterateRecords(view, NULL, ITERATE_CostFinalizeDirectories,
+ package);
+ msiobj_release(&view->hdr);
+ }
+
+ /* read components states from the registry */
+ ACTION_GetComponentInstallStates(package);
+
+ TRACE("File calculations\n");
+ msi_check_file_install_states( package );
+
TRACE("Evaluating Condition Table\n");
rc = MSI_DatabaseOpenViewW(package->db, ConditionQuery, &view);
TRACE("Enabling or Disabling Components\n");
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{
- if (comp->Condition)
+ if (MSI_EvaluateConditionW(package, comp->Condition) == MSICONDITION_FALSE)
{
- if (MSI_EvaluateConditionW(package,
- comp->Condition) == MSICONDITION_FALSE)
- {
- TRACE("Disabling component %s\n", debugstr_w(comp->Component));
- comp->Enabled = FALSE;
- }
+ TRACE("Disabling component %s\n", debugstr_w(comp->Component));
+ comp->Enabled = FALSE;
}
}
MSI_SetPropertyW(package,szlevel, szOne);
msi_free(level);
- ACTION_UpdateInstallStates(package);
+ ACTION_UpdateFeatureInstallStates(package);
return MSI_SetFeatureStates(package);
}
return ERROR_FUNCTION_FAILED;
}
-static UINT ALTER_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
-{
- MSIALTERVIEW *av = (MSIALTERVIEW*)view;
-
- TRACE("%p %d %d %04x\n", av, row, col, val );
-
- return ERROR_FUNCTION_FAILED;
-}
-
-static UINT ALTER_insert_row( struct tagMSIVIEW *view, MSIRECORD *record )
-{
- MSIALTERVIEW *av = (MSIALTERVIEW*)view;
-
- TRACE("%p %p\n", av, record );
-
- return ERROR_FUNCTION_FAILED;
-}
-
static UINT ALTER_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
MSIALTERVIEW *av = (MSIALTERVIEW*)view;
{
ALTER_fetch_int,
ALTER_fetch_stream,
- ALTER_set_int,
- ALTER_insert_row,
+ NULL,
+ NULL,
ALTER_execute,
ALTER_close,
ALTER_get_dimensions,
UINT ALTER_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name, int hold )
{
- MSIALTERVIEW *av = NULL;
+ MSIALTERVIEW *av;
- TRACE("%p\n", av );
+ TRACE("%p\n", view );
av = msi_alloc_zero( sizeof *av );
if( !av )
static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
{
MSIDATABASE *db = (MSIDATABASE *) arg;
- DWORD r;
msi_free(db->path);
free_cached_tables( db );
msi_free_transforms( db );
msi_destroy_stringtable( db->strings );
- r = IStorage_Release( db->storage );
- if( r )
- ERR("database reference count was not zero (%d)\n", r);
+ IStorage_Release( db->storage );
if (db->deletefile)
{
DeleteFileW( db->deletefile );
LPCWSTR type;
DWORD sql_size = 1, i, len;
WCHAR expanded[128], *ptr;
- WCHAR size[10], comma[2], extra[10];
+ WCHAR size[10], comma[2], extra[30];
static const WCHAR column_fmt[] = {'`','%','s','`',' ','%','s','%','s','%','s','%','s',' ',0};
static const WCHAR size_fmt[] = {'(','%','s',')',0};
static const WCHAR type_int[] = {'I','N','T',0};
static const WCHAR type_long[] = {'L','O','N','G',0};
static const WCHAR type_notnull[] = {' ','N','O','T',' ','N','U','L','L',0};
+ static const WCHAR localizable[] = {' ','L','O','C','A','L','I','Z','A','B','L','E',0};
columns = msi_alloc_zero(sql_size * sizeof(WCHAR));
if (!columns)
ptr = &types[i][1];
len = atolW(ptr);
+ extra[0] = '\0';
switch (types[i][0])
{
- case 'l': case 's':
+ case 'l':
lstrcpyW(extra, type_notnull);
- case 'L': case 'S':
+ case 'L':
+ lstrcatW(extra, localizable);
+ type = type_char;
+ sprintfW(size, size_fmt, ptr);
+ break;
+ case 's':
+ lstrcpyW(extra, type_notnull);
+ case 'S':
type = type_char;
sprintfW(size, size_fmt, ptr);
break;
return ERROR_FUNCTION_FAILED;
}
-static UINT DELETE_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
-{
- MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
-
- TRACE("%p %d %d %04x\n", dv, row, col, val );
-
- return ERROR_FUNCTION_FAILED;
-}
-
-static UINT DELETE_insert_row( struct tagMSIVIEW *view, MSIRECORD *record )
-{
- MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
-
- TRACE("%p %p\n", dv, record );
-
- return ERROR_FUNCTION_FAILED;
-}
-
static UINT DELETE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
- UINT r, i, j, rows = 0, cols = 0;
+ UINT r, i, rows = 0, cols = 0;
+ MSIRECORD *empty;
TRACE("%p %p\n", dv, record);
if( r != ERROR_SUCCESS )
return r;
- TRACE("blanking %d rows\n", rows);
+ TRACE("blanking %d rows\n", rows);
+
+ empty = MSI_CreateRecord( cols );
+ if (!empty)
+ return ERROR_FUNCTION_FAILED;
/* blank out all the rows that match */
- for( i=0; i<rows; i++ )
- for( j=1; j<=cols; j++ )
- dv->table->ops->set_int( dv->table, i, j, 0 );
+ for ( i=0; i<rows; i++ )
+ dv->table->ops->set_row( dv->table, i, empty, (1<<cols)-1 );
+
+ msiobj_release( &empty->hdr );
return ERROR_SUCCESS;
}
{
DELETE_fetch_int,
DELETE_fetch_stream,
- DELETE_set_int,
- DELETE_insert_row,
+ NULL,
+ NULL,
DELETE_execute,
DELETE_close,
DELETE_get_dimensions,
struct msi_scrolltext_info *info;
msi_control *control;
HMODULE hRichedit;
+ LPCWSTR text;
DWORD style;
info = msi_alloc( sizeof *info );
SetPropW( control->hwnd, szButtonData, info );
/* add the text into the richedit */
- msi_scrolltext_add_text( control, MSI_RecordGetString( rec, 10 ) );
+ text = MSI_RecordGetString( rec, 10 );
+ if (text)
+ msi_scrolltext_add_text( control, text );
return ERROR_SUCCESS;
}
case INSTALLSTATE_LOCAL:
case INSTALLSTATE_ADVERTISED:
case INSTALLSTATE_ABSENT:
- feature->ActionRequest = r;
- feature->Action = r;
+ msi_feature_set_state( feature, r );
break;
default:
FIXME("select feature and all children\n");
switch( msg )
{
case WM_LBUTTONDOWN:
- tvhti.pt.x = LOWORD( lParam );
- tvhti.pt.y = HIWORD( lParam );
+ tvhti.pt.x = (short)LOWORD( lParam );
+ tvhti.pt.y = (short)HIWORD( lParam );
tvhti.flags = 0;
tvhti.hItem = 0;
r = CallWindowProcW(info->oldproc, hWnd, TVM_HITTEST, 0, (LPARAM) &tvhti );
UnregisterClassW( szMsiHiddenWindow, NULL );
uiThreadId = 0;
}
+
+static UINT error_dialog_handler(MSIPACKAGE *package, LPCWSTR event,
+ LPCWSTR argument, msi_dialog* dialog)
+{
+ static const WCHAR end_dialog[] = {'E','n','d','D','i','a','l','o','g',0};
+ static const WCHAR error_abort[] = {'E','r','r','o','r','A','b','o','r','t',0};
+ static const WCHAR error_cancel[] = {'E','r','r','o','r','C','a','n','c','e','l',0};
+ static const WCHAR error_no[] = {'E','r','r','o','r','N','o',0};
+ static const WCHAR result_prop[] = {
+ 'M','S','I','E','r','r','o','r','D','i','a','l','o','g','R','e','s','u','l','t',0
+ };
+
+ if ( lstrcmpW( event, end_dialog ) )
+ return ERROR_SUCCESS;
+
+ if ( !lstrcmpW( argument, error_abort ) || !lstrcmpW( argument, error_cancel ) ||
+ !lstrcmpW( argument, error_no ) )
+ {
+ MSI_SetPropertyW( package, result_prop, error_abort );
+ }
+
+ ControlEvent_CleanupSubscriptions(package);
+ msi_dialog_end_dialog( dialog );
+
+ return ERROR_SUCCESS;
+}
+
+static UINT msi_error_dialog_set_error( MSIPACKAGE *package, LPWSTR error_dialog, LPWSTR error )
+{
+ MSIRECORD * row;
+
+ static const WCHAR update[] =
+ {'U','P','D','A','T','E',' ','`','C','o','n','t','r','o','l','`',' ',
+ 'S','E','T',' ','`','T','e','x','t','`',' ','=',' ','\'','%','s','\'',' ',
+ 'W','H','E','R','E', ' ','`','D','i','a','l','o','g','_','`',' ','=',' ','\'','%','s','\'',' ',
+ 'A','N','D',' ','`','C','o','n','t','r','o','l','`',' ','=',' ',
+ '\'','E','r','r','o','r','T','e','x','t','\'',0};
+
+ row = MSI_QueryGetRecord( package->db, update, error, error_dialog );
+ if (!row)
+ return ERROR_FUNCTION_FAILED;
+
+ msiobj_release(&row->hdr);
+ return ERROR_SUCCESS;
+}
+
+UINT msi_spawn_error_dialog( MSIPACKAGE *package, LPWSTR error_dialog, LPWSTR error )
+{
+ msi_dialog *dialog;
+ WCHAR result[MAX_PATH];
+ UINT r = ERROR_SUCCESS;
+ DWORD size = MAX_PATH;
+ int res;
+
+ static const WCHAR pn_prop[] = {'P','r','o','d','u','c','t','N','a','m','e',0};
+ static const WCHAR title_fmt[] = {'%','s',' ','W','a','r','n','i','n','g',0};
+ static const WCHAR error_abort[] = {'E','r','r','o','r','A','b','o','r','t',0};
+ static const WCHAR result_prop[] = {
+ 'M','S','I','E','r','r','o','r','D','i','a','l','o','g','R','e','s','u','l','t',0
+ };
+
+ if ( !error_dialog )
+ {
+ LPWSTR product_name = msi_dup_property( package, pn_prop );
+ WCHAR title[MAX_PATH];
+
+ sprintfW( title, title_fmt, product_name );
+ res = MessageBoxW( NULL, error, title, MB_OKCANCEL | MB_ICONWARNING );
+
+ msi_free( product_name );
+
+ if ( res == IDOK )
+ return ERROR_SUCCESS;
+ else
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ r = msi_error_dialog_set_error( package, error_dialog, error );
+ if ( r != ERROR_SUCCESS )
+ return r;
+
+ dialog = msi_dialog_create( package, error_dialog, package->dialog,
+ error_dialog_handler );
+ if ( !dialog )
+ return ERROR_FUNCTION_FAILED;
+
+ dialog->finished = FALSE;
+ r = msi_dialog_run_message_loop( dialog );
+ if ( r != ERROR_SUCCESS )
+ goto done;
+
+ r = MSI_GetPropertyW( package, result_prop, result, &size );
+ if ( r != ERROR_SUCCESS)
+ r = ERROR_SUCCESS;
+
+ if ( !lstrcmpW( result, error_abort ) )
+ r = ERROR_FUNCTION_FAILED;
+
+done:
+ msi_dialog_destroy( dialog );
+
+ return r;
+}
else
{
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
- {
- feature->ActionRequest = INSTALLSTATE_LOCAL;
- feature->Action = INSTALLSTATE_LOCAL;
- }
+ msi_feature_set_state( feature, INSTALLSTATE_LOCAL );
+
ACTION_UpdateComponentStates(package,argument);
}
return ERROR_SUCCESS;
else
{
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
- {
- feature->ActionRequest = INSTALLSTATE_ABSENT;
- feature->Action= INSTALLSTATE_ABSENT;
- }
+ msi_feature_set_state( feature, INSTALLSTATE_ABSENT );
+
ACTION_UpdateComponentStates(package,argument);
}
return ERROR_SUCCESS;
else
{
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
- {
- feature->ActionRequest = INSTALLSTATE_SOURCE;
- feature->Action = INSTALLSTATE_SOURCE;
- }
+ msi_feature_set_state( feature, INSTALLSTATE_SOURCE );
ACTION_UpdateComponentStates(package,argument);
}
return ERROR_SUCCESS;
static const WCHAR cszTempFolder[]= {'T','e','m','p','F','o','l','d','e','r',0};
+struct media_info {
+ UINT disk_id;
+ UINT last_sequence;
+ LPWSTR disk_prompt;
+ LPWSTR cabinet;
+ LPWSTR volume_label;
+ BOOL is_continuous;
+ WCHAR source[MAX_PATH];
+};
+
+static UINT msi_change_media( MSIPACKAGE *package, struct media_info *mi )
+{
+ LPWSTR error, error_dialog;
+ UINT r = ERROR_SUCCESS;
+
+ static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
+ static const WCHAR error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0};
+
+ if ( msi_get_property_int(package, szUILevel, 0) == INSTALLUILEVEL_NONE )
+ return ERROR_SUCCESS;
+
+ error = generate_error_string( package, 1302, 1, mi->disk_prompt );
+ error_dialog = msi_dup_property( package, error_prop );
+
+ while ( r == ERROR_SUCCESS && GetFileAttributesW( mi->source ) == INVALID_FILE_ATTRIBUTES )
+ r = msi_spawn_error_dialog( package, error_dialog, error );
+
+ msi_free( error );
+ msi_free( error_dialog );
+
+ return r;
+}
+
/*
* This is a helper function for handling embedded cabinet media
*/
typedef struct
{
MSIPACKAGE* package;
- LPCSTR cab_path;
+ struct media_info *mi;
} CabData;
static void * cabinet_alloc(ULONG cb)
ui_progress( package, 2, f->FileSize, 0, 0);
}
+static UINT msi_media_get_disk_info( CabData *data )
+{
+ MSIPACKAGE *package = data->package;
+ MSIRECORD *row;
+ LPWSTR ptr;
+
+ static const WCHAR query[] =
+ {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
+ '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
+ '`','D','i','s','k','I','d','`',' ','=',' ','%','i',0};
+
+ row = MSI_QueryGetRecord(package->db, query, data->mi->disk_id);
+ if (!row)
+ {
+ TRACE("Unable to query row\n");
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ data->mi->disk_prompt = strdupW(MSI_RecordGetString(row, 3));
+ data->mi->cabinet = strdupW(MSI_RecordGetString(row, 4));
+
+ ptr = strrchrW(data->mi->source, '\\') + 1;
+ lstrcpyW(ptr, data->mi->cabinet);
+
+ return ERROR_SUCCESS;
+}
+
static INT_PTR cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
{
+ TRACE("(%d)\n", fdint);
+
switch (fdint)
{
+ case fdintPARTIAL_FILE:
+ {
+ CabData *data = (CabData *)pfdin->pv;
+ data->mi->is_continuous = FALSE;
+ return 0;
+ }
+ case fdintNEXT_CABINET:
+ {
+ CabData *data = (CabData *)pfdin->pv;
+ struct media_info *mi = data->mi;
+ LPWSTR cab = strdupAtoW(pfdin->psz1);
+ UINT rc;
+
+ msi_free(mi->disk_prompt);
+
+ mi->disk_id++;
+ mi->is_continuous = TRUE;
+
+ rc = msi_media_get_disk_info(data);
+ if (rc != ERROR_SUCCESS)
+ {
+ ERR("Failed to get next cabinet information: %d\n", rc);
+ return -1;
+ }
+
+ if (lstrcmpiW(mi->cabinet, cab))
+ {
+ msi_free(cab);
+ ERR("Continuous cabinet does not match the next cabinet in the Media table\n");
+ return -1;
+ }
+
+ msi_free(cab);
+
+ TRACE("Searching for %s\n", debugstr_w(mi->source));
+
+ if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES)
+ rc = msi_change_media(data->package, mi);
+
+ if (rc != ERROR_SUCCESS)
+ return -1;
+
+ return 0;
+ }
case fdintCOPY_FILE:
{
CabData *data = (CabData*) pfdin->pv;
*
* Extract files from a cab file.
*/
-static BOOL extract_cabinet_file(MSIPACKAGE* package, LPCWSTR source,
- LPCWSTR path)
+static BOOL extract_cabinet_file(MSIPACKAGE* package, struct media_info *mi)
{
+ LPSTR cabinet, cab_path = NULL;
+ LPWSTR ptr;
HFDI hfdi;
ERF erf;
- BOOL ret;
- char *cabinet;
- char *cab_path;
- static CHAR empty[] = "";
+ BOOL ret = FALSE;
CabData data;
- TRACE("Extracting %s to %s\n",debugstr_w(source), debugstr_w(path));
-
- hfdi = FDICreate(cabinet_alloc,
- cabinet_free,
- cabinet_open,
- cabinet_read,
- cabinet_write,
- cabinet_close,
- cabinet_seek,
- 0,
- &erf);
+ TRACE("Extracting %s\n", debugstr_w(mi->source));
+
+ hfdi = FDICreate(cabinet_alloc, cabinet_free, cabinet_open, cabinet_read,
+ cabinet_write, cabinet_close, cabinet_seek, 0, &erf);
if (!hfdi)
{
ERR("FDICreate failed\n");
return FALSE;
}
- if (!(cabinet = strdupWtoA( source )))
- {
- FDIDestroy(hfdi);
- return FALSE;
- }
- if (!(cab_path = strdupWtoA( path )))
- {
- FDIDestroy(hfdi);
- msi_free(cabinet);
- return FALSE;
- }
+ ptr = strrchrW(mi->source, '\\') + 1;
+ cabinet = strdupWtoA(ptr);
+ if (!cabinet)
+ goto done;
- data.package = package;
- data.cab_path = cab_path;
+ cab_path = strdupWtoA(mi->source);
+ if (!cab_path)
+ goto done;
+
+ cab_path[ptr - mi->source] = '\0';
- ret = FDICopy(hfdi, cabinet, empty, 0, cabinet_notify, NULL, &data);
+ data.package = package;
+ data.mi = mi;
+ ret = FDICopy(hfdi, cabinet, cab_path, 0, cabinet_notify, NULL, &data);
if (!ret)
ERR("FDICopy failed\n");
+done:
FDIDestroy(hfdi);
-
msi_free(cabinet);
msi_free(cab_path);
return ret;
}
-static VOID set_file_source(MSIPACKAGE* package, MSIFILE* file, MSICOMPONENT*
- comp, LPCWSTR path)
+static VOID set_file_source(MSIPACKAGE* package, MSIFILE* file, LPCWSTR path)
{
if (!file->IsCompressed)
{
LPWSTR p, path;
- p = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL);
+ p = resolve_folder(package, file->Component->Directory, TRUE, FALSE, NULL);
path = build_directory_name(2, p, file->ShortName);
if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( path ))
{
file->SourcePath = build_directory_name(2, path, file->File);
}
-struct media_info {
- UINT last_sequence;
- LPWSTR last_volume;
- LPWSTR last_path;
- DWORD count;
- WCHAR source[MAX_PATH];
-};
-
-static struct media_info *create_media_info( void )
-{
- struct media_info *mi;
-
- mi = msi_alloc( sizeof *mi );
- if (mi)
- {
- mi->last_sequence = 0;
- mi->last_volume = NULL;
- mi->last_path = NULL;
- mi->count = 0;
- mi->source[0] = 0;
- }
-
- return mi;
-}
-
static void free_media_info( struct media_info *mi )
{
- msi_free( mi->last_path );
+ msi_free( mi->disk_prompt );
+ msi_free( mi->cabinet );
+ msi_free( mi->volume_label );
msi_free( mi );
}
-/* downloads a remote cabinet and extracts it if it exists */
-static UINT msi_extract_remote_cabinet( MSIPACKAGE *package, struct media_info *mi )
+static UINT download_remote_cabinet(MSIPACKAGE *package, struct media_info *mi)
{
- FDICABINETINFO cabinfo;
WCHAR temppath[MAX_PATH];
- WCHAR src[MAX_PATH];
- LPSTR cabpath;
- LPCWSTR file;
- LPWSTR ptr;
- HFDI hfdi;
- ERF erf;
- int hf;
+ LPWSTR src, ptr;
+ LPCWSTR cab;
- /* the URL is the path prefix of the package URL and the filename
- * of the file to download
- */
- ptr = strrchrW(package->PackagePath, '/');
- lstrcpynW(src, package->PackagePath, ptr - package->PackagePath + 2);
- ptr = strrchrW(mi->source, '\\');
- lstrcatW(src, ptr + 1);
-
- file = msi_download_file( src, temppath );
- lstrcpyW(mi->source, file);
+ src = strdupW(package->BaseURL);
+ if (!src)
+ return ERROR_OUTOFMEMORY;
- /* check if the remote cabinet still exists, ignore if it doesn't */
- hfdi = FDICreate(cabinet_alloc, cabinet_free, cabinet_open, cabinet_read,
- cabinet_write, cabinet_close, cabinet_seek, 0, &erf);
- if (!hfdi)
+ ptr = strrchrW(src, '/');
+ if (!ptr)
{
- ERR("FDICreate failed\n");
+ msi_free(src);
return ERROR_FUNCTION_FAILED;
}
- cabpath = strdupWtoA(mi->source);
- hf = cabinet_open(cabpath, _O_RDONLY, 0);
- if (!FDIIsCabinet(hfdi, hf, &cabinfo))
- {
- WARN("Remote cabinet %s does not exist.\n", debugstr_w(mi->source));
- msi_free(cabpath);
- return ERROR_SUCCESS;
- }
+ *(ptr + 1) = '\0';
+ ptr = strrchrW(mi->source, '\\');
+ lstrcatW(src, ptr + 1);
+
+ cab = msi_download_file(src, temppath);
+ lstrcpyW(mi->source, cab);
- msi_free(cabpath);
- return !extract_cabinet_file(package, mi->source, mi->last_path);
+ msi_free(src);
+ return ERROR_SUCCESS;
}
-static UINT ready_media_for_file( MSIPACKAGE *package, struct media_info *mi,
- MSIFILE *file )
+static UINT load_media_info(MSIPACKAGE *package, MSIFILE *file, struct media_info *mi)
{
- UINT rc = ERROR_SUCCESS;
- MSIRECORD * row = 0;
- static const WCHAR ExecSeqQuery[] =
- {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
- '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
- '`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ','>','=',
- ' ','%', 'i',' ','O','R','D','E','R',' ','B','Y',' ',
- '`','L','a','s','t','S','e','q','u','e','n','c','e','`',0};
- LPCWSTR cab, volume;
- DWORD sz;
- INT seq;
- LPCWSTR prompt;
- MSICOMPONENT *comp = file->Component;
+ MSIRECORD *row;
+ LPWSTR source_dir;
+ UINT r;
- if (file->Sequence <= mi->last_sequence)
- {
- set_file_source(package,file,comp,mi->last_path);
- TRACE("Media already ready (%u, %u)\n",file->Sequence,mi->last_sequence);
- return ERROR_SUCCESS;
- }
+ static const WCHAR query[] = {
+ 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
+ '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
+ '`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ','>','=',
+ ' ','%','i',' ','A','N','D',' ','`','D','i','s','k','I','d','`',' ','>','=',
+ ' ','%','i',' ','O','R','D','E','R',' ','B','Y',' ',
+ '`','D','i','s','k','I','d','`',0
+ };
- mi->count ++;
- row = MSI_QueryGetRecord(package->db, ExecSeqQuery, file->Sequence);
+ row = MSI_QueryGetRecord(package->db, query, file->Sequence, mi->disk_id);
if (!row)
{
TRACE("Unable to query row\n");
return ERROR_FUNCTION_FAILED;
}
- volume = MSI_RecordGetString(row, 5);
- prompt = MSI_RecordGetString(row, 3);
+ mi->disk_id = MSI_RecordGetInteger(row, 1);
+ mi->last_sequence = MSI_RecordGetInteger(row, 2);
+ mi->disk_prompt = strdupW(MSI_RecordGetString(row, 3));
+ mi->cabinet = strdupW(MSI_RecordGetString(row, 4));
+ mi->volume_label = strdupW(MSI_RecordGetString(row, 5));
+ msiobj_release(&row->hdr);
- msi_free(mi->last_path);
- mi->last_path = NULL;
+ source_dir = msi_dup_property(package, cszSourceDir);
- if (!file->IsCompressed)
+ if (mi->cabinet && mi->cabinet[0] == '#')
{
- mi->last_path = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL);
- set_file_source(package,file,comp,mi->last_path);
-
- MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
- MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, mi->count, volume,
- prompt);
-
- MsiSourceListSetInfoW(package->ProductCode, NULL,
- MSIINSTALLCONTEXT_USERMANAGED,
- MSICODE_PRODUCT|MSISOURCETYPE_MEDIA,
- INSTALLPROPERTY_LASTUSEDSOURCEW, mi->last_path);
- msiobj_release(&row->hdr);
- return rc;
+ r = writeout_cabinet_stream(package, &mi->cabinet[1], mi->source);
+ if (r != ERROR_SUCCESS)
+ {
+ ERR("Failed to extract cabinet stream\n");
+ return ERROR_FUNCTION_FAILED;
+ }
}
+ else
+ {
+ lstrcpyW(mi->source, source_dir);
- seq = MSI_RecordGetInteger(row,2);
- mi->last_sequence = seq;
- cab = MSI_RecordGetString(row,4);
- if (cab)
- {
- TRACE("Source is CAB %s\n",debugstr_w(cab));
- /* the stream does not contain the # character */
- if (cab[0]=='#')
- {
- LPWSTR path;
+ if (mi->cabinet)
+ lstrcatW(mi->source, mi->cabinet);
+ }
- writeout_cabinet_stream(package,&cab[1],mi->source);
- mi->last_path = strdupW(mi->source);
- *(strrchrW(mi->last_path,'\\')+1)=0;
+ MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT,
+ mi->disk_id, mi->volume_label, mi->disk_prompt);
- path = msi_dup_property( package, cszSourceDir );
+ MsiSourceListSetInfoW(package->ProductCode, NULL,
+ MSIINSTALLCONTEXT_USERMANAGED,
+ MSICODE_PRODUCT | MSISOURCETYPE_MEDIA,
+ INSTALLPROPERTY_LASTUSEDSOURCEW, mi->source);
- MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
- MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, mi->count,
- volume, prompt);
+ msi_free(source_dir);
+ return ERROR_SUCCESS;
+}
- MsiSourceListSetInfoW(package->ProductCode, NULL,
- MSIINSTALLCONTEXT_USERMANAGED,
- MSICODE_PRODUCT|MSISOURCETYPE_NETWORK,
- INSTALLPROPERTY_LASTUSEDSOURCEW, path);
+static UINT ready_media(MSIPACKAGE *package, MSIFILE *file, struct media_info *mi)
+{
+ UINT rc = ERROR_SUCCESS;
+ BOOL found = FALSE;
- msi_free(path);
- }
- else
+ /* media info for continuous cabinet is already loaded */
+ if (mi->is_continuous)
+ return ERROR_SUCCESS;
+
+ rc = load_media_info(package, file, mi);
+ if (rc != ERROR_SUCCESS)
+ {
+ ERR("Unable to load media info\n");
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ if (file->IsCompressed &&
+ GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES)
+ {
+ if (package->BaseURL && UrlIsW(package->BaseURL, URLIS_URL))
{
- sz = MAX_PATH;
- mi->last_path = msi_alloc(MAX_PATH*sizeof(WCHAR));
- if (MSI_GetPropertyW(package, cszSourceDir, mi->source, &sz))
- {
- ERR("No Source dir defined\n");
- rc = ERROR_FUNCTION_FAILED;
- }
- else
+ rc = download_remote_cabinet(package, mi);
+ if (rc == ERROR_SUCCESS &&
+ GetFileAttributesW(mi->source) != INVALID_FILE_ATTRIBUTES)
{
- strcpyW(mi->last_path,mi->source);
- strcatW(mi->source,cab);
-
- MsiSourceListSetInfoW(package->ProductCode, NULL,
- MSIINSTALLCONTEXT_USERMANAGED,
- MSICODE_PRODUCT|MSISOURCETYPE_MEDIA,
- INSTALLPROPERTY_LASTUSEDSOURCEW, mi->last_path);
-
- /* extract the cab file into a folder in the temp folder */
- sz = MAX_PATH;
- if (MSI_GetPropertyW(package, cszTempFolder,mi->last_path, &sz)
- != ERROR_SUCCESS)
- GetTempPathW(MAX_PATH,mi->last_path);
+ found = TRUE;
}
}
- /* only download the remote cabinet file if a local copy does not exist */
- if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES &&
- UrlIsW(package->PackagePath, URLIS_URL))
- {
- rc = msi_extract_remote_cabinet(package, mi);
- }
- else
- {
- rc = !extract_cabinet_file(package, mi->source, mi->last_path);
- }
- }
- else
- {
- sz = MAX_PATH;
- mi->last_path = msi_alloc(MAX_PATH*sizeof(WCHAR));
- MSI_GetPropertyW(package,cszSourceDir,mi->source,&sz);
- strcpyW(mi->last_path,mi->source);
-
- MsiSourceListSetInfoW(package->ProductCode, NULL,
- MSIINSTALLCONTEXT_USERMANAGED,
- MSICODE_PRODUCT|MSISOURCETYPE_MEDIA,
- INSTALLPROPERTY_LASTUSEDSOURCEW, mi->last_path);
+ if (!found)
+ rc = msi_change_media(package, mi);
}
- set_file_source(package, file, comp, mi->last_path);
-
- MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
- MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, mi->count, volume,
- prompt);
-
- msiobj_release(&row->hdr);
return rc;
}
return ERROR_FUNCTION_FAILED;
}
+static void schedule_install_files(MSIPACKAGE *package)
+{
+ MSIFILE *file;
+
+ LIST_FOR_EACH_ENTRY(file, &package->files, MSIFILE, entry)
+ {
+ if (!ACTION_VerifyComponentForAction(file->Component, INSTALLSTATE_LOCAL))
+ {
+ TRACE("File %s is not scheduled for install\n", debugstr_w(file->File));
+
+ ui_progress(package,2,file->FileSize,0,0);
+ file->state = msifs_skipped;
+ }
+ }
+}
+
+static UINT copy_install_file(MSIFILE *file)
+{
+ BOOL ret;
+ UINT gle;
+
+ TRACE("Copying %s to %s\n", debugstr_w(file->SourcePath),
+ debugstr_w(file->TargetPath));
+
+ ret = CopyFileW(file->SourcePath, file->TargetPath, FALSE);
+ if (ret)
+ {
+ file->state = msifs_installed;
+ return ERROR_SUCCESS;
+ }
+
+ gle = GetLastError();
+ if (gle == ERROR_ALREADY_EXISTS && file->state == msifs_overwrite)
+ {
+ TRACE("overwriting existing file\n");
+ gle = ERROR_SUCCESS;
+ }
+ else if (gle == ERROR_FILE_NOT_FOUND)
+ {
+ /* FIXME: this needs to be tested, I'm pretty sure it fails */
+ TRACE("Source file not found\n");
+ gle = ERROR_SUCCESS;
+ }
+ else if (!(file->Attributes & msidbFileAttributesVital))
+ {
+ TRACE("Ignoring error for nonvital\n");
+ gle = ERROR_SUCCESS;
+ }
+
+ return gle;
+}
+
/*
* ACTION_InstallFiles()
*
ptr = strrchrW(package->PackagePath,'\\');
if (ptr)
{
- ptr ++;
+ ptr++;
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT,
INSTALLPROPERTY_PACKAGENAMEW, ptr);
}
- /* FIXME("Write DiskPrompt\n"); */
-
- /* Pass 1 */
- LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
- {
- if (!ACTION_VerifyComponentForAction( file->Component, INSTALLSTATE_LOCAL ))
- {
- ui_progress(package,2,file->FileSize,0,0);
- TRACE("File %s is not scheduled for install\n",
- debugstr_w(file->File));
- file->state = msifs_skipped;
- }
- }
+ schedule_install_files(package);
/*
* Despite MSDN specifying that the CreateFolders action
*/
msi_create_component_directories( package );
- mi = create_media_info();
+ mi = msi_alloc_zero( sizeof(struct media_info) );
- /* Pass 2 */
LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
{
if (file->state != msifs_missing && file->state != msifs_overwrite)
continue;
- TRACE("Pass 2: %s\n",debugstr_w(file->File));
-
- rc = ready_media_for_file( package, mi, file );
- if (rc != ERROR_SUCCESS)
+ if (file->Sequence > mi->last_sequence || mi->is_continuous)
{
- ERR("Unable to ready media\n");
- rc = ERROR_FUNCTION_FAILED;
- break;
+ rc = ready_media(package, file, mi);
+ if (rc != ERROR_SUCCESS)
+ {
+ ERR("Failed to ready media\n");
+ rc = ERROR_FUNCTION_FAILED;
+ break;
+ }
+
+ if (file->IsCompressed && !extract_cabinet_file(package, mi))
+ {
+ ERR("Failed to extract cabinet: %s\n", debugstr_w(mi->cabinet));
+ rc = ERROR_FUNCTION_FAILED;
+ break;
+ }
}
+ set_file_source(package, file, mi->source);
+
TRACE("file paths %s to %s\n",debugstr_w(file->SourcePath),
debugstr_w(file->TargetPath));
- if (file->state != msifs_missing && file->state != msifs_overwrite)
- continue;
-
- /* compressed files are extracted in ready_media_for_file */
- if (file->IsCompressed)
+ if (!file->IsCompressed)
{
- if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(file->TargetPath))
- ERR("compressed file wasn't extracted (%s)\n",
- debugstr_w(file->TargetPath));
- continue;
- }
-
- rc = CopyFileW(file->SourcePath,file->TargetPath,FALSE);
- if (!rc)
- {
- rc = GetLastError();
- ERR("Unable to copy file (%s -> %s) (error %d)\n",
- debugstr_w(file->SourcePath), debugstr_w(file->TargetPath), rc);
- if (rc == ERROR_ALREADY_EXISTS && file->state == msifs_overwrite)
- {
- rc = 0;
- }
- else if (rc == ERROR_FILE_NOT_FOUND)
+ rc = copy_install_file(file);
+ if (rc != ERROR_SUCCESS)
{
- ERR("Source File Not Found! Continuing\n");
- rc = 0;
- }
- else if (file->Attributes & msidbFileAttributesVital)
- {
- ERR("Ignoring Error and continuing (nonvital file)...\n");
- rc = 0;
+ ERR("Failed to copy %s to %s (%d)\n", debugstr_w(file->SourcePath),
+ debugstr_w(file->TargetPath), rc);
+ rc = ERROR_INSTALL_FAILURE;
+ break;
}
}
- else
+ else if (file->state != msifs_installed)
{
- file->state = msifs_installed;
- rc = ERROR_SUCCESS;
+ ERR("compressed file wasn't extracted (%s)\n", debugstr_w(file->TargetPath));
+ rc = ERROR_INSTALL_FAILURE;
+ break;
}
}
- /* cleanup */
free_media_info( mi );
return rc;
}
goto out;
ret = msihandletable[handle].obj;
msiobj_addref( ret );
-
+
out:
LeaveCriticalSection( &MSI_handle_cs );
void msiobj_addref( MSIOBJECTHDR *info )
{
- TRACE("%p\n", info);
-
if( !info )
return;
{
int ret;
- TRACE("%p\n",info);
-
if( !info )
return -1;
return ERROR_SUCCESS;
}
+void msi_free_action_script(MSIPACKAGE *package, UINT script)
+{
+ int i;
+ for (i = 0; i < package->script->ActionCount[script]; i++)
+ msi_free(package->script->Actions[script][i]);
+
+ msi_free(package->script->Actions[script]);
+ package->script->Actions[script] = NULL;
+ package->script->ActionCount[script] = 0;
+}
+
static void remove_tracked_tempfiles(MSIPACKAGE* package)
{
struct list *item, *cursor;
if (package->script)
{
for (i = 0; i < TOTAL_SCRIPTS; i++)
- {
- int j;
- for (j = 0; j < package->script->ActionCount[i]; j++)
- msi_free(package->script->Actions[i][j]);
-
- msi_free(package->script->Actions[i]);
- }
+ msi_free_action_script(package, i);
for (i = 0; i < package->script->UniqueActionsCount; i++)
msi_free(package->script->UniqueActions[i]);
msi_free(package->script);
}
+ msi_free(package->BaseURL);
msi_free(package->PackagePath);
msi_free(package->ProductCode);
msi_free(package->ActionFormat);
continue;
if (newstate == INSTALLSTATE_LOCAL)
- {
- component->ActionRequest = INSTALLSTATE_LOCAL;
- component->Action = INSTALLSTATE_LOCAL;
- }
+ msi_component_set_state( component, INSTALLSTATE_LOCAL );
else
{
ComponentList *clist;
MSIFEATURE *f;
- component->ActionRequest = newstate;
- component->Action = newstate;
+ msi_component_set_state( component, newstate );
/*if any other feature wants is local we need to set it local*/
LIST_FOR_EACH_ENTRY( f, &package->features, MSIFEATURE, entry )
if (component->Attributes & msidbComponentAttributesOptional)
{
if (f->Attributes & msidbFeatureAttributesFavorSource)
- {
- component->Action = INSTALLSTATE_SOURCE;
- component->ActionRequest = INSTALLSTATE_SOURCE;
- }
+ msi_component_set_state( component, INSTALLSTATE_SOURCE );
else
- {
- component->Action = INSTALLSTATE_LOCAL;
- component->ActionRequest = INSTALLSTATE_LOCAL;
- }
+ msi_component_set_state( component, INSTALLSTATE_LOCAL );
}
else if (component->Attributes & msidbComponentAttributesSourceOnly)
- {
- component->Action = INSTALLSTATE_SOURCE;
- component->ActionRequest = INSTALLSTATE_SOURCE;
- }
+ msi_component_set_state( component, INSTALLSTATE_SOURCE );
else
- {
- component->Action = INSTALLSTATE_LOCAL;
- component->ActionRequest = INSTALLSTATE_LOCAL;
- }
+ msi_component_set_state( component, INSTALLSTATE_LOCAL );
}
}
}
}
/*
- * INSERT_merge_record
+ * msi_query_merge_record
*
* Merge a value_list and a record to create a second record.
* Replace wildcard entries in the valuelist with values from the record
*/
-static MSIRECORD *INSERT_merge_record( UINT fields, column_info *vl, MSIRECORD *rec )
+MSIRECORD *msi_query_merge_record( UINT fields, column_info *vl, MSIRECORD *rec )
{
MSIRECORD *merged;
DWORD wildcard_count = 1, i;
* Merge the wildcard values into the list of values provided
* in the query, and create a record containing both.
*/
- values = INSERT_merge_record( col_count, iv->vals, record );
+ values = msi_query_merge_record( col_count, iv->vals, record );
if( !values )
goto err;
feature->Attributes & msidbFeatureAttributesDisallowAdvertise)
return ERROR_FUNCTION_FAILED;
- feature->ActionRequest = iState;
- feature->Action = iState;
+ msi_feature_set_state( feature, iState );
ACTION_UpdateComponentStates(package,szFeature);
return r;
}
+
+/***********************************************************************
+ * MsiGetFeatureValidStatesW (MSI.@)
+ */
+UINT WINAPI MsiGetFeatureValidStatesW(MSIHANDLE hInstall, LPCWSTR szFeature,
+ DWORD* pInstallState)
+{
+ if(pInstallState) *pInstallState = 1<<INSTALLSTATE_LOCAL;
+ FIXME("%ld %s %p stub returning %d\n",
+ hInstall, debugstr_w(szFeature), pInstallState, pInstallState ? *pInstallState : 0);
+
+ return ERROR_SUCCESS;
+}
+
+/***********************************************************************
+ * MsiGetFeatureValidStatesA (MSI.@)
+ */
+UINT WINAPI MsiGetFeatureValidStatesA(MSIHANDLE hInstall, LPCSTR szFeature,
+ DWORD* pInstallState)
+{
+ UINT ret;
+ LPWSTR szwFeature = strdupAtoW(szFeature);
+
+ ret = MsiGetFeatureValidStatesW(hInstall, szwFeature, pInstallState);
+
+ msi_free(szwFeature);
+
+ return ret;
+}
MSIDATABASE *db;
MSIVIEW *left, *right;
UINT left_count, right_count;
- UINT left_key, right_key;
- UINT *pairs;
- UINT pair_count;
+ UINT left_rows, right_rows;
} MSIJOINVIEW;
static UINT JOIN_fetch_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT *val )
if( (col==0) || (col>(jv->left_count + jv->right_count)) )
return ERROR_FUNCTION_FAILED;
- if( row >= jv->pair_count )
+ if( row >= (jv->left_rows * jv->right_rows) )
return ERROR_FUNCTION_FAILED;
if( col <= jv->left_count )
{
table = jv->left;
- row = jv->pairs[ row*2 ];
+ row = (row/jv->right_rows);
}
else
{
table = jv->right;
- row = jv->pairs[ row*2 + 1 ];
+ row = (row % jv->right_rows);
col -= jv->left_count;
}
if( (col==0) || (col>(jv->left_count + jv->right_count)) )
return ERROR_FUNCTION_FAILED;
+ if( row >= jv->left_rows * jv->right_rows )
+ return ERROR_FUNCTION_FAILED;
+
if( row <= jv->left_count )
{
table = jv->left;
- row = jv->pairs[ row*2 ];
+ row = (row/jv->right_rows);
}
else
{
table = jv->right;
- row = jv->pairs[ row*2 + 1 ];
+ row = (row % jv->right_rows);
col -= jv->left_count;
}
return table->ops->fetch_stream( table, row, col, stm );
}
-static UINT JOIN_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
-{
- MSIJOINVIEW *jv = (MSIJOINVIEW*)view;
-
- TRACE("%p %d %d %04x\n", jv, row, col, val );
-
- return ERROR_FUNCTION_FAILED;
-}
-
-static UINT JOIN_insert_row( struct tagMSIVIEW *view, MSIRECORD *record )
-{
- MSIJOINVIEW *jv = (MSIJOINVIEW*)view;
-
- TRACE("%p %p\n", jv, record );
-
- return ERROR_FUNCTION_FAILED;
-}
-
-static int join_key_compare(const void *l, const void *r)
-{
- const UINT *left = l, *right = r;
- if (left[1] < right[1])
- return -1;
- if (left[1] == right[1])
- return 0;
- return 1;
-}
-
-static UINT join_load_key_column( MSIJOINVIEW *jv, MSIVIEW *table, UINT column,
- UINT **pdata, UINT *pcount )
-{
- UINT r, i, count = 0, *data = NULL;
-
- r = table->ops->get_dimensions( table, &count, NULL );
- if( r != ERROR_SUCCESS )
- return r;
-
- if (!count)
- goto end;
-
- data = msi_alloc( count * 2 * sizeof (UINT) );
- if (!data)
- return ERROR_SUCCESS;
-
- for (i=0; i<count; i++)
- {
- data[i*2] = i;
- r = table->ops->fetch_int( table, i, column, &data[i*2+1] );
- if (r != ERROR_SUCCESS)
- ERR("fetch data (%u,%u) failed\n", i, column);
- }
-
- qsort( data, count, 2 * sizeof (UINT), join_key_compare );
-
-end:
- *pdata = data;
- *pcount = count;
-
- return ERROR_SUCCESS;
-}
-
-static UINT join_match( UINT *ldata, UINT lcount,
- UINT *rdata, UINT rcount,
- UINT **ppairs, UINT *ppair_count )
-{
- UINT *pairs;
- UINT n, i, j;
-
- TRACE("left %u right %u\n", rcount, lcount);
-
- /* there can be at most max(lcount, rcount) matches */
- if (lcount > rcount)
- n = lcount;
- else
- n = rcount;
-
- pairs = msi_alloc( n * 2 * sizeof(UINT) );
- if (!pairs)
- return ERROR_OUTOFMEMORY;
-
- for (n=0, i=0, j=0; i<lcount && j<rcount; )
- {
- /* values match... store the row numbers */
- if (ldata[i*2+1] == rdata[j*2+1])
- {
- pairs[n*2] = ldata[i*2];
- pairs[n*2+1] = rdata[j*2];
- i++; /* FIXME: assumes primary key on the right */
- n++;
- continue;
- }
-
- /* values differ... move along */
- if (ldata[i*2+1] < rdata[j*2+1])
- i++;
- else
- j++;
- }
-
- *ppairs = pairs;
- *ppair_count = n;
-
- return ERROR_SUCCESS;
-}
-
static UINT JOIN_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
MSIJOINVIEW *jv = (MSIJOINVIEW*)view;
- UINT r, *ldata = NULL, *rdata = NULL, lcount = 0, rcount = 0;
+ UINT r, *ldata = NULL, *rdata = NULL;
TRACE("%p %p\n", jv, record);
if (r != ERROR_SUCCESS)
return r;
- r = join_load_key_column( jv, jv->left, jv->left_key, &ldata, &lcount );
- if (r != ERROR_SUCCESS)
- return r;
-
- r = join_load_key_column( jv, jv->right, jv->right_key, &rdata, &rcount );
- if (r != ERROR_SUCCESS)
+ /* get the number of rows in each table */
+ r = jv->left->ops->get_dimensions( jv->left, &jv->left_rows, NULL );
+ if( r != ERROR_SUCCESS )
+ {
+ ERR("can't get left table dimensions\n");
goto end;
+ }
- r = join_match( ldata, lcount, rdata, rcount, &jv->pairs, &jv->pair_count );
+ r = jv->right->ops->get_dimensions( jv->right, &jv->right_rows, NULL );
+ if( r != ERROR_SUCCESS )
+ {
+ ERR("can't get right table dimensions\n");
+ goto end;
+ }
end:
msi_free( ldata );
if( !jv->left || !jv->right )
return ERROR_FUNCTION_FAILED;
- *rows = jv->pair_count;
+ *rows = jv->left_rows * jv->right_rows;
}
return ERROR_SUCCESS;
jv->right->ops->delete( jv->right );
jv->right = NULL;
- msi_free( jv->pairs );
- jv->pairs = NULL;
-
msi_free( jv );
return ERROR_SUCCESS;
{
JOIN_fetch_int,
JOIN_fetch_stream,
- JOIN_set_int,
- JOIN_insert_row,
+ NULL,
+ NULL,
JOIN_execute,
JOIN_close,
JOIN_get_dimensions,
JOIN_find_matching_rows
};
-/*
- * join_check_condition
- *
- * This is probably overly strict about what kind of condition we need
- * for a join query.
- */
-static UINT join_check_condition(MSIJOINVIEW *jv, struct expr *cond)
-{
- UINT r;
-
- /* assume that we have `KeyColumn` = `SubkeyColumn` */
- if ( cond->type != EXPR_COMPLEX )
- return ERROR_FUNCTION_FAILED;
-
- if ( cond->u.expr.op != OP_EQ )
- return ERROR_FUNCTION_FAILED;
-
- if ( cond->u.expr.left->type != EXPR_COLUMN )
- return ERROR_FUNCTION_FAILED;
-
- if ( cond->u.expr.right->type != EXPR_COLUMN )
- return ERROR_FUNCTION_FAILED;
-
- /* make sure both columns exist */
- r = VIEW_find_column( jv->left, cond->u.expr.left->u.column, &jv->left_key );
- if (r != ERROR_SUCCESS)
- return ERROR_FUNCTION_FAILED;
-
- r = VIEW_find_column( jv->right, cond->u.expr.right->u.column, &jv->right_key );
- if (r != ERROR_SUCCESS)
- return ERROR_FUNCTION_FAILED;
-
- TRACE("left %s (%u) right %s (%u)\n",
- debugstr_w(cond->u.expr.left->u.column), jv->left_key,
- debugstr_w(cond->u.expr.right->u.column), jv->right_key);
-
- return ERROR_SUCCESS;
-}
-
UINT JOIN_CreateView( MSIDATABASE *db, MSIVIEW **view,
- LPCWSTR left, LPCWSTR right,
- struct expr *cond )
+ LPCWSTR left, LPCWSTR right )
{
MSIJOINVIEW *jv = NULL;
UINT r = ERROR_SUCCESS;
goto end;
}
- r = join_check_condition( jv, cond );
- if( r != ERROR_SUCCESS )
- {
- ERR("can't get join condition\n");
- goto end;
- }
-
*view = &jv->view;
return ERROR_SUCCESS;
58 stdcall MsiGetFeatureStateW(long wstr ptr ptr)
59 stdcall MsiGetFeatureUsageA(str str ptr ptr)
60 stdcall MsiGetFeatureUsageW(wstr wstr ptr ptr)
-61 stub MsiGetFeatureValidStatesA
-62 stub MsiGetFeatureValidStatesW
+61 stdcall MsiGetFeatureValidStatesA(long str ptr)
+62 stdcall MsiGetFeatureValidStatesW(long wstr ptr)
63 stdcall MsiGetLanguage(long)
64 stdcall MsiGetMode(long long)
65 stdcall MsiGetProductCodeA(str str)
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-LANGUAGE LANG_GERMAN, SUBLANG_DEFAULT
+LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
{
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-LANGUAGE LANG_DUTCH, SUBLANG_DEFAULT
+LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
STRINGTABLE DISCARDABLE
{
===================================================================
--- tokenize.c (revision 23808)
+++ tokenize.c (working copy)
-@@ -156,7 +156,7 @@
+@@ -87,7 +87,7 @@
+ ** These are the keywords
+ */
static const Keyword aKeywordTable[] = {
- { ABORT_W, TK_ABORT },
- { AFTER_W, TK_AFTER },
+ /*{ ALTER_W, TK_ALTER },*/
- { ALTER_W, TK_ALTER },
- { ALL_W, TK_ALL },
{ AND_W, TK_AND },
- { AS_W, TK_AS },
-@@ -247,7 +247,7 @@
+ { BY_W, TK_BY },
+ { CHAR_W, TK_CHAR },
+@@ -118,7 +118,7 @@
+ { SET_W, TK_SET },
{ SHORT_W, TK_SHORT },
- { STATEMENT_W, TK_STATEMENT },
{ TABLE_W, TK_TABLE },
+ /*{ TEMPORARY_W, TK_TEMPORARY },*/
- { TEMPORARY_W, TK_TEMPORARY },
- { THEN_W, TK_THEN },
- { TRANSACTION_W, TK_TRANSACTION },
- { TRIGGER_W, TK_TRIGGER },
+ { UPDATE_W, TK_UPDATE },
+ { VALUES_W, TK_VALUES },
+ { WHERE_W, TK_WHERE },
MSIFIELD fields[1]; /* nb. array size is count+1 */
} MSIRECORD;
-typedef void *MSIITERHANDLE;
+typedef const struct tagMSICOLUMNHASHENTRY *MSIITERHANDLE;
typedef struct tagMSIVIEWOPS
{
UINT (*fetch_stream)( struct tagMSIVIEW *, UINT row, UINT col, IStream **stm );
/*
- * get_int - sets one integer at {row,col} in the table
+ * set_row - sets values in a row as specified by mask
*
* Similar semantics to fetch_int
*/
- UINT (*set_int)( struct tagMSIVIEW *, UINT row, UINT col, UINT val );
+ UINT (*set_row)( struct tagMSIVIEW *, UINT row, MSIRECORD *rec, UINT mask );
/*
* Inserts a new row into the database from the records contents
struct list RunningActions;
+ LPWSTR BaseURL;
LPWSTR PackagePath;
LPWSTR ProductCode;
typedef struct tagMSISUMMARYINFO
{
MSIOBJECTHDR hdr;
- MSIDATABASE *db;
+ IStorage *storage;
DWORD update_count;
PROPVARIANT property[MSI_MAX_PROPS];
} MSISUMMARYINFO;
extern UINT msi_table_apply_transform( MSIDATABASE *db, IStorage *stg );
extern UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db,
LPCWSTR szTransformFile, int iErrorCond );
+extern void append_storage_to_db( MSIDATABASE *db, IStorage *stg );
/* action internals */
extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR );
extern UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel );
/* package internals */
-extern MSIPACKAGE *MSI_CreatePackage( MSIDATABASE * );
+extern MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *, LPWSTR );
extern UINT MSI_OpenPackageW( LPCWSTR szPackage, MSIPACKAGE ** );
extern UINT MSI_SetTargetPathW( MSIPACKAGE *, LPCWSTR, LPCWSTR );
extern UINT MSI_SetPropertyW( MSIPACKAGE *, LPCWSTR, LPCWSTR );
extern UINT msi_dialog_directorylist_up( msi_dialog *dialog );
extern msi_dialog *msi_dialog_get_parent( msi_dialog *dialog );
extern LPWSTR msi_dialog_get_name( msi_dialog *dialog );
+extern UINT msi_spawn_error_dialog( MSIPACKAGE*, LPWSTR, LPWSTR );
/* preview */
extern MSIPREVIEW *MSI_EnableUIPreview( MSIDATABASE * );
extern UINT MSI_PreviewDialogW( MSIPREVIEW *, LPCWSTR );
/* summary information */
-extern MSISUMMARYINFO *MSI_GetSummaryInformationW( MSIDATABASE *db, UINT uiUpdateCount );
+extern MSISUMMARYINFO *MSI_GetSummaryInformationW( IStorage *stg, UINT uiUpdateCount );
extern LPWSTR msi_suminfo_dup_string( MSISUMMARYINFO *si, UINT uiProperty );
+extern LPWSTR msi_get_suminfo_product( IStorage *stg );
/* undocumented functions */
UINT WINAPI MsiCreateAndVerifyInstallerDirectory( DWORD );
extern void ACTION_FinishCustomActions( MSIPACKAGE* package);
extern UINT ACTION_CustomAction(MSIPACKAGE *package,const WCHAR *action, BOOL execute);
+static inline void msi_feature_set_state( MSIFEATURE *feature, INSTALLSTATE state )
+{
+ feature->ActionRequest = state;
+ feature->Action = state;
+}
+
+static inline void msi_component_set_state( MSICOMPONENT *comp, INSTALLSTATE state )
+{
+ comp->ActionRequest = state;
+ comp->Action = state;
+}
+
/* actions in other modules */
extern UINT ACTION_AppSearch(MSIPACKAGE *package);
extern UINT ACTION_FindRelatedProducts(MSIPACKAGE *package);
extern MSIFOLDER *get_loaded_folder( MSIPACKAGE *package, LPCWSTR dir );
extern int track_tempfile(MSIPACKAGE *package, LPCWSTR name, LPCWSTR path);
extern UINT schedule_action(MSIPACKAGE *package, UINT script, LPCWSTR action);
+extern void msi_free_action_script(MSIPACKAGE *package, UINT script);
extern LPWSTR build_icon_path(MSIPACKAGE *, LPCWSTR);
extern LPWSTR build_directory_name(DWORD , ...);
extern BOOL create_full_pathW(const WCHAR *path);
return word_count;
}
-MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db )
+MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPWSTR base_url )
{
static const WCHAR szLevel[] = { 'U','I','L','e','v','e','l',0 };
static const WCHAR szpi[] = {'%','i',0};
package->WordCount = msi_get_word_count( package );
package->PackagePath = strdupW( db->path );
+ package->BaseURL = strdupW( base_url );
/* OK, here is where we do a slew of things to the database to
* prep for all that is to come as a package */
MSIDATABASE *db = NULL;
MSIPACKAGE *package;
MSIHANDLE handle;
+ LPWSTR ptr, base_url = NULL;
UINT r;
static const WCHAR OriginalDatabase[] =
LPCWSTR file;
if ( UrlIsW( szPackage, URLIS_URL ) )
+ {
file = msi_download_file( szPackage, temppath );
+
+ base_url = strdupW( szPackage );
+ if ( !base_url )
+ return ERROR_OUTOFMEMORY;
+
+ ptr = strrchrW( base_url, '/' );
+ if (ptr) *(ptr + 1) = '\0';
+ }
else
file = copy_package_to_temp( szPackage, temppath );
}
}
- package = MSI_CreatePackage( db );
+ package = MSI_CreatePackage( db, base_url );
+ msi_free( base_url );
msiobj_release( &db->hdr );
if( !package )
return ERROR_FUNCTION_FAILED;
MSIPREVIEW *preview = NULL;
MSIPACKAGE *package;
- package = MSI_CreatePackage( db );
+ package = MSI_CreatePackage( db, NULL );
if( package )
{
preview = alloc_msiobject( MSIHANDLETYPE_PREVIEW, sizeof (MSIPREVIEW),
#define EXPR_WILDCARD 9
#define EXPR_COL_NUMBER_STRING 10
#define EXPR_COL_NUMBER32 11
+#define EXPR_UNARY 12
struct sql_str {
LPCWSTR data;
UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table );
UINT JOIN_CreateView( MSIDATABASE *db, MSIVIEW **view,
- LPCWSTR left, LPCWSTR right,
- struct expr *cond );
+ LPCWSTR left, LPCWSTR right );
UINT ALTER_CreateView( MSIDATABASE *db, MSIVIEW **view, LPCWSTR name, int hold );
int sqliteGetToken(const WCHAR *z, int *tokenType);
+MSIRECORD *msi_query_merge_record( UINT fields, column_info *vl, MSIRECORD *rec );
+
#endif /* __WINE_MSI_QUERY_H */
len = (p - &szDescriptor[20]);
if( len > MAX_FEATURE_CHARS )
return ERROR_INVALID_PARAMETER;
- if (szFeature)
- {
- memcpy( szFeature, &szDescriptor[20], len*sizeof(WCHAR) );
- szFeature[len] = 0;
- }
- TRACE("feature %s\n", debugstr_w( &szDescriptor[20] ));
+ TRACE("feature %s\n", debugstr_wn( &szDescriptor[20], len ));
r = decode_base85_guid( p+1, &component );
if( !r )
StringFromGUID2( &product, szProduct, MAX_FEATURE_CHARS+1 );
if (szComponent)
StringFromGUID2( &component, szComponent, MAX_FEATURE_CHARS+1 );
+ if (szFeature)
+ {
+ memcpy( szFeature, &szDescriptor[20], len*sizeof(WCHAR) );
+ szFeature[len] = 0;
+ }
len = ( &p[21] - szDescriptor );
TRACE("length = %d\n", len);
r = MsiDecomposeDescriptorW( str, p, f, c, pUsed );
- WideCharToMultiByte( CP_ACP, 0, p, MAX_FEATURE_CHARS+1,
- szProduct, MAX_FEATURE_CHARS+1, NULL, NULL );
- WideCharToMultiByte( CP_ACP, 0, f, MAX_FEATURE_CHARS+1,
- szFeature, MAX_FEATURE_CHARS+1, NULL, NULL );
- WideCharToMultiByte( CP_ACP, 0, c, MAX_FEATURE_CHARS+1,
- szComponent, MAX_FEATURE_CHARS+1, NULL, NULL );
+ if (r == ERROR_SUCCESS)
+ {
+ WideCharToMultiByte( CP_ACP, 0, p, -1,
+ szProduct, MAX_FEATURE_CHARS+1, NULL, NULL );
+ WideCharToMultiByte( CP_ACP, 0, f, -1,
+ szFeature, MAX_FEATURE_CHARS+1, NULL, NULL );
+ WideCharToMultiByte( CP_ACP, 0, c, -1,
+ szComponent, MAX_FEATURE_CHARS+1, NULL, NULL );
+ }
msi_free( str );
return sv->table->ops->fetch_stream( sv->table, row, col, stm );
}
-static UINT SELECT_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
+static UINT SELECT_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
{
MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+ UINT i, expanded_mask = 0, r = ERROR_SUCCESS, col_count = 0;
+ MSIRECORD *expanded;
- TRACE("%p %d %d %04x\n", sv, row, col, val );
+ TRACE("%p %d %p %08x\n", sv, row, rec, mask );
- if( !sv->table )
+ if ( !sv->table )
return ERROR_FUNCTION_FAILED;
- if( (col==0) || (col>sv->num_cols) )
- return ERROR_FUNCTION_FAILED;
+ /* test if any of the mask bits are invalid */
+ if ( mask >= (1<<sv->num_cols) )
+ return ERROR_INVALID_PARAMETER;
- col = sv->cols[ col - 1 ];
+ /* find the number of columns in the table below */
+ r = sv->table->ops->get_dimensions( sv->table, NULL, &col_count );
+ if( r )
+ return r;
+
+ /* expand the record to the right size for the underlying table */
+ expanded = MSI_CreateRecord( col_count );
+ if ( !expanded )
+ return ERROR_FUNCTION_FAILED;
- return sv->table->ops->set_int( sv->table, row, col, val );
+ /* move the right fields across */
+ for ( i=0; i<sv->num_cols; i++ )
+ {
+ r = MSI_RecordCopyField( rec, i+1, expanded, sv->cols[ i ] );
+ if (r != ERROR_SUCCESS)
+ break;
+ expanded_mask |= (1<<(sv->cols[i]-1));
+ }
+
+ /* set the row in the underlying table */
+ if (r == ERROR_SUCCESS)
+ r = sv->table->ops->set_row( sv->table, row, expanded, expanded_mask );
+
+ msiobj_release( &expanded->hdr );
+ return r;
}
static UINT SELECT_insert_row( struct tagMSIVIEW *view, MSIRECORD *record )
{
SELECT_fetch_int,
SELECT_fetch_stream,
- SELECT_set_int,
+ SELECT_set_row,
SELECT_insert_row,
SELECT_execute,
SELECT_close,
/* found the source */
if (dwIndex > 0 && current_index != dwIndex)
FIXME("Need to reorder the sources!\n");
+ msi_free( source_struct.path );
}
else
{
-/* A Bison parser, made by GNU Bison 1.875c. */
+/* A Bison parser, made by GNU Bison 2.1. */
/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
/* Identify Bison output. */
#define YYBISON 1
+/* Bison version. */
+#define YYBISON_VERSION "2.1"
+
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
/* Using locations. */
#define YYLSP_NEEDED 0
-/* If NAME_PREFIX is specified substitute the variables and functions
- names. */
+/* Substitute the variable and function names. */
#define yyparse SQL_parse
#define yylex SQL_lex
#define yyerror SQL_error
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
- TK_ABORT = 258,
- TK_AFTER = 259,
- TK_AGG_FUNCTION = 260,
- TK_ALL = 261,
- TK_AND = 262,
- TK_AS = 263,
- TK_ASC = 264,
- TK_BEFORE = 265,
- TK_BEGIN = 266,
- TK_BETWEEN = 267,
- TK_BITAND = 268,
- TK_BITNOT = 269,
- TK_BITOR = 270,
- TK_BY = 271,
- TK_CASCADE = 272,
- TK_CASE = 273,
- TK_CHAR = 274,
- TK_CHECK = 275,
- TK_CLUSTER = 276,
- TK_COLLATE = 277,
- TK_COLUMN = 278,
- TK_COMMA = 279,
- TK_COMMENT = 280,
- TK_COMMIT = 281,
- TK_CONCAT = 282,
- TK_CONFLICT = 283,
- TK_CONSTRAINT = 284,
- TK_COPY = 285,
- TK_CREATE = 286,
- TK_DEFAULT = 287,
- TK_DEFERRABLE = 288,
- TK_DEFERRED = 289,
- TK_DELETE = 290,
- TK_DELIMITERS = 291,
- TK_DESC = 292,
- TK_DISTINCT = 293,
- TK_DOT = 294,
- TK_DROP = 295,
- TK_EACH = 296,
- TK_ELSE = 297,
- TK_END = 298,
- TK_END_OF_FILE = 299,
- TK_EQ = 300,
- TK_EXCEPT = 301,
- TK_EXPLAIN = 302,
- TK_FAIL = 303,
- TK_FLOAT = 304,
- TK_FOR = 305,
- TK_FOREIGN = 306,
- TK_FROM = 307,
- TK_FUNCTION = 308,
- TK_GE = 309,
- TK_GLOB = 310,
- TK_GROUP = 311,
- TK_GT = 312,
- TK_HAVING = 313,
- TK_HOLD = 314,
- TK_IGNORE = 315,
- TK_ILLEGAL = 316,
- TK_IMMEDIATE = 317,
- TK_IN = 318,
- TK_INDEX = 319,
- TK_INITIALLY = 320,
- TK_ID = 321,
- TK_INSERT = 322,
- TK_INSTEAD = 323,
- TK_INT = 324,
- TK_INTEGER = 325,
- TK_INTERSECT = 326,
- TK_INTO = 327,
- TK_IS = 328,
- TK_ISNULL = 329,
- TK_JOIN = 330,
- TK_JOIN_KW = 331,
- TK_KEY = 332,
- TK_LE = 333,
- TK_LIKE = 334,
- TK_LIMIT = 335,
- TK_LONG = 336,
- TK_LONGCHAR = 337,
- TK_LP = 338,
- TK_LSHIFT = 339,
- TK_LT = 340,
- TK_LOCALIZABLE = 341,
- TK_MATCH = 342,
- TK_MINUS = 343,
- TK_NE = 344,
- TK_NOT = 345,
- TK_NOTNULL = 346,
- TK_NULL = 347,
- TK_OBJECT = 348,
- TK_OF = 349,
- TK_OFFSET = 350,
- TK_ON = 351,
- TK_OR = 352,
- TK_ORACLE_OUTER_JOIN = 353,
- TK_ORDER = 354,
- TK_PLUS = 355,
- TK_PRAGMA = 356,
- TK_PRIMARY = 357,
- TK_RAISE = 358,
- TK_REFERENCES = 359,
- TK_REM = 360,
- TK_REPLACE = 361,
- TK_RESTRICT = 362,
- TK_ROLLBACK = 363,
- TK_ROW = 364,
- TK_RP = 365,
- TK_RSHIFT = 366,
- TK_SELECT = 367,
- TK_SEMI = 368,
- TK_SET = 369,
- TK_SHORT = 370,
- TK_SLASH = 371,
- TK_SPACE = 372,
- TK_STAR = 373,
- TK_STATEMENT = 374,
- TK_STRING = 375,
- TK_TABLE = 376,
- TK_TEMP = 377,
- TK_THEN = 378,
- TK_TRANSACTION = 379,
- TK_TRIGGER = 380,
- TK_UMINUS = 381,
- TK_UNCLOSED_STRING = 382,
- TK_UNION = 383,
- TK_UNIQUE = 384,
- TK_UPDATE = 385,
- TK_UPLUS = 386,
- TK_USING = 387,
- TK_VACUUM = 388,
- TK_VALUES = 389,
- TK_VIEW = 390,
- TK_WHEN = 391,
- TK_WHERE = 392,
- TK_WILDCARD = 393,
- COLUMN = 395,
- FUNCTION = 396,
- COMMENT = 397,
- UNCLOSED_STRING = 398,
- SPACE = 399,
- ILLEGAL = 400,
- END_OF_FILE = 401
+ TK_ALTER = 258,
+ TK_AND = 259,
+ TK_BY = 260,
+ TK_CHAR = 261,
+ TK_COMMA = 262,
+ TK_CREATE = 263,
+ TK_DELETE = 264,
+ TK_DISTINCT = 265,
+ TK_DOT = 266,
+ TK_EQ = 267,
+ TK_FREE = 268,
+ TK_FROM = 269,
+ TK_GE = 270,
+ TK_GT = 271,
+ TK_HOLD = 272,
+ TK_ID = 273,
+ TK_ILLEGAL = 274,
+ TK_INSERT = 275,
+ TK_INT = 276,
+ TK_INTEGER = 277,
+ TK_INTO = 278,
+ TK_IS = 279,
+ TK_KEY = 280,
+ TK_LE = 281,
+ TK_LONG = 282,
+ TK_LONGCHAR = 283,
+ TK_LP = 284,
+ TK_LT = 285,
+ TK_LOCALIZABLE = 286,
+ TK_MINUS = 287,
+ TK_NE = 288,
+ TK_NOT = 289,
+ TK_NULL = 290,
+ TK_OBJECT = 291,
+ TK_OR = 292,
+ TK_ORDER = 293,
+ TK_PRIMARY = 294,
+ TK_RP = 295,
+ TK_SELECT = 296,
+ TK_SET = 297,
+ TK_SHORT = 298,
+ TK_SPACE = 299,
+ TK_STAR = 300,
+ TK_STRING = 301,
+ TK_TABLE = 302,
+ TK_TEMPORARY = 303,
+ TK_UPDATE = 304,
+ TK_VALUES = 305,
+ TK_WHERE = 306,
+ TK_WILDCARD = 307,
+ COLUMN = 309,
+ FUNCTION = 310,
+ COMMENT = 311,
+ UNCLOSED_STRING = 312,
+ SPACE = 313,
+ ILLEGAL = 314,
+ END_OF_FILE = 315,
+ TK_LIKE = 316,
+ TK_NEGATION = 317
};
#endif
-#define TK_ABORT 258
-#define TK_AFTER 259
-#define TK_AGG_FUNCTION 260
-#define TK_ALL 261
-#define TK_AND 262
-#define TK_AS 263
-#define TK_ASC 264
-#define TK_BEFORE 265
-#define TK_BEGIN 266
-#define TK_BETWEEN 267
-#define TK_BITAND 268
-#define TK_BITNOT 269
-#define TK_BITOR 270
-#define TK_BY 271
-#define TK_CASCADE 272
-#define TK_CASE 273
-#define TK_CHAR 274
-#define TK_CHECK 275
-#define TK_CLUSTER 276
-#define TK_COLLATE 277
-#define TK_COLUMN 278
-#define TK_COMMA 279
-#define TK_COMMENT 280
-#define TK_COMMIT 281
-#define TK_CONCAT 282
-#define TK_CONFLICT 283
-#define TK_CONSTRAINT 284
-#define TK_COPY 285
-#define TK_CREATE 286
-#define TK_DEFAULT 287
-#define TK_DEFERRABLE 288
-#define TK_DEFERRED 289
-#define TK_DELETE 290
-#define TK_DELIMITERS 291
-#define TK_DESC 292
-#define TK_DISTINCT 293
-#define TK_DOT 294
-#define TK_DROP 295
-#define TK_EACH 296
-#define TK_ELSE 297
-#define TK_END 298
-#define TK_END_OF_FILE 299
-#define TK_EQ 300
-#define TK_EXCEPT 301
-#define TK_EXPLAIN 302
-#define TK_FAIL 303
-#define TK_FLOAT 304
-#define TK_FOR 305
-#define TK_FOREIGN 306
-#define TK_FROM 307
-#define TK_FUNCTION 308
-#define TK_GE 309
-#define TK_GLOB 310
-#define TK_GROUP 311
-#define TK_GT 312
-#define TK_HAVING 313
-#define TK_HOLD 314
-#define TK_IGNORE 315
-#define TK_ILLEGAL 316
-#define TK_IMMEDIATE 317
-#define TK_IN 318
-#define TK_INDEX 319
-#define TK_INITIALLY 320
-#define TK_ID 321
-#define TK_INSERT 322
-#define TK_INSTEAD 323
-#define TK_INT 324
-#define TK_INTEGER 325
-#define TK_INTERSECT 326
-#define TK_INTO 327
-#define TK_IS 328
-#define TK_ISNULL 329
-#define TK_JOIN 330
-#define TK_JOIN_KW 331
-#define TK_KEY 332
-#define TK_LE 333
-#define TK_LIKE 334
-#define TK_LIMIT 335
-#define TK_LONG 336
-#define TK_LONGCHAR 337
-#define TK_LP 338
-#define TK_LSHIFT 339
-#define TK_LT 340
-#define TK_LOCALIZABLE 341
-#define TK_MATCH 342
-#define TK_MINUS 343
-#define TK_NE 344
-#define TK_NOT 345
-#define TK_NOTNULL 346
-#define TK_NULL 347
-#define TK_OBJECT 348
-#define TK_OF 349
-#define TK_OFFSET 350
-#define TK_ON 351
-#define TK_OR 352
-#define TK_ORACLE_OUTER_JOIN 353
-#define TK_ORDER 354
-#define TK_PLUS 355
-#define TK_PRAGMA 356
-#define TK_PRIMARY 357
-#define TK_RAISE 358
-#define TK_REFERENCES 359
-#define TK_REM 360
-#define TK_REPLACE 361
-#define TK_RESTRICT 362
-#define TK_ROLLBACK 363
-#define TK_ROW 364
-#define TK_RP 365
-#define TK_RSHIFT 366
-#define TK_SELECT 367
-#define TK_SEMI 368
-#define TK_SET 369
-#define TK_SHORT 370
-#define TK_SLASH 371
-#define TK_SPACE 372
-#define TK_STAR 373
-#define TK_STATEMENT 374
-#define TK_STRING 375
-#define TK_TABLE 376
-#define TK_TEMP 377
-#define TK_THEN 378
-#define TK_TRANSACTION 379
-#define TK_TRIGGER 380
-#define TK_UMINUS 381
-#define TK_UNCLOSED_STRING 382
-#define TK_UNION 383
-#define TK_UNIQUE 384
-#define TK_UPDATE 385
-#define TK_UPLUS 386
-#define TK_USING 387
-#define TK_VACUUM 388
-#define TK_VALUES 389
-#define TK_VIEW 390
-#define TK_WHEN 391
-#define TK_WHERE 392
-#define TK_WILDCARD 393
-#define COLUMN 395
-#define FUNCTION 396
-#define COMMENT 397
-#define UNCLOSED_STRING 398
-#define SPACE 399
-#define ILLEGAL 400
-#define END_OF_FILE 401
+/* Tokens. */
+#define TK_ALTER 258
+#define TK_AND 259
+#define TK_BY 260
+#define TK_CHAR 261
+#define TK_COMMA 262
+#define TK_CREATE 263
+#define TK_DELETE 264
+#define TK_DISTINCT 265
+#define TK_DOT 266
+#define TK_EQ 267
+#define TK_FREE 268
+#define TK_FROM 269
+#define TK_GE 270
+#define TK_GT 271
+#define TK_HOLD 272
+#define TK_ID 273
+#define TK_ILLEGAL 274
+#define TK_INSERT 275
+#define TK_INT 276
+#define TK_INTEGER 277
+#define TK_INTO 278
+#define TK_IS 279
+#define TK_KEY 280
+#define TK_LE 281
+#define TK_LONG 282
+#define TK_LONGCHAR 283
+#define TK_LP 284
+#define TK_LT 285
+#define TK_LOCALIZABLE 286
+#define TK_MINUS 287
+#define TK_NE 288
+#define TK_NOT 289
+#define TK_NULL 290
+#define TK_OBJECT 291
+#define TK_OR 292
+#define TK_ORDER 293
+#define TK_PRIMARY 294
+#define TK_RP 295
+#define TK_SELECT 296
+#define TK_SET 297
+#define TK_SHORT 298
+#define TK_SPACE 299
+#define TK_STAR 300
+#define TK_STRING 301
+#define TK_TABLE 302
+#define TK_TEMPORARY 303
+#define TK_UPDATE 304
+#define TK_VALUES 305
+#define TK_WHERE 306
+#define TK_WILDCARD 307
+#define COLUMN 309
+#define FUNCTION 310
+#define COMMENT 311
+#define UNCLOSED_STRING 312
+#define SPACE 313
+#define ILLEGAL 314
+#define END_OF_FILE 315
+#define TK_LIKE 316
+#define TK_NEGATION 317
/* Copy the first part of user declarations. */
-#line 1 "./sql.y"
+#line 1 "sql.y"
/*
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define YYLEX_PARAM info
#define YYPARSE_PARAM info
-extern int SQL_error(const char *str);
+static int SQL_error(const char *str);
WINE_DEFAULT_DEBUG_CHANNEL(msi);
static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys);
static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r );
+static struct expr * EXPR_unary( void *info, struct expr *l, UINT op );
static struct expr * EXPR_column( void *info, column_info *column );
static struct expr * EXPR_ival( void *info, int val );
static struct expr * EXPR_sval( void *info, struct sql_str * );
# define YYERROR_VERBOSE 0
#endif
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 72 "./sql.y"
+#line 73 "sql.y"
typedef union YYSTYPE {
struct sql_str str;
LPWSTR string;
USHORT column_type;
int integer;
} YYSTYPE;
-/* Line 191 of yacc.c. */
-#line 453 "sql.tab.c"
+/* Line 196 of yacc.c. */
+#line 294 "sql.tab.c"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
/* Copy the second part of user declarations. */
-/* Line 214 of yacc.c. */
-#line 465 "sql.tab.c"
+/* Line 219 of yacc.c. */
+#line 306 "sql.tab.c"
-#if ! defined (yyoverflow) || YYERROR_VERBOSE
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus))
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
-# ifndef YYFREE
-# define YYFREE free
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
# endif
-# ifndef YYMALLOC
-# define YYMALLOC malloc
+# ifndef YY_
+# define YY_(msgid) msgid
# endif
+#endif
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
# ifdef YYSTACK_USE_ALLOCA
# if YYSTACK_USE_ALLOCA
-# define YYSTACK_ALLOC alloca
-# endif
-# else
-# if defined (alloca) || defined (_ALLOCA_H)
-# define YYSTACK_ALLOC alloca
-# else
# ifdef __GNUC__
# define YYSTACK_ALLOC __builtin_alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYINCLUDED_STDLIB_H
+# endif
# endif
# endif
# endif
# ifdef YYSTACK_ALLOC
/* Pacify GCC's `empty if-body' warning. */
# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
-# else
-# if defined (__STDC__) || defined (__cplusplus)
-# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */
# endif
+# else
# define YYSTACK_ALLOC YYMALLOC
# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1)
+# endif
+# ifdef __cplusplus
+extern "C" {
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \
+ && (defined (__STDC__) || defined (__cplusplus)))
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \
+ && (defined (__STDC__) || defined (__cplusplus)))
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifdef __cplusplus
+}
+# endif
# endif
#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
/* A type that is properly aligned for any stack member. */
union yyalloc
{
- short yyss;
+ short int yyss;
YYSTYPE yyvs;
};
/* The size of an array large to enough to hold all stacks, each with
N elements. */
# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \
+ YYSTACK_GAP_MAXIMUM)
/* Copy COUNT objects from FROM to TO. The source and destination do
# define YYCOPY(To, From, Count) \
do \
{ \
- register YYSIZE_T yyi; \
+ YYSIZE_T yyi; \
for (yyi = 0; yyi < (Count); yyi++) \
(To)[yyi] = (From)[yyi]; \
} \
#if defined (__STDC__) || defined (__cplusplus)
typedef signed char yysigned_char;
#else
- typedef short yysigned_char;
+ typedef short int yysigned_char;
#endif
/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 29
+#define YYFINAL 32
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 124
+#define YYLAST 133
/* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS 147
+#define YYNTOKENS 63
/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 31
+#define YYNNTS 33
/* YYNRULES -- Number of rules. */
-#define YYNRULES 69
+#define YYNRULES 75
/* YYNRULES -- Number of states. */
-#define YYNSTATES 127
+#define YYNSTATES 136
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYUNDEFTOK 2
-#define YYMAXUTOK 401
+#define YYMAXUTOK 317
-#define YYTRANSLATE(YYX) \
+#define YYTRANSLATE(YYX) \
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
- 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
- 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
- 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
- 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
- 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
- 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
- 135, 136, 137, 138, 139, 140, 141, 142, 143, 144,
- 145, 146
+ 55, 56, 57, 58, 59, 60, 61, 62
};
#if YYDEBUG
YYRHS. */
static const unsigned char yyprhs[] =
{
- 0, 0, 3, 5, 7, 9, 11, 13, 15, 26,
- 38, 45, 53, 60, 63, 68, 72, 74, 77, 79,
- 82, 84, 88, 90, 95, 97, 99, 101, 103, 105,
- 107, 112, 114, 117, 121, 124, 126, 130, 132, 134,
- 138, 141, 145, 149, 153, 157, 161, 165, 169, 173,
- 177, 181, 185, 190, 192, 194, 196, 200, 202, 206,
- 210, 212, 215, 217, 219, 221, 225, 227, 229, 231
+ 0, 0, 3, 5, 7, 9, 11, 13, 15, 17,
+ 28, 40, 47, 55, 62, 67, 70, 75, 77, 79,
+ 84, 88, 90, 93, 95, 98, 101, 103, 107, 109,
+ 114, 116, 118, 120, 122, 124, 126, 131, 133, 136,
+ 140, 143, 145, 149, 151, 153, 157, 160, 165, 169,
+ 173, 177, 181, 185, 189, 193, 197, 201, 205, 210,
+ 212, 214, 216, 220, 222, 226, 230, 232, 235, 237,
+ 239, 241, 245, 247, 249, 251
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
-static const short yyrhs[] =
+static const yysigned_char yyrhs[] =
{
- 148, 0, -1, 149, -1, 161, -1, 151, -1, 150,
- -1, 152, -1, 153, -1, 67, 72, 175, 83, 164,
- 110, 134, 83, 169, 110, -1, 67, 72, 175, 83,
- 164, 110, 134, 83, 169, 110, 122, -1, 31, 121,
- 175, 83, 154, 110, -1, 31, 121, 175, 83, 154,
- 110, 59, -1, 130, 175, 114, 170, 137, 167, -1,
- 35, 165, -1, 155, 102, 77, 164, -1, 155, 24,
- 156, -1, 156, -1, 174, 157, -1, 158, -1, 158,
- 86, -1, 159, -1, 159, 90, 92, -1, 19, -1,
- 19, 83, 160, 110, -1, 82, -1, 115, -1, 69,
- -1, 81, -1, 93, -1, 177, -1, 162, 99, 16,
- 164, -1, 162, -1, 112, 163, -1, 112, 38, 163,
- -1, 164, 165, -1, 174, -1, 174, 24, 164, -1,
- 118, -1, 166, -1, 166, 137, 167, -1, 52, 175,
- -1, 83, 167, 110, -1, 173, 45, 173, -1, 167,
- 7, 167, -1, 167, 97, 167, -1, 173, 45, 168,
- -1, 173, 57, 168, -1, 173, 85, 168, -1, 173,
- 78, 168, -1, 173, 54, 168, -1, 173, 89, 168,
- -1, 173, 73, 92, -1, 173, 73, 90, 92, -1,
- 173, -1, 172, -1, 172, -1, 172, 24, 169, -1,
- 171, -1, 171, 24, 170, -1, 174, 45, 172, -1,
- 177, -1, 88, 177, -1, 120, -1, 138, -1, 174,
- -1, 175, 39, 176, -1, 176, -1, 176, -1, 66,
- -1, 70, -1
+ 64, 0, -1, 65, -1, 79, -1, 67, -1, 66,
+ -1, 68, -1, 69, -1, 70, -1, 20, 23, 93,
+ 29, 82, 40, 50, 29, 87, 40, -1, 20, 23,
+ 93, 29, 82, 40, 50, 29, 87, 40, 48, -1,
+ 8, 47, 93, 29, 72, 40, -1, 8, 47, 93,
+ 29, 72, 40, 17, -1, 49, 93, 42, 88, 51,
+ 85, -1, 49, 93, 42, 88, -1, 9, 83, -1,
+ 3, 47, 93, 71, -1, 17, -1, 13, -1, 73,
+ 39, 25, 82, -1, 73, 7, 74, -1, 74, -1,
+ 92, 75, -1, 76, -1, 76, 31, -1, 76, 48,
+ -1, 77, -1, 77, 34, 35, -1, 6, -1, 6,
+ 29, 78, 40, -1, 28, -1, 43, -1, 21, -1,
+ 27, -1, 36, -1, 95, -1, 80, 38, 5, 82,
+ -1, 80, -1, 41, 81, -1, 41, 10, 81, -1,
+ 82, 83, -1, 92, -1, 92, 7, 82, -1, 45,
+ -1, 84, -1, 84, 51, 85, -1, 14, 93, -1,
+ 14, 93, 7, 93, -1, 29, 85, 40, -1, 85,
+ 4, 85, -1, 85, 37, 85, -1, 91, 12, 86,
+ -1, 91, 16, 86, -1, 91, 30, 86, -1, 91,
+ 26, 86, -1, 91, 15, 86, -1, 91, 33, 86,
+ -1, 91, 24, 35, -1, 91, 24, 34, 35, -1,
+ 91, -1, 90, -1, 90, -1, 90, 7, 87, -1,
+ 89, -1, 89, 7, 88, -1, 92, 12, 90, -1,
+ 95, -1, 32, 95, -1, 46, -1, 52, -1, 92,
+ -1, 93, 11, 94, -1, 94, -1, 94, -1, 18,
+ -1, 22, -1
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
-static const unsigned short yyrline[] =
+static const unsigned short int yyrline[] =
{
- 0, 138, 138, 146, 147, 148, 149, 150, 154, 165,
- 178, 190, 205, 218, 231, 241, 251, 258, 266, 270,
- 277, 281, 288, 292, 296, 300, 304, 308, 312, 319,
- 328, 340, 344, 348, 364, 385, 386, 390, 397, 398,
- 414, 427, 433, 439, 445, 451, 457, 463, 469, 475,
- 481, 487, 493, 502, 503, 507, 514, 525, 526, 534,
- 542, 548, 554, 560, 569, 578, 584, 593, 600, 609
+ 0, 123, 123, 131, 132, 133, 134, 135, 136, 140,
+ 151, 164, 176, 191, 201, 214, 227, 240, 244, 251,
+ 261, 271, 278, 286, 290, 294, 301, 305, 312, 316,
+ 320, 324, 328, 332, 336, 343, 352, 364, 368, 372,
+ 388, 409, 410, 414, 421, 422, 438, 448, 461, 467,
+ 473, 479, 485, 491, 497, 503, 509, 515, 521, 530,
+ 531, 535, 542, 553, 554, 562, 570, 576, 582, 588,
+ 597, 606, 612, 621, 628, 637
};
#endif
-#if YYDEBUG || YYERROR_VERBOSE
-/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
- "$end", "error", "$undefined", "TK_ABORT", "TK_AFTER",
- "TK_AGG_FUNCTION", "TK_ALL", "TK_AND", "TK_AS", "TK_ASC", "TK_BEFORE",
- "TK_BEGIN", "TK_BETWEEN", "TK_BITAND", "TK_BITNOT", "TK_BITOR", "TK_BY",
- "TK_CASCADE", "TK_CASE", "TK_CHAR", "TK_CHECK", "TK_CLUSTER",
- "TK_COLLATE", "TK_COLUMN", "TK_COMMA", "TK_COMMENT", "TK_COMMIT",
- "TK_CONCAT", "TK_CONFLICT", "TK_CONSTRAINT", "TK_COPY", "TK_CREATE",
- "TK_DEFAULT", "TK_DEFERRABLE", "TK_DEFERRED", "TK_DELETE",
- "TK_DELIMITERS", "TK_DESC", "TK_DISTINCT", "TK_DOT", "TK_DROP",
- "TK_EACH", "TK_ELSE", "TK_END", "TK_END_OF_FILE", "TK_EQ", "TK_EXCEPT",
- "TK_EXPLAIN", "TK_FAIL", "TK_FLOAT", "TK_FOR", "TK_FOREIGN", "TK_FROM",
- "TK_FUNCTION", "TK_GE", "TK_GLOB", "TK_GROUP", "TK_GT", "TK_HAVING",
- "TK_HOLD", "TK_IGNORE", "TK_ILLEGAL", "TK_IMMEDIATE", "TK_IN",
- "TK_INDEX", "TK_INITIALLY", "TK_ID", "TK_INSERT", "TK_INSTEAD", "TK_INT",
- "TK_INTEGER", "TK_INTERSECT", "TK_INTO", "TK_IS", "TK_ISNULL", "TK_JOIN",
- "TK_JOIN_KW", "TK_KEY", "TK_LE", "TK_LIKE", "TK_LIMIT", "TK_LONG",
- "TK_LONGCHAR", "TK_LP", "TK_LSHIFT", "TK_LT", "TK_LOCALIZABLE",
- "TK_MATCH", "TK_MINUS", "TK_NE", "TK_NOT", "TK_NOTNULL", "TK_NULL",
- "TK_OBJECT", "TK_OF", "TK_OFFSET", "TK_ON", "TK_OR",
- "TK_ORACLE_OUTER_JOIN", "TK_ORDER", "TK_PLUS", "TK_PRAGMA", "TK_PRIMARY",
- "TK_RAISE", "TK_REFERENCES", "TK_REM", "TK_REPLACE", "TK_RESTRICT",
- "TK_ROLLBACK", "TK_ROW", "TK_RP", "TK_RSHIFT", "TK_SELECT", "TK_SEMI",
- "TK_SET", "TK_SHORT", "TK_SLASH", "TK_SPACE", "TK_STAR", "TK_STATEMENT",
- "TK_STRING", "TK_TABLE", "TK_TEMP", "TK_THEN", "TK_TRANSACTION",
- "TK_TRIGGER", "TK_UMINUS", "TK_UNCLOSED_STRING", "TK_UNION", "TK_UNIQUE",
- "TK_UPDATE", "TK_UPLUS", "TK_USING", "TK_VACUUM", "TK_VALUES", "TK_VIEW",
- "TK_WHEN", "TK_WHERE", "TK_WILDCARD", "AGG_FUNCTION.", "COLUMN",
- "FUNCTION", "COMMENT", "UNCLOSED_STRING", "SPACE", "ILLEGAL",
- "END_OF_FILE", "$accept", "query", "onequery", "oneinsert", "onecreate",
- "oneupdate", "onedelete", "table_def", "column_def", "column_and_type",
- "column_type", "data_type_l", "data_type", "data_count", "oneselect",
- "unorderedsel", "selectfrom", "selcollist", "from", "fromtable", "expr",
- "val", "constlist", "update_assign_list", "column_assignment",
- "const_val", "column_val", "column", "table", "id", "number", 0
+ "$end", "error", "$undefined", "TK_ALTER", "TK_AND", "TK_BY", "TK_CHAR",
+ "TK_COMMA", "TK_CREATE", "TK_DELETE", "TK_DISTINCT", "TK_DOT", "TK_EQ",
+ "TK_FREE", "TK_FROM", "TK_GE", "TK_GT", "TK_HOLD", "TK_ID", "TK_ILLEGAL",
+ "TK_INSERT", "TK_INT", "TK_INTEGER", "TK_INTO", "TK_IS", "TK_KEY",
+ "TK_LE", "TK_LONG", "TK_LONGCHAR", "TK_LP", "TK_LT", "TK_LOCALIZABLE",
+ "TK_MINUS", "TK_NE", "TK_NOT", "TK_NULL", "TK_OBJECT", "TK_OR",
+ "TK_ORDER", "TK_PRIMARY", "TK_RP", "TK_SELECT", "TK_SET", "TK_SHORT",
+ "TK_SPACE", "TK_STAR", "TK_STRING", "TK_TABLE", "TK_TEMPORARY",
+ "TK_UPDATE", "TK_VALUES", "TK_WHERE", "TK_WILDCARD", "AGG_FUNCTION.",
+ "COLUMN", "FUNCTION", "COMMENT", "UNCLOSED_STRING", "SPACE", "ILLEGAL",
+ "END_OF_FILE", "TK_LIKE", "TK_NEGATION", "$accept", "query", "onequery",
+ "oneinsert", "onecreate", "oneupdate", "onedelete", "onealter",
+ "alterop", "table_def", "column_def", "column_and_type", "column_type",
+ "data_type_l", "data_type", "data_count", "oneselect", "unorderedsel",
+ "selectfrom", "selcollist", "from", "fromtable", "expr", "val",
+ "constlist", "update_assign_list", "column_assignment", "const_val",
+ "column_val", "column", "table", "id", "number", 0
};
#endif
# ifdef YYPRINT
/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
token YYLEX-NUM. */
-static const unsigned short yytoknum[] =
+static const unsigned short int yytoknum[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
- 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
- 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
- 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
- 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
- 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
- 365, 366, 367, 368, 369, 370, 371, 372, 373, 374,
- 375, 376, 377, 378, 379, 380, 381, 382, 383, 384,
- 385, 386, 387, 388, 389, 390, 391, 392, 393, 394,
- 395, 396, 397, 398, 399, 400, 401
+ 315, 316, 317
};
# endif
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const unsigned char yyr1[] =
{
- 0, 147, 148, 149, 149, 149, 149, 149, 150, 150,
- 151, 151, 152, 153, 154, 155, 155, 156, 157, 157,
- 158, 158, 159, 159, 159, 159, 159, 159, 159, 160,
- 161, 161, 162, 162, 163, 164, 164, 164, 165, 165,
- 166, 167, 167, 167, 167, 167, 167, 167, 167, 167,
- 167, 167, 167, 168, 168, 169, 169, 170, 170, 171,
- 172, 172, 172, 172, 173, 174, 174, 175, 176, 177
+ 0, 63, 64, 65, 65, 65, 65, 65, 65, 66,
+ 66, 67, 67, 68, 68, 69, 70, 71, 71, 72,
+ 73, 73, 74, 75, 75, 75, 76, 76, 77, 77,
+ 77, 77, 77, 77, 77, 78, 79, 79, 80, 80,
+ 81, 82, 82, 82, 83, 83, 84, 84, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 85, 85, 86,
+ 86, 87, 87, 88, 88, 89, 90, 90, 90, 90,
+ 91, 92, 92, 93, 94, 95
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const unsigned char yyr2[] =
{
- 0, 2, 1, 1, 1, 1, 1, 1, 10, 11,
- 6, 7, 6, 2, 4, 3, 1, 2, 1, 2,
- 1, 3, 1, 4, 1, 1, 1, 1, 1, 1,
- 4, 1, 2, 3, 2, 1, 3, 1, 1, 3,
- 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 4, 1, 1, 1, 3, 1, 3, 3,
- 1, 2, 1, 1, 1, 3, 1, 1, 1, 1
+ 0, 2, 1, 1, 1, 1, 1, 1, 1, 10,
+ 11, 6, 7, 6, 4, 2, 4, 1, 1, 4,
+ 3, 1, 2, 1, 2, 2, 1, 3, 1, 4,
+ 1, 1, 1, 1, 1, 1, 4, 1, 2, 3,
+ 2, 1, 3, 1, 1, 3, 2, 4, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 4, 1,
+ 1, 1, 3, 1, 3, 3, 1, 2, 1, 1,
+ 1, 3, 1, 1, 1, 1
};
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
means the default is an error. */
static const unsigned char yydefact[] =
{
- 0, 0, 0, 0, 0, 0, 0, 2, 5, 4,
- 6, 7, 3, 31, 0, 0, 13, 38, 0, 0,
- 68, 37, 32, 0, 35, 0, 66, 0, 67, 1,
- 0, 0, 40, 0, 0, 33, 34, 0, 0, 0,
- 0, 0, 0, 39, 0, 64, 0, 36, 65, 0,
- 57, 0, 30, 0, 0, 16, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 5,
+ 4, 6, 7, 8, 3, 37, 0, 0, 0, 15,
+ 44, 0, 0, 74, 43, 38, 0, 41, 0, 72,
+ 0, 73, 1, 0, 0, 0, 46, 0, 0, 39,
+ 40, 0, 0, 0, 0, 18, 17, 16, 0, 0,
+ 0, 45, 0, 70, 0, 42, 71, 14, 63, 0,
+ 36, 0, 0, 21, 0, 47, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 10, 0, 0, 22, 26, 27, 24, 28, 25,
- 17, 18, 20, 41, 43, 44, 69, 0, 62, 63,
- 45, 54, 42, 60, 49, 53, 46, 0, 51, 48,
- 47, 50, 0, 12, 58, 59, 11, 15, 0, 0,
- 19, 0, 61, 52, 0, 14, 0, 29, 21, 0,
- 23, 0, 55, 8, 0, 9, 56
+ 11, 0, 0, 28, 32, 33, 30, 34, 31, 22,
+ 23, 26, 48, 49, 50, 75, 0, 68, 69, 51,
+ 60, 59, 66, 55, 52, 0, 57, 54, 53, 56,
+ 0, 13, 64, 65, 12, 20, 0, 0, 24, 25,
+ 0, 67, 58, 0, 19, 0, 35, 27, 0, 29,
+ 0, 61, 9, 0, 10, 62
};
/* YYDEFGOTO[NTERM-NUM]. */
-static const yysigned_char yydefgoto[] =
+static const short int yydefgoto[] =
{
- -1, 6, 7, 8, 9, 10, 11, 53, 54, 55,
- 80, 81, 82, 116, 12, 13, 22, 23, 16, 17,
- 43, 90, 121, 49, 50, 91, 44, 45, 25, 26,
- 93
+ -1, 7, 8, 9, 10, 11, 12, 13, 47, 61,
+ 62, 63, 89, 90, 91, 125, 14, 15, 25, 26,
+ 19, 20, 51, 99, 130, 57, 58, 100, 101, 53,
+ 28, 29, 102
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
-#define YYPACT_NINF -111
+#define YYPACT_NINF -89
static const yysigned_char yypact[] =
{
- -28, -110, -38, -46, -32, -42, 29, -111, -111, -111,
- -111, -111, -111, -67, -42, -42, -111, -99, -42, -48,
- -111, -111, -111, -38, 17, 7, 11, -62, -111, -111,
- 37, -22, -111, -43, -16, -111, -111, -48, -42, -42,
- -48, -42, -43, -3, -29, -111, -48, -111, -111, -68,
- 48, 28, -111, -36, -19, -111, -18, -5, -43, -43,
- -58, -58, -58, -70, -58, -58, -58, -34, -43, -42,
- -61, 20, -42, 5, 2, -111, -111, -111, -111, -111,
- -111, 1, -2, -111, -3, -3, -111, 19, -111, -111,
- -111, -111, -111, -111, -111, -111, -111, -1, -111, -111,
- -111, -111, -41, -3, -111, -111, -111, -111, -48, 19,
- -111, 3, -111, -111, 13, -111, -12, -111, -111, -61,
- -111, -9, 91, -13, -61, -111, -111
+ 3, -34, -28, 31, 25, 48, 36, 60, -89, -89,
+ -89, -89, -89, -89, -89, 32, 36, 36, 36, -89,
+ 28, 36, 12, -89, -89, -89, 31, 81, 78, 79,
+ 49, -89, -89, 87, 1, 69, 92, 51, 74, -89,
+ -89, 12, 36, 36, 12, -89, -89, -89, 36, 36,
+ 51, 5, 71, -89, 12, -89, -89, 54, 93, 94,
+ -89, 67, -4, -89, 35, -89, 0, 51, 51, 50,
+ 50, 50, -2, 50, 50, 50, 68, 51, 36, 29,
+ 98, 36, 91, 88, -89, -89, -89, -89, -89, -89,
+ -24, 84, -89, -89, 115, -89, 99, -89, -89, -89,
+ -89, -89, -89, -89, -89, 85, -89, -89, -89, -89,
+ 72, 5, -89, -89, -89, -89, 12, 99, -89, -89,
+ 89, -89, -89, 96, -89, 83, -89, -89, 29, -89,
+ 86, 120, 80, 29, -89, -89
};
/* YYPGOTO[NTERM-NUM]. */
static const yysigned_char yypgoto[] =
{
- -111, -111, -111, -111, -111, -111, -111, -111, -111, 47,
- -111, -111, -111, -111, -111, -111, 101, -27, 98, -111,
- -11, 52, 0, 53, -111, -53, 46, -4, 85, 40,
- -66
+ -89, -89, -89, -89, -89, -89, -89, -89, -89, -89,
+ -89, 52, -89, -89, -89, -89, -89, -89, 107, -39,
+ 104, -89, 17, 39, -1, 53, -89, -78, -3, -5,
+ 10, 4, -88
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, syntax error. */
-#define YYTABLE_NINF -68
-static const yysigned_char yytable[] =
+#define YYTABLE_NINF -74
+static const short int yytable[] =
{
- 24, 74, 58, 1, 58, 72, 19, 2, 20, 86,
- 47, 14, 86, 52, 15, 24, 60, 105, 20, 67,
- 97, 112, 98, 20, 20, 61, 18, 87, 62, 29,
- 87, 57, 30, 24, 20, 51, 24, 56, 33, 3,
- 42, 37, 24, 117, 63, 28, 38, 84, 85, 64,
- -67, 75, 39, 40, 28, 28, 65, 103, 28, 88,
- 66, 41, 88, 76, 77, 51, 122, 46, 56, 68,
- 21, 122, 69, 70, 71, 78, 102, 89, 48, 106,
- 89, 115, 108, 73, 4, 109, 21, 110, 111, 86,
- 27, 113, 59, 114, 59, 118, 119, 79, 120, 31,
- 32, 123, 5, 34, 24, 83, 92, 95, 95, 125,
- 95, 95, 95, 94, 96, 124, 99, 100, 101, 107,
- 35, 36, 104, 0, 126
+ 27, 113, 55, 81, 67, 60, 1, 118, 121, 67,
+ 31, 2, 3, 16, 45, 76, 30, 27, 46, 17,
+ 31, 31, 31, 4, 119, 31, 34, 35, 36, 126,
+ 23, 38, 105, 106, 52, 82, 27, 68, 59, 27,
+ 92, 83, 68, 64, 5, 18, 56, 52, 21, 27,
+ 131, 95, 6, 31, 23, 131, 84, 24, 22, 65,
+ 32, 96, 85, 86, 52, 52, 23, 66, 23, 23,
+ 33, 87, 95, 59, 52, 97, 64, 124, 88, 37,
+ 50, 98, 96, 69, 93, 94, 70, 71, 41, 42,
+ -73, 43, 44, 24, 111, 72, 97, 73, 48, 49,
+ 78, 74, 98, 54, 75, 77, 79, 80, 110, 103,
+ 104, 27, 107, 108, 109, 114, 116, 117, 120, 67,
+ 122, 95, 123, 129, 127, 128, 132, 133, 134, 39,
+ 40, 112, 135, 115
};
-static const short yycheck[] =
+static const unsigned char yycheck[] =
{
- 4, 19, 7, 31, 7, 24, 38, 35, 66, 70,
- 37, 121, 70, 40, 52, 19, 45, 70, 66, 46,
- 90, 87, 92, 66, 66, 54, 72, 88, 57, 0,
- 88, 42, 99, 37, 66, 39, 40, 41, 137, 67,
- 83, 24, 46, 109, 73, 5, 39, 58, 59, 78,
- 39, 69, 114, 16, 14, 15, 85, 68, 18, 120,
- 89, 83, 120, 81, 82, 69, 119, 83, 72, 137,
- 118, 124, 24, 45, 110, 93, 110, 138, 38, 59,
- 138, 108, 77, 102, 112, 83, 118, 86, 90, 70,
- 5, 92, 97, 134, 97, 92, 83, 115, 110, 14,
- 15, 110, 130, 18, 108, 110, 60, 61, 62, 122,
- 64, 65, 66, 61, 62, 24, 64, 65, 66, 72,
- 19, 23, 69, -1, 124
+ 5, 79, 41, 7, 4, 44, 3, 31, 96, 4,
+ 6, 8, 9, 47, 13, 54, 6, 22, 17, 47,
+ 16, 17, 18, 20, 48, 21, 16, 17, 18, 117,
+ 18, 21, 34, 35, 37, 39, 41, 37, 43, 44,
+ 40, 6, 37, 48, 41, 14, 42, 50, 23, 54,
+ 128, 22, 49, 49, 18, 133, 21, 45, 10, 49,
+ 0, 32, 27, 28, 67, 68, 18, 50, 18, 18,
+ 38, 36, 22, 78, 77, 46, 81, 116, 43, 51,
+ 29, 52, 32, 12, 67, 68, 15, 16, 7, 11,
+ 11, 42, 5, 45, 77, 24, 46, 26, 29, 7,
+ 7, 30, 52, 29, 33, 51, 12, 40, 40, 70,
+ 71, 116, 73, 74, 75, 17, 25, 29, 34, 4,
+ 35, 22, 50, 40, 35, 29, 40, 7, 48, 22,
+ 26, 78, 133, 81
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
symbol of state STATE-NUM. */
static const unsigned char yystos[] =
{
- 0, 31, 35, 67, 112, 130, 148, 149, 150, 151,
- 152, 153, 161, 162, 121, 52, 165, 166, 72, 38,
- 66, 118, 163, 164, 174, 175, 176, 175, 176, 0,
- 99, 175, 175, 137, 175, 163, 165, 24, 39, 114,
- 16, 83, 83, 167, 173, 174, 83, 164, 176, 170,
- 171, 174, 164, 154, 155, 156, 174, 167, 7, 97,
- 45, 54, 57, 73, 78, 85, 89, 164, 137, 24,
- 45, 110, 24, 102, 19, 69, 81, 82, 93, 115,
- 157, 158, 159, 110, 167, 167, 70, 88, 120, 138,
- 168, 172, 173, 177, 168, 173, 168, 90, 92, 168,
- 168, 168, 110, 167, 170, 172, 59, 156, 77, 83,
- 86, 90, 177, 92, 134, 164, 160, 177, 92, 83,
- 110, 169, 172, 110, 24, 122, 169
+ 0, 3, 8, 9, 20, 41, 49, 64, 65, 66,
+ 67, 68, 69, 70, 79, 80, 47, 47, 14, 83,
+ 84, 23, 10, 18, 45, 81, 82, 92, 93, 94,
+ 93, 94, 0, 38, 93, 93, 93, 51, 93, 81,
+ 83, 7, 11, 42, 5, 13, 17, 71, 29, 7,
+ 29, 85, 91, 92, 29, 82, 94, 88, 89, 92,
+ 82, 72, 73, 74, 92, 93, 85, 4, 37, 12,
+ 15, 16, 24, 26, 30, 33, 82, 51, 7, 12,
+ 40, 7, 39, 6, 21, 27, 28, 36, 43, 75,
+ 76, 77, 40, 85, 85, 22, 32, 46, 52, 86,
+ 90, 91, 95, 86, 86, 34, 35, 86, 86, 86,
+ 40, 85, 88, 90, 17, 74, 25, 29, 31, 48,
+ 34, 95, 35, 50, 82, 78, 95, 35, 29, 40,
+ 87, 90, 40, 7, 48, 87
};
-#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
-# define YYSIZE_T __SIZE_TYPE__
-#endif
-#if ! defined (YYSIZE_T) && defined (size_t)
-# define YYSIZE_T size_t
-#endif
-#if ! defined (YYSIZE_T)
-# if defined (__STDC__) || defined (__cplusplus)
-# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-# define YYSIZE_T size_t
-# endif
-#endif
-#if ! defined (YYSIZE_T)
-# define YYSIZE_T unsigned int
-#endif
-
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY (-2)
goto yybackup; \
} \
else \
- { \
- yyerror ("syntax error: cannot back up");\
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
YYERROR; \
} \
while (0)
+
#define YYTERROR 1
#define YYERRCODE 256
-/* YYLLOC_DEFAULT -- Compute the default location (before the actions
- are run). */
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- ((Current).first_line = (Rhs)[1].first_line, \
- (Current).first_column = (Rhs)[1].first_column, \
- (Current).last_line = (Rhs)[N].last_line, \
- (Current).last_column = (Rhs)[N].last_column)
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (N) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (0)
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
#endif
+
/* YYLEX -- calling `yylex' with the right arguments. */
#ifdef YYLEX_PARAM
YYFPRINTF Args; \
} while (0)
-# define YYDSYMPRINT(Args) \
-do { \
- if (yydebug) \
- yysymprint Args; \
-} while (0)
-
-# define YYDSYMPRINTF(Title, Token, Value, Location) \
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
do { \
if (yydebug) \
{ \
YYFPRINTF (stderr, "%s ", Title); \
- yysymprint (stderr, \
- Token, Value); \
+ yysymprint (stderr, \
+ Type, Value); \
YYFPRINTF (stderr, "\n"); \
} \
} while (0)
#if defined (__STDC__) || defined (__cplusplus)
static void
-yy_stack_print (short *bottom, short *top)
+yy_stack_print (short int *bottom, short int *top)
#else
static void
yy_stack_print (bottom, top)
- short *bottom;
- short *top;
+ short int *bottom;
+ short int *top;
#endif
{
YYFPRINTF (stderr, "Stack now");
#endif
{
int yyi;
- unsigned int yylno = yyrline[yyrule];
- YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ",
yyrule - 1, yylno);
/* Print the symbols being reduced, and their result. */
for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
- YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
- YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+ YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+ YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]);
}
# define YY_REDUCE_PRINT(Rule) \
int yydebug;
#else /* !YYDEBUG */
# define YYDPRINTF(Args)
-# define YYDSYMPRINT(Args)
-# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
# define YY_STACK_PRINT(Bottom, Top)
# define YY_REDUCE_PRINT(Rule)
#endif /* !YYDEBUG */
if the built-in stack extension method is used).
Do not make this value too large; the results are undefined if
- SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
evaluated with infinite-precision integer arithmetic. */
-#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
-# undef YYMAXDEPTH
-#endif
-
#ifndef YYMAXDEPTH
# define YYMAXDEPTH 10000
#endif
const char *yystr;
# endif
{
- register const char *yys = yystr;
+ const char *yys = yystr;
while (*yys++ != '\0')
continue;
const char *yysrc;
# endif
{
- register char *yyd = yydest;
- register const char *yys = yysrc;
+ char *yyd = yydest;
+ const char *yys = yysrc;
while ((*yyd++ = *yys++) != '\0')
continue;
# endif
# endif
-#endif /* !YYERROR_VERBOSE */
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ size_t yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+#endif /* YYERROR_VERBOSE */
\f
(void) yyvaluep;
if (yytype < YYNTOKENS)
- {
- YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-# ifdef YYPRINT
- YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# endif
- }
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
else
YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
switch (yytype)
{
default:
#if defined (__STDC__) || defined (__cplusplus)
static void
-yydestruct (int yytype, YYSTYPE *yyvaluep)
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
#else
static void
-yydestruct (yytype, yyvaluep)
+yydestruct (yymsg, yytype, yyvaluep)
+ const char *yymsg;
int yytype;
YYSTYPE *yyvaluep;
#endif
/* Pacify ``unused variable'' warnings. */
(void) yyvaluep;
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
switch (yytype)
{
#else
int
yyparse ()
-
+ ;
#endif
#endif
{
- /* The lookahead symbol. */
+ /* The look-ahead symbol. */
int yychar;
-/* The semantic value of the lookahead symbol. */
+/* The semantic value of the look-ahead symbol. */
YYSTYPE yylval;
/* Number of syntax errors so far. */
int yynerrs;
- register int yystate;
- register int yyn;
+ int yystate;
+ int yyn;
int yyresult;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
- /* Lookahead token as an internal (translated) token number. */
+ /* Look-ahead token as an internal (translated) token number. */
int yytoken = 0;
/* Three stacks and their tools:
to reallocate them elsewhere. */
/* The state stack. */
- short yyssa[YYINITDEPTH];
- short *yyss = yyssa;
- register short *yyssp;
+ short int yyssa[YYINITDEPTH];
+ short int *yyss = yyssa;
+ short int *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs = yyvsa;
- register YYSTYPE *yyvsp;
+ YYSTYPE *yyvsp;
these so that the &'s don't force the real ones into
memory. */
YYSTYPE *yyvs1 = yyvs;
- short *yyss1 = yyss;
+ short int *yyss1 = yyss;
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
conditional around just the two extra args, but that might
be undefined if yyoverflow is a macro. */
- yyoverflow ("parser stack overflow",
+ yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
}
#else /* no yyoverflow */
# ifndef YYSTACK_RELOCATE
- goto yyoverflowlab;
+ goto yyexhaustedlab;
# else
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
- goto yyoverflowlab;
+ goto yyexhaustedlab;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
{
- short *yyss1 = yyss;
+ short int *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
- goto yyoverflowlab;
+ goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss);
YYSTACK_RELOCATE (yyvs);
yybackup:
/* Do appropriate processing given the current state. */
-/* Read a lookahead token if we need one and don't already have one. */
+/* Read a look-ahead token if we need one and don't already have one. */
/* yyresume: */
- /* First try to decide what to do without reference to lookahead token. */
+ /* First try to decide what to do without reference to look-ahead token. */
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
goto yydefault;
- /* Not known => get a lookahead token if don't already have one. */
+ /* Not known => get a look-ahead token if don't already have one. */
- /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
else
{
yytoken = YYTRANSLATE (yychar);
- YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
}
/* If the proper action on seeing token YYTOKEN is to reduce or to
if (yyn == YYFINAL)
YYACCEPT;
- /* Shift the lookahead token. */
- YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+ /* Shift the look-ahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
/* Discard the token being shifted unless it is eof. */
if (yychar != YYEOF)
switch (yyn)
{
case 2:
-#line 139 "./sql.y"
+#line 124 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
- *sql->view = yyvsp[0].query;
+ *sql->view = (yyvsp[0].query);
;}
break;
- case 8:
-#line 155 "./sql.y"
+ case 9:
+#line 141 "sql.y"
{
SQL_input *sql = (SQL_input*) info;
- MSIVIEW *insert = NULL;
+ MSIVIEW *insert = NULL;
UINT r;
- r = INSERT_CreateView( sql->db, &insert, yyvsp[-7].string, yyvsp[-5].column_list, yyvsp[-1].column_list, FALSE );
+ r = INSERT_CreateView( sql->db, &insert, (yyvsp[-7].string), (yyvsp[-5].column_list), (yyvsp[-1].column_list), FALSE );
if( !insert )
YYABORT;
- yyval.query = insert;
+ (yyval.query) = insert;
;}
break;
- case 9:
-#line 166 "./sql.y"
+ case 10:
+#line 152 "sql.y"
{
SQL_input *sql = (SQL_input*) info;
- MSIVIEW *insert = NULL;
+ MSIVIEW *insert = NULL;
- INSERT_CreateView( sql->db, &insert, yyvsp[-8].string, yyvsp[-6].column_list, yyvsp[-2].column_list, TRUE );
+ INSERT_CreateView( sql->db, &insert, (yyvsp[-8].string), (yyvsp[-6].column_list), (yyvsp[-2].column_list), TRUE );
if( !insert )
YYABORT;
- yyval.query = insert;
+ (yyval.query) = insert;
;}
break;
- case 10:
-#line 179 "./sql.y"
+ case 11:
+#line 165 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
- MSIVIEW *create = NULL;
+ MSIVIEW *create = NULL;
- if( !yyvsp[-1].column_list )
+ if( !(yyvsp[-1].column_list) )
YYABORT;
- CREATE_CreateView( sql->db, &create, yyvsp[-3].string, yyvsp[-1].column_list, FALSE );
+ CREATE_CreateView( sql->db, &create, (yyvsp[-3].string), (yyvsp[-1].column_list), FALSE );
if( !create )
YYABORT;
- yyval.query = create;
+ (yyval.query) = create;
;}
break;
- case 11:
-#line 191 "./sql.y"
+ case 12:
+#line 177 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
- MSIVIEW *create = NULL;
+ MSIVIEW *create = NULL;
- if( !yyvsp[-2].column_list )
+ if( !(yyvsp[-2].column_list) )
YYABORT;
- CREATE_CreateView( sql->db, &create, yyvsp[-4].string, yyvsp[-2].column_list, TRUE );
+ CREATE_CreateView( sql->db, &create, (yyvsp[-4].string), (yyvsp[-2].column_list), TRUE );
if( !create )
YYABORT;
- yyval.query = create;
+ (yyval.query) = create;
;}
break;
- case 12:
-#line 206 "./sql.y"
+ case 13:
+#line 192 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
- MSIVIEW *update = NULL;
+ MSIVIEW *update = NULL;
- UPDATE_CreateView( sql->db, &update, yyvsp[-4].string, yyvsp[-2].column_list, yyvsp[0].expr );
+ UPDATE_CreateView( sql->db, &update, (yyvsp[-4].string), (yyvsp[-2].column_list), (yyvsp[0].expr) );
if( !update )
YYABORT;
- yyval.query = update;
+ (yyval.query) = update;
;}
break;
- case 13:
-#line 219 "./sql.y"
+ case 14:
+#line 202 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
- MSIVIEW *delete = NULL;
+ MSIVIEW *update = NULL;
- DELETE_CreateView( sql->db, &delete, yyvsp[0].query );
- if( !delete )
+ UPDATE_CreateView( sql->db, &update, (yyvsp[-2].string), (yyvsp[0].column_list), NULL );
+ if( !update )
YYABORT;
- yyval.query = delete;
- ;}
- break;
-
- case 14:
-#line 232 "./sql.y"
- {
- if( SQL_MarkPrimaryKeys( yyvsp[-3].column_list, yyvsp[0].column_list ) )
- yyval.column_list = yyvsp[-3].column_list;
- else
- yyval.column_list = NULL;
+ (yyval.query) = update;
;}
break;
case 15:
-#line 242 "./sql.y"
+#line 215 "sql.y"
{
- column_info *ci;
-
- for( ci = yyvsp[-2].column_list; ci->next; ci = ci->next )
- ;
+ SQL_input* sql = (SQL_input*) info;
+ MSIVIEW *delete = NULL;
- ci->next = yyvsp[0].column_list;
- yyval.column_list = yyvsp[-2].column_list;
+ DELETE_CreateView( sql->db, &delete, (yyvsp[0].query) );
+ if( !delete )
+ YYABORT;
+ (yyval.query) = delete;
;}
break;
case 16:
-#line 252 "./sql.y"
+#line 228 "sql.y"
{
- yyval.column_list = yyvsp[0].column_list;
+ SQL_input* sql = (SQL_input*) info;
+ MSIVIEW *alter = NULL;
+
+ ALTER_CreateView( sql->db, &alter, (yyvsp[-1].string), (yyvsp[0].integer) );
+ if( !alter )
+ YYABORT;
+ (yyval.query) = alter;
;}
break;
case 17:
-#line 259 "./sql.y"
+#line 241 "sql.y"
{
- yyval.column_list = yyvsp[-1].column_list;
- yyval.column_list->type = yyvsp[0].column_type | MSITYPE_VALID;
+ (yyval.integer) = 1;
;}
break;
case 18:
-#line 267 "./sql.y"
+#line 245 "sql.y"
{
- yyval.column_type = yyvsp[0].column_type;
+ (yyval.integer) = -1;
;}
break;
case 19:
-#line 271 "./sql.y"
+#line 252 "sql.y"
{
- yyval.column_type = yyvsp[-1].column_type | MSITYPE_LOCALIZABLE;
+ if( SQL_MarkPrimaryKeys( (yyvsp[-3].column_list), (yyvsp[0].column_list) ) )
+ (yyval.column_list) = (yyvsp[-3].column_list);
+ else
+ (yyval.column_list) = NULL;
;}
break;
case 20:
-#line 278 "./sql.y"
+#line 262 "sql.y"
{
- yyval.column_type |= MSITYPE_NULLABLE;
+ column_info *ci;
+
+ for( ci = (yyvsp[-2].column_list); ci->next; ci = ci->next )
+ ;
+
+ ci->next = (yyvsp[0].column_list);
+ (yyval.column_list) = (yyvsp[-2].column_list);
;}
break;
case 21:
-#line 282 "./sql.y"
+#line 272 "sql.y"
{
- yyval.column_type = yyvsp[-2].column_type;
+ (yyval.column_list) = (yyvsp[0].column_list);
;}
break;
case 22:
-#line 289 "./sql.y"
+#line 279 "sql.y"
{
- yyval.column_type = MSITYPE_STRING | 1;
+ (yyval.column_list) = (yyvsp[-1].column_list);
+ (yyval.column_list)->type = (yyvsp[0].column_type) | MSITYPE_VALID;
;}
break;
case 23:
-#line 293 "./sql.y"
+#line 287 "sql.y"
{
- yyval.column_type = MSITYPE_STRING | 0x400 | yyvsp[-1].column_type;
+ (yyval.column_type) = (yyvsp[0].column_type);
;}
break;
case 24:
-#line 297 "./sql.y"
+#line 291 "sql.y"
{
- yyval.column_type = 2;
+ (yyval.column_type) = (yyvsp[-1].column_type) | MSITYPE_LOCALIZABLE;
;}
break;
case 25:
-#line 301 "./sql.y"
+#line 295 "sql.y"
{
- yyval.column_type = 2;
+ FIXME("temporary column\n");
;}
break;
case 26:
-#line 305 "./sql.y"
+#line 302 "sql.y"
{
- yyval.column_type = 2;
+ (yyval.column_type) |= MSITYPE_NULLABLE;
;}
break;
case 27:
-#line 309 "./sql.y"
+#line 306 "sql.y"
{
- yyval.column_type = 4;
+ (yyval.column_type) = (yyvsp[-2].column_type);
;}
break;
case 28:
-#line 313 "./sql.y"
+#line 313 "sql.y"
{
- yyval.column_type = MSITYPE_STRING | MSITYPE_VALID;
+ (yyval.column_type) = MSITYPE_STRING | 1;
;}
break;
case 29:
-#line 320 "./sql.y"
+#line 317 "sql.y"
{
- if( ( yyvsp[0].integer > 255 ) || ( yyvsp[0].integer < 0 ) )
- YYABORT;
- yyval.column_type = yyvsp[0].integer;
+ (yyval.column_type) = MSITYPE_STRING | 0x400 | (yyvsp[-1].column_type);
;}
break;
case 30:
-#line 329 "./sql.y"
+#line 321 "sql.y"
+ {
+ (yyval.column_type) = 2;
+ ;}
+ break;
+
+ case 31:
+#line 325 "sql.y"
+ {
+ (yyval.column_type) = 2;
+ ;}
+ break;
+
+ case 32:
+#line 329 "sql.y"
+ {
+ (yyval.column_type) = 2;
+ ;}
+ break;
+
+ case 33:
+#line 333 "sql.y"
+ {
+ (yyval.column_type) = 4;
+ ;}
+ break;
+
+ case 34:
+#line 337 "sql.y"
+ {
+ (yyval.column_type) = MSITYPE_STRING | MSITYPE_VALID;
+ ;}
+ break;
+
+ case 35:
+#line 344 "sql.y"
+ {
+ if( ( (yyvsp[0].integer) > 255 ) || ( (yyvsp[0].integer) < 0 ) )
+ YYABORT;
+ (yyval.column_type) = (yyvsp[0].integer);
+ ;}
+ break;
+
+ case 36:
+#line 353 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
- yyval.query = NULL;
- if( yyvsp[0].column_list )
- ORDER_CreateView( sql->db, &yyval.query, yyvsp[-3].query, yyvsp[0].column_list );
+ (yyval.query) = NULL;
+ if( (yyvsp[0].column_list) )
+ ORDER_CreateView( sql->db, &(yyval.query), (yyvsp[-3].query), (yyvsp[0].column_list) );
else
- yyval.query = yyvsp[-3].query;
- if( !yyval.query )
+ (yyval.query) = (yyvsp[-3].query);
+ if( !(yyval.query) )
YYABORT;
;}
break;
- case 32:
-#line 345 "./sql.y"
+ case 38:
+#line 369 "sql.y"
{
- yyval.query = yyvsp[0].query;
+ (yyval.query) = (yyvsp[0].query);
;}
break;
- case 33:
-#line 349 "./sql.y"
+ case 39:
+#line 373 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
UINT r;
- yyval.query = NULL;
- r = DISTINCT_CreateView( sql->db, &yyval.query, yyvsp[0].query );
+ (yyval.query) = NULL;
+ r = DISTINCT_CreateView( sql->db, &(yyval.query), (yyvsp[0].query) );
if (r != ERROR_SUCCESS)
{
- yyvsp[0].query->ops->delete(yyvsp[0].query);
+ (yyvsp[0].query)->ops->delete((yyvsp[0].query));
YYABORT;
}
;}
break;
- case 34:
-#line 365 "./sql.y"
+ case 40:
+#line 389 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
UINT r;
- yyval.query = NULL;
- if( yyvsp[-1].column_list )
+ (yyval.query) = NULL;
+ if( (yyvsp[-1].column_list) )
{
- r = SELECT_CreateView( sql->db, &yyval.query, yyvsp[0].query, yyvsp[-1].column_list );
+ r = SELECT_CreateView( sql->db, &(yyval.query), (yyvsp[0].query), (yyvsp[-1].column_list) );
if (r != ERROR_SUCCESS)
{
- yyvsp[0].query->ops->delete(yyvsp[0].query);
+ (yyvsp[0].query)->ops->delete((yyvsp[0].query));
YYABORT;
}
}
else
- yyval.query = yyvsp[0].query;
+ (yyval.query) = (yyvsp[0].query);
;}
break;
- case 36:
-#line 387 "./sql.y"
- {
- yyvsp[-2].column_list->next = yyvsp[0].column_list;
+ case 42:
+#line 411 "sql.y"
+ {
+ (yyvsp[-2].column_list)->next = (yyvsp[0].column_list);
;}
break;
- case 37:
-#line 391 "./sql.y"
+ case 43:
+#line 415 "sql.y"
{
- yyval.column_list = NULL;
+ (yyval.column_list) = NULL;
;}
break;
- case 39:
-#line 399 "./sql.y"
- {
+ case 45:
+#line 423 "sql.y"
+ {
SQL_input* sql = (SQL_input*) info;
UINT r;
- yyval.query = NULL;
- r = WHERE_CreateView( sql->db, &yyval.query, yyvsp[-2].query, yyvsp[0].expr );
+ (yyval.query) = NULL;
+ r = WHERE_CreateView( sql->db, &(yyval.query), (yyvsp[-2].query), (yyvsp[0].expr) );
if( r != ERROR_SUCCESS )
{
- yyvsp[-2].query->ops->delete( yyvsp[-2].query );
+ (yyvsp[-2].query)->ops->delete( (yyvsp[-2].query) );
YYABORT;
}
;}
break;
- case 40:
-#line 415 "./sql.y"
+ case 46:
+#line 439 "sql.y"
{
SQL_input* sql = (SQL_input*) info;
UINT r;
- yyval.query = NULL;
- r = TABLE_CreateView( sql->db, yyvsp[0].string, &yyval.query );
- if( r != ERROR_SUCCESS || !yyval.query )
+ (yyval.query) = NULL;
+ r = TABLE_CreateView( sql->db, (yyvsp[0].string), &(yyval.query) );
+ if( r != ERROR_SUCCESS || !(yyval.query) )
YYABORT;
;}
break;
- case 41:
-#line 428 "./sql.y"
+ case 47:
+#line 449 "sql.y"
{
- yyval.expr = yyvsp[-1].expr;
- if( !yyval.expr )
+ SQL_input* sql = (SQL_input*) info;
+ UINT r;
+
+ /* only support inner joins on two tables */
+ r = JOIN_CreateView( sql->db, &(yyval.query), (yyvsp[-2].string), (yyvsp[0].string) );
+ if( r != ERROR_SUCCESS )
YYABORT;
;}
break;
- case 42:
-#line 434 "./sql.y"
+ case 48:
+#line 462 "sql.y"
{
- yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_EQ, yyvsp[0].expr );
- if( !yyval.expr )
+ (yyval.expr) = (yyvsp[-1].expr);
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 43:
-#line 440 "./sql.y"
+ case 49:
+#line 468 "sql.y"
{
- yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_AND, yyvsp[0].expr );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_AND, (yyvsp[0].expr) );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 44:
-#line 446 "./sql.y"
+ case 50:
+#line 474 "sql.y"
{
- yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_OR, yyvsp[0].expr );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_OR, (yyvsp[0].expr) );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 45:
-#line 452 "./sql.y"
+ case 51:
+#line 480 "sql.y"
{
- yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_EQ, yyvsp[0].expr );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_EQ, (yyvsp[0].expr) );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 46:
-#line 458 "./sql.y"
+ case 52:
+#line 486 "sql.y"
{
- yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_GT, yyvsp[0].expr );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_GT, (yyvsp[0].expr) );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 47:
-#line 464 "./sql.y"
+ case 53:
+#line 492 "sql.y"
{
- yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_LT, yyvsp[0].expr );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_LT, (yyvsp[0].expr) );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 48:
-#line 470 "./sql.y"
+ case 54:
+#line 498 "sql.y"
{
- yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_LE, yyvsp[0].expr );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_LE, (yyvsp[0].expr) );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 49:
-#line 476 "./sql.y"
+ case 55:
+#line 504 "sql.y"
{
- yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_GE, yyvsp[0].expr );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_GE, (yyvsp[0].expr) );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 50:
-#line 482 "./sql.y"
+ case 56:
+#line 510 "sql.y"
{
- yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_NE, yyvsp[0].expr );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_complex( info, (yyvsp[-2].expr), OP_NE, (yyvsp[0].expr) );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 51:
-#line 488 "./sql.y"
+ case 57:
+#line 516 "sql.y"
{
- yyval.expr = EXPR_complex( info, yyvsp[-2].expr, OP_ISNULL, NULL );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_unary( info, (yyvsp[-2].expr), OP_ISNULL );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 52:
-#line 494 "./sql.y"
+ case 58:
+#line 522 "sql.y"
{
- yyval.expr = EXPR_complex( info, yyvsp[-3].expr, OP_NOTNULL, NULL );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_unary( info, (yyvsp[-3].expr), OP_NOTNULL );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 55:
-#line 508 "./sql.y"
+ case 61:
+#line 536 "sql.y"
{
- yyval.column_list = parser_alloc_column( info, NULL, NULL );
- if( !yyval.column_list )
+ (yyval.column_list) = parser_alloc_column( info, NULL, NULL );
+ if( !(yyval.column_list) )
YYABORT;
- yyval.column_list->val = yyvsp[0].expr;
+ (yyval.column_list)->val = (yyvsp[0].expr);
;}
break;
- case 56:
-#line 515 "./sql.y"
+ case 62:
+#line 543 "sql.y"
{
- yyval.column_list = parser_alloc_column( info, NULL, NULL );
- if( !yyval.column_list )
+ (yyval.column_list) = parser_alloc_column( info, NULL, NULL );
+ if( !(yyval.column_list) )
YYABORT;
- yyval.column_list->val = yyvsp[-2].expr;
- yyval.column_list->next = yyvsp[0].column_list;
+ (yyval.column_list)->val = (yyvsp[-2].expr);
+ (yyval.column_list)->next = (yyvsp[0].column_list);
;}
break;
- case 58:
-#line 527 "./sql.y"
+ case 64:
+#line 555 "sql.y"
{
- yyval.column_list = yyvsp[-2].column_list;
- yyval.column_list->next = yyvsp[0].column_list;
+ (yyval.column_list) = (yyvsp[-2].column_list);
+ (yyval.column_list)->next = (yyvsp[0].column_list);
;}
break;
- case 59:
-#line 535 "./sql.y"
+ case 65:
+#line 563 "sql.y"
{
- yyval.column_list = yyvsp[-2].column_list;
- yyval.column_list->val = yyvsp[0].expr;
+ (yyval.column_list) = (yyvsp[-2].column_list);
+ (yyval.column_list)->val = (yyvsp[0].expr);
;}
break;
- case 60:
-#line 543 "./sql.y"
+ case 66:
+#line 571 "sql.y"
{
- yyval.expr = EXPR_ival( info, yyvsp[0].integer );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_ival( info, (yyvsp[0].integer) );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 61:
-#line 549 "./sql.y"
+ case 67:
+#line 577 "sql.y"
{
- yyval.expr = EXPR_ival( info, -yyvsp[0].integer );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_ival( info, -(yyvsp[0].integer) );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 62:
-#line 555 "./sql.y"
+ case 68:
+#line 583 "sql.y"
{
- yyval.expr = EXPR_sval( info, &yyvsp[0].str );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_sval( info, &(yyvsp[0].str) );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 63:
-#line 561 "./sql.y"
+ case 69:
+#line 589 "sql.y"
{
- yyval.expr = EXPR_wildcard( info );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_wildcard( info );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 64:
-#line 570 "./sql.y"
+ case 70:
+#line 598 "sql.y"
{
- yyval.expr = EXPR_column( info, yyvsp[0].column_list );
- if( !yyval.expr )
+ (yyval.expr) = EXPR_column( info, (yyvsp[0].column_list) );
+ if( !(yyval.expr) )
YYABORT;
;}
break;
- case 65:
-#line 579 "./sql.y"
+ case 71:
+#line 607 "sql.y"
{
- yyval.column_list = parser_alloc_column( info, yyvsp[-2].string, yyvsp[0].string );
- if( !yyval.column_list )
+ (yyval.column_list) = parser_alloc_column( info, (yyvsp[-2].string), (yyvsp[0].string) );
+ if( !(yyval.column_list) )
YYABORT;
;}
break;
- case 66:
-#line 585 "./sql.y"
+ case 72:
+#line 613 "sql.y"
{
- yyval.column_list = parser_alloc_column( info, NULL, yyvsp[0].string );
- if( !yyval.column_list )
+ (yyval.column_list) = parser_alloc_column( info, NULL, (yyvsp[0].string) );
+ if( !(yyval.column_list) )
YYABORT;
;}
break;
- case 67:
-#line 594 "./sql.y"
+ case 73:
+#line 622 "sql.y"
{
- yyval.string = yyvsp[0].string;
+ (yyval.string) = (yyvsp[0].string);
;}
break;
- case 68:
-#line 601 "./sql.y"
+ case 74:
+#line 629 "sql.y"
{
- yyval.string = SQL_getstring( info, &yyvsp[0].str );
- if( !yyval.string )
+ (yyval.string) = SQL_getstring( info, &(yyvsp[0].str) );
+ if( !(yyval.string) )
YYABORT;
;}
break;
- case 69:
-#line 610 "./sql.y"
+ case 75:
+#line 638 "sql.y"
{
- yyval.integer = SQL_getint( info );
+ (yyval.integer) = SQL_getint( info );
;}
break;
+ default: break;
}
-/* Line 1000 of yacc.c. */
-#line 2054 "sql.tab.c"
+/* Line 1126 of yacc.c. */
+#line 2029 "sql.tab.c"
\f
yyvsp -= yylen;
yyssp -= yylen;
if (YYPACT_NINF < yyn && yyn < YYLAST)
{
- YYSIZE_T yysize = 0;
int yytype = YYTRANSLATE (yychar);
- const char* yyprefix;
- char *yymsg;
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ char *yymsg = 0;
+# define YYERROR_VERBOSE_ARGS_MAXIMUM 5
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
int yyx;
+#if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+#endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. */
int yyxbegin = yyn < 0 ? -yyn : 0;
/* Stay within bounds of both yycheck and yytname. */
int yychecklim = YYLAST - yyn;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
- int yycount = 0;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
- yyprefix = ", expecting ";
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
{
- yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
- yycount += 1;
- if (yycount == 5)
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
{
- yysize = 0;
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
break;
}
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= yysize1 < yysize;
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
}
- yysize += (sizeof ("syntax error, unexpected ")
- + yystrlen (yytname[yytype]));
- yymsg = (char *) YYSTACK_ALLOC (yysize);
- if (yymsg != 0)
- {
- char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
- yyp = yystpcpy (yyp, yytname[yytype]);
- if (yycount < 5)
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= yysize1 < yysize;
+ yysize = yysize1;
+
+ if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM)
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyf))
{
- yyprefix = ", expecting ";
- for (yyx = yyxbegin; yyx < yyxend; ++yyx)
- if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
- {
- yyp = yystpcpy (yyp, yyprefix);
- yyp = yystpcpy (yyp, yytname[yyx]);
- yyprefix = " or ";
- }
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
}
yyerror (yymsg);
YYSTACK_FREE (yymsg);
}
else
- yyerror ("syntax error; also virtual memory exhausted");
+ {
+ yyerror (YY_("syntax error"));
+ goto yyexhaustedlab;
+ }
}
else
#endif /* YYERROR_VERBOSE */
- yyerror ("syntax error");
+ yyerror (YY_("syntax error"));
}
if (yyerrstatus == 3)
{
- /* If just tried and failed to reuse lookahead token after an
+ /* If just tried and failed to reuse look-ahead token after an
error, discard it. */
if (yychar <= YYEOF)
{
- /* If at end of input, pop the error token,
- then the rest of the stack, then return failure. */
+ /* Return failure if at end of input. */
if (yychar == YYEOF)
- for (;;)
- {
- YYPOPSTACK;
- if (yyssp == yyss)
- YYABORT;
- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
- yydestruct (yystos[*yyssp], yyvsp);
- }
+ YYABORT;
}
else
{
- YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
- yydestruct (yytoken, &yylval);
+ yydestruct ("Error: discarding", yytoken, &yylval);
yychar = YYEMPTY;
-
}
}
- /* Else will try to reuse lookahead token after shifting the error
+ /* Else will try to reuse look-ahead token after shifting the error
token. */
goto yyerrlab1;
`---------------------------------------------------*/
yyerrorlab:
-#ifdef __GNUC__
- /* Pacify GCC when the user code never invokes YYERROR and the label
- yyerrorlab therefore never appears in user code. */
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
if (0)
goto yyerrorlab;
-#endif
- yyvsp -= yylen;
+yyvsp -= yylen;
yyssp -= yylen;
yystate = *yyssp;
goto yyerrlab1;
if (yyssp == yyss)
YYABORT;
- YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
- yydestruct (yystos[yystate], yyvsp);
+
+ yydestruct ("Error: popping", yystos[yystate], yyvsp);
YYPOPSTACK;
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
if (yyn == YYFINAL)
YYACCEPT;
- YYDPRINTF ((stderr, "Shifting error token, "));
-
*++yyvsp = yylval;
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
yystate = yyn;
goto yynewstate;
goto yyreturn;
#ifndef yyoverflow
-/*----------------------------------------------.
-| yyoverflowlab -- parser overflow comes here. |
-`----------------------------------------------*/
-yyoverflowlab:
- yyerror ("parser stack overflow");
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
yyresult = 2;
/* Fall through. */
#endif
yyreturn:
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK;
+ }
#ifndef yyoverflow
if (yyss != yyssa)
YYSTACK_FREE (yyss);
}
-#line 615 "./sql.y"
+#line 643 "sql.y"
static void *parser_alloc( void *info, unsigned int sz )
return col;
}
-int SQL_lex( void *SQL_lval, SQL_input *sql )
+static int SQL_lex( void *SQL_lval, SQL_input *sql )
{
int token;
struct sql_str * str = SQL_lval;
while( token == TK_SPACE );
/* TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len)); */
-
+
return token;
}
LPWSTR str;
/* if there's quotes, remove them */
- if( ( (p[0]=='`') && (p[len-1]=='`') ) ||
+ if( ( (p[0]=='`') && (p[len-1]=='`') ) ||
( (p[0]=='\'') && (p[len-1]=='\'') ) )
{
p++;
return r;
}
-int SQL_error( const char *str )
+static int SQL_error( const char *str )
{
return 0;
}
return e;
}
+static struct expr * EXPR_unary( void *info, struct expr *l, UINT op )
+{
+ struct expr *e = parser_alloc( info, sizeof *e );
+ if( e )
+ {
+ e->type = EXPR_UNARY;
+ e->u.expr.left = l;
+ e->u.expr.op = op;
+ e->u.expr.right = NULL;
+ }
+ return e;
+}
+
static struct expr * EXPR_column( void *info, column_info *column )
{
struct expr *e = parser_alloc( info, sizeof *e );
-/* A Bison parser, made by GNU Bison 1.875c. */
+/* A Bison parser, made by GNU Bison 2.1. */
/* Skeleton parser for Yacc-like parsing with Bison,
- Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
- TK_ABORT = 258,
- TK_AFTER = 259,
- TK_AGG_FUNCTION = 260,
- TK_ALL = 261,
- TK_AND = 262,
- TK_AS = 263,
- TK_ASC = 264,
- TK_BEFORE = 265,
- TK_BEGIN = 266,
- TK_BETWEEN = 267,
- TK_BITAND = 268,
- TK_BITNOT = 269,
- TK_BITOR = 270,
- TK_BY = 271,
- TK_CASCADE = 272,
- TK_CASE = 273,
- TK_CHAR = 274,
- TK_CHECK = 275,
- TK_CLUSTER = 276,
- TK_COLLATE = 277,
- TK_COLUMN = 278,
- TK_COMMA = 279,
- TK_COMMENT = 280,
- TK_COMMIT = 281,
- TK_CONCAT = 282,
- TK_CONFLICT = 283,
- TK_CONSTRAINT = 284,
- TK_COPY = 285,
- TK_CREATE = 286,
- TK_DEFAULT = 287,
- TK_DEFERRABLE = 288,
- TK_DEFERRED = 289,
- TK_DELETE = 290,
- TK_DELIMITERS = 291,
- TK_DESC = 292,
- TK_DISTINCT = 293,
- TK_DOT = 294,
- TK_DROP = 295,
- TK_EACH = 296,
- TK_ELSE = 297,
- TK_END = 298,
- TK_END_OF_FILE = 299,
- TK_EQ = 300,
- TK_EXCEPT = 301,
- TK_EXPLAIN = 302,
- TK_FAIL = 303,
- TK_FLOAT = 304,
- TK_FOR = 305,
- TK_FOREIGN = 306,
- TK_FROM = 307,
- TK_FUNCTION = 308,
- TK_GE = 309,
- TK_GLOB = 310,
- TK_GROUP = 311,
- TK_GT = 312,
- TK_HAVING = 313,
- TK_HOLD = 314,
- TK_IGNORE = 315,
- TK_ILLEGAL = 316,
- TK_IMMEDIATE = 317,
- TK_IN = 318,
- TK_INDEX = 319,
- TK_INITIALLY = 320,
- TK_ID = 321,
- TK_INSERT = 322,
- TK_INSTEAD = 323,
- TK_INT = 324,
- TK_INTEGER = 325,
- TK_INTERSECT = 326,
- TK_INTO = 327,
- TK_IS = 328,
- TK_ISNULL = 329,
- TK_JOIN = 330,
- TK_JOIN_KW = 331,
- TK_KEY = 332,
- TK_LE = 333,
- TK_LIKE = 334,
- TK_LIMIT = 335,
- TK_LONG = 336,
- TK_LONGCHAR = 337,
- TK_LP = 338,
- TK_LSHIFT = 339,
- TK_LT = 340,
- TK_LOCALIZABLE = 341,
- TK_MATCH = 342,
- TK_MINUS = 343,
- TK_NE = 344,
- TK_NOT = 345,
- TK_NOTNULL = 346,
- TK_NULL = 347,
- TK_OBJECT = 348,
- TK_OF = 349,
- TK_OFFSET = 350,
- TK_ON = 351,
- TK_OR = 352,
- TK_ORACLE_OUTER_JOIN = 353,
- TK_ORDER = 354,
- TK_PLUS = 355,
- TK_PRAGMA = 356,
- TK_PRIMARY = 357,
- TK_RAISE = 358,
- TK_REFERENCES = 359,
- TK_REM = 360,
- TK_REPLACE = 361,
- TK_RESTRICT = 362,
- TK_ROLLBACK = 363,
- TK_ROW = 364,
- TK_RP = 365,
- TK_RSHIFT = 366,
- TK_SELECT = 367,
- TK_SEMI = 368,
- TK_SET = 369,
- TK_SHORT = 370,
- TK_SLASH = 371,
- TK_SPACE = 372,
- TK_STAR = 373,
- TK_STATEMENT = 374,
- TK_STRING = 375,
- TK_TABLE = 376,
- TK_TEMP = 377,
- TK_THEN = 378,
- TK_TRANSACTION = 379,
- TK_TRIGGER = 380,
- TK_UMINUS = 381,
- TK_UNCLOSED_STRING = 382,
- TK_UNION = 383,
- TK_UNIQUE = 384,
- TK_UPDATE = 385,
- TK_UPLUS = 386,
- TK_USING = 387,
- TK_VACUUM = 388,
- TK_VALUES = 389,
- TK_VIEW = 390,
- TK_WHEN = 391,
- TK_WHERE = 392,
- TK_WILDCARD = 393,
- COLUMN = 395,
- FUNCTION = 396,
- COMMENT = 397,
- UNCLOSED_STRING = 398,
- SPACE = 399,
- ILLEGAL = 400,
- END_OF_FILE = 401
+ TK_ALTER = 258,
+ TK_AND = 259,
+ TK_BY = 260,
+ TK_CHAR = 261,
+ TK_COMMA = 262,
+ TK_CREATE = 263,
+ TK_DELETE = 264,
+ TK_DISTINCT = 265,
+ TK_DOT = 266,
+ TK_EQ = 267,
+ TK_FREE = 268,
+ TK_FROM = 269,
+ TK_GE = 270,
+ TK_GT = 271,
+ TK_HOLD = 272,
+ TK_ID = 273,
+ TK_ILLEGAL = 274,
+ TK_INSERT = 275,
+ TK_INT = 276,
+ TK_INTEGER = 277,
+ TK_INTO = 278,
+ TK_IS = 279,
+ TK_KEY = 280,
+ TK_LE = 281,
+ TK_LONG = 282,
+ TK_LONGCHAR = 283,
+ TK_LP = 284,
+ TK_LT = 285,
+ TK_LOCALIZABLE = 286,
+ TK_MINUS = 287,
+ TK_NE = 288,
+ TK_NOT = 289,
+ TK_NULL = 290,
+ TK_OBJECT = 291,
+ TK_OR = 292,
+ TK_ORDER = 293,
+ TK_PRIMARY = 294,
+ TK_RP = 295,
+ TK_SELECT = 296,
+ TK_SET = 297,
+ TK_SHORT = 298,
+ TK_SPACE = 299,
+ TK_STAR = 300,
+ TK_STRING = 301,
+ TK_TABLE = 302,
+ TK_TEMPORARY = 303,
+ TK_UPDATE = 304,
+ TK_VALUES = 305,
+ TK_WHERE = 306,
+ TK_WILDCARD = 307,
+ COLUMN = 309,
+ FUNCTION = 310,
+ COMMENT = 311,
+ UNCLOSED_STRING = 312,
+ SPACE = 313,
+ ILLEGAL = 314,
+ END_OF_FILE = 315,
+ TK_LIKE = 316,
+ TK_NEGATION = 317
};
#endif
-#define TK_ABORT 258
-#define TK_AFTER 259
-#define TK_AGG_FUNCTION 260
-#define TK_ALL 261
-#define TK_AND 262
-#define TK_AS 263
-#define TK_ASC 264
-#define TK_BEFORE 265
-#define TK_BEGIN 266
-#define TK_BETWEEN 267
-#define TK_BITAND 268
-#define TK_BITNOT 269
-#define TK_BITOR 270
-#define TK_BY 271
-#define TK_CASCADE 272
-#define TK_CASE 273
-#define TK_CHAR 274
-#define TK_CHECK 275
-#define TK_CLUSTER 276
-#define TK_COLLATE 277
-#define TK_COLUMN 278
-#define TK_COMMA 279
-#define TK_COMMENT 280
-#define TK_COMMIT 281
-#define TK_CONCAT 282
-#define TK_CONFLICT 283
-#define TK_CONSTRAINT 284
-#define TK_COPY 285
-#define TK_CREATE 286
-#define TK_DEFAULT 287
-#define TK_DEFERRABLE 288
-#define TK_DEFERRED 289
-#define TK_DELETE 290
-#define TK_DELIMITERS 291
-#define TK_DESC 292
-#define TK_DISTINCT 293
-#define TK_DOT 294
-#define TK_DROP 295
-#define TK_EACH 296
-#define TK_ELSE 297
-#define TK_END 298
-#define TK_END_OF_FILE 299
-#define TK_EQ 300
-#define TK_EXCEPT 301
-#define TK_EXPLAIN 302
-#define TK_FAIL 303
-#define TK_FLOAT 304
-#define TK_FOR 305
-#define TK_FOREIGN 306
-#define TK_FROM 307
-#define TK_FUNCTION 308
-#define TK_GE 309
-#define TK_GLOB 310
-#define TK_GROUP 311
-#define TK_GT 312
-#define TK_HAVING 313
-#define TK_HOLD 314
-#define TK_IGNORE 315
-#define TK_ILLEGAL 316
-#define TK_IMMEDIATE 317
-#define TK_IN 318
-#define TK_INDEX 319
-#define TK_INITIALLY 320
-#define TK_ID 321
-#define TK_INSERT 322
-#define TK_INSTEAD 323
-#define TK_INT 324
-#define TK_INTEGER 325
-#define TK_INTERSECT 326
-#define TK_INTO 327
-#define TK_IS 328
-#define TK_ISNULL 329
-#define TK_JOIN 330
-#define TK_JOIN_KW 331
-#define TK_KEY 332
-#define TK_LE 333
-#define TK_LIKE 334
-#define TK_LIMIT 335
-#define TK_LONG 336
-#define TK_LONGCHAR 337
-#define TK_LP 338
-#define TK_LSHIFT 339
-#define TK_LT 340
-#define TK_LOCALIZABLE 341
-#define TK_MATCH 342
-#define TK_MINUS 343
-#define TK_NE 344
-#define TK_NOT 345
-#define TK_NOTNULL 346
-#define TK_NULL 347
-#define TK_OBJECT 348
-#define TK_OF 349
-#define TK_OFFSET 350
-#define TK_ON 351
-#define TK_OR 352
-#define TK_ORACLE_OUTER_JOIN 353
-#define TK_ORDER 354
-#define TK_PLUS 355
-#define TK_PRAGMA 356
-#define TK_PRIMARY 357
-#define TK_RAISE 358
-#define TK_REFERENCES 359
-#define TK_REM 360
-#define TK_REPLACE 361
-#define TK_RESTRICT 362
-#define TK_ROLLBACK 363
-#define TK_ROW 364
-#define TK_RP 365
-#define TK_RSHIFT 366
-#define TK_SELECT 367
-#define TK_SEMI 368
-#define TK_SET 369
-#define TK_SHORT 370
-#define TK_SLASH 371
-#define TK_SPACE 372
-#define TK_STAR 373
-#define TK_STATEMENT 374
-#define TK_STRING 375
-#define TK_TABLE 376
-#define TK_TEMP 377
-#define TK_THEN 378
-#define TK_TRANSACTION 379
-#define TK_TRIGGER 380
-#define TK_UMINUS 381
-#define TK_UNCLOSED_STRING 382
-#define TK_UNION 383
-#define TK_UNIQUE 384
-#define TK_UPDATE 385
-#define TK_UPLUS 386
-#define TK_USING 387
-#define TK_VACUUM 388
-#define TK_VALUES 389
-#define TK_VIEW 390
-#define TK_WHEN 391
-#define TK_WHERE 392
-#define TK_WILDCARD 393
-#define COLUMN 395
-#define FUNCTION 396
-#define COMMENT 397
-#define UNCLOSED_STRING 398
-#define SPACE 399
-#define ILLEGAL 400
-#define END_OF_FILE 401
+/* Tokens. */
+#define TK_ALTER 258
+#define TK_AND 259
+#define TK_BY 260
+#define TK_CHAR 261
+#define TK_COMMA 262
+#define TK_CREATE 263
+#define TK_DELETE 264
+#define TK_DISTINCT 265
+#define TK_DOT 266
+#define TK_EQ 267
+#define TK_FREE 268
+#define TK_FROM 269
+#define TK_GE 270
+#define TK_GT 271
+#define TK_HOLD 272
+#define TK_ID 273
+#define TK_ILLEGAL 274
+#define TK_INSERT 275
+#define TK_INT 276
+#define TK_INTEGER 277
+#define TK_INTO 278
+#define TK_IS 279
+#define TK_KEY 280
+#define TK_LE 281
+#define TK_LONG 282
+#define TK_LONGCHAR 283
+#define TK_LP 284
+#define TK_LT 285
+#define TK_LOCALIZABLE 286
+#define TK_MINUS 287
+#define TK_NE 288
+#define TK_NOT 289
+#define TK_NULL 290
+#define TK_OBJECT 291
+#define TK_OR 292
+#define TK_ORDER 293
+#define TK_PRIMARY 294
+#define TK_RP 295
+#define TK_SELECT 296
+#define TK_SET 297
+#define TK_SHORT 298
+#define TK_SPACE 299
+#define TK_STAR 300
+#define TK_STRING 301
+#define TK_TABLE 302
+#define TK_TEMPORARY 303
+#define TK_UPDATE 304
+#define TK_VALUES 305
+#define TK_WHERE 306
+#define TK_WILDCARD 307
+#define COLUMN 309
+#define FUNCTION 310
+#define COMMENT 311
+#define UNCLOSED_STRING 312
+#define SPACE 313
+#define ILLEGAL 314
+#define END_OF_FILE 315
+#define TK_LIKE 316
+#define TK_NEGATION 317
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 72 "./sql.y"
+#line 73 "sql.y"
typedef union YYSTYPE {
struct sql_str str;
LPWSTR string;
USHORT column_type;
int integer;
} YYSTYPE;
-/* Line 1275 of yacc.c. */
-#line 337 "sql.tab.h"
+/* Line 1447 of yacc.c. */
+#line 170 "sql.tab.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys);
static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r );
+static struct expr * EXPR_unary( void *info, struct expr *l, UINT op );
static struct expr * EXPR_column( void *info, column_info *column );
static struct expr * EXPR_ival( void *info, int val );
static struct expr * EXPR_sval( void *info, struct sql_str * );
int integer;
}
-%token TK_ABORT TK_AFTER TK_AGG_FUNCTION TK_ALL TK_ALTER TK_AND TK_AS TK_ASC
-%token TK_BEFORE TK_BEGIN TK_BETWEEN TK_BITAND TK_BITNOT TK_BITOR TK_BY
-%token TK_CASCADE TK_CASE TK_CHAR TK_CHECK TK_CLUSTER TK_COLLATE TK_COLUMN
-%token TK_COMMA TK_COMMENT TK_COMMIT TK_CONCAT TK_CONFLICT
-%token TK_CONSTRAINT TK_COPY TK_CREATE
-%token TK_DEFAULT TK_DEFERRABLE TK_DEFERRED TK_DELETE TK_DELIMITERS TK_DESC
-%token TK_DISTINCT TK_DOT TK_DROP TK_EACH
-%token TK_ELSE TK_END TK_END_OF_FILE TK_EQ TK_EXCEPT TK_EXPLAIN
-%token TK_FAIL TK_FLOAT TK_FOR TK_FOREIGN TK_FREE TK_FROM TK_FUNCTION
-%token TK_GE TK_GLOB TK_GROUP TK_GT
-%token TK_HAVING TK_HOLD
-%token TK_IGNORE TK_ILLEGAL TK_IMMEDIATE TK_IN TK_INDEX TK_INITIALLY
-%token <str> TK_ID
-%token TK_INSERT TK_INSTEAD TK_INT
+%token TK_ALTER TK_AND TK_BY TK_CHAR TK_COMMA TK_CREATE TK_DELETE
+%token TK_DISTINCT TK_DOT TK_EQ TK_FREE TK_FROM TK_GE TK_GT TK_HOLD
+%token <str> TK_ID
+%token TK_ILLEGAL TK_INSERT TK_INT
%token <str> TK_INTEGER
-%token TK_INTERSECT TK_INTO TK_IS
-%token TK_ISNULL
-%token TK_JOIN TK_JOIN_KW
-%token TK_KEY
-%token TK_LE TK_LIKE TK_LIMIT TK_LONG TK_LONGCHAR TK_LP TK_LSHIFT TK_LT
-%token TK_LOCALIZABLE
-%token TK_MATCH TK_MINUS
-%token TK_NE TK_NOT TK_NOTNULL TK_NULL
-%token TK_OBJECT TK_OF TK_OFFSET TK_ON TK_OR TK_ORACLE_OUTER_JOIN TK_ORDER
-%token TK_PLUS TK_PRAGMA TK_PRIMARY
-%token TK_RAISE TK_REFERENCES TK_REM TK_REPLACE TK_RESTRICT TK_ROLLBACK
-%token TK_ROW TK_RP TK_RSHIFT
-%token TK_SELECT TK_SEMI TK_SET TK_SHORT TK_SLASH TK_SPACE TK_STAR TK_STATEMENT
+%token TK_INTO TK_IS TK_KEY TK_LE TK_LONG TK_LONGCHAR TK_LP TK_LT
+%token TK_LOCALIZABLE TK_MINUS TK_NE TK_NOT TK_NULL
+%token TK_OBJECT TK_OR TK_ORDER TK_PRIMARY TK_RP
+%token TK_SELECT TK_SET TK_SHORT TK_SPACE TK_STAR
%token <str> TK_STRING
-%token TK_TABLE TK_TEMPORARY TK_THEN TK_TRANSACTION TK_TRIGGER
-%token TK_UMINUS TK_UNCLOSED_STRING TK_UNION TK_UNIQUE
-%token TK_UPDATE TK_UPLUS TK_USING
-%token TK_VACUUM TK_VALUES TK_VIEW
-%token TK_WHEN TK_WHERE TK_WILDCARD
+%token TK_TABLE TK_TEMPORARY TK_UPDATE TK_VALUES TK_WHERE TK_WILDCARD
/*
* These are extra tokens used by the lexer but never seen by the
%type <string> table id
%type <column_list> selcollist column column_and_type column_def table_def
%type <column_list> column_assignment update_assign_list constlist
-%type <query> query multifrom from fromtable selectfrom unorderedsel
+%type <query> query from fromtable selectfrom unorderedsel
%type <query> oneupdate onedelete oneselect onequery onecreate oneinsert onealter
%type <expr> expr val column_val const_val
%type <column_type> column_type data_type data_type_l data_count
%left TK_OR
%left TK_AND
%left TK_NOT
-%left TK_EQ TK_NE TK_LT TK_GT TK_LE TK_GE TK_ISNULL TK_LIKE TK_BETWEEN TK_IN
-%left TK_PLUS TK_MINUS TK_CONCAT
+%left TK_EQ TK_NE TK_LT TK_GT TK_LE TK_GE TK_LIKE
%right TK_NEGATION
%%
TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP
{
SQL_input *sql = (SQL_input*) info;
- MSIVIEW *insert = NULL;
+ MSIVIEW *insert = NULL;
UINT r;
- r = INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE );
+ r = INSERT_CreateView( sql->db, &insert, $3, $5, $9, FALSE );
if( !insert )
YYABORT;
$$ = insert;
| TK_INSERT TK_INTO table TK_LP selcollist TK_RP TK_VALUES TK_LP constlist TK_RP TK_TEMPORARY
{
SQL_input *sql = (SQL_input*) info;
- MSIVIEW *insert = NULL;
+ MSIVIEW *insert = NULL;
- INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE );
+ INSERT_CreateView( sql->db, &insert, $3, $5, $9, TRUE );
if( !insert )
YYABORT;
$$ = insert;
TK_CREATE TK_TABLE table TK_LP table_def TK_RP
{
SQL_input* sql = (SQL_input*) info;
- MSIVIEW *create = NULL;
+ MSIVIEW *create = NULL;
if( !$5 )
YYABORT;
| TK_CREATE TK_TABLE table TK_LP table_def TK_RP TK_HOLD
{
SQL_input* sql = (SQL_input*) info;
- MSIVIEW *create = NULL;
+ MSIVIEW *create = NULL;
if( !$5 )
YYABORT;
TK_UPDATE table TK_SET update_assign_list TK_WHERE expr
{
SQL_input* sql = (SQL_input*) info;
- MSIVIEW *update = NULL;
+ MSIVIEW *update = NULL;
UPDATE_CreateView( sql->db, &update, $2, $4, $6 );
if( !update )
YYABORT;
$$ = update;
}
+ | TK_UPDATE table TK_SET update_assign_list
+ {
+ SQL_input* sql = (SQL_input*) info;
+ MSIVIEW *update = NULL;
+
+ UPDATE_CreateView( sql->db, &update, $2, $4, NULL );
+ if( !update )
+ YYABORT;
+ $$ = update;
+ }
;
onedelete:
TK_DELETE from
{
SQL_input* sql = (SQL_input*) info;
- MSIVIEW *delete = NULL;
+ MSIVIEW *delete = NULL;
DELETE_CreateView( sql->db, &delete, $2 );
if( !delete )
;
selectfrom:
- selcollist multifrom
+ selcollist from
{
SQL_input* sql = (SQL_input*) info;
UINT r;
;
selcollist:
- column
+ column
| column TK_COMMA selcollist
- {
+ {
$1->next = $3;
}
| TK_STAR
}
;
-multifrom:
- from
- | TK_FROM table TK_COMMA table TK_WHERE expr
- {
- SQL_input* sql = (SQL_input*) info;
- UINT r;
-
- /* only support inner joins on two tables */
- r = JOIN_CreateView( sql->db, &$$, $2, $4, $6 );
- if( r != ERROR_SUCCESS )
- YYABORT;
- }
- ;
-
from:
fromtable
| fromtable TK_WHERE expr
- {
+ {
SQL_input* sql = (SQL_input*) info;
UINT r;
if( r != ERROR_SUCCESS || !$$ )
YYABORT;
}
+ | TK_FROM table TK_COMMA table
+ {
+ SQL_input* sql = (SQL_input*) info;
+ UINT r;
+
+ /* only support inner joins on two tables */
+ r = JOIN_CreateView( sql->db, &$$, $2, $4 );
+ if( r != ERROR_SUCCESS )
+ YYABORT;
+ }
;
expr:
}
| column_val TK_IS TK_NULL
{
- $$ = EXPR_complex( info, $1, OP_ISNULL, NULL );
+ $$ = EXPR_unary( info, $1, OP_ISNULL );
if( !$$ )
YYABORT;
}
| column_val TK_IS TK_NOT TK_NULL
{
- $$ = EXPR_complex( info, $1, OP_NOTNULL, NULL );
+ $$ = EXPR_unary( info, $1, OP_NOTNULL );
if( !$$ )
YYABORT;
}
;
column_val:
- column
+ column
{
$$ = EXPR_column( info, $1 );
if( !$$ )
while( token == TK_SPACE );
/* TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len)); */
-
+
return token;
}
LPWSTR str;
/* if there's quotes, remove them */
- if( ( (p[0]=='`') && (p[len-1]=='`') ) ||
+ if( ( (p[0]=='`') && (p[len-1]=='`') ) ||
( (p[0]=='\'') && (p[len-1]=='\'') ) )
{
p++;
return e;
}
+static struct expr * EXPR_unary( void *info, struct expr *l, UINT op )
+{
+ struct expr *e = parser_alloc( info, sizeof *e );
+ if( e )
+ {
+ e->type = EXPR_UNARY;
+ e->u.expr.left = l;
+ e->u.expr.op = op;
+ e->u.expr.right = NULL;
+ }
+ return e;
+}
+
static struct expr * EXPR_column( void *info, column_info *column )
{
struct expr *e = parser_alloc( info, sizeof *e );
for( i = 0; i < MSI_MAX_PROPS; i++ )
free_prop( &si->property[i] );
- msiobj_release( &si->db->hdr );
+ IStorage_Release( si->storage );
}
static UINT get_type( UINT uiProperty )
{
case PID_CODEPAGE:
return VT_I2;
-
+
case PID_SUBJECT:
case PID_AUTHOR:
case PID_KEYWORDS:
return ERROR_SUCCESS;
}
-MSISUMMARYINFO *MSI_GetSummaryInformationW( MSIDATABASE *db, UINT uiUpdateCount )
+MSISUMMARYINFO *MSI_GetSummaryInformationW( IStorage *stg, UINT uiUpdateCount )
{
IStream *stm = NULL;
MSISUMMARYINFO *si;
DWORD grfMode;
HRESULT r;
- TRACE("%p %d\n", db, uiUpdateCount );
+ TRACE("%p %d\n", stg, uiUpdateCount );
si = alloc_msiobject( MSIHANDLETYPE_SUMMARYINFO,
sizeof (MSISUMMARYINFO), MSI_CloseSummaryInfo );
if( !si )
return si;
- msiobj_addref( &db->hdr );
- si->db = db;
memset( &si->property, 0, sizeof si->property );
si->update_count = uiUpdateCount;
+ IStorage_AddRef( stg );
+ si->storage = stg;
/* read the stream... if we fail, we'll start with an empty property set */
grfMode = STGM_READ | STGM_SHARE_EXCLUSIVE;
- r = IStorage_OpenStream( si->db->storage, szSumInfo, 0, grfMode, 0, &stm );
+ r = IStorage_OpenStream( si->storage, szSumInfo, 0, grfMode, 0, &stm );
if( SUCCEEDED(r) )
{
load_summary_info( si, stm );
return ERROR_INVALID_PARAMETER;
}
- si = MSI_GetSummaryInformationW( db, uiUpdateCount );
+ si = MSI_GetSummaryInformationW( db->storage, uiUpdateCount );
if (si)
{
*pHandle = alloc_msihandle( &si->hdr );
return strdupAtoW( prop->u.pszVal );
}
+LPWSTR msi_get_suminfo_product( IStorage *stg )
+{
+ MSISUMMARYINFO *si;
+ LPWSTR prod;
+
+ si = MSI_GetSummaryInformationW( stg, 0 );
+ if (!si)
+ {
+ ERR("no summary information!\n");
+ return NULL;
+ }
+ prod = msi_suminfo_dup_string( si, PID_REVNUMBER );
+ msiobj_release( &si->hdr );
+ return prod;
+}
+
UINT WINAPI MsiSummaryInfoGetPropertyA(
MSIHANDLE handle, UINT uiProperty, UINT *puiDataType, INT *piValue,
FILETIME *pftValue, LPSTR szValueBuf, DWORD *pcchValueBuf)
return ERROR_INVALID_HANDLE;
grfMode = STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE;
- r = IStorage_CreateStream( si->db->storage, szSumInfo, grfMode, 0, 0, &stm );
+ r = IStorage_CreateStream( si->storage, szSumInfo, grfMode, 0, 0, &stm );
if( SUCCEEDED(r) )
{
ret = save_summary_info( si, stm );
{
case 4:
offset = tv->columns[col-1].offset/2;
- *val = tv->table->data[row][offset] +
+ *val = tv->table->data[row][offset] +
(tv->table->data[row][offset + 1] << 16);
break;
case 2:
return r;
}
-static UINT TABLE_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
+static UINT TABLE_set_int( MSITABLEVIEW *tv, UINT row, UINT col, UINT val )
{
- MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
UINT offset, n;
if( !tv->table )
return ERROR_SUCCESS;
}
+static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
+{
+ MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
+ UINT i, val, r = ERROR_SUCCESS;
+
+ if ( !tv->table )
+ return ERROR_INVALID_PARAMETER;
+
+ /* test if any of the mask bits are invalid */
+ if ( mask >= (1<<tv->num_cols) )
+ return ERROR_INVALID_PARAMETER;
+
+ for ( i = 0; i < tv->num_cols; i++ )
+ {
+ /* only update the fields specified in the mask */
+ if ( !(mask&(1<<i)) )
+ continue;
+
+ /* FIXME: should we allow updating keys? */
+
+ val = 0;
+ if ( !MSI_RecordIsNull( rec, i + 1 ) )
+ {
+ if ( MSITYPE_IS_BINARY(tv->columns[ i ].type) )
+ {
+ val = 1; /* refers to the first key column */
+ }
+ else if ( tv->columns[i].type & MSITYPE_STRING )
+ {
+ LPCWSTR sval = MSI_RecordGetString( rec, i + 1 );
+ val = msi_addstringW( tv->db->strings, 0, sval, -1, 1 );
+ }
+ else if ( 2 == bytes_per_column( &tv->columns[ i ] ) )
+ {
+ val = 0x8000 + MSI_RecordGetInteger( rec, i + 1 );
+ if ( val & 0xffff0000 )
+ {
+ ERR("field %u value %d out of range\n", i+1, val - 0x8000 );
+ return ERROR_FUNCTION_FAILED;
+ }
+ }
+ else
+ {
+ INT ival = MSI_RecordGetInteger( rec, i + 1 );
+ val = ival ^ 0x80000000;
+ }
+ }
+
+ r = TABLE_set_int( tv, row, i+1, val );
+ if ( r != ERROR_SUCCESS )
+ break;
+ }
+ return r;
+}
+
static UINT table_create_new_row( struct tagMSIVIEW *view, UINT *num )
{
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
return ERROR_SUCCESS;
}
-static UINT msi_table_modify_row( MSITABLEVIEW *tv, MSIRECORD *rec,
- UINT row, UINT mask )
-{
- UINT i, val, r = ERROR_SUCCESS;
-
- TRACE("%p %p %u %08x\n", tv, rec, row, mask );
-
- for( i = 0; i < tv->num_cols; i++ )
- {
- /* set keys or values specified in the mask */
- if( (~tv->columns[i].type & MSITYPE_KEY) && (~mask & (1<<i)) )
- continue;
-
- if( (tv->columns[i].type & MSITYPE_STRING) &&
- ! MSITYPE_IS_BINARY(tv->columns[i].type) )
- {
- const WCHAR *str = MSI_RecordGetString( rec, i+1 );
- val = msi_addstringW( tv->db->strings, 0, str, -1, 1 );
- }
- else
- {
- val = MSI_RecordGetInteger( rec, i+1 );
- if ( 2 == bytes_per_column( &tv->columns[i] ) )
- val ^= 0x8000;
- else
- val ^= 0x80000000;
- }
- r = TABLE_set_int( &tv->view, row, i+1, val );
- if( r )
- break;
- }
-
- return r;
-}
-
static UINT TABLE_insert_row( struct tagMSIVIEW *view, MSIRECORD *rec )
{
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
if( r != ERROR_SUCCESS )
return r;
- return msi_table_modify_row( tv, rec, row, ~0 );
+ return TABLE_set_row( view, row, rec, (1<<tv->num_cols) - 1 );
}
static UINT TABLE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
if( !*handle )
entry = tv->columns[col-1].hash_table[val % MSITABLE_HASH_TABLE_SIZE];
else
- entry = ((const MSICOLUMNHASHENTRY *)*handle)->next;
+ entry = (*handle)->next;
while (entry && entry->value != val)
entry = entry->next;
- *handle = (MSIITERHANDLE)entry;
+ *handle = entry;
if (!entry)
return ERROR_NO_MORE_ITEMS;
{
TABLE_fetch_int,
TABLE_fetch_stream,
- TABLE_set_int,
+ TABLE_set_row,
TABLE_insert_row,
TABLE_execute,
TABLE_close,
static UINT msi_delete_row( MSITABLEVIEW *tv, UINT row )
{
UINT i;
+
for( i=1; i<=tv->num_cols; i++ )
- tv->view.ops->set_int( &tv->view, row, i, 0 );
+ TABLE_set_int( tv, row, i, 0 );
return ERROR_SUCCESS;
}
else if ( mask )
{
TRACE("modifying row [%d]:\n", row);
- msi_table_modify_row( tv, rec, row, mask );
+ TABLE_set_row( &tv->view, row, rec, mask );
}
else
{
goto end;
/*
- * Apply _Tables and _Coluimns transforms first so that
+ * Apply _Tables and _Columns transforms first so that
* the table metadata is correct, and empty tables exist.
*/
ret = msi_table_load_transform( db, stg, strings, szTables );
}
if ( ret == ERROR_SUCCESS )
- {
- MSITRANSFORM *t;
-
- t = msi_alloc( sizeof *t );
- t->stg = stg;
- IStorage_AddRef( stg );
- list_add_tail( &db->transforms, &t->entry );
- }
+ append_storage_to_db( db, stg );
end:
if ( stgenum )
return ret;
}
+void append_storage_to_db( MSIDATABASE *db, IStorage *stg )
+{
+ MSITRANSFORM *t;
+
+ t = msi_alloc( sizeof *t );
+ t->stg = stg;
+ IStorage_AddRef( stg );
+ list_add_tail( &db->transforms, &t->entry );
+}
+
void msi_free_transforms( MSIDATABASE *db )
{
while( !list_empty( &db->transforms ) )
#define MAX_TOKEN_LEN 11
-static const WCHAR ABORT_W[] = { 'A','B','O','R','T',0 };
-static const WCHAR AFTER_W[] = { 'A','F','T','E','R',0 };
static const WCHAR ALTER_W[] = { 'A','L','T','E','R',0 };
-static const WCHAR ALL_W[] = { 'A','L','L',0 };
static const WCHAR AND_W[] = { 'A','N','D',0 };
-static const WCHAR AS_W[] = { 'A','S',0 };
-static const WCHAR ASC_W[] = { 'A','S','C',0 };
-static const WCHAR BEFORE_W[] = { 'B','E','F','O','R','E',0 };
-static const WCHAR BEGIN_W[] = { 'B','E','G','I','N','W',0 };
-static const WCHAR BETWEEN_W[] = { 'B','E','T','W','E','E','N',0 };
static const WCHAR BY_W[] = { 'B','Y',0 };
-static const WCHAR CASCADE_W[] = { 'C','A','S','C','A','D','E',0 };
-static const WCHAR CASE_W[] = { 'C','A','S','E',0 };
static const WCHAR CHAR_W[] = { 'C','H','A','R',0 };
static const WCHAR CHARACTER_W[] = { 'C','H','A','R','A','C','T','E','R',0 };
-static const WCHAR CHECK_W[] = { 'C','H','E','C','K',0 };
-static const WCHAR CLUSTER_W[] = { 'C','L','U','S','T','E','R',0 };
-static const WCHAR COLLATE_W[] = { 'C','O','L','L','A','T','E',0 };
-static const WCHAR COMMIT_W[] = { 'C','O','M','M','I','T',0 };
-static const WCHAR CONFLICT_W[] = { 'C','O','N','F','L','I','C','T',0 };
-static const WCHAR CONSTRAINT_W[] = { 'C','O','N','S','T','R','A','I','N','T',0 };
-static const WCHAR COPY_W[] = { 'C','O','P','Y',0 };
static const WCHAR CREATE_W[] = { 'C','R','E','A','T','E',0 };
static const WCHAR CROSS_W[] = { 'C','R','O','S','S',0 };
-static const WCHAR DEFAULT_W[] = { 'D','E','F','A','U','L','T',0 };
-static const WCHAR DEFERRED_W[] = { 'D','E','F','E','R','R','E','D',0 };
-static const WCHAR DEFERRABLE_W[] = { 'D','E','F','E','R','R','A','B','L','E',0 };
static const WCHAR DELETE_W[] = { 'D','E','L','E','T','E',0 };
-static const WCHAR DELIMITERS_W[] = { 'D','E','L','I','M','I','T','E','R','S',0 };
-static const WCHAR DESC_W[] = { 'D','E','S','C',0 };
static const WCHAR DISTINCT_W[] = { 'D','I','S','T','I','N','C','T',0 };
-static const WCHAR DROP_W[] = { 'D','R','O','P',0 };
-static const WCHAR END_W[] = { 'E','N','D',0 };
-static const WCHAR EACH_W[] = { 'E','A','C','H',0 };
-static const WCHAR ELSE_W[] = { 'E','L','S','E',0 };
-static const WCHAR EXCEPT_W[] = { 'E','X','C','E','P','T',0 };
-static const WCHAR EXPLAIN_W[] = { 'E','X','P','L','A','I','N',0 };
-static const WCHAR FAIL_W[] = { 'F','A','I','L',0 };
-static const WCHAR FOR_W[] = { 'F','O','R',0 };
-static const WCHAR FOREIGN_W[] = { 'F','O','R','E','I','G','N',0 };
static const WCHAR FREE_W[] = { 'F','R','E','E',0 };
static const WCHAR FROM_W[] = { 'F','R','O','M',0 };
static const WCHAR FULL_W[] = { 'F','U','L','L',0 };
-static const WCHAR GLOB_W[] = { 'G','L','O','B',0 };
-static const WCHAR GROUP_W[] = { 'G','R','O','U','P',0 };
-static const WCHAR HAVING_W[] = { 'H','A','V','I','N','G',0 };
static const WCHAR HOLD_W[] = { 'H','O','L','D',0 };
-static const WCHAR IGNORE_W[] = { 'I','G','N','O','R','E',0 };
-static const WCHAR IMMEDIATE_W[] = { 'I','M','M','E','D','I','A','T','E',0 };
-static const WCHAR IN_W[] = { 'I','N',0 };
-static const WCHAR INDEX_W[] = { 'I','N','D','E','X',0 };
-static const WCHAR INITIALLY_W[] = { 'I','N','I','T','I','A','L','L','Y',0 };
static const WCHAR INNER_W[] = { 'I','N','N','E','R',0 };
static const WCHAR INSERT_W[] = { 'I','N','S','E','R','T',0 };
-static const WCHAR INSTEAD_W[] = { 'I','N','S','T','E','A','D',0 };
static const WCHAR INT_W[] = { 'I','N','T',0 };
-static const WCHAR INTERSECT_W[] = { 'I','N','T','E','R','S','E','C','T',0 };
+static const WCHAR INTEGER_W[] = { 'I','N','T','E','G','E','R',0 };
static const WCHAR INTO_W[] = { 'I','N','T','O',0 };
static const WCHAR IS_W[] = { 'I','S',0 };
-static const WCHAR ISNULL_W[] = { 'I','S','N','U','L','L',0 };
static const WCHAR JOIN_W[] = { 'J','O','I','N',0 };
static const WCHAR KEY_W[] = { 'K','E','Y',0 };
static const WCHAR LEFT_W[] = { 'L','E','F','T',0 };
static const WCHAR LIKE_W[] = { 'L','I','K','E',0 };
-static const WCHAR LIMIT_W[] = { 'L','I','M','I','T',0 };
static const WCHAR LOCALIZABLE_W[] = { 'L','O','C','A','L','I','Z','A','B','L','E',0 };
static const WCHAR LONG_W[] = { 'L','O','N','G',0 };
static const WCHAR LONGCHAR_W[] = { 'L','O','N','G','C','H','A','R',0 };
-static const WCHAR MATCH_W[] = { 'M','A','T','C','H',0 };
static const WCHAR NATURAL_W[] = { 'N','A','T','U','R','A','L',0 };
static const WCHAR NOT_W[] = { 'N','O','T',0 };
-static const WCHAR NOTNULL_W[] = { 'N','O','T','N','U','L','L',0 };
static const WCHAR NULL_W[] = { 'N','U','L','L',0 };
static const WCHAR OBJECT_W[] = { 'O','B','J','E','C','T',0 };
-static const WCHAR OF_W[] = { 'O','F',0 };
-static const WCHAR OFFSET_W[] = { 'O','F','F','S','E','T',0 };
-static const WCHAR ON_W[] = { 'O','N',0 };
static const WCHAR OR_W[] = { 'O','R',0 };
static const WCHAR ORDER_W[] = { 'O','R','D','E','R',0 };
static const WCHAR OUTER_W[] = { 'O','U','T','E','R',0 };
-static const WCHAR PRAGMA_W[] = { 'P','R','A','G','M','A',0 };
static const WCHAR PRIMARY_W[] = { 'P','R','I','M','A','R','Y',0 };
-static const WCHAR RAISE_W[] = { 'R','A','I','S','E',0 };
-static const WCHAR REFERENCES_W[] = { 'R','E','F','E','R','E','N','C','E','S',0 };
-static const WCHAR REPLACE_W[] = { 'R','E','P','L','A','C','E',0 };
-static const WCHAR RESTRICT_W[] = { 'R','E','S','T','R','I','C','T',0 };
static const WCHAR RIGHT_W[] = { 'R','I','G','H','T',0 };
-static const WCHAR ROLLBACK_W[] = { 'R','O','L','L','B','A','C','K',0 };
-static const WCHAR ROW_W[] = { 'R','O','W',0 };
static const WCHAR SELECT_W[] = { 'S','E','L','E','C','T',0 };
static const WCHAR SET_W[] = { 'S','E','T',0 };
static const WCHAR SHORT_W[] = { 'S','H','O','R','T',0 };
-static const WCHAR STATEMENT_W[] = { 'S','T','A','T','E','M','E','N','T',0 };
static const WCHAR TABLE_W[] = { 'T','A','B','L','E',0 };
static const WCHAR TEMP_W[] = { 'T','E','M','P',0 };
static const WCHAR TEMPORARY_W[] = { 'T','E','M','P','O','R','A','R','Y',0 };
-static const WCHAR THEN_W[] = { 'T','H','E','N',0 };
-static const WCHAR TRANSACTION_W[] = { 'T','R','A','N','S','A','C','T','I','O','N',0 };
-static const WCHAR TRIGGER_W[] = { 'T','R','I','G','G','E','R',0 };
-static const WCHAR UNION_W[] = { 'U','N','I','O','N',0 };
-static const WCHAR UNIQUE_W[] = { 'U','N','I','Q','U','E',0 };
static const WCHAR UPDATE_W[] = { 'U','P','D','A','T','E',0 };
-static const WCHAR USING_W[] = { 'U','S','I','N','G',0 };
-static const WCHAR VACUUM_W[] = { 'V','A','C','U','U','M',0 };
static const WCHAR VALUES_W[] = { 'V','A','L','U','E','S',0 };
-static const WCHAR VIEW_W[] = { 'V','I','E','W',0 };
-static const WCHAR WHEN_W[] = { 'W','H','E','N',0 };
static const WCHAR WHERE_W[] = { 'W','H','E','R','E',0 };
/*
** These are the keywords
*/
static const Keyword aKeywordTable[] = {
- { ABORT_W, TK_ABORT },
- { AFTER_W, TK_AFTER },
/*{ ALTER_W, TK_ALTER },*/
- { ALL_W, TK_ALL },
{ AND_W, TK_AND },
- { AS_W, TK_AS },
- { ASC_W, TK_ASC },
- { BEFORE_W, TK_BEFORE },
- { BEGIN_W, TK_BEGIN },
- { BETWEEN_W, TK_BETWEEN },
{ BY_W, TK_BY },
- { CASCADE_W, TK_CASCADE },
- { CASE_W, TK_CASE },
{ CHAR_W, TK_CHAR },
{ CHARACTER_W, TK_CHAR },
- { CHECK_W, TK_CHECK },
- { CLUSTER_W, TK_CLUSTER },
- { COLLATE_W, TK_COLLATE },
- { COMMIT_W, TK_COMMIT },
- { CONFLICT_W, TK_CONFLICT },
- { CONSTRAINT_W, TK_CONSTRAINT },
- { COPY_W, TK_COPY },
{ CREATE_W, TK_CREATE },
- { CROSS_W, TK_JOIN_KW },
- { DEFAULT_W, TK_DEFAULT },
- { DEFERRED_W, TK_DEFERRED },
- { DEFERRABLE_W, TK_DEFERRABLE },
{ DELETE_W, TK_DELETE },
- { DELIMITERS_W, TK_DELIMITERS },
- { DESC_W, TK_DESC },
{ DISTINCT_W, TK_DISTINCT },
- { DROP_W, TK_DROP },
- { END_W, TK_END },
- { EACH_W, TK_EACH },
- { ELSE_W, TK_ELSE },
- { EXCEPT_W, TK_EXCEPT },
- { EXPLAIN_W, TK_EXPLAIN },
- { FAIL_W, TK_FAIL },
- { FOR_W, TK_FOR },
- { FOREIGN_W, TK_FOREIGN },
+ { FREE_W, TK_FREE },
{ FROM_W, TK_FROM },
- { FULL_W, TK_JOIN_KW },
- { GLOB_W, TK_GLOB },
- { GROUP_W, TK_GROUP },
- { HAVING_W, TK_HAVING },
{ HOLD_W, TK_HOLD },
- { IGNORE_W, TK_IGNORE },
- { IMMEDIATE_W, TK_IMMEDIATE },
- { IN_W, TK_IN },
- { INDEX_W, TK_INDEX },
- { INITIALLY_W, TK_INITIALLY },
- { INNER_W, TK_JOIN_KW },
{ INSERT_W, TK_INSERT },
- { INSTEAD_W, TK_INSTEAD },
{ INT_W, TK_INT },
- { INTERSECT_W, TK_INTERSECT },
+ { INTEGER_W, TK_INT },
{ INTO_W, TK_INTO },
{ IS_W, TK_IS },
- { ISNULL_W, TK_ISNULL },
- { JOIN_W, TK_JOIN },
{ KEY_W, TK_KEY },
- { LEFT_W, TK_JOIN_KW },
{ LIKE_W, TK_LIKE },
- { LIMIT_W, TK_LIMIT },
{ LOCALIZABLE_W, TK_LOCALIZABLE },
{ LONG_W, TK_LONG },
{ LONGCHAR_W, TK_LONGCHAR },
- { MATCH_W, TK_MATCH },
- { NATURAL_W, TK_JOIN_KW },
{ NOT_W, TK_NOT },
- { NOTNULL_W, TK_NOTNULL },
{ NULL_W, TK_NULL },
{ OBJECT_W, TK_OBJECT },
- { OF_W, TK_OF },
- { OFFSET_W, TK_OFFSET },
- { ON_W, TK_ON },
{ OR_W, TK_OR },
{ ORDER_W, TK_ORDER },
- { OUTER_W, TK_JOIN_KW },
- { PRAGMA_W, TK_PRAGMA },
{ PRIMARY_W, TK_PRIMARY },
- { RAISE_W, TK_RAISE },
- { REFERENCES_W, TK_REFERENCES },
- { REPLACE_W, TK_REPLACE },
- { RESTRICT_W, TK_RESTRICT },
- { RIGHT_W, TK_JOIN_KW },
- { ROLLBACK_W, TK_ROLLBACK },
- { ROW_W, TK_ROW },
{ SELECT_W, TK_SELECT },
{ SET_W, TK_SET },
{ SHORT_W, TK_SHORT },
- { STATEMENT_W, TK_STATEMENT },
{ TABLE_W, TK_TABLE },
/*{ TEMPORARY_W, TK_TEMPORARY },*/
- { THEN_W, TK_THEN },
- { TRANSACTION_W, TK_TRANSACTION },
- { TRIGGER_W, TK_TRIGGER },
- { UNION_W, TK_UNION },
- { UNIQUE_W, TK_UNIQUE },
{ UPDATE_W, TK_UPDATE },
- { USING_W, TK_USING },
- { VACUUM_W, TK_VACUUM },
{ VALUES_W, TK_VALUES },
- { VIEW_W, TK_VIEW },
- { WHEN_W, TK_WHEN },
{ WHERE_W, TK_WHERE },
};
}
case '-': {
if( z[1]==0 ) return -1;
- if( z[1]=='-' ){
- for(i=2; z[i] && z[i]!='\n'; i++){}
- *tokenType = TK_COMMENT;
- return i;
- }
*tokenType = TK_MINUS;
return 1;
}
- case '(': {
- if( z[1]=='+' && z[2]==')' ){
- *tokenType = TK_ORACLE_OUTER_JOIN;
- return 3;
- }else{
- *tokenType = TK_LP;
- return 1;
- }
- }
- case ')': {
- *tokenType = TK_RP;
- return 1;
- }
- case ';': {
- *tokenType = TK_SEMI;
+ case '(':
+ *tokenType = TK_LP;
return 1;
- }
- case '+': {
- *tokenType = TK_PLUS;
+ case ')':
+ *tokenType = TK_RP;
return 1;
- }
- case '*': {
+ case '*':
*tokenType = TK_STAR;
return 1;
- }
- case '/': {
- if( z[1]!='*' || z[2]==0 ){
- *tokenType = TK_SLASH;
- return 1;
- }
- for(i=3; z[i] && (z[i]!='/' || z[i-1]!='*'); i++){}
- if( z[i] ) i++;
- *tokenType = TK_COMMENT;
- return i;
- }
- case '%': {
- *tokenType = TK_REM;
- return 1;
- }
- case '=': {
+ case '=':
*tokenType = TK_EQ;
- return 1 + (z[1]=='=');
- }
+ return 1;
case '<': {
if( z[1]=='=' ){
*tokenType = TK_LE;
}else if( z[1]=='>' ){
*tokenType = TK_NE;
return 2;
- }else if( z[1]=='<' ){
- *tokenType = TK_LSHIFT;
- return 2;
}else{
*tokenType = TK_LT;
return 1;
if( z[1]=='=' ){
*tokenType = TK_GE;
return 2;
- }else if( z[1]=='>' ){
- *tokenType = TK_RSHIFT;
- return 2;
}else{
*tokenType = TK_GT;
return 1;
return 2;
}
}
- case '|': {
- if( z[1]!='|' ){
- *tokenType = TK_BITOR;
- return 1;
- }else{
- *tokenType = TK_CONCAT;
- return 2;
- }
- }
- case '?': {
+ case '?':
*tokenType = TK_WILDCARD;
return 1;
- }
- case ',': {
+ case ',':
*tokenType = TK_COMMA;
return 1;
- }
- case '&': {
- *tokenType = TK_BITAND;
- return 1;
- }
- case '~': {
- *tokenType = TK_BITNOT;
- return 1;
- }
case '`': case '\'': case '"': {
int delim = z[0];
for(i=1; z[i]; i++){
case '5': case '6': case '7': case '8': case '9': {
*tokenType = TK_INTEGER;
for(i=1; isdigit(z[i]); i++){}
- if( z[i]=='.' ){
- i++;
- while( isdigit(z[i]) ){ i++; }
- *tokenType = TK_FLOAT;
- }
- if( (z[i]=='e' || z[i]=='E') &&
- ( isdigit(z[i+1])
- || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))
- )
- ){
- i += 2;
- while( isdigit(z[i]) ){ i++; }
- *tokenType = TK_FLOAT;
- }else if( z[0]=='.' ){
- *tokenType = TK_FLOAT;
- }
return i;
}
case '[': {
static UINT UPDATE_execute( struct tagMSIVIEW *view, MSIRECORD *record )
{
MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
- UINT n, type, val, r, row, col_count = 0, row_count = 0;
+ UINT i, r, col_count = 0, row_count = 0;
+ MSIRECORD *values = NULL;
MSIVIEW *wv;
TRACE("%p %p\n", uv, record );
- if( !record )
- return ERROR_FUNCTION_FAILED;
-
wv = uv->wv;
if( !wv )
return ERROR_FUNCTION_FAILED;
r = wv->ops->get_dimensions( wv, &row_count, &col_count );
if( r )
- goto err;
+ return r;
- for( row = 0; row < row_count; row++ )
+ values = msi_query_merge_record( col_count, uv->vals, record );
+ if (!values)
+ return ERROR_FUNCTION_FAILED;
+
+ for ( i=0; i<row_count; i++ )
{
- for( n = 1; n <= col_count; n++ )
- {
- r = wv->ops->get_column_info( wv, n, NULL, &type );
- if( r )
- break;
-
- if( type & MSITYPE_STRING )
- {
- const WCHAR *str = MSI_RecordGetString( record, n );
- val = msi_addstringW( uv->db->strings, 0, str, -1, 1 );
- }
- else
- {
- val = MSI_RecordGetInteger( record, n );
- val |= 0x8000;
- }
- r = wv->ops->set_int( wv, row, n, val );
- if( r )
- break;
- }
+ r = wv->ops->set_row( wv, i, values, (1 << col_count) - 1 );
+ if (r != ERROR_SUCCESS)
+ break;
}
-err:
- return ERROR_SUCCESS;
+ msiobj_release( &values->hdr );
+
+ return r;
}
if( r != ERROR_SUCCESS )
return r;
- /* add conditions first */
- r = WHERE_CreateView( db, &wv, tv, expr );
- if( r != ERROR_SUCCESS )
+ if (expr)
{
- tv->ops->delete( tv );
- return r;
+ /* add conditions first */
+ r = WHERE_CreateView( db, &wv, tv, expr );
+ if( r != ERROR_SUCCESS )
+ {
+ tv->ops->delete( tv );
+ return r;
+ }
}
-
+ else
+ wv = tv;
+
/* then select the columns we want */
r = SELECT_CreateView( db, &sv, wv, columns );
if( r != ERROR_SUCCESS )
return wv->table->ops->fetch_stream( wv->table, row, col, stm );
}
-static UINT WHERE_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT val )
+static UINT WHERE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask )
{
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
- TRACE("%p %d %d %04x\n", wv, row, col, val );
+ TRACE("%p %d %p %08x\n", wv, row, rec, mask );
if( !wv->table )
return ERROR_FUNCTION_FAILED;
-
+
if( row > wv->row_count )
return ERROR_NO_MORE_ITEMS;
-
+
row = wv->reorder[ row ];
-
- return wv->table->ops->set_int( wv->table, row, col, val );
+
+ return wv->table->ops->set_row( wv->table, row, rec, mask );
}
-static INT INT_evaluate( INT lval, UINT op, INT rval )
+static INT INT_evaluate_binary( INT lval, UINT op, INT rval )
{
switch( op )
{
return ( lval >= rval );
case OP_NE:
return ( lval != rval );
+ default:
+ ERR("Unknown operator %d\n", op );
+ }
+ return 0;
+}
+
+static INT INT_evaluate_unary( INT lval, UINT op )
+{
+ switch( op )
+ {
case OP_ISNULL:
return ( !lval );
case OP_NOTNULL:
r = WHERE_evaluate( db, table, row, cond->u.expr.right, &rval, record );
if( r != ERROR_SUCCESS )
return r;
- *val = INT_evaluate( lval, cond->u.expr.op, rval );
+ *val = INT_evaluate_binary( lval, cond->u.expr.op, rval );
+ return ERROR_SUCCESS;
+
+ case EXPR_UNARY:
+ r = table->ops->fetch_int( table, row, cond->u.expr.left->u.col_number, &tval );
+ if( r != ERROR_SUCCESS )
+ return r;
+ *val = INT_evaluate_unary( tval, cond->u.expr.op );
return ERROR_SUCCESS;
case EXPR_STRCMP:
default:
ERR("Invalid expression type\n");
break;
- }
+ }
return ERROR_SUCCESS;
{
WHERE_fetch_int,
WHERE_fetch_stream,
- WHERE_set_int,
+ WHERE_set_row,
NULL,
WHERE_execute,
WHERE_close,
}
break;
+ case EXPR_UNARY:
+ if ( cond->u.expr.left->type != EXPR_COLUMN )
+ {
+ *valid = FALSE;
+ return ERROR_INVALID_PARAMETER;
+ }
+ r = WHERE_VerifyCondition( db, table, cond->u.expr.left, valid );
+ if( r != ERROR_SUCCESS )
+ return r;
+ break;
case EXPR_IVAL:
*valid = 1;
cond->type = EXPR_UVAL;
ERR("Invalid expression type\n");
*valid = 0;
break;
- }
+ }
return ERROR_SUCCESS;
}