4700 lines
170 KiB
Plaintext
4700 lines
170 KiB
Plaintext
|
|
%{
|
|
//--------------------------------------------------------------------
|
|
// 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;
|
|
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);
|
|
|
|
if ( 0 == pct->value.pdbidValue->uName.pwszName )
|
|
{
|
|
pct->value.pdbidValue->eKind = DBKIND_GUID_PROPID;
|
|
DeleteDBQT( pct );
|
|
pct = 0;
|
|
}
|
|
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);
|
|
|
|
if ( 0 == pct->value.pdbidValue->uName.pwszName )
|
|
{
|
|
pct->value.pdbidValue->eKind = DBKIND_GUID_PROPID;
|
|
DeleteDBQT( pct );
|
|
pct = 0;
|
|
break;
|
|
}
|
|
|
|
// need to allocate and copy guid
|
|
pct->value.pdbidValue->uGuid.pguid = (GUID*)CoTaskMemAlloc(sizeof(GUID));
|
|
if ( 0 == pct->value.pdbidValue->uName.pwszName )
|
|
{
|
|
CoTaskMemFree( pct->value.pdbidValue->uName.pwszName );
|
|
pct->value.pdbidValue->uName.pwszName = 0;
|
|
pct->value.pdbidValue->eKind = DBKIND_GUID_PROPID;
|
|
DeleteDBQT( pct );
|
|
pct = 0;
|
|
break;
|
|
}
|
|
|
|
*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));
|
|
|
|
if ( 0 == pct->value.pdbidValue->uGuid.pguid )
|
|
{
|
|
pct->value.pdbidValue->eKind = DBKIND_GUID_PROPID;
|
|
DeleteDBQT( pct );
|
|
pct = 0;
|
|
break;
|
|
}
|
|
|
|
*pct->value.pdbidValue->uGuid.pguid = *pDBID->uGuid.pguid;
|
|
break;
|
|
}
|
|
default:
|
|
Assert(0);
|
|
}
|
|
}
|
|
}
|
|
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(<datepart>, <negative integer>, <relative date/time>)
|
|
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);
|
|
|
|
if ( NULL == $$ )
|
|
{
|
|
m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY );
|
|
YYABORT( E_OUTOFMEMORY );
|
|
}
|
|
|
|
}
|
|
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);
|
|
if ( NULL == $$ )
|
|
{
|
|
m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY );
|
|
YYABORT( E_OUTOFMEMORY );
|
|
}
|
|
$$->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"<literal>");
|
|
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);
|
|
if ( NULL == $$ )
|
|
{
|
|
m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY );
|
|
YYABORT( E_OUTOFMEMORY );
|
|
}
|
|
$$->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"<base Indexing Service dbtype1");
|
|
YYABORT(DB_E_ERRORSINCOMMAND);
|
|
}
|
|
|
|
DeleteDBQT($1);
|
|
$1 = NULL;
|
|
$$ = PctCreateNode(DBOP_scalar_constant, DBVALUEKIND_UI2, NULL);
|
|
if ( NULL == $$ )
|
|
{
|
|
m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY );
|
|
YYABORT( E_OUTOFMEMORY );
|
|
}
|
|
if (DBTYPE_WSTR == dbType || DBTYPE_STR == dbType)
|
|
dbType = dbType | DBTYPE_BYREF;
|
|
$$->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);
|
|
if ( NULL == $$ )
|
|
{
|
|
m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_OUT_OF_MEMORY );
|
|
YYABORT( E_OUTOFMEMORY );
|
|
}
|
|
$$->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"<unqualified temporary view name>" );
|
|
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"<select list>" );
|
|
YYABORT( DB_E_ERRORSINCOMMAND );
|
|
}
|
|
|
|
Assert( DBOP_content_table == $3->op );
|
|
AssertReq( $3->pctNextSibling ); // name of the view
|
|
|
|
SCODE sc = S_OK;
|
|
|
|
// This is the LA_proj, which doesn't have a NextSibling.
|
|
// Use the next sibling to store contenttable tree
|
|
// specified in the from_clause
|
|
Assert( 0 == $6->pctNextSibling );
|
|
|
|
if ( L'#' != $3->pctNextSibling->value.pwszValue[0] )
|
|
{
|
|
if ( m_pIPSession->GetGlobalDefinition() )
|
|
sc = m_pIPSession->GetGlobalViewList()->SetViewDefinition(
|
|
m_pIPSession,
|
|
m_pIPTProperties,
|
|
$3->pctNextSibling->value.pwszValue,
|
|
NULL, // all catalogs
|
|
$6);
|
|
else
|
|
{
|
|
m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR );
|
|
m_pIPTProperties->SetErrorToken( $3->pctNextSibling->value.pwszValue );
|
|
m_pIPTProperties->SetErrorToken( L"<temporary view name>" );
|
|
YYABORT( DB_E_ERRORSINCOMMAND );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( 1 >= wcslen($3->pctNextSibling->value.pwszValue) )
|
|
{
|
|
m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR );
|
|
m_pIPTProperties->SetErrorToken( $3->pctNextSibling->value.pwszValue );
|
|
m_pIPTProperties->SetErrorToken( L"<temporary view name>" );
|
|
YYABORT( DB_E_ERRORSINCOMMAND );
|
|
}
|
|
else if ( L'#' == $3->pctNextSibling->value.pwszValue[1] )
|
|
{
|
|
// store the scope information for the view
|
|
|
|
$6->pctNextSibling = $7;
|
|
$7 = 0;
|
|
|
|
sc = m_pIPSession->GetLocalViewList()->SetViewDefinition(
|
|
m_pIPSession,
|
|
m_pIPTProperties,
|
|
$3->pctNextSibling->value.pwszValue,
|
|
($3->value.pdbcntnttblValue)->pwszCatalog,
|
|
$6);
|
|
}
|
|
else
|
|
{
|
|
$6->pctNextSibling = $7;
|
|
$7 = 0;
|
|
|
|
sc = m_pIPSession->GetGlobalViewList()->SetViewDefinition(
|
|
m_pIPSession,
|
|
m_pIPTProperties,
|
|
$3->pctNextSibling->value.pwszValue,
|
|
($3->value.pdbcntnttblValue)->pwszCatalog,
|
|
$6);
|
|
}
|
|
}
|
|
|
|
if ( FAILED(sc) )
|
|
{
|
|
if ( E_INVALIDARG == sc )
|
|
{
|
|
m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_VIEW_ALREADY_DEFINED );
|
|
m_pIPTProperties->SetErrorToken( $3->pctNextSibling->value.pwszValue );
|
|
m_pIPTProperties->SetErrorToken( ($3->value.pdbcntnttblValue)->pwszCatalog );
|
|
YYABORT( DB_E_ERRORSINCOMMAND );
|
|
}
|
|
else
|
|
{
|
|
m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR );
|
|
m_pIPTProperties->SetErrorToken( $3->pctNextSibling->value.pwszValue );
|
|
YYABORT( DB_E_ERRORSINCOMMAND );
|
|
}
|
|
}
|
|
|
|
DeleteDBQT( $3 );
|
|
DeleteDBQT( $6 );
|
|
|
|
if ( 0 != $7 )
|
|
DeleteDBQT( $7 );
|
|
|
|
$$ = 0;
|
|
}
|
|
;
|
|
|
|
|
|
|
|
|
|
|
|
/* 4.x DROP VIEW Statement */
|
|
|
|
drop_view_statement:
|
|
_DROP _VIEW view_name
|
|
{
|
|
AssertReq( $3 );
|
|
AssertReq( $3->pctNextSibling ); // name of the view
|
|
|
|
SCODE sc = S_OK;
|
|
if ( L'#' != $3->pctNextSibling->value.pwszValue[0] )
|
|
{
|
|
if ( m_pIPSession->GetGlobalDefinition() )
|
|
sc = m_pIPSession->GetGlobalViewList()->DropViewDefinition( $3->pctNextSibling->value.pwszValue, NULL );
|
|
else
|
|
{
|
|
m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR );
|
|
m_pIPTProperties->SetErrorToken( $3->pctNextSibling->value.pwszValue );
|
|
m_pIPTProperties->SetErrorToken( L"<temporary view name>" );
|
|
YYABORT( DB_E_ERRORSINCOMMAND );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( 1 >= wcslen($3->pctNextSibling->value.pwszValue) )
|
|
{
|
|
m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_PARSE_ERROR );
|
|
m_pIPTProperties->SetErrorToken( $3->pctNextSibling->value.pwszValue );
|
|
m_pIPTProperties->SetErrorToken( L"<temporary view name>" );
|
|
YYABORT( DB_E_ERRORSINCOMMAND );
|
|
}
|
|
else if ( L'#' == $3->pctNextSibling->value.pwszValue[1] )
|
|
sc = m_pIPSession->GetLocalViewList()->DropViewDefinition( $3->pctNextSibling->value.pwszValue,
|
|
($3->value.pdbcntnttblValue)->pwszCatalog );
|
|
else
|
|
sc = m_pIPSession->GetGlobalViewList()->DropViewDefinition( $3->pctNextSibling->value.pwszValue,
|
|
($3->value.pdbcntnttblValue)->pwszCatalog );
|
|
}
|
|
if ( FAILED(sc) )
|
|
{
|
|
m_pIPTProperties->SetErrorHResult( DB_E_ERRORSINCOMMAND, MONSQL_VIEW_NOT_DEFINED );
|
|
m_pIPTProperties->SetErrorToken( $3->pctNextSibling->value.pwszValue );
|
|
m_pIPTProperties->SetErrorToken( ($3->value.pdbcntnttblValue)->pwszCatalog );
|
|
YYABORT( DB_E_ERRORSINCOMMAND );
|
|
}
|
|
DeleteDBQT( $3 );
|
|
$$ = 0;
|
|
}
|
|
;
|