persistentstorage/dbms/pcdbms/usql/UQ_PARSE.CPP
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // SQL parser
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "UQ_STD.H"
       
    19 #include "D32Assert.h"
       
    20 
       
    21 // class TSqlParser
       
    22 
       
    23 const TInt KSqlError = -1;
       
    24 
       
    25 TSqlParser::TSqlParser(const TDesC& aSql)
       
    26 	: iSql(aSql)
       
    27 	{
       
    28 	NextToken();		// parse the first token
       
    29 	}
       
    30 
       
    31 TSqlTokenType TSqlParser::NextToken()
       
    32 	{
       
    33 	return iSql.NextToken(iToken);
       
    34 	}
       
    35 
       
    36 CSqlSearchCondition* TSqlParser::SqlError()
       
    37 	{
       
    38 	if (!Error())
       
    39 		iToken.SetError(KErrArgument);
       
    40 	return 0;
       
    41 	}
       
    42 
       
    43 TSqlTokenType TSqlParser::SqlErrorL()
       
    44 //
       
    45 // Report a SQL syntax error
       
    46 //
       
    47 	{
       
    48 	return TSqlTokenType(__LEAVE_IF_ERROR(KErrArgument));
       
    49 	}
       
    50 
       
    51 TSqlTokenType TSqlParser::Parse(TSqlKeyword aKeyword)
       
    52 //
       
    53 // look for requested keyword, skip to the next token if found
       
    54 // return the next token if found, else ESqlNoToken (==0)
       
    55 //
       
    56 	{
       
    57 	return TSqlLexer::IsKeyword(aKeyword,iToken) ? NextToken() : ESqlNoToken;
       
    58 	}
       
    59 
       
    60 TSqlTokenType TSqlParser::ParseL(TSqlTokenType aToken)
       
    61 //
       
    62 // parse the desired token
       
    63 //
       
    64 	{
       
    65 	return iToken!=aToken ? SqlErrorL() : NextToken();
       
    66 	}
       
    67 
       
    68 TSqlTokenType TSqlParser::ParseL(TSqlKeyword aKeyword)
       
    69 //
       
    70 // parse the desired keyword
       
    71 //
       
    72 	{
       
    73 	TSqlTokenType t=Parse(aKeyword);
       
    74 	return t==ESqlNoToken ? SqlErrorL() : t;
       
    75 	}
       
    76 
       
    77 TSqlKeyword TSqlParser::Keyword()
       
    78 //
       
    79 // parse a keyword
       
    80 //
       
    81 	{
       
    82 	TSqlKeyword k=TSqlLexer::Keyword(iToken);
       
    83 	if (k!=ESqlNotKeyword)
       
    84 		NextToken();
       
    85 	return k;
       
    86 	}
       
    87 
       
    88 TSqlTokenType TSqlParser::RightBracketL()
       
    89 //
       
    90 // parse a right bracket, and fail if not found
       
    91 //
       
    92 	{
       
    93 	return ParseL(ESqlRightBracket);
       
    94 	}
       
    95 
       
    96 void TSqlParser::EndL()
       
    97 //
       
    98 // Check that the SQL has been fully parsed
       
    99 //
       
   100 	{
       
   101 	if (iToken!=ESqlEos)
       
   102 		SqlErrorL();
       
   103 	}
       
   104 
       
   105 TSqlTokenType TSqlParser::IdentifierL(TPtrC& aIdentifier)
       
   106 //
       
   107 // parse an identifer, fail if not found
       
   108 //
       
   109 	{
       
   110 	if (iToken!=ESqlIdentifier)
       
   111 		return SqlErrorL();
       
   112 	const TText* p=iToken.Literal().Ptr();
       
   113 	TInt len=iToken.Literal().End()-p;
       
   114 	aIdentifier.Set(p,len);
       
   115 	return NextToken();
       
   116 	}
       
   117 
       
   118 TPtrC TSqlParser::IdentifierL()
       
   119 //
       
   120 // parse an identifer, fail if not found
       
   121 //
       
   122 	{
       
   123 	if (iToken!=ESqlIdentifier)
       
   124 		SqlErrorL();
       
   125 	return iToken.Literal().DesC();
       
   126 	}
       
   127 
       
   128 TSqlTokenType TSqlParser::ColumnNameL(RSqlColumnList& aList)
       
   129 //
       
   130 // Parse a column-identifier
       
   131 //
       
   132 	{
       
   133 	__LEAVE_IF_ERROR(aList.Append(IdentifierL()));
       
   134 	return NextToken();
       
   135 	}
       
   136 
       
   137 TSqlTokenType TSqlParser::ColumnListL(RSqlColumnList& aList)
       
   138 //
       
   139 // Parse a column-identifier-comma-list
       
   140 //
       
   141 	{
       
   142 	for (;;)
       
   143 		{
       
   144 		TSqlTokenType t=ColumnNameL(aList);
       
   145 		if (t!=ESqlComma)
       
   146 			return t;
       
   147 		NextToken();
       
   148 		}
       
   149 	}
       
   150 
       
   151 TSqlTokenType TSqlParser::AddColumnSpecL(TDbCol& aDef)
       
   152 //
       
   153 // Parse an add-column-spec
       
   154 //
       
   155 	{
       
   156 	aDef.iAttributes=0;
       
   157 	aDef.iName=IdentifierL();
       
   158 	NextToken();
       
   159 //
       
   160 	TDbColType type;
       
   161 	switch (Keyword())
       
   162 		{
       
   163 	case ESqlKeyword_bit:
       
   164 		type=EDbColBit;
       
   165 		break;
       
   166 	case ESqlKeyword_tinyint:
       
   167 		type=EDbColInt8;
       
   168 		break;
       
   169 	case ESqlKeyword_smallint:
       
   170 		type=EDbColInt16;
       
   171 		break;
       
   172 	case ESqlKeyword_integer:
       
   173 		type=EDbColInt32;
       
   174 		break;
       
   175 	case ESqlKeyword_counter:
       
   176 		aDef.iAttributes=aDef.EAutoIncrement;
       
   177 		type=EDbColUint32;
       
   178 		break;
       
   179 	case ESqlKeyword_bigint:
       
   180 		type=EDbColInt64;
       
   181 		break;
       
   182 	case ESqlKeyword_real:
       
   183 		type=EDbColReal32;
       
   184 		break;
       
   185 	case ESqlKeyword_double:
       
   186 		Parse(ESqlKeyword_precision);
       
   187 		// fall through
       
   188 	case ESqlKeyword_float:
       
   189 		type=EDbColReal64;
       
   190 		break;
       
   191 	case ESqlKeyword_date:
       
   192 	case ESqlKeyword_time:
       
   193 	case ESqlKeyword_timestamp:
       
   194 		type=EDbColDateTime;
       
   195 		break;
       
   196 	case ESqlKeyword_char:
       
   197 	case ESqlKeyword_varchar:
       
   198 		type=EDbColText;
       
   199 		break;
       
   200 	case ESqlKeyword_char8:
       
   201 	case ESqlKeyword_varchar8:
       
   202 		type=EDbColText8;
       
   203 		break;
       
   204 	case ESqlKeyword_binary:
       
   205 	case ESqlKeyword_varbinary:
       
   206 		type=EDbColBinary;
       
   207 		break;
       
   208 	case ESqlKeyword_unsigned:	// unsigned tinyint, smallint or integer
       
   209 		switch (Keyword())
       
   210 			{
       
   211 		case ESqlKeyword_tinyint:
       
   212 			type=EDbColUint8;
       
   213 			break;
       
   214 		case ESqlKeyword_smallint:
       
   215 			type=EDbColUint16;
       
   216 			break;
       
   217 		case ESqlKeyword_integer:
       
   218 			type=EDbColUint32;
       
   219 			break;
       
   220 		default:
       
   221 			return SqlErrorL();
       
   222 			};
       
   223 		break;
       
   224 	case ESqlKeyword_long:		// varchar or varbinary
       
   225 		switch (Keyword())
       
   226 			{
       
   227 		case ESqlKeyword_varchar8:
       
   228 			type=EDbColLongText8;
       
   229 			break;
       
   230 		case ESqlKeyword_varchar:
       
   231 			type=EDbColLongText;
       
   232 			break;
       
   233 		case ESqlKeyword_varbinary:
       
   234 			type=EDbColLongBinary;
       
   235 			break;
       
   236 		default:
       
   237 			return SqlErrorL();
       
   238 			};
       
   239 		break;
       
   240 	default:
       
   241 		return SqlErrorL();
       
   242 		}
       
   243 	aDef.iType=type;
       
   244 //
       
   245 // get any optional length
       
   246 	aDef.iMaxLength=KDbUndefinedLength;
       
   247 	TSqlTokenType t=iToken.Type();
       
   248 	switch (type)
       
   249 		{
       
   250 	case EDbColText:
       
   251 	case EDbColBinary:
       
   252 		if (t==ESqlLeftBracket)
       
   253 			{
       
   254 			if (NextToken()==ESqlLiteralInt)
       
   255 				{
       
   256 				iToken.Literal().ToInt32L();
       
   257 				aDef.iMaxLength=iToken.Literal().Int32();
       
   258 				NextToken();
       
   259 				t=RightBracketL();
       
   260 				}
       
   261 			else
       
   262 				return SqlErrorL();
       
   263 			}
       
   264 		break;
       
   265 	default:
       
   266 		break;
       
   267 		}
       
   268 	return t;
       
   269 	}
       
   270 
       
   271 CSqlSearchCondition* TSqlParser::SearchCondition(TInt aNot)
       
   272 //
       
   273 // Parse a search-condition
       
   274 //
       
   275 	{
       
   276 	CSqlSearchCondition* left=BooleanTerm(aNot);
       
   277 	if (left==0 || Parse(ESqlKeyword_or)==ESqlNoToken)
       
   278 		return left;
       
   279 	return CSqlMultiNode::New(aNot ? CSqlMultiNode::EAnd : CSqlMultiNode::EOr,left,SearchCondition(aNot));
       
   280 	}
       
   281 
       
   282 CSqlSearchCondition* TSqlParser::BooleanTerm(TInt aNot)
       
   283 //
       
   284 // Parse a boolean-term
       
   285 //
       
   286 	{
       
   287 	CSqlSearchCondition* left=BooleanFactor(aNot);
       
   288 	if (left==0 || Parse(ESqlKeyword_and)==ESqlNoToken)
       
   289 		return left;
       
   290 	return CSqlMultiNode::New(aNot ? CSqlMultiNode::EOr : CSqlMultiNode::EAnd,left,BooleanTerm(aNot));
       
   291 	}
       
   292 
       
   293 CSqlSearchCondition* TSqlParser::BooleanFactor(TInt aNot)
       
   294 //
       
   295 // Parse a boolean-factor
       
   296 //
       
   297 	{
       
   298 	while (Parse(ESqlKeyword_not))
       
   299 		aNot=~aNot;
       
   300 	return BooleanPrimary(aNot);
       
   301 	}
       
   302 
       
   303 CSqlSearchCondition* TSqlParser::BooleanPrimary(TInt aNot)
       
   304 //
       
   305 // Parse a boolean-factor
       
   306 //
       
   307 	{
       
   308 	// brackets only allowed in this element, so this ordering is valid
       
   309 	if (iToken!=ESqlLeftBracket)
       
   310 		return Predicate(aNot);
       
   311 	// bracketed search condition
       
   312 	NextToken();
       
   313 	CSqlSearchCondition* node=SearchCondition(aNot);
       
   314 	if (!node)
       
   315 		return node;
       
   316 	if (iToken==ESqlRightBracket)
       
   317 		{
       
   318 		NextToken();
       
   319 		return node;
       
   320 		}
       
   321 	delete node;
       
   322 	return SqlError();
       
   323 	}
       
   324 
       
   325 CSqlSearchCondition* TSqlParser::Predicate(TInt aNot)
       
   326 //
       
   327 // Parse predicate
       
   328 // On null return, error will already be set
       
   329 //
       
   330 	{
       
   331 	if (iToken!=ESqlIdentifier)	// column name
       
   332 		return SqlError();
       
   333 	TPtrC column(iToken.Literal().DesC());
       
   334 	TSqlTokenType t=NextToken();
       
   335 	if (t==ESqlIdentifier)
       
   336 		{	// like-predicate or null-predicate
       
   337 		switch (Keyword())
       
   338 			{
       
   339 		case ESqlKeyword_is:	// IS [NOT] NULL
       
   340 			if (Parse(ESqlKeyword_not))
       
   341 				aNot=~aNot;
       
   342 			if (Parse(ESqlKeyword_null)==ESqlNoToken)
       
   343 				return SqlError();
       
   344 			return new CSqlNullPredicate(aNot ? CSqlNullPredicate::EIsNotNull : CSqlNullPredicate::EIsNull,column);
       
   345 		case ESqlKeyword_not:	// NOT LIKE
       
   346 			if (Parse(ESqlKeyword_like)==ESqlNoToken)
       
   347 				return SqlError();
       
   348 			aNot=~aNot;
       
   349 			// drop through to Like
       
   350 		case ESqlKeyword_like:	// LIKE
       
   351 			{
       
   352 			if (iToken!=ESqlLiteralText)
       
   353 				return SqlError();
       
   354 
       
   355 			//Following code is for the implementation of limited-ESCAPE-clause 
       
   356 			const TText *next = iSql.Next(); 
       
   357 			TPtrC pattern(iToken.Literal().DesC());
       
   358 			RSqlLiteral tmp = iToken.Literal();
       
   359 		
       
   360 			NextToken(); // Searching for ESCAPE Key word
       
   361 
       
   362 			if (Keyword() == ESqlKeyword_escape)
       
   363 				{
       
   364 				TInt length = pattern.Length();
       
   365 				if (length <= 0 || length > (KMaxSegmentLength + 2 ))
       
   366 					return SqlError();
       
   367 				TPtrC escapeChar(iToken.Literal().DesC());
       
   368 				if (escapeChar.Length() <= 0)
       
   369 					return SqlError();
       
   370 				TChar escchar = escapeChar[0];
       
   371 				TText newPattern[KMaxSegmentLength + 2]; // '*' can come as first and last char
       
   372 				TInt count = PatternFilter(pattern,escchar, newPattern);
       
   373 				if (count <=0 )
       
   374 					return SqlError();
       
   375 				iToken.Literal().SetText(newPattern,(newPattern + count));
       
   376 				// copy the text to RSqlLiteral as newpattern could go out of scope
       
   377 				if (iToken.Literal().CopyText() != KErrNone)
       
   378 					{
       
   379 					return SqlError();
       
   380 					}
       
   381 				CSqlSearchCondition* node = new CSqlLikePredicate(aNot ? CSqlLikePredicate::ENotLike : CSqlLikePredicate::ELike,column,iToken.Literal());
       
   382 				if (node)
       
   383 					{
       
   384 					NextToken();
       
   385 					node->iIsEscape = ETrue;
       
   386 					}
       
   387 				return node;						
       
   388 				}
       
   389 			else
       
   390 				{
       
   391 				//Setto the previous node
       
   392 				iSql.Set(next);
       
   393 				CSqlSearchCondition* node = new CSqlLikePredicate(aNot ? CSqlLikePredicate::ENotLike : CSqlLikePredicate::ELike,column,tmp);
       
   394 				if(node)
       
   395 					NextToken();
       
   396 				return node;
       
   397 				
       
   398 				}
       
   399 			}
       
   400 		default:
       
   401 			return SqlError();
       
   402 			}
       
   403 		}
       
   404 	// Comparison predicate...
       
   405 	CSqlSearchCondition::TType op;
       
   406 	switch (t)
       
   407 		{
       
   408 	case ESqlGreaterEqual:
       
   409 		aNot=~aNot;
       
   410 		// drop through to less
       
   411 	case ESqlLess:
       
   412 		op=aNot ? CSqlSearchCondition::EGreaterEqual : CSqlSearchCondition::ELess;
       
   413 		break;
       
   414 	case ESqlGreater:
       
   415 		aNot=~aNot;
       
   416 		// drop through to less equal
       
   417 	case ESqlLessEqual:
       
   418 		op=aNot ? CSqlSearchCondition::EGreater: CSqlSearchCondition::ELessEqual;
       
   419 		break;
       
   420 	case ESqlNotEqual:
       
   421 		aNot=~aNot;
       
   422 		// drop through to equal
       
   423 	case ESqlEqual:
       
   424 		op=aNot ? CSqlSearchCondition::ENotEqual : CSqlSearchCondition::EEqual;
       
   425 		break;
       
   426 	default:
       
   427 		return SqlError();
       
   428 		}
       
   429 	t=NextToken();
       
   430 	if (t!=ESqlLiteralInt && t!=ESqlLiteralReal && 
       
   431 			t!=ESqlLiteralTime && t!=ESqlLiteralText &&
       
   432 			t!=ESqlLiteralBlob )
       
   433 		return SqlError();
       
   434 	CSqlSearchCondition* node=new CSqlCompPredicate(op,column,iToken.Literal());
       
   435 	if (node)
       
   436 		NextToken();
       
   437 	return node;
       
   438 	}
       
   439 
       
   440 CSqlSearchCondition* TSqlParser::SearchConditionL()
       
   441 //
       
   442 // Parse a search-condition
       
   443 //
       
   444 	{
       
   445 	CSqlSearchCondition* sc=SearchCondition(0);
       
   446 	if (!sc)
       
   447 		{
       
   448 		__LEAVE_IF_ERROR(Error());	// syntax error
       
   449 		User::LeaveNoMemory();		// otherwise a OOM error
       
   450 		}
       
   451 	return sc;
       
   452 	}
       
   453 
       
   454 void TSqlParser::SortSpecificationL(CDbKey& aKey)
       
   455 //
       
   456 // Parse a sort-specification
       
   457 //
       
   458 	{
       
   459 	for (;;)
       
   460 		{
       
   461 		TDbKeyCol col(IdentifierL());
       
   462 		NextToken();
       
   463 		if (Parse(ESqlKeyword_desc))
       
   464 			col.iOrder=col.EDesc;
       
   465 		else
       
   466 			{
       
   467 			Parse(ESqlKeyword_asc);
       
   468 			col.iOrder=col.EAsc;
       
   469 			}
       
   470 		aKey.AddL(col);
       
   471 		if (iToken!=ESqlComma)
       
   472 			break;
       
   473 		NextToken();
       
   474 		}
       
   475 	}
       
   476 
       
   477 CSqlQuery* TSqlParser::QueryLC()
       
   478 //
       
   479 // Generate a CSqlQuery
       
   480 //
       
   481 	{
       
   482 	CSqlQuery* query=new(ELeave) CSqlQuery;
       
   483 	CleanupStack::PushL(query);
       
   484 	if (ParseL(ESqlKeyword_select)==ESqlAsterisk)
       
   485 		NextToken();
       
   486 	else
       
   487 		ColumnListL(query->iColumns);
       
   488 	ParseL(ESqlKeyword_from);
       
   489 	IdentifierL(query->iTable);
       
   490 	if (Parse(ESqlKeyword_where))
       
   491 		query->iSearchCondition=SearchConditionL();
       
   492 	if (Parse(ESqlKeyword_order))
       
   493 		{
       
   494 		ParseL(ESqlKeyword_by);
       
   495 		SortSpecificationL(query->SortSpecificationL());
       
   496 		}
       
   497 	EndL();
       
   498 	return query;
       
   499 	}
       
   500 
       
   501 CSqlSearchCondition* TSqlParser::SearchConditionLC()
       
   502 //
       
   503 // Parse a standalone search-condition
       
   504 //
       
   505 	{
       
   506 	CSqlSearchCondition* sc=SearchConditionL();
       
   507 	CleanupStack::PushL(sc);
       
   508 	EndL();
       
   509 	return sc;
       
   510 	}
       
   511 
       
   512 CSqlDDLStatement* TSqlParser::CreateTableLC()
       
   513 //
       
   514 // Parse a CREATE TABLE statement
       
   515 //
       
   516 	{
       
   517 	CSqlCreateTableStatement* statement=new(ELeave) CSqlCreateTableStatement;
       
   518 	CleanupStack::PushL(statement);
       
   519 	IdentifierL(statement->iName);
       
   520 	ParseL(ESqlLeftBracket);
       
   521 	TDbCol def;
       
   522 	for (;;)
       
   523 		{
       
   524 		AddColumnSpecL(def);
       
   525 		if (Parse(ESqlKeyword_not))
       
   526 			{
       
   527 			ParseL(ESqlKeyword_null);
       
   528 			def.iAttributes|=TDbCol::ENotNull;
       
   529 			}
       
   530 		if (Parse(ESqlKeyword_autoincrement))
       
   531 			{
       
   532 			def.iAttributes|=TDbCol::EAutoIncrement;
       
   533 			}
       
   534 		statement->iColumns.AddL(def);
       
   535 		if (iToken!=ESqlComma)
       
   536 			break;
       
   537 		NextToken();
       
   538 		}
       
   539 	RightBracketL();
       
   540 	return statement;
       
   541 	}
       
   542 
       
   543 CSqlDDLStatement* TSqlParser::DropTableLC()
       
   544 //
       
   545 // Parse a DROP TABLE statement
       
   546 //
       
   547 	{
       
   548 	CSqlDropTableStatement* statement=new(ELeave) CSqlDropTableStatement;
       
   549 	CleanupStack::PushL(statement);
       
   550 	IdentifierL(statement->iName);
       
   551 	return statement;
       
   552 	}
       
   553 
       
   554 CSqlDDLStatement* TSqlParser::AlterTableLC()
       
   555 //
       
   556 // Parse a CREATE TABLE statement
       
   557 //
       
   558 	{
       
   559 	CSqlAlterTableStatement* statement=new(ELeave) CSqlAlterTableStatement;
       
   560 	CleanupStack::PushL(statement);
       
   561 	IdentifierL(statement->iName);
       
   562 	TSqlTokenType t=Parse(ESqlKeyword_add);
       
   563 	if (t!=ESqlNoToken)
       
   564 		{
       
   565 		TDbCol def;
       
   566 		if (t==ESqlLeftBracket)
       
   567 			{
       
   568 			NextToken();
       
   569 			for (;;)
       
   570 				{
       
   571 				t=AddColumnSpecL(def);
       
   572 				statement->iAdd.AddL(def);
       
   573 				if (t!=ESqlComma)
       
   574 					break;
       
   575 				NextToken();
       
   576 				}
       
   577 			RightBracketL();
       
   578 			}
       
   579 		else
       
   580 			{
       
   581 			AddColumnSpecL(def);
       
   582 			statement->iAdd.AddL(def);
       
   583 			}
       
   584 		}
       
   585 	t=Parse(ESqlKeyword_drop);
       
   586 	if (t!=ESqlNoToken)
       
   587 		{
       
   588 		if (t!=ESqlLeftBracket)
       
   589 			ColumnNameL(statement->iDrop);
       
   590 		else
       
   591 			{
       
   592 			NextToken();
       
   593 			ColumnListL(statement->iDrop);
       
   594 			RightBracketL();
       
   595 			}
       
   596 		}
       
   597 	return statement;
       
   598 	}
       
   599 
       
   600 CSqlDDLStatement* TSqlParser::CreateIndexLC(TBool aUnique)
       
   601 //
       
   602 // Parse a CREATE INDEX statement
       
   603 //
       
   604 	{
       
   605 	CSqlCreateIndexStatement* statement=new(ELeave) CSqlCreateIndexStatement;
       
   606 	CleanupStack::PushL(statement);
       
   607 	if (aUnique)
       
   608 		statement->iKey.MakeUnique();
       
   609 	IdentifierL(statement->iName);
       
   610 	ParseL(ESqlKeyword_on);
       
   611 	IdentifierL(statement->iTable);
       
   612 	ParseL(ESqlLeftBracket);
       
   613 	SortSpecificationL(statement->iKey);
       
   614 	RightBracketL();
       
   615 	statement->iKey.SetComparison(EDbCompareNormal);
       
   616 	TSqlTokenType collate=Parse(ESqlKeyword_collate);
       
   617 	if ( collate != ESqlNoToken )
       
   618 		{
       
   619 		TSqlTokenType normal=Parse(ESqlKeyword_normal);
       
   620 		if ( normal == ESqlNoToken )
       
   621 			{
       
   622 			TSqlTokenType collated=Parse(ESqlKeyword_collated);
       
   623 			if ( collated == ESqlNoToken )
       
   624 				{
       
   625 				TSqlTokenType folded=Parse(ESqlKeyword_folded);
       
   626 				if ( folded != ESqlNoToken)
       
   627 					{
       
   628 					statement->iKey.SetComparison(EDbCompareFolded);
       
   629 					}
       
   630 				}
       
   631 			else 
       
   632 				{
       
   633 				statement->iKey.SetComparison(EDbCompareCollated);
       
   634 				}
       
   635 			}
       
   636 		}
       
   637 	return statement;
       
   638 	}
       
   639 
       
   640 CSqlDDLStatement* TSqlParser::DropIndexLC()
       
   641 //
       
   642 // Parse a DROP INDEX statement
       
   643 //
       
   644 	{
       
   645 	CSqlDropIndexStatement* statement=new(ELeave) CSqlDropIndexStatement;
       
   646 	CleanupStack::PushL(statement);
       
   647 	IdentifierL(statement->iName);
       
   648 	ParseL(ESqlKeyword_from);
       
   649 	IdentifierL(statement->iTable);
       
   650 	return statement;
       
   651 	}
       
   652 
       
   653 CSqlDDLStatement* TSqlParser::DDLStatementLC()
       
   654 	{
       
   655 	CSqlDDLStatement* statement;
       
   656 	if (Parse(ESqlKeyword_create))
       
   657 		{
       
   658 		if (Parse(ESqlKeyword_table))
       
   659 			statement=CreateTableLC();
       
   660 		else
       
   661 			{
       
   662 			TSqlTokenType unique=Parse(ESqlKeyword_unique);
       
   663 			ParseL(ESqlKeyword_index);
       
   664 			statement=CreateIndexLC(unique);
       
   665 			}
       
   666 		}
       
   667 	else if (Parse(ESqlKeyword_drop))
       
   668 		{
       
   669 		if (Parse(ESqlKeyword_table))
       
   670 			statement=DropTableLC();
       
   671 		else
       
   672 			{
       
   673 			ParseL(ESqlKeyword_index);
       
   674 			statement=DropIndexLC();
       
   675 			}
       
   676 		}
       
   677 	else
       
   678 		{
       
   679 		ParseL(ESqlKeyword_alter);
       
   680 		ParseL(ESqlKeyword_table);
       
   681 		statement=AlterTableLC();
       
   682 		}
       
   683 	EndL();
       
   684 	return statement;
       
   685 	}
       
   686 
       
   687 TSqlTokenType TSqlParser::ColumnValueL(CSqlValues& aValues)
       
   688 //
       
   689 // parse a column-value and add to aValues
       
   690 //
       
   691 	{
       
   692 	switch (iToken.Type())
       
   693 		{
       
   694 	case ESqlLiteralInt:
       
   695 	case ESqlLiteralReal:
       
   696 	case ESqlLiteralTime:
       
   697 	case ESqlLiteralText:
       
   698 	case ESqlLiteralBlob:
       
   699 		aValues.AddL(iToken.Literal());
       
   700 		return NextToken();
       
   701 	case ESqlIdentifier:	// NULL
       
   702 		{
       
   703 		TSqlTokenType t=ParseL(ESqlKeyword_null);
       
   704 		aValues.AddL(RSqlLiteral());		// default c'ted RSqlLiteral is null
       
   705 		return t;
       
   706 		}
       
   707 	default:	// SQL error
       
   708 		return SqlErrorL();
       
   709 		}
       
   710 	}
       
   711 
       
   712 CSqlDMLStatement* TSqlParser::InsertStatementLC()
       
   713 //
       
   714 // parse an insert-statement
       
   715 //
       
   716 	{
       
   717 	ParseL(ESqlKeyword_into);
       
   718 	CSqlInsertStatement* statement=CSqlInsertStatement::NewLC();
       
   719 	if (IdentifierL(statement->iQuery.iTable)==ESqlLeftBracket)
       
   720 		{
       
   721 		NextToken();
       
   722 		ColumnListL(statement->iQuery.iColumns);
       
   723 		RightBracketL();
       
   724 		}
       
   725 	ParseL(ESqlKeyword_values);
       
   726 	ParseL(ESqlLeftBracket);
       
   727 	CSqlValues& values=statement->ValuesL();
       
   728 	while (ColumnValueL(values)==ESqlComma)
       
   729 		NextToken();
       
   730 	RightBracketL();
       
   731 	return statement;
       
   732 	}
       
   733 
       
   734 CSqlDMLStatement* TSqlParser::UpdateStatementLC()
       
   735 //
       
   736 // parse an update-statement
       
   737 //
       
   738 	{
       
   739 	CSqlModifyStatement* statement=CSqlModifyStatement::NewLC();
       
   740 	IdentifierL(statement->iQuery.iTable);
       
   741 	ParseL(ESqlKeyword_set);
       
   742 	CSqlValues& values=statement->ValuesL();
       
   743 	for (;;)
       
   744 		{
       
   745 		ColumnNameL(statement->iQuery.iColumns);
       
   746 		ParseL(ESqlEqual);
       
   747 		if (ColumnValueL(values)!=ESqlComma)
       
   748 			break;
       
   749 		NextToken();
       
   750 		}
       
   751 	if (Parse(ESqlKeyword_where))
       
   752 		statement->iQuery.iSearchCondition=SearchConditionL();
       
   753 	return statement;
       
   754 	}
       
   755 
       
   756 CSqlDMLStatement* TSqlParser::DeleteStatementLC()
       
   757 //
       
   758 // parse a delete-statement
       
   759 //
       
   760 	{
       
   761 	ParseL(ESqlKeyword_from);
       
   762 	CSqlModifyStatement* statement=CSqlModifyStatement::NewLC();
       
   763 	IdentifierL(statement->iQuery.iTable);
       
   764 	if (Parse(ESqlKeyword_where))
       
   765 		statement->iQuery.iSearchCondition=SearchConditionL();
       
   766 	return statement;
       
   767 	}
       
   768 
       
   769 CSqlDMLStatement* TSqlParser::DMLStatementLC()
       
   770 	{
       
   771 	CSqlDMLStatement* statement;
       
   772 	if (Parse(ESqlKeyword_insert))
       
   773 		statement=InsertStatementLC();
       
   774 	else if (Parse(ESqlKeyword_update))
       
   775 		statement=UpdateStatementLC();
       
   776 	else 
       
   777 		{
       
   778 		ParseL(ESqlKeyword_delete);
       
   779 		statement=DeleteStatementLC();
       
   780 		}
       
   781 	EndL();
       
   782 	return statement;
       
   783 	}
       
   784 
       
   785 Sql::TStatementType TSqlParser::Type()
       
   786 	{
       
   787 	TSqlKeyword k=TSqlLexer::Keyword(iToken);
       
   788 	if (k==ESqlKeyword_create || k==ESqlKeyword_alter || k==ESqlKeyword_drop)
       
   789 		return Sql::EDDL;
       
   790 	if (k==ESqlKeyword_insert || k==ESqlKeyword_update || k==ESqlKeyword_delete)
       
   791 		return Sql::EDML;
       
   792 	return Sql::ENone;
       
   793 	}
       
   794 	
       
   795 TInt TSqlParser::PatternFilter(const TDesC& aPattern,const TChar aEscape,TText *aNewPatternBuffer )
       
   796 	{
       
   797 	TInt length = aPattern.Length();
       
   798 	TInt count =0;
       
   799 	
       
   800 	// Ensure that the pattern begins and ends with an '*'
       
   801 	if ((length < 2) || (aPattern[0] != KMatchAny || aPattern[length-1] != KMatchAny))
       
   802  		{
       
   803  		return KSqlError;	
       
   804  		}	
       
   805 
       
   806 	for (TInt i = 1 ; i< length -1 ;++i)
       
   807 		{
       
   808 		if (aPattern[i]== (TUint)aEscape) 
       
   809 			{
       
   810 			if ((aPattern[i + 1] == KMatchAny) || (aPattern[i + 1] == KMatchOne) || (aPattern[i + 1] == (TUint)aEscape))
       
   811 				{
       
   812 				i++;
       
   813 				aNewPatternBuffer[count++] = aPattern[i];
       
   814 				}
       
   815 			else
       
   816 				{
       
   817 				return KSqlError;  
       
   818 				}
       
   819 			}
       
   820 		else
       
   821 			{
       
   822 			if ((aPattern[i] == KMatchAny || aPattern[i] == KMatchOne)  )
       
   823 				{
       
   824 				return KSqlError;
       
   825 				}
       
   826 			else
       
   827 				{
       
   828 				aNewPatternBuffer[count++] = aPattern[i];
       
   829 				}
       
   830 			}					
       
   831 		}
       
   832 
       
   833 	return count;
       
   834 	}