%{ //-------------------------------------------------------------------- // Microsoft Monarch // // Copyright (c) Microsoft Corporation, 1997 - 1999. // // @doc OPTIONAL EXTRACTION CODES // // @module MS-sql.y | // Monarch SQL YACC Script // // @devnote none // // @rev 0 | 04-Feb-97 | v-charca | Created // /* 3.4 Object identifier for Database Language SQL */ #pragma hdrstop #pragma optimize("g", off) #include "msidxtr.h" EXTERN_C const IID IID_IColumnMapperCreator; #define VAL_AND_CCH_MINUS_NULL(p1) (p1), ((sizeof(p1) / sizeof(*(p1))) - 1) #ifdef YYDEBUG #define YYTRACE(a,b,c) wprintf(L"** %s[%s%s] ** \n", a, b, c); #else #define YYTRACE(a,b,c) #endif #ifdef DEBUG #define AssertReq(x) Assert(x != NULL) #else #define AssertReq(x) #endif #define DEFAULTWEIGHT 1000 typedef struct tagDBTYPENAMETABLE { LPWSTR pwszDBTypeName; DBTYPE dbType; } DBTYPENAMETABLE; // J F M A M J J A S O N D const short LeapDays[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; const short Days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; #define IsLeapYear(yrs) ( \ (((yrs) % 400 == 0) || \ ((yrs) % 100 != 0) && ((yrs) % 4 == 0)) ? \ TRUE \ : \ FALSE \ ) #define DaysInMonth(YEAR,MONTH) ( \ IsLeapYear(YEAR) ? \ LeapDays[(MONTH)] : \ Days[(MONTH)] \ ) //----------------------------------------------------------------------------- // @func GetDBTypeFromStr // // This function takes a TypeName as input, and returns the DBTYPE of the string // // @rdesc DBTYPE //----------------------------------------------------------------------------- DBTYPE GetDBTypeFromStr( LPWSTR pwszDBTypeName ) // @parm IN { DBTYPE dbType = DBTYPE_EMPTY; if ( 9 <= wcslen(pwszDBTypeName) ) switch ( pwszDBTypeName[7] ) { case L'U': case L'u': if (10 == wcslen(pwszDBTypeName)) switch ( pwszDBTypeName[9]) { case L'1': if (0 == _wcsicmp(L"DBTYPE_UI1", pwszDBTypeName)) dbType = DBTYPE_UI1; break; case L'2': if (0 == _wcsicmp(L"DBTYPE_UI2", pwszDBTypeName)) dbType = DBTYPE_UI2; break; case L'4': if (0 == _wcsicmp(L"DBTYPE_UI4", pwszDBTypeName)) dbType = DBTYPE_UI4; break; case L'8': if (0 == _wcsicmp(L"DBTYPE_UI8", pwszDBTypeName)) dbType = DBTYPE_UI8; break; default: break; } break; case L'I': case L'i': switch ( pwszDBTypeName[8] ) { case L'1': if ( 0 == _wcsicmp(L"DBTYPE_I1", pwszDBTypeName) ) dbType = DBTYPE_I1; break; case L'2': if ( 0 == _wcsicmp(L"DBTYPE_I2", pwszDBTypeName) ) dbType = DBTYPE_I2; break; case L'4': if ( 0 == _wcsicmp(L"DBTYPE_I4", pwszDBTypeName) ) dbType = DBTYPE_I4; break; case L'8': if ( 0 == _wcsicmp(L"DBTYPE_I8", pwszDBTypeName) ) dbType = DBTYPE_I8; break; default: break; } break; case L'R': case L'r': switch ( pwszDBTypeName[8] ) { case L'4': if ( 0 == _wcsicmp(L"DBTYPE_R4", pwszDBTypeName) ) dbType = DBTYPE_R4; break; case L'8': if (0 == _wcsicmp(L"DBTYPE_R8", pwszDBTypeName)) dbType = DBTYPE_R8; break; default: break; } break; case L'B': case L'b': if ( 10 <= wcslen(pwszDBTypeName) ) switch ( pwszDBTypeName[8] ) { case L'S': case L's': if ( 0 == _wcsicmp(L"DBTYPE_BSTR", pwszDBTypeName) ) dbType = DBTYPE_BSTR; break; case L'O': case L'o': if ( 0 == _wcsicmp(L"DBTYPE_BOOL", pwszDBTypeName) ) dbType = DBTYPE_BOOL; break; case L'Y': case L'y': if ( 0 == _wcsicmp(L"DBTYPE_BYREF", pwszDBTypeName) ) dbType = DBTYPE_BYREF; break; default: break; } break; case L'E': case L'e': if ( 0 == _wcsicmp(L"DBTYPE_EMPTY", pwszDBTypeName) ) dbType = DBTYPE_EMPTY; break; case L'N': case L'n': if ( 0 == _wcsicmp(L"DBTYPE_NULL", pwszDBTypeName) ) dbType = DBTYPE_NULL; break; case L'C': case L'c': if ( 0 == _wcsicmp(L"DBTYPE_CY", pwszDBTypeName) ) dbType = DBTYPE_CY; break; case L'D': case L'd': if ( 0 == _wcsicmp(L"DBTYPE_DATE", pwszDBTypeName) ) dbType = DBTYPE_DATE; break; case L'G': case L'g': if ( 0 == _wcsicmp(L"DBTYPE_GUID", pwszDBTypeName) ) dbType = DBTYPE_GUID; break; case L'S': case L's': if ( 0 == _wcsicmp(L"DBTYPE_STR", pwszDBTypeName) ) dbType = DBTYPE_STR; break; case L'W': case L'w': if ( 0 == _wcsicmp(L"DBTYPE_WSTR", pwszDBTypeName) ) dbType = DBTYPE_WSTR; break; case L'T': case L't': if ( 0 == _wcsicmp(L"VT_FILETIME", pwszDBTypeName) ) dbType = VT_FILETIME; break; case L'V': case L'v': if ( 0 == _wcsicmp(L"DBTYPE_VECTOR", pwszDBTypeName) ) dbType = DBTYPE_VECTOR; break; default: break; } return dbType; } const DBTYPENAMETABLE dbTypeNameTable[] = { {L"DBTYPE_EMPTY", DBTYPE_EMPTY}, {L"DBTYPE_NULL", DBTYPE_NULL}, {L"DBTYPE_I2", DBTYPE_I2}, {L"DBTYPE_I4", DBTYPE_I4}, {L"DBTYPE_R4", DBTYPE_R4}, {L"DBTYPE_R8", DBTYPE_R8}, {L"DBTYPE_CY", DBTYPE_CY}, {L"DBTYPE_DATE", DBTYPE_DATE}, {L"DBTYPE_BSTR", DBTYPE_BSTR}, {L"DBTYPE_BOOL", DBTYPE_BOOL}, {L"DBTYPE_UI1", DBTYPE_UI1}, {L"DBTYPE_I1", DBTYPE_I1}, {L"DBTYPE_UI2", DBTYPE_UI2}, {L"DBTYPE_UI4", DBTYPE_UI4}, {L"DBTYPE_I8", DBTYPE_I8}, {L"DBTYPE_UI8", DBTYPE_UI8}, {L"DBTYPE_GUID", DBTYPE_GUID}, {L"DBTYPE_STR", DBTYPE_STR}, {L"DBTYPE_WSTR", DBTYPE_WSTR}, {L"DBTYPE_BYREF", DBTYPE_BYREF}, {L"VT_FILETIME", VT_FILETIME}, {L"DBTYPE_VECTOR", DBTYPE_VECTOR} }; //----------------------------------------------------------------------------- // @func PctCreateContentNode // // This function takes a content string as input and creates a content node // with the specified generate method and weight. // // @rdesc DBCOMMANDTREE* //----------------------------------------------------------------------------- DBCOMMANDTREE* PctCreateContentNode( LPWSTR pwszContent, // @parm IN | content for the node DWORD dwGenerateMethod,//@parm IN | generate method LONG lWeight, // @parm IN | weight LCID lcid, // @parm IN | locale identifier DBCOMMANDTREE* pctFirstChild ) // @parm IN | node to link to new node { DBCOMMANDTREE* pct = PctCreateNode( DBOP_content, DBVALUEKIND_CONTENT, pctFirstChild, NULL ); if ( 0 != pct ) { pct->value.pdbcntntValue->pwszPhrase = CoTaskStrDup( pwszContent ); if (pct->value.pdbcntntValue->pwszPhrase) { pct->value.pdbcntntValue->dwGenerateMethod = dwGenerateMethod; pct->value.pdbcntntValue->lWeight = lWeight; pct->value.pdbcntntValue->lcid = lcid; } else { DeleteDBQT( pct ); pct = 0; } } return pct; } //----------------------------------------------------------------------------- // @func PctCreateBooleanNode // // This function creates a content node with the specified children and weight. // // @rdesc DBCOMMANDTREE* //----------------------------------------------------------------------------- DBCOMMANDTREE* PctCreateBooleanNode( DBCOMMANDOP op, // @parm IN | op tag for new node LONG lWeight, // @parm IN | Weight of the boolean node DBCOMMANDTREE* pctChild, // @parm IN | child of boolean node DBCOMMANDTREE* pctSibling )// @parm IN | second child of boolean node { DBCOMMANDTREE* pct = PctCreateNode( op, DBVALUEKIND_I4, pctChild, pctSibling, NULL ); if ( 0 != pct ) pct->value.lValue = lWeight; return pct; } //----------------------------------------------------------------------------- // @func PctCreateNotNode // // This function creates a not node with the specified child and weight. // // @rdesc DBCOMMANDTREE* //----------------------------------------------------------------------------- DBCOMMANDTREE* PctCreateNotNode( LONG lWeight, // @parm IN | Weight of the boolean node DBCOMMANDTREE* pctChild ) // @parm IN | child of NOT node { DBCOMMANDTREE* pct = PctCreateNode( DBOP_not, DBVALUEKIND_I4, pctChild, NULL ); if ( 0 != pct ) pct->value.lValue = lWeight; return pct; } //----------------------------------------------------------------------------- // @func PctCreateRelationalNode // // This function creates a relational node with the specied op and weight. // // @rdesc DBCOMMANDTREE* //----------------------------------------------------------------------------- DBCOMMANDTREE* PctCreateRelationalNode( DBCOMMANDOP op, // @parm IN | op tag for new node LONG lWeight ) // @parm IN | Weight of the relational node { DBCOMMANDTREE* pct = PctCreateNode(op, DBVALUEKIND_I4, NULL); if ( 0 != pct) pct->value.lValue = lWeight; return pct; } //----------------------------------------------------------------------------- // @func SetLWeight // // This function sets the lWeight value for vector searches // //----------------------------------------------------------------------------- void SetLWeight( DBCOMMANDTREE* pct, // @parm IN | node or subtree to set LONG lWeight ) // @parm IN | weight value for node(s) { if ( DBOP_content == pct->op ) pct->value.pdbcntntValue->lWeight = lWeight; else { AssertReq( pct->pctFirstChild ); AssertReq( pct->pctFirstChild->pctNextSibling ); SetLWeight(pct->pctFirstChild, lWeight); DBCOMMANDTREE* pctNext = pct->pctFirstChild->pctNextSibling; while ( pctNext ) { // A content_proximity node can have lots of siblings SetLWeight( pctNext, lWeight ); pctNext = pctNext->pctNextSibling; } } } //----------------------------------------------------------------------------- // @func GetLWeight // // This function gets the lWeight value for vector searches //----------------------------------------------------------------------------- LONG GetLWeight( DBCOMMANDTREE* pct ) // @parm IN | node or subtree to set { if ( DBOP_content == pct->op ) return pct->value.pdbcntntValue->lWeight; else { AssertReq( pct->pctFirstChild ); return GetLWeight( pct->pctFirstChild ); } } //----------------------------------------------------------------------------- // @func PctBuiltInProperty // // This function takes a column name string as input and creates a column_name // node containing the appropriate GUID information if the column_name is a // built-in property // // @rdesc DBCOMMANDTREE* //----------------------------------------------------------------------------- DBCOMMANDTREE* PctBuiltInProperty( LPWSTR pwszColumnName, // @parm IN | name of column CImpIParserSession* pIPSession, // @parm IN | Parser Session CImpIParserTreeProperties* pIPTProps ) // @parm IN | Parser Properties { DBCOMMANDTREE* pct = 0; DBID *pDBID = 0; DBTYPE uwType = 0; UINT uiWidth = 0; BOOL fOk = 0; ICiPropertyList* pIPropList = 0; IColumnMapper* pIColumnMapper = pIPSession->GetColumnMapperPtr(); if ( 0 != pIColumnMapper ) { // we were able to use the IColumnMapper interface HRESULT hr = S_OK; // Olympus kludge if ( 0 == _wcsicmp(pwszColumnName, L"URL") ) hr = pIColumnMapper->GetPropInfoFromName( L"VPATH", &pDBID, &uwType, &uiWidth ); else hr = pIColumnMapper->GetPropInfoFromName( pwszColumnName, &pDBID, &uwType, &uiWidth ); if ( SUCCEEDED(hr) ) fOk = TRUE; else fOk = FALSE; } else fOk = FALSE; // @TODO: this should generate some sort of error message. if ( fOk ) // this is a built-in (well known) property { pIPTProps->SetDBType( uwType ); // remember the type of this pct = PctCreateNode( DBOP_column_name, DBVALUEKIND_ID, NULL ); if ( 0 != pct ) { pct->value.pdbidValue->eKind = pDBID->eKind; pct->value.pdbidValue->uGuid.guid = pDBID->uGuid.guid; switch ( pct->value.pdbidValue->eKind ) { case DBKIND_NAME: case DBKIND_GUID_NAME: // need to create a new string pct->value.pdbidValue->uName.pwszName = CoTaskStrDup(pDBID->uName.pwszName); break; case DBKIND_GUID: case DBKIND_GUID_PROPID: pct->value.pdbidValue->uName.pwszName = pDBID->uName.pwszName; break; case DBKIND_PGUID_NAME: // need to create a new string pct->value.pdbidValue->uName.pwszName = CoTaskStrDup(pDBID->uName.pwszName); // need to allocate and copy guid pct->value.pdbidValue->uGuid.pguid = (GUID*)CoTaskMemAlloc(sizeof(GUID)); *pct->value.pdbidValue->uGuid.pguid = *pDBID->uGuid.pguid; break; case DBKIND_PGUID_PROPID: // need to allocate and copy guid pct->value.pdbidValue->uGuid.pguid = (GUID*)CoTaskMemAlloc(sizeof(GUID)); *pct->value.pdbidValue->uGuid.pguid = *pDBID->uGuid.pguid; break; default: Assert(0); } } if ( 0 != pIPropList ) pIPropList->Release(); } return pct; } //----------------------------------------------------------------------------- // @func PctMkColNodeFromStr // // This function takes a column name string as input and creates a column_name // node containing the appropriate GUID information. // // @rdesc DBCOMMANDTREE* //----------------------------------------------------------------------------- DBCOMMANDTREE* PctMkColNodeFromStr( LPWSTR pwszColumnName, // @parm IN | name of column CImpIParserSession* pIPSession, // @parm IN | Parser Session CImpIParserTreeProperties* pIPTProps ) // @parm IN | Parser Properties { DBCOMMANDTREE* pct = 0; pct = PctBuiltInProperty( pwszColumnName, pIPSession, pIPTProps ); if ( 0 == pct ) { // this may be a user defined property, or is undefined DBTYPE dbType = 0; HRESULT hr = pIPSession->m_pCPropertyList->LookUpPropertyName( pwszColumnName, &pct, &dbType ); if ( E_OUTOFMEMORY == hr ) pIPTProps->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); else if ( FAILED(hr) ) { pIPTProps->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_COLUMN_NOT_DEFINED ); pIPTProps->SetErrorToken( pwszColumnName ); } else { AssertReq( 0 != pct ); pIPTProps->SetDBType( dbType ); } } return pct; } /* ************************************************************************************************ */ /* ************************************************************************************************ */ /* ************************************************************************************************ */ %} /*** *** Tokens (used also by flex via sql_tab.h) ***/ %left ',' %left '=' %left _OR %left _AND %left _NOT %left '+' '-' %left '*' '/' %left '(' ')' %nonassoc _UMINUS %left mHighest /*** *** reserved_words ***/ %token _ALL %token _ANY %token _ARRAY %token _AS %token _ASC %token _CAST %token _COERCE %token _CONTAINS %token _CONTENTS %token _CREATE %token _DEEP_TRAVERSAL %token _DESC %token _DOT %token _DOTDOT %token _DOTDOT_SCOPE %token _DOTDOTDOT %token _DOTDOTDOT_SCOPE %token _DROP %token _EXCLUDE_SEARCH_TRAVERSAL %token _FALSE %token _FREETEXT %token _FROM %token _IS %token _ISABOUT %token _IS_NOT %token _LIKE %token _MATCHES %token _NEAR %token _NOT_LIKE %token _NULL %token _OF %token _ORDER_BY %token _PASSTHROUGH %token _PROPERTYNAME %token _PROPID %token _RANKMETHOD %token _SELECT %token _SET %token _SCOPE %token _SHALLOW_TRAVERSAL %token _FORMSOF %token _SOME %token _TABLE %token _TRUE %token _TYPE %token _UNION %token _UNKNOWN %token _URL %token _VIEW %token _WHERE %token _WEIGHT /*** *** Two character comparison tokens ***/ %token _GE %token _LE %token _NE /*** *** Terminal tokens ***/ %token _CONST %token _ID %token _TEMPVIEW %token _INTNUM %token _REALNUM %token _SCALAR_FUNCTION_REF %token _STRING %token _DATE %token _PREFIX_STRING /*** *** Terminal tokens that don't actually make it out of the lexer ***/ %token _DELIMITED_ID // A delimited id is processed (quotes stripped) in ms-sql.l. // A regular id is converted to upper case in ms-sql.l // _ID is returned for either case. %start entry_point %% /*** *** SQL YACC grammar ***/ entry_point: definition_list { $$ = NULL; } | definition_list executable_statement { $$ = $2; } | executable_statement { $$ = $1; } ; executable_statement: ordered_query_specification semicolon { if ($2) { // There is a semicolon, either as a statement terminator or as // a statement separator. We don't allow either of those. m_pIPTProperties->SetErrorHResult(DB_E_MULTIPLESTATEMENTS, MONSQL_SEMI_COLON); YYABORT(DB_E_MULTIPLESTATEMENTS); } $$ = $1; } /* *************************************************** * | _PASSTHROUGH '(' _STRING ',' _STRING ',' _STRING ')' { CITextToFullTree(((PROPVARIANT*)$5->value.pvValue)->bstrVal, // pwszRestriction ((PROPVARIANT*)$3->value.pvValue)->bstrVal, // pwszColumns ((PROPVARIANT*)$7->value.pvValue)->bstrVal, // pwszSortColumns NULL, // pwszGroupings, not used yet. Must be NULL &$$, 0, NULL, m_pIPSession->GetLCID()); } /* *************************************************** */ ; semicolon: /* empty (correct) */ { $$ = NULL; } | ';' { $$ = PctAllocNode(DBVALUEKIND_NULL, DBOP_NULL); } ; definition_list: definition_list definition opt_semi { $$ = NULL; } | definition opt_semi { $$ = NULL; } ; definition: create_view_statement { $$ = NULL; } | drop_view_statement { $$ = NULL; } | set_statement { $$ = NULL; } ; opt_semi: /* empty */ | ';' ; typed_literal: _INTNUM { AssertReq($1); Assert(VT_UI8 == ((PROPVARIANT*)$1->value.pvValue)->vt || VT_I8 == ((PROPVARIANT*)$1->value.pvValue)->vt || VT_BSTR == ((PROPVARIANT*)$1->value.pvValue)->vt); m_pIPTProperties->AppendCiRestriction((YY_CHAR*)m_yylex.YYText(), wcslen(m_yylex.YYText())); HRESULT hr = CoerceScalar(m_pIPTProperties->GetDBType(), &$1); if (S_OK != hr) YYABORT(hr); $$ = $1; } | _REALNUM { AssertReq($1); Assert(VT_R8 == ((PROPVARIANT*)$1->value.pvValue)->vt || VT_BSTR == ((PROPVARIANT*)$1->value.pvValue)->vt); m_pIPTProperties->AppendCiRestriction((YY_CHAR*)m_yylex.YYText(), wcslen(m_yylex.YYText())); HRESULT hr = CoerceScalar(m_pIPTProperties->GetDBType(), &$1); if (S_OK != hr) YYABORT(hr); $$ = $1; } | _STRING { AssertReq($1); Assert(VT_BSTR == ((PROPVARIANT*)$1->value.pvValue)->vt); if (VT_DATE == m_pIPTProperties->GetDBType() || VT_FILETIME == m_pIPTProperties->GetDBType()) m_pIPTProperties->AppendCiRestriction(((PROPVARIANT*)$1->value.pvValue)->bstrVal, wcslen(((PROPVARIANT*)$1->value.pvValue)->bstrVal)); else { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"\"")); m_pIPTProperties->AppendCiRestriction(((PROPVARIANT*)$1->value.pvValue)->bstrVal, wcslen(((PROPVARIANT*)$1->value.pvValue)->bstrVal)); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"\"")); } HRESULT hr = CoerceScalar(m_pIPTProperties->GetDBType(), &$1); if (S_OK != hr) YYABORT(hr); $$ = $1; } | relative_date_time { AssertReq($1); Assert(VT_FILETIME == ((PROPVARIANT*)$1->value.pvValue)->vt); SYSTEMTIME stValue = {0, 0, 0, 0, 0, 0, 0, 0}; if (FileTimeToSystemTime(&(((PROPVARIANT*)$1->value.pvValue)->filetime), &stValue)) { WCHAR wchDateTime[50]; if (NULL == wchDateTime) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } int cItems = swprintf(wchDateTime, L" %4d/%02d/%02d %02d:%02d:%02d", stValue.wYear, stValue.wMonth, stValue.wDay, stValue.wHour, stValue.wMinute, stValue.wSecond); m_pIPTProperties->AppendCiRestriction(wchDateTime, wcslen(wchDateTime)); } HRESULT hr = CoerceScalar(m_pIPTProperties->GetDBType(), &$1); if (S_OK != hr) YYABORT(hr); $$ = $1; } | boolean_literal { m_pIPTProperties->AppendCiRestriction((YY_CHAR*)m_yylex.YYText(), wcslen(m_yylex.YYText())); HRESULT hr = CoerceScalar(m_pIPTProperties->GetDBType(), &$1); if (S_OK != hr) YYABORT(hr); $$ = $1; } ; unsigned_integer: _INTNUM { HRESULT hr = CoerceScalar(VT_UI4, &$1); if (S_OK != hr) YYABORT(hr); $$ = $1; } ; integer: _INTNUM { HRESULT hr = CoerceScalar(VT_I4, &$1); if (S_OK != hr) YYABORT(hr); $$ = $1; } ; relative_date_time: identifier '(' identifier ',' _INTNUM ',' relative_date_time ')' { // should be DateAdd(, , ) AssertReq($1); AssertReq($3); AssertReq($5); AssertReq($7); if (0 != _wcsicmp(L"DateAdd", $1->value.pwszValue)) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken($1->value.pwszValue); m_pIPTProperties->SetErrorToken(L"DateAdd"); YYABORT(DB_E_ERRORSINCOMMAND); } HRESULT hr = CoerceScalar(VT_I4, &$5); if (S_OK != hr) YYABORT(hr); if (((PROPVARIANT*)$5->value.pvValue)->iVal > 0) { WCHAR wchError[30]; m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); swprintf(wchError, L"%d", ((PROPVARIANT*)$5->value.pvValue)->iVal); m_pIPTProperties->SetErrorToken(wchError); swprintf(wchError, L"%d", -((PROPVARIANT*)$5->value.pvValue)->iVal); m_pIPTProperties->SetErrorToken(wchError); YYABORT(DB_E_ERRORSINCOMMAND); } LARGE_INTEGER hWeek = {686047232, 1408}; LARGE_INTEGER hDay = {711573504, 201}; LARGE_INTEGER hHour = {1640261632, 8}; LARGE_INTEGER hMinute = {600000000, 0}; LARGE_INTEGER hSecond = {10000000, 0}; LARGE_INTEGER hIncr = {0,0}; bool fHandleMonth = false; ULONG ulMonths = 1; switch ( $3->value.pwszValue[0] ) { case L'Y': case L'y': if (0 == (_wcsicmp(L"YY", $3->value.pwszValue) & _wcsicmp(L"YEAR", $3->value.pwszValue))) { // fall through and handle as 12 months ulMonths = 12; } case L'Q': case L'q': if (0 == (_wcsicmp(L"QQ", $3->value.pwszValue) & _wcsicmp(L"QUARTER", $3->value.pwszValue))) { // fall through and handle as 3 months ulMonths = 3; } case L'M': case L'm': if ( 0 == (_wcsicmp(L"YY", $3->value.pwszValue) & _wcsicmp(L"YEAR", $3->value.pwszValue)) || 0 == (_wcsicmp(L"QQ", $3->value.pwszValue) & _wcsicmp(L"QUARTER", $3->value.pwszValue)) || 0 == (_wcsicmp(L"MM", $3->value.pwszValue) & _wcsicmp(L"MONTH", $3->value.pwszValue))) { // // Convert to system time // SYSTEMTIME st = { 0, 0, 0, 0, 0, 0, 0, 0 }; FileTimeToSystemTime( &((PROPVARIANT*)$7->value.pvValue)->filetime, &st ); LONGLONG llDays = 0; LONG lMonthsLeft = ulMonths * -((PROPVARIANT*)$5->value.pvValue)->iVal; LONG yr = st.wYear; LONG lCurMonth = st.wMonth-1; while ( lMonthsLeft ) { LONG lMonthsDone = 1; while ( lMonthsDone<=lMonthsLeft ) { // Will we still be in the current year when looking at the prev month? if ( 0 == lCurMonth ) break; // Subtract the number of days in the previous month. We will adjust llDays += DaysInMonth( yr, lCurMonth-1); lMonthsDone++; lCurMonth--; } // Months left over in prev year lMonthsLeft -= lMonthsDone-1; if ( 0 != lMonthsLeft ) { yr--; lCurMonth = 12; // 11 is December. } } // // adjust current date to at most max of destination month // if ( llDays > 0 && st.wDay > DaysInMonth(yr, lCurMonth-1) ) llDays += st.wDay - DaysInMonth(yr, lCurMonth-1); hIncr.QuadPart = hDay.QuadPart * llDays; fHandleMonth = true; } else if (0 == (_wcsicmp(L"MI", $3->value.pwszValue) & _wcsicmp(L"MINUTE", $3->value.pwszValue))) hIncr = hMinute; break; case L'W': case L'w': if (0 == (_wcsicmp(L"WK", $3->value.pwszValue) & _wcsicmp(L"WEEK", $3->value.pwszValue))) hIncr = hWeek; break; case L'D': case L'd': if (0 == (_wcsicmp(L"DD", $3->value.pwszValue) & _wcsicmp(L"DAY", $3->value.pwszValue))) hIncr = hDay; break; case L'H': case L'h': if (0 == (_wcsicmp(L"HH", $3->value.pwszValue) & _wcsicmp(L"HOUR", $3->value.pwszValue))) hIncr = hHour; break; case L'S': case L's': if (0 == (_wcsicmp(L"SS", $3->value.pwszValue) & _wcsicmp(L"SECOND", $3->value.pwszValue))) hIncr = hSecond; break; default: break; } if (0 == hIncr.LowPart && 0 == hIncr.HighPart) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken($3->value.pwszValue); m_pIPTProperties->SetErrorToken( L"YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND"); YYABORT(DB_E_ERRORSINCOMMAND); } if ( fHandleMonth ) { ((PROPVARIANT*)$7->value.pvValue)->hVal.QuadPart -= hIncr.QuadPart; #ifdef DEBUG SYSTEMTIME st1 = { 0, 0, 0, 0, 0, 0, 0, 0 }; FileTimeToSystemTime( &((PROPVARIANT*)$7->value.pvValue)->filetime, &st1 ); #endif } else { for (int i = 0; i < -((PROPVARIANT*)$5->value.pvValue)->iVal; i++) ((PROPVARIANT*)$7->value.pvValue)->hVal.QuadPart -= hIncr.QuadPart; } $$ = $7; DeleteDBQT($1); DeleteDBQT($3); DeleteDBQT($5); } | identifier '(' ')' { // should be getgmdate() AssertReq($1); if (0 != _wcsicmp(L"GetGMTDate", $1->value.pwszValue)) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken($1->value.pwszValue); m_pIPTProperties->SetErrorToken(L"GetGMTDate"); YYABORT(DB_E_ERRORSINCOMMAND); } DeleteDBQT($1); $1 = 0; $$ = PctAllocNode(DBVALUEKIND_VARIANT, DBOP_scalar_constant); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } HRESULT hr = CoFileTimeNow(&(((PROPVARIANT*)$$->value.pvValue)->filetime)); ((PROPVARIANT*)$$->value.pvValue)->vt = VT_FILETIME; } ; boolean_literal: _TRUE { $$ = PctAllocNode(DBVALUEKIND_VARIANT, DBOP_scalar_constant); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } ((PROPVARIANT*)$$->value.pvValue)->vt = VT_BOOL; ((PROPVARIANT*)$$->value.pvValue)->boolVal = VARIANT_TRUE; } | _FALSE { $$ = PctAllocNode(DBVALUEKIND_VARIANT, DBOP_scalar_constant); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } ((PROPVARIANT*)$$->value.pvValue)->vt = VT_BOOL; ((PROPVARIANT*)$$->value.pvValue)->boolVal = VARIANT_FALSE; } ; identifier: _ID ; correlation_name: identifier ; /* 4.1 Query Specification */ ordered_query_specification: query_specification opt_order_by_clause { AssertReq($1); // need a query specification tree if (NULL != $2) // add optional ORDER BY nodes { // Is project list built correctly? AssertReq($1->pctFirstChild); AssertReq($1->pctFirstChild->pctNextSibling); AssertReq($1->pctFirstChild->pctNextSibling->pctFirstChild); Assert(($1->op == DBOP_project) && ($1->pctFirstChild->pctNextSibling->op == DBOP_project_list_anchor)); DBCOMMANDTREE* pctSortList = $2->pctFirstChild; AssertReq(pctSortList); while (pctSortList) { // Is sort list built correctly? Assert(pctSortList->op == DBOP_sort_list_element); AssertReq(pctSortList->pctFirstChild); Assert((pctSortList->pctFirstChild->op == DBOP_column_name) || (pctSortList->pctFirstChild->op == DBOP_scalar_constant)); if (pctSortList->pctFirstChild->op == DBOP_scalar_constant) { // we've got an ordinal rather than a column number, so we've got to // walk through the project list to find the corresponding column Assert(DBVALUEKIND_VARIANT == pctSortList->pctFirstChild->wKind); Assert(VT_I4 == pctSortList->pctFirstChild->value.pvarValue->vt); DBCOMMANDTREE* pctProjectList = $1->pctFirstChild->pctNextSibling->pctFirstChild; AssertReq(pctProjectList); LONG cProjectListElements = GetNumberOfSiblings(pctProjectList); if ((cProjectListElements < pctSortList->pctFirstChild->value.pvarValue->lVal) || (0 >= pctSortList->pctFirstChild->value.pvarValue->lVal)) { // ordinal is larger than number of elements in project list WCHAR wchError[30]; m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_ORDINAL_OUT_OF_RANGE); swprintf(wchError, L"%d", pctSortList->pctFirstChild->value.pvarValue->lVal); m_pIPTProperties->SetErrorToken(wchError); swprintf(wchError, L"%d", cProjectListElements); m_pIPTProperties->SetErrorToken(wchError); YYABORT(DB_E_ERRORSINCOMMAND); } else { LONG lColumnNumber = 1; while (pctProjectList && (lColumnNumber < pctSortList->pctFirstChild->value.pvarValue->lVal)) { // find the ulVal'th column in the project list Assert(pctProjectList->op == DBOP_project_list_element); pctProjectList = pctProjectList->pctNextSibling; lColumnNumber++; } DeleteDBQT(pctSortList->pctFirstChild); HRESULT hr = HrQeTreeCopy(&pctSortList->pctFirstChild, pctProjectList->pctFirstChild); if (FAILED(hr)) { m_pIPTProperties->SetErrorHResult(hr, MONSQL_OUT_OF_MEMORY); YYABORT(hr); } } } pctSortList = pctSortList->pctNextSibling; } m_pIPTProperties->SetSortDesc(QUERY_SORTASCEND); // reset "stick" sort direction $$ = PctCreateNode(DBOP_sort, $1, $2, NULL); } else { $$ = $1; } AssertReq($$); } ; query_specification: _SELECT opt_set_quantifier select_list from_clause opt_where_clause { AssertReq($3); // need a select list AssertReq($4); // need a from clause if (NULL != $4->pctNextSibling) { // the from clause is a from view if (DBOP_outall_name == $3->op) { DeleteDBQT( $3 ); $3 = $4; $4 = $3->pctNextSibling; $3->pctNextSibling = NULL; AssertReq( $3->pctFirstChild ); // first project list element DBCOMMANDTREE* pct = $3->pctFirstChild; while ( pct ) { // recheck the properties to get current definitions DeleteDBQT( pct->pctFirstChild ); pct->pctFirstChild = PctMkColNodeFromStr( pct->value.pwszValue, m_pIPSession, m_pIPTProperties ); if ( 0 == pct->pctFirstChild ) YYABORT( DB_E_ERRORSINCOMMAND ); pct = pct->pctNextSibling; } } else { $1 = $4; $4 = $1->pctNextSibling; $1->pctNextSibling = NULL; AssertReq($3); // project list anchor AssertReq($3->pctFirstChild); // first project list element DBCOMMANDTREE* pctNewPrjLst = $3->pctFirstChild; AssertReq($1); // project list anchor AssertReq($1->pctFirstChild); // first project list element DBCOMMANDTREE* pctViewPrjLst = NULL; // initialized within loop while (pctNewPrjLst) { pctViewPrjLst = $1->pctFirstChild; Assert( DBOP_project_list_element == pctNewPrjLst->op ); Assert( DBVALUEKIND_WSTR == pctNewPrjLst->wKind ); while ( pctViewPrjLst ) { Assert( DBOP_project_list_element == pctViewPrjLst->op ); Assert( DBVALUEKIND_WSTR == pctViewPrjLst->wKind ); if ( 0 == _wcsicmp(pctNewPrjLst->value.pwszValue, pctViewPrjLst->value.pwszValue) ) break; pctViewPrjLst = pctViewPrjLst->pctNextSibling; if ( !pctViewPrjLst ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_NOT_COLUMN_OF_VIEW ); m_pIPTProperties->SetErrorToken( pctNewPrjLst->value.pwszValue ); // UNDONE: Might want to include a view name on error message YYABORT( DB_E_ERRORSINCOMMAND ); } } pctNewPrjLst = pctNewPrjLst->pctNextSibling; } DeleteDBQT( $1 ); $1 = 0; } } else { // "standard" from clause if ( DBOP_outall_name == $3->op ) if ( DBDIALECT_MSSQLJAWS != m_pIPSession->GetSQLDialect() ) { // SELECT * only allowed in JAWS m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_SELECT_STAR ); YYABORT( DB_E_ERRORSINCOMMAND ); } else { $3 = PctCreateNode( DBOP_project_list_element, $3, NULL ); if ( NULL == $3 ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } $3 = PctCreateNode( DBOP_project_list_anchor, $3, NULL ); if ( NULL == $3 ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } } } if ( NULL != $5 ) { $1 = PctCreateNode( DBOP_select, $4, $5, NULL ); if ( NULL == $1 ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } } else $1 = $4; $$ = PctCreateNode( DBOP_project, $1, $3, NULL ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } } ; opt_set_quantifier: /* empty */ { $$ = NULL; } | _ALL { // ignore ALL keyword, its just noise $$ = NULL; } ; select_list: select_sublist { AssertReq($1); $1 = PctReverse($1); $$ = PctCreateNode(DBOP_project_list_anchor, $1, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } } | '*' { $$ = PctCreateNode(DBOP_outall_name, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } } ; select_sublist: select_sublist ',' derived_column { AssertReq($1); AssertReq($3); // // chain project list elements together // $$ = PctLink( $3, $1 ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } } | derived_column ; derived_column: identifier { AssertReq($1); $1->op = DBOP_project_list_element; $1->pctFirstChild = PctMkColNodeFromStr($1->value.pwszValue, m_pIPSession, m_pIPTProperties); if (NULL == $1->pctFirstChild) YYABORT(DB_E_ERRORSINCOMMAND); $$ = $1; } | correlation_name '.' identifier { AssertReq($1); AssertReq($3); DeleteDBQT($1); // UNDONE: Don't use the correlation name for now $1 = NULL; $3->op = DBOP_project_list_element; $3->pctFirstChild = PctMkColNodeFromStr($3->value.pwszValue, m_pIPSession, m_pIPTProperties); if (NULL == $3->pctFirstChild) YYABORT(DB_E_ERRORSINCOMMAND); $$ = $3; } | _CREATE { $$ = PctMkColNodeFromStr(L"CREATE", m_pIPSession, m_pIPTProperties); if (NULL == $$) YYABORT(DB_E_ERRORSINCOMMAND); $$ = PctCreateNode(DBOP_project_list_element, DBVALUEKIND_WSTR, $$, NULL); $$->value.pwszValue = CoTaskStrDup(L"CREATE"); } ; /* 4.3 FROM Clause */ from_clause: common_from_clause | from_view_clause ; common_from_clause: _FROM scope_specification opt_AS_clause { AssertReq( $2 ); $$ = $2; if ( NULL != $3 ) { $3->pctFirstChild = $$; $$ = $3; } } ; scope_specification: unqualified_scope_specification { AssertReq( $1 ); $$ = $1; } | qualified_scope_specification { AssertReq( $1 ); $$ = $1; } | union_all_scope_specification { AssertReq( $1 ); $$ = $1; } ; unqualified_scope_specification: _SCOPE '(' scope_definition ')' { // _SCOPE '(' scope_definition ')' AssertReq( $3 ); // // Set the machine and catalog to the defaults // ($3->value.pdbcntnttblValue)->pwszMachine = CoTaskStrDup( m_pIPSession->GetDefaultMachine() ); if ( NULL == ($3->value.pdbcntnttblValue)->pwszMachine ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($3->value.pdbcntnttblValue)->pwszCatalog = CoTaskStrDup( m_pIPSession->GetDefaultCatalog() ); if ( NULL == ($3->value.pdbcntnttblValue)->pwszCatalog ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } $$ = $3; } ; qualified_scope_specification: machine_name _DOTDOTDOT_SCOPE '(' scope_definition ')' { // machine_name _DOTDOTDOT_SCOPE '(' scope_definition ')' AssertReq( $1 ); AssertReq( $4 ); ($4->value.pdbcntnttblValue)->pwszMachine = CoTaskStrDup( $1->value.pwszValue ); if ( NULL == ($4->value.pdbcntnttblValue)->pwszMachine ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } SCODE sc = m_pIPSession->GetIPVerifyPtr()->VerifyCatalog( $1->value.pwszValue, m_pIPSession->GetDefaultCatalog() ); if ( S_OK != sc ) { m_pIPTProperties->SetErrorHResult( sc, MONSQL_INVALID_CATALOG ); m_pIPTProperties->SetErrorToken( m_pIPSession->GetDefaultCatalog() ); YYABORT( sc ); } ($4->value.pdbcntnttblValue)->pwszCatalog = CoTaskStrDup( m_pIPSession->GetDefaultCatalog() ); if ( NULL == ($4->value.pdbcntnttblValue)->pwszCatalog ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } DeleteDBQT( $1 ); $$ = $4; } | machine_name _DOT catalog_name _DOTDOT_SCOPE '(' scope_definition ')' { // machine_name _DOT catalog_name _DOTDOT_SCOPE '(' scope_definition ')' AssertReq( $1 ); AssertReq( $3 ); AssertReq( $6 ); ($6->value.pdbcntnttblValue)->pwszMachine = CoTaskStrDup( $1->value.pwszValue ); if ( NULL == ($6->value.pdbcntnttblValue)->pwszMachine ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } // // Verify catalog on machine specified // SCODE sc = m_pIPSession->GetIPVerifyPtr()->VerifyCatalog( $1->value.pwszValue, $3->value.pwszValue ); if ( S_OK != sc ) { m_pIPTProperties->SetErrorHResult( sc, MONSQL_INVALID_CATALOG ); m_pIPTProperties->SetErrorToken( $3->value.pwszValue ); YYABORT( sc ); } ($6->value.pdbcntnttblValue)->pwszCatalog = CoTaskStrDup( $3->value.pwszValue ); if ( NULL == ($6->value.pdbcntnttblValue)->pwszCatalog ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } DeleteDBQT( $1 ); DeleteDBQT( $3 ); $$ = $6; } | catalog_name _DOTDOT_SCOPE '(' scope_definition ')' { // catalog_name _DOTDOT_SCOPE '(' scope_definition ')' AssertReq( $1 ); AssertReq( $4 ); ($4->value.pdbcntnttblValue)->pwszMachine = CoTaskStrDup( m_pIPSession->GetDefaultMachine() ); if ( NULL == ($4->value.pdbcntnttblValue)->pwszMachine ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } // // See if catalog is valid on default machine // SCODE sc = m_pIPSession->GetIPVerifyPtr()->VerifyCatalog( m_pIPSession->GetDefaultMachine(), $1->value.pwszValue ); if ( S_OK != sc ) { m_pIPTProperties->SetErrorHResult( sc, MONSQL_INVALID_CATALOG ); m_pIPTProperties->SetErrorToken( $1->value.pwszValue ); YYABORT( sc ); } ($4->value.pdbcntnttblValue)->pwszCatalog = CoTaskStrDup( $1->value.pwszValue ); if ( NULL == ($4->value.pdbcntnttblValue)->pwszCatalog ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } DeleteDBQT( $1 ); $$ = $4; } ; machine_name: identifier { AssertReq( $1 ); $$ = $1; } ; catalog_name: identifier { AssertReq( $1 ); // // Defer validation of the catalog to the point where we // know the machine name. Return whatever was parsed here. // $$ = $1; } ; scope_definition: /* empty */ { // empty rule for scope_definition // // Create a DBOP_content_table node with default scope settings // $$ = PctAllocNode( DBVALUEKIND_CONTENTTABLE, DBOP_content_table ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } } | scope_element_list { // scope_element_list AssertReq($1); $1 = PctReverse( $1 ); $$ = PctCreateNode( DBOP_scope_list_anchor, $1, NULL ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } $$ = PctCreateNode( DBOP_content_table, DBVALUEKIND_CONTENTTABLE, $$, NULL ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } } ; scope_element_list: scope_element_list ',' scope_element { AssertReq( $1 ); AssertReq( $3); // // chain scope list elements together // $$ = PctLink( $3, $1 ); } | scope_element { AssertReq( $1 ); $$ = $1; } ; scope_element: '\'' opt_traversal_exclusivity path_or_virtual_root_list '\'' { AssertReq( $2 ); AssertReq( $3 ); $3 = PctReverse( $3 ); SetDepthAndInclusion( $2, $3 ); DeleteDBQT( $2 ); $$ = $3; } | '\'' opt_traversal_exclusivity '(' path_or_virtual_root_list ')' '\'' { AssertReq( $2 ); AssertReq( $4 ); $4 = PctReverse( $4 ); SetDepthAndInclusion( $2, $4 ); DeleteDBQT( $2 ); $$ = $4; } ; opt_traversal_exclusivity: /* empty */ { $$ = PctAllocNode( DBVALUEKIND_CONTENTSCOPE, DBOP_scope_list_element ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } $$->value.pdbcntntscpValue->dwFlags |= SCOPE_FLAG_DEEP; $$->value.pdbcntntscpValue->dwFlags |= SCOPE_FLAG_INCLUDE; } | _DEEP_TRAVERSAL _OF { $$ = PctAllocNode( DBVALUEKIND_CONTENTSCOPE, DBOP_scope_list_element ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } $$->value.pdbcntntscpValue->dwFlags |= SCOPE_FLAG_DEEP; $$->value.pdbcntntscpValue->dwFlags |= SCOPE_FLAG_INCLUDE; } | _SHALLOW_TRAVERSAL _OF { $$ = PctAllocNode( DBVALUEKIND_CONTENTSCOPE, DBOP_scope_list_element ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } $$->value.pdbcntntscpValue->dwFlags &= ~(SCOPE_FLAG_DEEP); $$->value.pdbcntntscpValue->dwFlags |= SCOPE_FLAG_INCLUDE; } /* ************* UNDONE ******************** | _EXCLUDE_SEARCH_TRAVERSAL _OF { // m_pIPTProperties->GetScopeDataPtr()->SetTemporaryDepth(QUERY_EXCLUDE); $$ = PctCreateNode( DBOP_scope_list_element, NULL ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } $$->value.pdbcntntscpValue->dwFlags &= ~(SCOPE_FLAG_DEEP); $$->value.pdbcntntscpValue->dwFlags &= ~(SCOPE_FLAG_INCLUDE); } ************* UNDONE ******************** */ ; path_or_virtual_root_list: path_or_virtual_root_list ',' path_or_virtual_root { AssertReq( $1 ); AssertReq( $3 ); // // chain path/vpath nodes together // $$ = PctLink( $3, $1 ); } | path_or_virtual_root { AssertReq( $1 ); $$ = $1; } ; path_or_virtual_root: _URL { AssertReq( $1 ); $$ = PctAllocNode( DBVALUEKIND_CONTENTSCOPE, DBOP_scope_list_element ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } $$->value.pdbcntntscpValue->pwszElementValue = CoTaskStrDup( ($1->value.pvarValue)->bstrVal ); if ( NULL == $$->value.pdbcntntscpValue->pwszElementValue ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } if ( NULL != wcschr(((PROPVARIANT*)$1->value.pvValue)->bstrVal, L'/')) $$->value.pdbcntntscpValue->dwFlags |= SCOPE_TYPE_VPATH; else $$->value.pdbcntntscpValue->dwFlags |= SCOPE_TYPE_WINPATH; // // Path names need backlashes not forward slashes // for (WCHAR *wcsLetter = $$->value.pdbcntntscpValue->pwszElementValue; *wcsLetter != L'\0'; wcsLetter++) if (L'/' == *wcsLetter) *wcsLetter = L'\\'; DeleteDBQT( $1 ); } ; opt_AS_clause: /* empty */ { $$ = NULL; } | _AS correlation_name { AssertReq($2); // $2->op = DBOP_alias; // retag _ID node to be table alias // $$ = $2; // UNDONE: This doesn't work with Index Server DeleteDBQT($2); $2 = NULL; $$ = NULL; } ; /* 4,3,4 View Name */ from_view_clause: _FROM view_name { // _FROM view_name AssertReq( $2 ); // node telling where the view is defined Assert( DBOP_content_table == $2->op ); // name of the view AssertReq( $2->pctNextSibling ); $$ = m_pIPSession->GetLocalViewList()->GetViewDefinition( m_pIPTProperties, $2->pctNextSibling->value.pwszValue, ($2->value.pdbcntnttblValue)->pwszCatalog ); if ( 0 == $$ ) $$ = m_pIPSession->GetGlobalViewList()->GetViewDefinition( m_pIPTProperties, $2->pctNextSibling->value.pwszValue, ($2->value.pdbcntnttblValue)->pwszCatalog ); if ( 0 == $$ ) { // If this isn't JAWS, this is an undefined view if (DBDIALECT_MSSQLJAWS != m_pIPSession->GetSQLDialect()) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_VIEW_NOT_DEFINED ); m_pIPTProperties->SetErrorToken( $2->pctNextSibling->value.pwszValue ); m_pIPTProperties->SetErrorToken( ($2->value.pdbcntnttblValue)->pwszCatalog ); YYABORT( DB_E_ERRORSINCOMMAND ); } // setting the default scope for JAWS CScopeData* pScopeData = m_pIPTProperties->GetScopeDataPtr(); pScopeData->SetTemporaryDepth(QUERY_DEEP); pScopeData->MaskTemporaryDepth(QUERY_VIRTUAL_PATH); pScopeData->SetTemporaryScope(VAL_AND_CCH_MINUS_NULL(L"/")); pScopeData->SetTemporaryCatalog($2->value.pwszValue, wcslen($2->value.pwszValue)); pScopeData->IncrementScopeCount(); $$ = $2->pctNextSibling; $2->pctNextSibling = NULL; DeleteDBQT($2); } else // actually a view name { // If we didn't store scope information (global views), set up the scope now if ( 0 == $$->pctNextSibling ) { // name of the view DeleteDBQT( $2->pctNextSibling ); $2->pctNextSibling = 0; $$->pctNextSibling = $2; } else { AssertReq( DBOP_content_table == $$->pctNextSibling->op ); DeleteDBQT( $2 ); // throw away the view name } } } ; view_name: _TEMPVIEW { // _TEMPVIEW AssertReq( $1 ); $$ = PctAllocNode( DBVALUEKIND_CONTENTTABLE, DBOP_content_table ); if ( 0 == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszMachine = CoTaskStrDup( m_pIPSession->GetDefaultMachine() ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszMachine ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszCatalog = CoTaskStrDup( m_pIPSession->GetDefaultCatalog() ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszCatalog ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } $$->pctNextSibling = $1; } | identifier { // identifier AssertReq( $1 ); $$ = PctAllocNode( DBVALUEKIND_CONTENTTABLE, DBOP_content_table ); if ( 0 == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszMachine = CoTaskStrDup( m_pIPSession->GetDefaultMachine() ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszMachine ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszCatalog = CoTaskStrDup( m_pIPSession->GetDefaultCatalog() ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszCatalog ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } $$->pctNextSibling = $1; } | catalog_name _DOTDOT _TEMPVIEW { // catalog_name _DOTDOT _TEMPVIEW AssertReq($1); AssertReq($3); $$ = PctAllocNode( DBVALUEKIND_CONTENTTABLE, DBOP_content_table ); if ( 0 == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszMachine = CoTaskStrDup( m_pIPSession->GetDefaultMachine() ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszMachine ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszCatalog = CoTaskStrDup( $1->value.pwszValue ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszCatalog ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } DeleteDBQT( $1 ); $$->pctNextSibling = $3; } | catalog_name _DOTDOT identifier { // catalog_name _DOTDOT identifier AssertReq($1); AssertReq($3); $$ = PctAllocNode( DBVALUEKIND_CONTENTTABLE, DBOP_content_table ); if ( 0 == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszMachine = CoTaskStrDup( m_pIPSession->GetDefaultMachine() ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszMachine ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszCatalog = CoTaskStrDup( $1->value.pwszValue ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszCatalog ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } DeleteDBQT( $1 ); $$->pctNextSibling = $3; } | machine_name _DOT catalog_name _DOTDOT _TEMPVIEW { // machine_name _DOT catalog_name _DOTDOT _TEMPVIEW AssertReq( $1 ); AssertReq( $3 ); AssertReq( $5 ); $$ = PctAllocNode( DBVALUEKIND_CONTENTTABLE, DBOP_content_table ); if ( 0 == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszMachine = CoTaskStrDup( $1->value.pwszValue ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszMachine ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszCatalog = CoTaskStrDup( $3->value.pwszValue ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszCatalog ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } DeleteDBQT( $1 ); DeleteDBQT( $3 ); $$->pctNextSibling = $5; } | machine_name _DOT catalog_name _DOTDOT identifier { // machine_name _DOT catalog_name _DOTDOT identifier AssertReq( $1 ); AssertReq( $3 ); AssertReq( $5 ); $$ = PctAllocNode( DBVALUEKIND_CONTENTTABLE, DBOP_content_table ); if ( 0 == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszMachine = CoTaskStrDup( $1->value.pwszValue ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszMachine ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszCatalog = CoTaskStrDup( $3->value.pwszValue ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszCatalog ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } DeleteDBQT( $1 ); DeleteDBQT( $3 ); $$->pctNextSibling = $5; } | machine_name _DOTDOTDOT identifier { // machine_name _DOTDOTDOT identifier AssertReq( $1 ); AssertReq( $3 ); $$ = PctAllocNode( DBVALUEKIND_CONTENTTABLE, DBOP_content_table ); if ( 0 == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszMachine = CoTaskStrDup( $1->value.pwszValue ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszMachine ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszCatalog = CoTaskStrDup( m_pIPSession->GetDefaultCatalog() ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszCatalog ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } DeleteDBQT( $1 ); $$->pctNextSibling = $3; } | machine_name _DOTDOTDOT _TEMPVIEW { // machine_name _DOTDOTDOT _TEMPVIEW AssertReq( $1 ); AssertReq( $3 ); $$ = PctAllocNode( DBVALUEKIND_CONTENTTABLE, DBOP_content_table ); if ( 0 == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszMachine = CoTaskStrDup( $1->value.pwszValue ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszMachine ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } ($$->value.pdbcntnttblValue)->pwszCatalog = CoTaskStrDup( m_pIPSession->GetDefaultCatalog() ); if ( 0 == ($$->value.pdbcntnttblValue)->pwszCatalog ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } DeleteDBQT( $1 ); $$->pctNextSibling = $3; } ; /* 4.3.6 Olympus FROM Clause */ union_all_scope_specification: '(' union_all_scope_element ')' { $$ = $2; } ; union_all_scope_element: union_all_scope_element _UNION _ALL explicit_table { AssertReq( $1 ); AssertReq( $4 ); $$ = PctCreateNode( DBOP_set_union, $1, $4, NULL ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } } | explicit_table _UNION _ALL explicit_table { AssertReq( $1 ); AssertReq( $4 ); $$ = PctCreateNode( DBOP_set_union, $1, $4, NULL ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } } ; explicit_table: _TABLE qualified_scope_specification { AssertReq( $2 ); $$ = $2; } ; /* 4.4 WHERE Clause */ opt_where_clause: /* empty */ { $$ = NULL; } | where_clause ; where_clause: _WHERE search_condition { AssertReq($2); $$ = $2; } | _WHERE _PASSTHROUGH '(' _STRING ')' { AssertReq($4); if (wcslen(((PROPVARIANT*)$4->value.pvValue)->bstrVal)) m_pIPTProperties->AppendCiRestriction(((PROPVARIANT*)$4->value.pvValue)->bstrVal, wcslen(((PROPVARIANT*)$4->value.pvValue)->bstrVal)); UINT cSize = 0; CIPROPERTYDEF* pPropTable = m_pIPSession->m_pCPropertyList->GetPropertyTable(&cSize); if (!pPropTable) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } if (FAILED(CITextToSelectTreeEx(((PROPVARIANT*)$4->value.pvValue)->bstrVal, ISQLANG_V2, &yyval, cSize, pPropTable, m_pIPSession->GetLCID()))) { m_pIPSession->m_pCPropertyList->DeletePropertyTable(pPropTable, cSize); m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_CITEXTTOSELECTTREE_FAILED); m_pIPTProperties->SetErrorToken(((PROPVARIANT*)$4->value.pvValue)->bstrVal); YYABORT(DB_E_ERRORSINCOMMAND); } DeleteDBQT($4); $4 = NULL; m_pIPSession->m_pCPropertyList->DeletePropertyTable(pPropTable, cSize); } ; predicate: comparison_predicate | contains_predicate | freetext_predicate | like_predicate | matches_predicate | vector_comparison_predicate | null_predicate ; /* 4.4.3 Comparison Predicate */ comparison_predicate: column_reference_or_cast comp_op typed_literal { AssertReq($1); AssertReq($2); if (m_pIPTProperties->GetDBType() & DBTYPE_VECTOR) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken(L""); m_pIPTProperties->SetErrorToken(L"ARRAY"); YYABORT(DB_E_ERRORSINCOMMAND); } $1->pctNextSibling = $3; $2->pctFirstChild = $1; $$ = $2; } ; column_reference_or_cast: column_reference { AssertReq($1); m_pIPTProperties->UseCiColumn(L'@'); $$ = $1; } | _CAST '(' column_reference _AS dbtype ')' { AssertReq($3); AssertReq($5); if (DBDIALECT_MSSQLJAWS != m_pIPSession->GetSQLDialect()) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken(L"CAST"); m_pIPTProperties->SetErrorToken(L"column_reference"); YYABORT(DB_E_ERRORSINCOMMAND); } m_pIPTProperties->UseCiColumn(L'@'); m_pIPTProperties->SetDBType($5->value.usValue); DeleteDBQT($5); $$ = $3; } ; column_reference: identifier { AssertReq($1); $$ = PctMkColNodeFromStr($1->value.pwszValue, m_pIPSession, m_pIPTProperties); if (NULL == $$) YYABORT(DB_E_ERRORSINCOMMAND); m_pIPTProperties->SetCiColumn($1->value.pwszValue); DeleteDBQT($1); $1 = NULL; } | correlation_name '.' identifier { AssertReq($1); AssertReq($3); $$ = PctMkColNodeFromStr($3->value.pwszValue, m_pIPSession, m_pIPTProperties); if (NULL == $$) YYABORT(DB_E_ERRORSINCOMMAND); m_pIPTProperties->SetCiColumn($3->value.pwszValue); DeleteDBQT($3); $3 = NULL; DeleteDBQT($1); // UNDONE: Don't use the correlation name for now $1 = NULL; } | _CREATE { m_pIPTProperties->SetCiColumn(L"CREATE"); $$ = PctMkColNodeFromStr(L"CREATE", m_pIPSession, m_pIPTProperties); if (NULL == $$) YYABORT(DB_E_ERRORSINCOMMAND); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"CREATE ")); } ; comp_op: '=' { $$ = PctCreateRelationalNode(DBOP_equal, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"=")); } | _NE { $$ = PctCreateRelationalNode(DBOP_not_equal, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"!=")); } | '<' { $$ = PctCreateRelationalNode(DBOP_less, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"<")); } | '>' { $$ = PctCreateRelationalNode(DBOP_greater, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L">")); } | _LE { $$ = PctCreateRelationalNode(DBOP_less_equal, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"<=")); } | _GE { $$ = PctCreateRelationalNode(DBOP_greater_equal, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L">=")); } ; /* 4.4.4 Contains Predicate */ contains_predicate: _CONTAINS '(' opt_contents_column_reference '\'' content_search_condition '\'' ')' opt_greater_than_zero { AssertReq(!$3); // should have been NULLed out in opt_contents_column_reference AssertReq($5); $$ = $5; DeleteDBQT(m_pIPTProperties->GetContainsColumn()); m_pIPTProperties->SetContainsColumn(NULL); } ; opt_contents_column_reference: /* empty */ { // opt_contents_column_reference empty rule $$ = PctMkColNodeFromStr(L"CONTENTS", m_pIPSession, m_pIPTProperties); if (NULL == $$) YYABORT(DB_E_ERRORSINCOMMAND); m_pIPTProperties->SetCiColumn(L"CONTENTS"); m_pIPTProperties->SetContainsColumn($$); $$ = NULL; } | column_reference ',' { // column_reference ',' m_pIPTProperties->SetContainsColumn($1); $$ = NULL; } ; content_search_condition: /* empty */ { // This forces a left parentheses before the content search condition // The matching right paren will be added below. m_pIPTProperties->CiNeedLeftParen(); $$ = NULL; } content_search_cond { AssertReq($2); $$ = $2; m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L")")); } ; content_search_cond: content_boolean_term | content_search_cond or_operator content_boolean_term { if (DBOP_not == $3->op) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OR_NOT); YYABORT(DB_E_ERRORSINCOMMAND); } $$ = PctCreateBooleanNode(DBOP_or, DEFAULTWEIGHT, $1, $3); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } } ; content_boolean_term: content_boolean_factor | content_boolean_term and_operator content_boolean_factor { $$ = PctCreateBooleanNode(DBOP_and, DEFAULTWEIGHT, $1, $3); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } } ; content_boolean_factor: content_boolean_primary | not_operator content_boolean_primary { $$ = PctCreateNotNode(DEFAULTWEIGHT, $2); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } } ; content_boolean_primary: content_search_term | '(' { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"(")); } content_search_cond ')' { AssertReq($3); $$ = $3; m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L")")); } ; content_search_term: simple_term | prefix_term | proximity_term | stemming_term | isabout_term ; or_operator: _OR { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" | ")); } | '|' { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" | ")); } ; and_operator: _AND { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" & ")); } | '&' { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" & ")); } ; not_operator: _NOT { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" ! ")); } | '!' { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" ! ")); } ; simple_term: _STRING { AssertReq($1); HRESULT hr = HrQeTreeCopy(&$$, m_pIPTProperties->GetContainsColumn()); if (FAILED(hr)) { m_pIPTProperties->SetErrorHResult(hr, MONSQL_OUT_OF_MEMORY); YYABORT(hr); } m_pIPTProperties->UseCiColumn(L'@'); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"\"")); m_pIPTProperties->AppendCiRestriction(((PROPVARIANT*)$1->value.pvValue)->bstrVal, wcslen(((PROPVARIANT*)$1->value.pvValue)->bstrVal)); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"\"")); $$ = PctCreateContentNode(((PROPVARIANT*)$1->value.pvValue)->bstrVal, GENERATE_METHOD_EXACT, DEFAULTWEIGHT, m_pIPSession->GetLCID(), $$); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } DeleteDBQT($1); $1 = NULL; } ; prefix_term: _PREFIX_STRING { AssertReq($1); Assert(((PROPVARIANT*)$1->value.pvValue)->bstrVal[wcslen( ((PROPVARIANT*)$1->value.pvValue)->bstrVal)-1] == L'*'); m_pIPTProperties->UseCiColumn(L'@'); m_pIPTProperties->AppendCiRestriction(((PROPVARIANT*)$1->value.pvValue)->bstrVal, wcslen(((PROPVARIANT*)$1->value.pvValue)->bstrVal)); ((PROPVARIANT*)$1->value.pvValue)->bstrVal[wcslen( ((PROPVARIANT*)$1->value.pvValue)->bstrVal)-1] = L'\0'; HRESULT hr = HrQeTreeCopy(&$$, m_pIPTProperties->GetContainsColumn()); if (FAILED(hr)) { m_pIPTProperties->SetErrorHResult(hr, MONSQL_OUT_OF_MEMORY); YYABORT(hr); } $$ = PctCreateContentNode(((PROPVARIANT*)$1->value.pvValue)->bstrVal, GENERATE_METHOD_PREFIX, DEFAULTWEIGHT, m_pIPSession->GetLCID(), $$); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } DeleteDBQT($1); $1 = NULL; } proximity_term: proximity_operand proximity_expression_list { AssertReq($1); AssertReq($2); $2 = PctReverse($2); $$ = PctCreateNode(DBOP_content_proximity, DBVALUEKIND_CONTENTPROXIMITY, $1, $2, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } $$->value.pdbcntntproxValue->dwProximityUnit = PROXIMITY_UNIT_WORD; $$->value.pdbcntntproxValue->ulProximityDistance = 50; $$->value.pdbcntntproxValue->lWeight = DEFAULTWEIGHT; } ; proximity_expression_list: proximity_expression_list proximity_expression { AssertReq($1); AssertReq($2); $$ = PctLink($2, $1); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } } | proximity_expression ; proximity_expression: proximity_specification proximity_operand { AssertReq($2); $$ = $2; // UNDONE: What is proximity_specification good for? } ; proximity_operand: simple_term | prefix_term ; proximity_specification: _NEAR { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" ~ ")); } | _NEAR '(' ')' { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" ~ ")); } /* ************* Not for BETA3 ******************** | _NEAR '(' distance_type ',' distance_value ')' { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"~")); } ************* Not for BETA3 ********************/ | '~' { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" ~ ")); } ; /* ************* Not for BETA2 ******************** distance_type: identifier { This should be WORD, SENTENCE, or PARAGRAPH if (0==_wcsicmp($1->value.pwszValue, L"Jaccard")) ... } ; distance_value: _INTNUM NOTE: Lexer doesn't allower INTNUM in this context so you'll have to convert a string to an integer ; ************* Not for BETA2 ********************/ stemming_term: _FORMSOF '(' stem_type ',' stemmed_simple_term_list ')' { AssertReq($5); // UNDONE: Should make use of $3 somewhere in here $$ = $5; } ; stem_type: _STRING { if (0 == _wcsicmp(((PROPVARIANT*)$1->value.pvValue)->bstrVal, L"INFLECTIONAL")) { DeleteDBQT($1); $1 = NULL; $$ = NULL; } /* *************************************NOT IMPLEMENTED BY INDEX SERVER ************************************** else if (0 == _wcsicmp(((PROPVARIANT*)$1->value.pvValue)->bstrVal, L"DERIVATIONAL")) { m_pIPTProperties->SetErrorHResult(E_NOTIMPL, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken(L"DERIVATIONAL"); YYABORT(E_NOTIMPL); } else if (0 == _wcsicmp(((PROPVARIANT*)$1->value.pvValue)->bstrVal, L"SOUNDEX")) { m_pIPTProperties->SetErrorHResult(E_NOTIMPL, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken(L"DERIVATIONAL"); YYABORT(E_NOTIMPL); } else if (0 == _wcsicmp(((PROPVARIANT*)$1->value.pvValue)->bstrVal, L"THESAURUS")) { m_pIPTProperties->SetErrorHResult(E_NOTIMPL, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken(L"THESAURUS"); YYABORT(E_NOTIMPL); } *************************************NOT IMPLEMENTED BY INDEX SERVER ************************************** */ else { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken(((PROPVARIANT*)$1->value.pvValue)->bstrVal); m_pIPTProperties->SetErrorToken(L"INFLECTIONAL"); YYABORT(E_NOTIMPL); } } ; stemmed_simple_term_list: stemmed_simple_term_list ',' simple_term { AssertReq($1); AssertReq($3); Assert(DBOP_content == $3->op); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"**")); $3->value.pdbcntntValue->dwGenerateMethod = GENERATE_METHOD_INFLECT; $$ = PctCreateBooleanNode(DBOP_or, DEFAULTWEIGHT, $1, $3); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } } | simple_term { AssertReq($1); Assert(DBOP_content == $1->op); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"**")); $1->value.pdbcntntValue->dwGenerateMethod = GENERATE_METHOD_INFLECT; $$ = $1; } ; isabout_term: _ISABOUT '(' vector_component_list ')' { AssertReq($3); $3 = PctReverse($3); $$ = PctCreateNode(DBOP_content_vector_or, DBVALUEKIND_CONTENTVECTOR, $3, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } $$->value.pdbcntntvcValue->dwRankingMethod = m_pIPSession->GetRankingMethod(); $$->value.pdbcntntvcValue->lWeight = DEFAULTWEIGHT; } /* *************************************NOT IMPLEMENTED BY INDEX SERVER ************************************** | _COERCE '(' vector_term ')' { m_pIPTProperties->SetErrorHResult(E_NOTIMPL, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken(L"COERCE"); YYABORT(E_NOTIMPL); } *************************************NOT IMPLEMENTED BY INDEX SERVER ************************************** */ ; vector_component_list: vector_component_list ',' vector_component { AssertReq($1); AssertReq($3); Assert((DBOP_content == $3->op) || (DBOP_or == $3->op) || (DBOP_content_proximity == $3->op)); $$ = PctLink($3, $1); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } } | vector_component { AssertReq($1); Assert((DBOP_content == $1->op) || (DBOP_or == $1->op) || (DBOP_content_proximity == $1->op)); $$ = $1; } ; vector_component: vector_term _WEIGHT '(' weight_value ')' { AssertReq($1); AssertReq($4); if (($4->value.pvarValue->dblVal < 0.0) || ($4->value.pvarValue->dblVal > 1.0)) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_WEIGHT_OUT_OF_RANGE); WCHAR wchErr[30]; swprintf(wchErr, L"%f", $4->value.pvarValue->dblVal); m_pIPTProperties->SetErrorToken(wchErr); YYABORT(DB_E_ERRORSINCOMMAND); } $$ = $1; SetLWeight($$, (LONG) ($4->value.pvarValue->dblVal * DEFAULTWEIGHT)); WCHAR wchWeight[10]; if (swprintf(wchWeight, L"%d", (LONG) ($4->value.pvarValue->dblVal * DEFAULTWEIGHT))) { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"[")); m_pIPTProperties->AppendCiRestriction(wchWeight, wcslen(wchWeight)); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"] ")); } DeleteDBQT($4); $4 = NULL; } | vector_term { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" ")); $$ = $1; } ; vector_term: simple_term | prefix_term | proximity_term | stemming_term ; weight_value: _STRING { HRESULT hr = CoerceScalar(VT_R8, &$1); if (S_OK != hr) YYABORT(hr); $$ = $1; } ; opt_greater_than_zero: /* empty */ { $$ = NULL; } | '>' _INTNUM { HRESULT hr = CoerceScalar(VT_I4, &$2); if (S_OK != hr) YYABORT(hr); if (0 != $2->value.pvarValue->lVal) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); WCHAR wchErr[30]; swprintf(wchErr, L"%d", $2->value.pvarValue->lVal); m_pIPTProperties->SetErrorToken(wchErr); m_pIPTProperties->SetErrorToken(L"0"); YYABORT(DB_E_ERRORSINCOMMAND); } DeleteDBQT($2); $2 = NULL; $$ = NULL; } ; /* 4.4.5 Free-Text Predicate */ freetext_predicate: _FREETEXT '(' opt_contents_column_reference _STRING ')' opt_greater_than_zero { AssertReq(!$3); AssertReq($4); HRESULT hr = HrQeTreeCopy(&$$, m_pIPTProperties->GetContainsColumn()); if (FAILED(hr)) { m_pIPTProperties->SetErrorHResult(hr, MONSQL_OUT_OF_MEMORY); YYABORT(hr); } m_pIPTProperties->UseCiColumn(L'$'); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"\"")); m_pIPTProperties->AppendCiRestriction(((PROPVARIANT*)$4->value.pvValue)->bstrVal, wcslen(((PROPVARIANT*)$4->value.pvValue)->bstrVal)); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"\"")); $$ = PctCreateNode(DBOP_content_freetext, DBVALUEKIND_CONTENT, $$, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } $$->value.pdbcntntValue->pwszPhrase = CoTaskStrDup(((PROPVARIANT*)$4->value.pvValue)->bstrVal); $$->value.pdbcntntValue->dwGenerateMethod = GENERATE_METHOD_EXACT; $$->value.pdbcntntValue->lWeight = DEFAULTWEIGHT; $$->value.pdbcntntValue->lcid = m_pIPSession->GetLCID(); DeleteDBQT(m_pIPTProperties->GetContainsColumn()); m_pIPTProperties->SetContainsColumn(NULL); DeleteDBQT($4); $4 = NULL; } ; /* 4.4.6 Like Predicate */ like_predicate: column_reference _LIKE wildcard_search_pattern { AssertReq($1); AssertReq($3); m_pIPTProperties->UseCiColumn(L'#'); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"\"")); m_pIPTProperties->AppendCiRestriction(((PROPVARIANT*)$3->value.pvValue)->pwszVal, wcslen(((PROPVARIANT*)$3->value.pvValue)->pwszVal)); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"\"")); $$ = PctCreateNode(DBOP_like, DBVALUEKIND_LIKE, $1, $3, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } $$->value.pdblikeValue->guidDialect = DBGUID_LIKE_OFS; $$->value.pdblikeValue->lWeight = DEFAULTWEIGHT; } | column_reference _NOT_LIKE wildcard_search_pattern { AssertReq($1); AssertReq($3); m_pIPTProperties->UseCiColumn(L'#'); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"\"")); m_pIPTProperties->AppendCiRestriction(((PROPVARIANT*)$3->value.pvValue)->pwszVal, wcslen(((PROPVARIANT*)$3->value.pvValue)->pwszVal)); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"\"")); $2 = PctCreateNode(DBOP_like, DBVALUEKIND_LIKE, $1, $3, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } $2->value.pdblikeValue->guidDialect = DBGUID_LIKE_OFS; $2->value.pdblikeValue->lWeight = DEFAULTWEIGHT; $$ = PctCreateNotNode(DEFAULTWEIGHT, $2); } ; wildcard_search_pattern: _STRING { UINT cLen = wcslen(((PROPVARIANT*)$1->value.pvValue)->bstrVal); BSTR bstrCopy = SysAllocStringLen(NULL, 4 * cLen); if ( 0 == bstrCopy ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } UINT j = 0; for (UINT i = 0; i <= cLen; i++) { switch ( ((PROPVARIANT*)$1->value.pvValue)->bstrVal[i] ) { case L'%': bstrCopy[j++] = L'*'; break; case L'_': bstrCopy[j++] = L'?'; break; case L'|': bstrCopy[j++] = L'|'; bstrCopy[j++] = L'|'; break; case L'*': bstrCopy[j++] = L'|'; bstrCopy[j++] = L'['; bstrCopy[j++] = L'*'; bstrCopy[j++] = L']'; break; case L'?': bstrCopy[j++] = L'|'; bstrCopy[j++] = L'['; bstrCopy[j++] = L'?'; bstrCopy[j++] = L']'; break; case L'[': // UNDONE: Make sure we're not going out of range with these tests if ((L'%' == ((PROPVARIANT*)$1->value.pvValue)->bstrVal[i+1]) && (L']' == ((PROPVARIANT*)$1->value.pvValue)->bstrVal[i+2])) { bstrCopy[j++] = L'%'; i = i + 2; } else if ((L'_' == ((PROPVARIANT*)$1->value.pvValue)->bstrVal[i+1]) && (L']' == ((PROPVARIANT*)$1->value.pvValue)->bstrVal[i+2])) { bstrCopy[j++] = L'_'; i = i + 2; } else if ((L'[' == ((PROPVARIANT*)$1->value.pvValue)->bstrVal[i+1]) && (L']' == ((PROPVARIANT*)$1->value.pvValue)->bstrVal[i+2])) { bstrCopy[j++] = L'['; i = i + 2; } else if ((L'^' == ((PROPVARIANT*)$1->value.pvValue)->bstrVal[i+1]) && (L']' == ((PROPVARIANT*)$1->value.pvValue)->bstrVal[i+2]) && (wcschr((WCHAR*)&(((PROPVARIANT*)$1->value.pvValue)->bstrVal[i+3]), L']'))) { bstrCopy[j++] = L'|'; bstrCopy[j++] = L'['; bstrCopy[j++] = L'^'; bstrCopy[j++] = L']'; i = i + 2; } else { bstrCopy[j++] = L'|'; bstrCopy[j++] = ((PROPVARIANT*)$1->value.pvValue)->bstrVal[i++]; while ((((PROPVARIANT*)$1->value.pvValue)->bstrVal[i] != L']') && (i < cLen)) bstrCopy[j++] = ((PROPVARIANT*)$1->value.pvValue)->bstrVal[i++]; if (i < cLen) bstrCopy[j++] = ((PROPVARIANT*)$1->value.pvValue)->bstrVal[i]; } break; default: bstrCopy[j++] = ((PROPVARIANT*)$1->value.pvValue)->bstrVal[i]; break; } } SysFreeString(((PROPVARIANT*)$1->value.pvValue)->bstrVal); ((PROPVARIANT*)$1->value.pvValue)->pwszVal = CoTaskStrDup(bstrCopy); ((PROPVARIANT*)$1->value.pvValue)->vt = VT_LPWSTR; SysFreeString(bstrCopy); $$ = $1; } ; /* 4.4.6 Matches Predicate */ matches_predicate: _MATCHES '(' column_reference ',' matches_string ')' opt_greater_than_zero { AssertReq($3); AssertReq($5); m_pIPTProperties->UseCiColumn(L'#'); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"\"")); m_pIPTProperties->AppendCiRestriction(((PROPVARIANT*)$5->value.pvValue)->pwszVal, wcslen(((PROPVARIANT*)$5->value.pvValue)->pwszVal)); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"\"")); $$ = PctCreateNode(DBOP_like, DBVALUEKIND_LIKE, $3, $5, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY); } $$->value.pdblikeValue->guidDialect = DBGUID_LIKE_OFS; $$->value.pdblikeValue->lWeight = DEFAULTWEIGHT; } ; matches_string: _STRING { AssertReq($1); HRESULT hr = CoerceScalar(VT_LPWSTR, &$1); if (S_OK != hr) YYABORT(hr); LPWSTR pwszMatchString = ((PROPVARIANT*)$1->value.pvValue)->pwszVal; while (*pwszMatchString) { // perform some soundness checking on string since Index Server won't be happy // with an ill formed string if (L'|' == *pwszMatchString++) { hr = DB_E_ERRORSINCOMMAND; switch ( *pwszMatchString++ ) { case L'(': while (*pwszMatchString) if (L'|' == *pwszMatchString++) if (*pwszMatchString) if (L')' == *pwszMatchString++) { hr = S_OK; break; } break; case L'{': while (*pwszMatchString) if (L'|' == *pwszMatchString++) if (*pwszMatchString) if (L'}' == *pwszMatchString++) { hr = S_OK; break; } break; default: hr = S_OK; } } } if (S_OK != hr) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_MATCH_STRING); YYABORT(hr); } $$ = $1; } ; /* 4.4.7 Qantified Comparison Predicate */ vector_comparison_predicate: column_reference_or_cast vector_comp_op vector_literal { AssertReq($1); AssertReq($2); DBCOMMANDTREE * pct = 0; if ( m_pIPTProperties->GetDBType() & DBTYPE_VECTOR ) { pct = PctAllocNode(DBVALUEKIND_VARIANT, DBOP_scalar_constant); if (NULL == pct) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } DBCOMMANDTREE* pctList=$3; UINT i = 0; pct->value.pvarValue->vt = m_pIPTProperties->GetDBType(); ((PROPVARIANT*)pct->value.pvarValue)->caub.cElems = GetNumberOfSiblings($3); if (0 == ((PROPVARIANT*)pct->value.pvarValue)->caub.cElems) { ((PROPVARIANT*)pct->value.pvarValue)->caub.pElems = (UCHAR*) NULL; } else { switch ( m_pIPTProperties->GetDBType() ) { case (VT_UI1|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->caub.pElems = (UCHAR*) CoTaskMemAlloc(sizeof(UCHAR)*((PROPVARIANT*)pct->value.pvarValue)->caub.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->caub.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->caub.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->caub.pElems[i] = pctList->value.pvarValue->bVal; pctList = pctList->pctNextSibling; } break; case (VT_I1|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->cac.pElems = (CHAR*) CoTaskMemAlloc(sizeof(CHAR)*((PROPVARIANT*)pct->value.pvarValue)->cac.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->cac.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->cac.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->cac.pElems[i] = pctList->value.pvarValue->cVal; pctList = pctList->pctNextSibling; } break; case (VT_UI2|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->caui.pElems = (USHORT*) CoTaskMemAlloc(sizeof(USHORT)*((PROPVARIANT*)pct->value.pvarValue)->caui.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->caui.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->caui.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->caui.pElems[i] = pctList->value.pvarValue->uiVal; pctList = pctList->pctNextSibling; } break; case (VT_I2|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->cai.pElems = (SHORT*) CoTaskMemAlloc(sizeof(SHORT)*((PROPVARIANT*)pct->value.pvarValue)->cai.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->cai.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->cai.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->cai.pElems[i] = pctList->value.pvarValue->iVal; pctList = pctList->pctNextSibling; } break; case (VT_UI4|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->caul.pElems = (ULONG*) CoTaskMemAlloc(sizeof(ULONG)*((PROPVARIANT*)pct->value.pvarValue)->caul.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->caul.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->caul.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->caul.pElems[i] = pctList->value.pvarValue->ulVal; pctList = pctList->pctNextSibling; } break; case (VT_I4|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->cal.pElems = (LONG*) CoTaskMemAlloc(sizeof(LONG)*((PROPVARIANT*)pct->value.pvarValue)->cal.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->cal.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->cal.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->cal.pElems[i] = pctList->value.pvarValue->lVal; pctList = pctList->pctNextSibling; } break; case (VT_UI8|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->cauh.pElems = (ULARGE_INTEGER*) CoTaskMemAlloc(sizeof(ULARGE_INTEGER)*((PROPVARIANT*)pct->value.pvarValue)->cauh.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->cauh.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->cauh.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->cauh.pElems[i] = ((PROPVARIANT*)pctList->value.pvarValue)->uhVal; pctList = pctList->pctNextSibling; } break; case (VT_I8|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->cah.pElems = (LARGE_INTEGER*) CoTaskMemAlloc(sizeof(LARGE_INTEGER)*((PROPVARIANT*)pct->value.pvarValue)->cah.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->cah.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->cah.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->cah.pElems[i] = ((PROPVARIANT*)pctList->value.pvarValue)->hVal; pctList = pctList->pctNextSibling; } break; case (VT_R4|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->caflt.pElems = (float*) CoTaskMemAlloc(sizeof(float)*((PROPVARIANT*)pct->value.pvarValue)->caflt.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->caflt.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->caflt.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->caflt.pElems[i] = pctList->value.pvarValue->fltVal; pctList = pctList->pctNextSibling; } break; case (VT_R8|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->cadbl.pElems = (double*) CoTaskMemAlloc(sizeof(double)*((PROPVARIANT*)pct->value.pvarValue)->cadbl.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->cadbl.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->cadbl.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->cadbl.pElems[i] = pctList->value.pvarValue->dblVal; pctList = pctList->pctNextSibling; } break; case (VT_BOOL|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->cabool.pElems = (VARIANT_BOOL*) CoTaskMemAlloc(sizeof(VARIANT_BOOL)*((PROPVARIANT*)pct->value.pvarValue)->cabool.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->cabool.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->cabool.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->cabool.pElems[i] = pctList->value.pvarValue->boolVal; pctList = pctList->pctNextSibling; } break; case (VT_CY|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->cacy.pElems = (CY*) CoTaskMemAlloc(sizeof(CY)*((PROPVARIANT*)pct->value.pvarValue)->cacy.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->cacy.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->cacy.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->cacy.pElems[i] = ((PROPVARIANT*)pctList->value.pvarValue)->cyVal; pctList = pctList->pctNextSibling; } break; case (VT_DATE|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->cadbl.pElems = (double*) CoTaskMemAlloc(sizeof(double)*((PROPVARIANT*)pct->value.pvarValue)->cadbl.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->cadbl.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->cadbl.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->cadbl.pElems[i] = ((PROPVARIANT*)pctList->value.pvarValue)->date; pctList = pctList->pctNextSibling; } break; case (VT_FILETIME|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->cafiletime.pElems = (FILETIME*) CoTaskMemAlloc(sizeof(FILETIME)*((PROPVARIANT*)pct->value.pvarValue)->cafiletime.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->cafiletime.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->cafiletime.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->cafiletime.pElems[i] = ((PROPVARIANT*)pctList->value.pvarValue)->filetime; pctList = pctList->pctNextSibling; } break; case (VT_BSTR|VT_VECTOR): ((PROPVARIANT*)pct->value.pvarValue)->cabstr.pElems = (BSTR*) CoTaskMemAlloc(sizeof(BSTR)*((PROPVARIANT*)pct->value.pvarValue)->cabstr.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->cabstr.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->cabstr.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->cabstr.pElems[i] = SysAllocString(pctList->value.pvarValue->bstrVal); if ( 0 == ((PROPVARIANT*)pct->value.pvarValue)->cabstr.pElems[i] ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } pctList = pctList->pctNextSibling; } break; case (DBTYPE_STR|VT_VECTOR): pct->value.pvarValue->vt = VT_LPSTR | VT_VECTOR; ((PROPVARIANT*)pct->value.pvarValue)->calpstr.pElems = (LPSTR*) CoTaskMemAlloc(sizeof(LPSTR)*((PROPVARIANT*)pct->value.pvarValue)->calpstr.cElems); if (NULL == ((PROPVARIANT*)pct->value.pvarValue)->calpstr.pElems) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for (i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->calpstr.cElems; i++) { ((PROPVARIANT*)pct->value.pvarValue)->calpstr.pElems[i] = (LPSTR)CoTaskMemAlloc((lstrlenA(((PROPVARIANT*)pctList->value.pvarValue)->pszVal)+2)*sizeof(CHAR)); if ( 0 == ((PROPVARIANT*)pct->value.pvarValue)->calpstr.pElems[i] ) { // free allocations made so far for ( int j = i-1; j >= 0; j++ ) CoTaskMemFree( ((PROPVARIANT*)pct->value.pvarValue)->calpstr.pElems[i] ); CoTaskMemFree( ((PROPVARIANT*)pct->value.pvarValue)->calpstr.pElems ); m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } strcpy(((PROPVARIANT*)pct->value.pvarValue)->calpstr.pElems[i], ((PROPVARIANT*)pctList->value.pvarValue)->pszVal); pctList = pctList->pctNextSibling; } break; case (DBTYPE_WSTR|VT_VECTOR): pct->value.pvarValue->vt = VT_LPWSTR | VT_VECTOR; ((PROPVARIANT*)pct->value.pvarValue)->calpwstr.pElems = (LPWSTR*) CoTaskMemAlloc(sizeof(LPWSTR)*((PROPVARIANT*)pct->value.pvarValue)->calpwstr.cElems); if ( 0 == ((PROPVARIANT*)pct->value.pvarValue)->calpwstr.pElems ) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } for ( i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->calpwstr.cElems; i++ ) { ((PROPVARIANT*)pct->value.pvarValue)->calpwstr.pElems[i] = CoTaskStrDup(((PROPVARIANT*)pctList->value.pvarValue)->pwszVal); if ( 0 == ((PROPVARIANT*)pct->value.pvarValue)->calpwstr.pElems[i] ) { // free allocations made so far for ( int j = i-1; j >= 0; j++ ) CoTaskMemFree( ((PROPVARIANT*)pct->value.pvarValue)->calpwstr.pElems[i] ); CoTaskMemFree( ((PROPVARIANT*)pct->value.pvarValue)->calpwstr.pElems ); m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } pctList = pctList->pctNextSibling; } break; case (VT_CLSID|VT_VECTOR): pct->value.pvarValue->vt = VT_CLSID | VT_VECTOR; ((PROPVARIANT*)pct->value.pvarValue)->cauuid.pElems = (GUID*) CoTaskMemAlloc(sizeof(GUID)*((PROPVARIANT*)pct->value.pvarValue)->cauuid.cElems); if ( NULL == ((PROPVARIANT*)pct->value.pvarValue)->cauuid.pElems ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } for ( i = 0; i<((PROPVARIANT*)pct->value.pvarValue)->cauuid.cElems; i++ ) { ((PROPVARIANT*)pct->value.pvarValue)->cauuid.pElems[i] = *((PROPVARIANT*)pctList->value.pvarValue)->puuid; pctList = pctList->pctNextSibling; } break; default: assert(!"PctAllocNode: illegal wKind"); m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken(L"ARRAY"); DeleteDBQT( pct ); YYABORT(DB_E_ERRORSINCOMMAND); } } } else { switch ( m_pIPTProperties->GetDBType() ) { case VT_UI1: case VT_UI2: case VT_UI4: case VT_UI8: // Allows: // DBOP_allbits // DBOP_anybits // when the LHS is a non vector. // // There isn't a way to say the following through SQL currently: // DBOP_anybits_all // DBOP_anybits_any // DBOP_allbits_all // DBOP_allbits_any pct = $3; $3 = 0; break; default: assert(!"PctAllocNode: illegal wKind"); m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken(L"ARRAY"); YYABORT(DB_E_ERRORSINCOMMAND); } } if ($3) { DeleteDBQT($3); $3 = NULL; } $1->pctNextSibling = pct; $2->pctFirstChild = $1; $$ = $2; } ; all: _ALL ; some: _SOME | _ANY ; vector_comp_op: '=' { if ( m_pIPTProperties->GetDBType() & DBTYPE_VECTOR ) $$ = PctCreateRelationalNode( DBOP_equal, DEFAULTWEIGHT ); else $$ = PctCreateRelationalNode( DBOP_equal, DEFAULTWEIGHT ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction( VAL_AND_CCH_MINUS_NULL(L" = ") ); } | '=' all { if ( m_pIPTProperties->GetDBType() & DBTYPE_VECTOR ) $$ = PctCreateRelationalNode( DBOP_equal_all, DEFAULTWEIGHT ); else $$ = PctCreateRelationalNode( DBOP_allbits, DEFAULTWEIGHT ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } if ( m_pIPTProperties->GetDBType() & DBTYPE_VECTOR ) m_pIPTProperties->AppendCiRestriction( VAL_AND_CCH_MINUS_NULL(L" = ^a ") ); else m_pIPTProperties->AppendCiRestriction( VAL_AND_CCH_MINUS_NULL(L" ^a ") ); } | '=' some { if ( m_pIPTProperties->GetDBType() & DBTYPE_VECTOR ) $$ = PctCreateRelationalNode( DBOP_equal_any, DEFAULTWEIGHT ); else $$ = PctCreateRelationalNode( DBOP_anybits, DEFAULTWEIGHT ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } if ( m_pIPTProperties->GetDBType() & DBTYPE_VECTOR ) m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" = ^s ")); else m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" ^s ")); } | _NE { if ( m_pIPTProperties->GetDBType() & DBTYPE_VECTOR ) $$ = PctCreateRelationalNode( DBOP_not_equal, DEFAULTWEIGHT ); if ( NULL == $$ ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY ); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" != ") ); } | _NE all { $$ = PctCreateRelationalNode(DBOP_not_equal_all, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" != ^a ")); } | _NE some { $$ = PctCreateRelationalNode(DBOP_not_equal_any, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" != ^s ")); } | '<' { $$ = PctCreateRelationalNode(DBOP_less, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" < ")); } | '<' all { $$ = PctCreateRelationalNode(DBOP_less_all, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" < ^a ")); } | '<' some { $$ = PctCreateRelationalNode(DBOP_less_any, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" < ^s ")); } | '>' { $$ = PctCreateRelationalNode(DBOP_greater, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" > ")); } | '>' all { $$ = PctCreateRelationalNode(DBOP_greater_all, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" > ^a ")); } | '>' some { $$ = PctCreateRelationalNode(DBOP_greater_any, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" > ^s ")); } | _LE { $$ = PctCreateRelationalNode(DBOP_less_equal, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" <= ")); } | _LE all { $$ = PctCreateRelationalNode(DBOP_less_equal_all, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" <= ^a ")); } | _LE some { $$ = PctCreateRelationalNode(DBOP_less_equal_any, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" <= ^s ")); } | _GE { $$ = PctCreateRelationalNode(DBOP_greater_equal, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" >= ")); } | _GE all { $$ = PctCreateRelationalNode(DBOP_greater_equal_all, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" >= ^a ")); } | _GE some { $$ = PctCreateRelationalNode(DBOP_greater_equal_any, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" >= ^s ")); } ; vector_literal: _ARRAY left_sqbrkt opt_literal_list right_sqbrkt { $$ = PctReverse($3); } ; left_sqbrkt: '[' { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"{")); } ; right_sqbrkt: ']' { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"}")); } ; opt_literal_list: /* empty */ { $$ = NULL; } | literal_list ; literal_list: literal_list comma typed_literal { AssertReq($1); if (NULL == $3) YYABORT(DB_E_CANTCONVERTVALUE); $$ = PctLink($3, $1); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } } | typed_literal { if (NULL == $1) YYABORT(DB_E_CANTCONVERTVALUE); $$ = $1; } ; comma: ',' { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L",")); } ; /* 4.4.x NULL Predicate */ null_predicate: column_reference _IS _NULL { AssertReq($1); $2 = PctAllocNode(DBVALUEKIND_VARIANT, DBOP_scalar_constant); if (NULL == $2) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } ((PROPVARIANT*)$2->value.pvValue)->vt = VT_EMPTY; $$ = PctCreateRelationalNode(DBOP_equal, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } $$->pctFirstChild = $1; $1->pctNextSibling = $2; } | column_reference _IS_NOT _NULL { AssertReq($1); $2 = PctAllocNode(DBVALUEKIND_VARIANT, DBOP_scalar_constant); if (NULL == $2) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } ((PROPVARIANT*)$2->value.pvValue)->vt = VT_EMPTY; // $$ = PctCreateRelationalNode(DBOP_not_equal, DEFAULTWEIGHT); $$ = PctCreateRelationalNode(DBOP_equal, DEFAULTWEIGHT); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } $$->pctFirstChild = $1; $1->pctNextSibling = $2; $$ = PctCreateNotNode(DEFAULTWEIGHT, $$); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } } ; /* 8.12 search_condition */ search_condition: boolean_term | search_condition or_op boolean_term { AssertReq($1); AssertReq($3); $$ = PctCreateBooleanNode(DBOP_or, DEFAULTWEIGHT, $1, $3); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } } ; boolean_term: boolean_factor | boolean_term and_op boolean_factor { AssertReq($1); AssertReq($3); $$ = PctCreateBooleanNode(DBOP_and, DEFAULTWEIGHT, $1, $3); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } } ; boolean_factor: boolean_test | not_op boolean_test %prec mHighest { AssertReq($2); $$ = PctCreateNotNode(DEFAULTWEIGHT, $2); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } } ; or_op: _OR { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" OR ")); } ; and_op: _AND { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" AND ")); } ; not_op: _NOT { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L" NOT ")); } ; boolean_test: boolean_primary | boolean_primary _IS _TRUE { AssertReq($1); $$ = PctCreateNode(DBOP_is_TRUE, $1, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } } | boolean_primary _IS _FALSE { AssertReq($1); $$ = PctCreateNode(DBOP_is_FALSE, $1, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } } | boolean_primary _IS _UNKNOWN { AssertReq($1); $$ = PctCreateNode(DBOP_is_INVALID, $1, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } } | boolean_primary _IS_NOT _TRUE { AssertReq($1); $2 = PctCreateNode(DBOP_is_TRUE, $1, NULL); if (NULL == $2) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } $$ = PctCreateNotNode(DEFAULTWEIGHT, $2); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } } | boolean_primary _IS_NOT _FALSE { AssertReq($1); $2 = PctCreateNode(DBOP_is_FALSE, $1, NULL); if (NULL == $2) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } $$ = PctCreateNotNode(DEFAULTWEIGHT, $2); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } } | boolean_primary _IS_NOT _UNKNOWN { AssertReq($1); $2 = PctCreateNode(DBOP_is_INVALID, $1, NULL); if (NULL == $2) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } $$ = PctCreateNotNode(DEFAULTWEIGHT, $2); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } } ; boolean_primary: /* empty */ { m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L"(")); $$ = NULL; } predicate { AssertReq($2); m_pIPTProperties->AppendCiRestriction(VAL_AND_CCH_MINUS_NULL(L")")); $$ = $2; } | '(' search_condition ')' { AssertReq($2); $$ = $2; } ; order_by_clause: _ORDER_BY sort_specification_list { AssertReq($2); $2 = PctReverse($2); $$ = PctCreateNode(DBOP_sort_list_anchor, $2, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } } ; sort_specification_list: sort_specification_list ',' sort_specification { AssertReq($1); AssertReq($3); $$ = PctLink($3, $1); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } } | sort_specification ; sort_specification: sort_key opt_ordering_specification { AssertReq($1); AssertReq($2); $2->value.pdbsrtinfValue->lcid = m_pIPSession->GetLCID(); $2->pctFirstChild = $1; $$ = $2; } ; opt_ordering_specification: /* empty */ { $$ = PctCreateNode(DBOP_sort_list_element, DBVALUEKIND_SORTINFO, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } $$->value.pdbsrtinfValue->fDesc = m_pIPTProperties->GetSortDesc(); } | _ASC { $$ = PctCreateNode(DBOP_sort_list_element, DBVALUEKIND_SORTINFO, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } $$->value.pdbsrtinfValue->fDesc = QUERY_SORTASCEND; m_pIPTProperties->SetSortDesc(QUERY_SORTASCEND); } | _DESC { $$ = PctCreateNode(DBOP_sort_list_element, DBVALUEKIND_SORTINFO, NULL); if (NULL == $$) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT(E_OUTOFMEMORY ); } $$->value.pdbsrtinfValue->fDesc = QUERY_SORTDESCEND; m_pIPTProperties->SetSortDesc(QUERY_SORTDESCEND); } ; sort_key: column_reference { //@SetCiColumn does the clear m_pCMonarchSessionData->ClearCiColumn(); } | integer ; opt_order_by_clause: /* empty */ { $$ = NULL; } | order_by_clause { $$ = $1; } ; /* 4.6 SET Statement */ set_statement: set_propertyname_statement | set_rankmethod_statement | set_global_directive ; set_propertyname_statement: _SET _PROPERTYNAME guid_format _PROPID property_id _AS column_alias opt_type_clause { HRESULT hr = S_OK; $1 = PctBuiltInProperty($7->value.pwszValue, m_pIPSession, m_pIPTProperties); if (NULL != $1) { // This is a built-in friendly name. Definition better match built in definition. if (*$3->value.pGuid != $1->value.pdbidValue->uGuid.guid || m_pIPTProperties->GetDBType() != $8->value.usValue || DBKIND_GUID_PROPID != $1->value.pdbidValue->eKind || $5->value.pvarValue->lVal != (long)$1->value.pdbidValue->uName.ulPropid) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_BUILTIN_PROPERTY); m_pIPTProperties->SetErrorToken($7->value.pwszValue); YYABORT(DB_E_ERRORSINCOMMAND); } } else m_pIPSession->m_pCPropertyList->SetPropertyEntry($7->value.pwszValue, $8->value.ulValue, *$3->value.pGuid, DBKIND_GUID_PROPID, (LPWSTR) LongToPtr( $5->value.pvarValue->lVal ), m_pIPSession->GetGlobalDefinition()); if (FAILED(hr)) { // Unable to store the property name and/or values in the symbol table m_pIPTProperties->SetErrorHResult(hr, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken($7->value.pwszValue); YYABORT(DB_E_ERRORSINCOMMAND); } if ($1) DeleteDBQT($1); DeleteDBQT($3); DeleteDBQT($5); DeleteDBQT($7); DeleteDBQT($8); $$ = NULL; } | _SET _PROPERTYNAME guid_format _PROPID property_name _AS column_alias opt_type_clause { HRESULT hr = S_OK; $1 = PctBuiltInProperty($7->value.pwszValue, m_pIPSession, m_pIPTProperties); if (NULL != $1) { // This is a built-in friendly name. Definition better match built in definition. if (*$3->value.pGuid != $1->value.pdbidValue->uGuid.guid || m_pIPTProperties->GetDBType() != $8->value.ulValue || DBKIND_GUID_NAME != $1->value.pdbidValue->eKind || 0 != _wcsicmp(((PROPVARIANT*)$5->value.pvValue)->bstrVal, $1->value.pdbidValue->uName.pwszName)) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_BUILTIN_PROPERTY); // m_pIPTProperties->SetErrorToken($1->value.pwszValue); YYABORT(DB_E_ERRORSINCOMMAND); } } else hr = m_pIPSession->m_pCPropertyList->SetPropertyEntry($7->value.pwszValue, $8->value.ulValue, *$3->value.pGuid, DBKIND_GUID_NAME, ((PROPVARIANT*)$5->value.pvValue)->bstrVal, m_pIPSession->GetGlobalDefinition()); if (FAILED(hr)) { // Unable to store the property name and/or values in the symbol table m_pIPTProperties->SetErrorHResult(hr, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken($7->value.pwszValue); YYABORT(DB_E_ERRORSINCOMMAND); } if ($1) DeleteDBQT($1); DeleteDBQT($3); DeleteDBQT($5); DeleteDBQT($7); DeleteDBQT($8); } ; column_alias: identifier ; opt_type_clause: /* empty */ { $$ = PctCreateNode(DBOP_scalar_constant, DBVALUEKIND_UI2, NULL); $$->value.usValue = DBTYPE_WSTR|DBTYPE_BYREF; } | _TYPE dbtype { $$ = $2; } ; dbtype: base_dbtype { AssertReq($1); DBTYPE dbType = GetDBTypeFromStr($1->value.pwszValue); if ((DBTYPE_EMPTY == dbType) || (DBTYPE_BYREF == dbType) || (DBTYPE_VECTOR == dbType)) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken($1->value.pwszValue); m_pIPTProperties->SetErrorToken(L"value.usValue = dbType; } | base_dbtype '|' base_dbtype { AssertReq($1); AssertReq($3); DBTYPE dbType1 = GetDBTypeFromStr($1->value.pwszValue); DBTYPE dbType2 = GetDBTypeFromStr($3->value.pwszValue); if ((DBTYPE_BYREF == dbType1 || DBTYPE_VECTOR == dbType1) && (DBTYPE_BYREF == dbType2 || DBTYPE_VECTOR == dbType2)) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken($3->value.pwszValue); m_pIPTProperties->SetErrorToken( L"DBTYPE_I2, DBTYPE_I4, DBTYPE_R4, DBTYPE_R8, DBTYPE_CY, DBTYPE_DATE, DBTYPE_BSTR, DBTYPE_BOOL, DBTYPE_STR, DBTYPE_WSTR"); YYABORT(DB_E_ERRORSINCOMMAND); } if (DBTYPE_BYREF != dbType1 && DBTYPE_VECTOR != dbType1 && DBTYPE_BYREF != dbType2 && DBTYPE_VECTOR != dbType2) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken($3->value.pwszValue); m_pIPTProperties->SetErrorToken(L"DBTYPE_BYREF, DBTYPE_VECTOR"); YYABORT(DB_E_ERRORSINCOMMAND); } DeleteDBQT($1); $1 = NULL; DeleteDBQT($3); $3 = NULL; $$ = PctCreateNode(DBOP_scalar_constant, DBVALUEKIND_UI2, NULL); $$->value.usValue = dbType1 | dbType2; } ; base_dbtype: identifier ; property_id: unsigned_integer ; property_name: _STRING ; guid_format: _STRING { GUID* pGuid = (GUID*) CoTaskMemAlloc(sizeof GUID); // this will become part of tree if (NULL == pGuid) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY); YYABORT( E_OUTOFMEMORY ); } BOOL bRet = ParseGuid(((PROPVARIANT*)$1->value.pvValue)->bstrVal, *pGuid); if ( bRet && GUID_NULL != *pGuid) { SCODE sc = PropVariantClear((PROPVARIANT*)$1->value.pvValue); Assert(SUCCEEDED(sc)); // UNDONE: meaningful error message CoTaskMemFree($1->value.pvValue); $1->wKind = DBVALUEKIND_GUID; $1->value.pGuid = pGuid; $$ = $1; } else { CoTaskMemFree(pGuid); m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken(((PROPVARIANT*)$1->value.pvValue)->bstrVal); YYABORT(DB_E_ERRORSINCOMMAND); } } ; set_rankmethod_statement: _SET _RANKMETHOD rankmethod { $$ = NULL; } ; rankmethod: _ID _ID { AssertReq($1); AssertReq($2); if ((0==_wcsicmp($1->value.pwszValue, L"Jaccard")) && (0==_wcsicmp($2->value.pwszValue, L"coefficient"))) m_pIPSession->SetRankingMethod(VECTOR_RANK_JACCARD); else if ((0==_wcsicmp($1->value.pwszValue, L"dice")) && (0==_wcsicmp($2->value.pwszValue, L"coefficient"))) m_pIPSession->SetRankingMethod(VECTOR_RANK_DICE); else if ((0==_wcsicmp($1->value.pwszValue, L"inner")) && (0==_wcsicmp($2->value.pwszValue, L"product"))) m_pIPSession->SetRankingMethod(VECTOR_RANK_INNER); else { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken($1->value.pwszValue); m_pIPTProperties->SetErrorToken(L"MINIMUM, MAXIMUM, JACCARD COEFFICIENT, DICE COEFFICIENT, INNER PRODUCT"); YYABORT(DB_E_ERRORSINCOMMAND); } DeleteDBQT($2); $2 = NULL; DeleteDBQT($1); $1 = NULL; $$ = NULL; } | _ID { AssertReq($1); if (0==_wcsicmp($1->value.pwszValue, L"minimum")) m_pIPSession->SetRankingMethod(VECTOR_RANK_MIN); else if (0==_wcsicmp($1->value.pwszValue, L"maximum")) m_pIPSession->SetRankingMethod(VECTOR_RANK_MAX); else { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken($1->value.pwszValue); m_pIPTProperties->SetErrorToken(L"MINIMUM, MAXIMUM, JACCARD COEFFICIENT, DICE COEFFICIENT, INNER PRODUCT"); YYABORT(DB_E_ERRORSINCOMMAND); } DeleteDBQT($1); $1 = NULL; $$ = NULL; } ; set_global_directive: _SET _ID _ID { if (0 != _wcsicmp($2->value.pwszValue, L"GLOBAL")) { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken($2->value.pwszValue); m_pIPTProperties->SetErrorToken(L"GLOBAL"); YYABORT(DB_E_ERRORSINCOMMAND); } if (0 == _wcsicmp($3->value.pwszValue, L"ON")) m_pIPSession->SetGlobalDefinition(TRUE); else if (0 == _wcsicmp($3->value.pwszValue, L"OFF")) m_pIPSession->SetGlobalDefinition(FALSE); else { m_pIPTProperties->SetErrorHResult(DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken($3->value.pwszValue); m_pIPTProperties->SetErrorToken(L"ON, OFF"); YYABORT(DB_E_ERRORSINCOMMAND); } DeleteDBQT($2); DeleteDBQT($3); $$ = NULL; } ; /* 4.7 CREATE VIEW Statement */ create_view_statement: _CREATE _VIEW view_name _AS _SELECT select_list from_clause { // _CREATE _VIEW view_name _AS _SELECT select_list from_clause AssertReq( $3 ); AssertReq( $6 ); AssertReq( $7 ); // // Can create views only on the current catalog // if ( 0 != _wcsicmp(($3->value.pdbcntnttblValue)->pwszMachine, m_pIPSession->GetDefaultMachine()) && 0 != _wcsicmp(($3->value.pdbcntnttblValue)->pwszCatalog, m_pIPSession->GetDefaultCatalog()) ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR); m_pIPTProperties->SetErrorToken( ($3->pctNextSibling)->value.pwszValue ); m_pIPTProperties->SetErrorToken( L"" ); YYABORT( DB_E_ERRORSINCOMMAND ); } if ( DBOP_outall_name == $6->op ) { m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR ); m_pIPTProperties->SetErrorToken( L"*" ); m_pIPTProperties->SetErrorToken( L"