1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/dbms/pcdbms/usql/UQ_PARSE.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,834 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// SQL parser
1.18 +//
1.19 +//
1.20 +
1.21 +#include "UQ_STD.H"
1.22 +#include "D32Assert.h"
1.23 +
1.24 +// class TSqlParser
1.25 +
1.26 +const TInt KSqlError = -1;
1.27 +
1.28 +TSqlParser::TSqlParser(const TDesC& aSql)
1.29 + : iSql(aSql)
1.30 + {
1.31 + NextToken(); // parse the first token
1.32 + }
1.33 +
1.34 +TSqlTokenType TSqlParser::NextToken()
1.35 + {
1.36 + return iSql.NextToken(iToken);
1.37 + }
1.38 +
1.39 +CSqlSearchCondition* TSqlParser::SqlError()
1.40 + {
1.41 + if (!Error())
1.42 + iToken.SetError(KErrArgument);
1.43 + return 0;
1.44 + }
1.45 +
1.46 +TSqlTokenType TSqlParser::SqlErrorL()
1.47 +//
1.48 +// Report a SQL syntax error
1.49 +//
1.50 + {
1.51 + return TSqlTokenType(__LEAVE_IF_ERROR(KErrArgument));
1.52 + }
1.53 +
1.54 +TSqlTokenType TSqlParser::Parse(TSqlKeyword aKeyword)
1.55 +//
1.56 +// look for requested keyword, skip to the next token if found
1.57 +// return the next token if found, else ESqlNoToken (==0)
1.58 +//
1.59 + {
1.60 + return TSqlLexer::IsKeyword(aKeyword,iToken) ? NextToken() : ESqlNoToken;
1.61 + }
1.62 +
1.63 +TSqlTokenType TSqlParser::ParseL(TSqlTokenType aToken)
1.64 +//
1.65 +// parse the desired token
1.66 +//
1.67 + {
1.68 + return iToken!=aToken ? SqlErrorL() : NextToken();
1.69 + }
1.70 +
1.71 +TSqlTokenType TSqlParser::ParseL(TSqlKeyword aKeyword)
1.72 +//
1.73 +// parse the desired keyword
1.74 +//
1.75 + {
1.76 + TSqlTokenType t=Parse(aKeyword);
1.77 + return t==ESqlNoToken ? SqlErrorL() : t;
1.78 + }
1.79 +
1.80 +TSqlKeyword TSqlParser::Keyword()
1.81 +//
1.82 +// parse a keyword
1.83 +//
1.84 + {
1.85 + TSqlKeyword k=TSqlLexer::Keyword(iToken);
1.86 + if (k!=ESqlNotKeyword)
1.87 + NextToken();
1.88 + return k;
1.89 + }
1.90 +
1.91 +TSqlTokenType TSqlParser::RightBracketL()
1.92 +//
1.93 +// parse a right bracket, and fail if not found
1.94 +//
1.95 + {
1.96 + return ParseL(ESqlRightBracket);
1.97 + }
1.98 +
1.99 +void TSqlParser::EndL()
1.100 +//
1.101 +// Check that the SQL has been fully parsed
1.102 +//
1.103 + {
1.104 + if (iToken!=ESqlEos)
1.105 + SqlErrorL();
1.106 + }
1.107 +
1.108 +TSqlTokenType TSqlParser::IdentifierL(TPtrC& aIdentifier)
1.109 +//
1.110 +// parse an identifer, fail if not found
1.111 +//
1.112 + {
1.113 + if (iToken!=ESqlIdentifier)
1.114 + return SqlErrorL();
1.115 + const TText* p=iToken.Literal().Ptr();
1.116 + TInt len=iToken.Literal().End()-p;
1.117 + aIdentifier.Set(p,len);
1.118 + return NextToken();
1.119 + }
1.120 +
1.121 +TPtrC TSqlParser::IdentifierL()
1.122 +//
1.123 +// parse an identifer, fail if not found
1.124 +//
1.125 + {
1.126 + if (iToken!=ESqlIdentifier)
1.127 + SqlErrorL();
1.128 + return iToken.Literal().DesC();
1.129 + }
1.130 +
1.131 +TSqlTokenType TSqlParser::ColumnNameL(RSqlColumnList& aList)
1.132 +//
1.133 +// Parse a column-identifier
1.134 +//
1.135 + {
1.136 + __LEAVE_IF_ERROR(aList.Append(IdentifierL()));
1.137 + return NextToken();
1.138 + }
1.139 +
1.140 +TSqlTokenType TSqlParser::ColumnListL(RSqlColumnList& aList)
1.141 +//
1.142 +// Parse a column-identifier-comma-list
1.143 +//
1.144 + {
1.145 + for (;;)
1.146 + {
1.147 + TSqlTokenType t=ColumnNameL(aList);
1.148 + if (t!=ESqlComma)
1.149 + return t;
1.150 + NextToken();
1.151 + }
1.152 + }
1.153 +
1.154 +TSqlTokenType TSqlParser::AddColumnSpecL(TDbCol& aDef)
1.155 +//
1.156 +// Parse an add-column-spec
1.157 +//
1.158 + {
1.159 + aDef.iAttributes=0;
1.160 + aDef.iName=IdentifierL();
1.161 + NextToken();
1.162 +//
1.163 + TDbColType type;
1.164 + switch (Keyword())
1.165 + {
1.166 + case ESqlKeyword_bit:
1.167 + type=EDbColBit;
1.168 + break;
1.169 + case ESqlKeyword_tinyint:
1.170 + type=EDbColInt8;
1.171 + break;
1.172 + case ESqlKeyword_smallint:
1.173 + type=EDbColInt16;
1.174 + break;
1.175 + case ESqlKeyword_integer:
1.176 + type=EDbColInt32;
1.177 + break;
1.178 + case ESqlKeyword_counter:
1.179 + aDef.iAttributes=aDef.EAutoIncrement;
1.180 + type=EDbColUint32;
1.181 + break;
1.182 + case ESqlKeyword_bigint:
1.183 + type=EDbColInt64;
1.184 + break;
1.185 + case ESqlKeyword_real:
1.186 + type=EDbColReal32;
1.187 + break;
1.188 + case ESqlKeyword_double:
1.189 + Parse(ESqlKeyword_precision);
1.190 + // fall through
1.191 + case ESqlKeyword_float:
1.192 + type=EDbColReal64;
1.193 + break;
1.194 + case ESqlKeyword_date:
1.195 + case ESqlKeyword_time:
1.196 + case ESqlKeyword_timestamp:
1.197 + type=EDbColDateTime;
1.198 + break;
1.199 + case ESqlKeyword_char:
1.200 + case ESqlKeyword_varchar:
1.201 + type=EDbColText;
1.202 + break;
1.203 + case ESqlKeyword_char8:
1.204 + case ESqlKeyword_varchar8:
1.205 + type=EDbColText8;
1.206 + break;
1.207 + case ESqlKeyword_binary:
1.208 + case ESqlKeyword_varbinary:
1.209 + type=EDbColBinary;
1.210 + break;
1.211 + case ESqlKeyword_unsigned: // unsigned tinyint, smallint or integer
1.212 + switch (Keyword())
1.213 + {
1.214 + case ESqlKeyword_tinyint:
1.215 + type=EDbColUint8;
1.216 + break;
1.217 + case ESqlKeyword_smallint:
1.218 + type=EDbColUint16;
1.219 + break;
1.220 + case ESqlKeyword_integer:
1.221 + type=EDbColUint32;
1.222 + break;
1.223 + default:
1.224 + return SqlErrorL();
1.225 + };
1.226 + break;
1.227 + case ESqlKeyword_long: // varchar or varbinary
1.228 + switch (Keyword())
1.229 + {
1.230 + case ESqlKeyword_varchar8:
1.231 + type=EDbColLongText8;
1.232 + break;
1.233 + case ESqlKeyword_varchar:
1.234 + type=EDbColLongText;
1.235 + break;
1.236 + case ESqlKeyword_varbinary:
1.237 + type=EDbColLongBinary;
1.238 + break;
1.239 + default:
1.240 + return SqlErrorL();
1.241 + };
1.242 + break;
1.243 + default:
1.244 + return SqlErrorL();
1.245 + }
1.246 + aDef.iType=type;
1.247 +//
1.248 +// get any optional length
1.249 + aDef.iMaxLength=KDbUndefinedLength;
1.250 + TSqlTokenType t=iToken.Type();
1.251 + switch (type)
1.252 + {
1.253 + case EDbColText:
1.254 + case EDbColBinary:
1.255 + if (t==ESqlLeftBracket)
1.256 + {
1.257 + if (NextToken()==ESqlLiteralInt)
1.258 + {
1.259 + iToken.Literal().ToInt32L();
1.260 + aDef.iMaxLength=iToken.Literal().Int32();
1.261 + NextToken();
1.262 + t=RightBracketL();
1.263 + }
1.264 + else
1.265 + return SqlErrorL();
1.266 + }
1.267 + break;
1.268 + default:
1.269 + break;
1.270 + }
1.271 + return t;
1.272 + }
1.273 +
1.274 +CSqlSearchCondition* TSqlParser::SearchCondition(TInt aNot)
1.275 +//
1.276 +// Parse a search-condition
1.277 +//
1.278 + {
1.279 + CSqlSearchCondition* left=BooleanTerm(aNot);
1.280 + if (left==0 || Parse(ESqlKeyword_or)==ESqlNoToken)
1.281 + return left;
1.282 + return CSqlMultiNode::New(aNot ? CSqlMultiNode::EAnd : CSqlMultiNode::EOr,left,SearchCondition(aNot));
1.283 + }
1.284 +
1.285 +CSqlSearchCondition* TSqlParser::BooleanTerm(TInt aNot)
1.286 +//
1.287 +// Parse a boolean-term
1.288 +//
1.289 + {
1.290 + CSqlSearchCondition* left=BooleanFactor(aNot);
1.291 + if (left==0 || Parse(ESqlKeyword_and)==ESqlNoToken)
1.292 + return left;
1.293 + return CSqlMultiNode::New(aNot ? CSqlMultiNode::EOr : CSqlMultiNode::EAnd,left,BooleanTerm(aNot));
1.294 + }
1.295 +
1.296 +CSqlSearchCondition* TSqlParser::BooleanFactor(TInt aNot)
1.297 +//
1.298 +// Parse a boolean-factor
1.299 +//
1.300 + {
1.301 + while (Parse(ESqlKeyword_not))
1.302 + aNot=~aNot;
1.303 + return BooleanPrimary(aNot);
1.304 + }
1.305 +
1.306 +CSqlSearchCondition* TSqlParser::BooleanPrimary(TInt aNot)
1.307 +//
1.308 +// Parse a boolean-factor
1.309 +//
1.310 + {
1.311 + // brackets only allowed in this element, so this ordering is valid
1.312 + if (iToken!=ESqlLeftBracket)
1.313 + return Predicate(aNot);
1.314 + // bracketed search condition
1.315 + NextToken();
1.316 + CSqlSearchCondition* node=SearchCondition(aNot);
1.317 + if (!node)
1.318 + return node;
1.319 + if (iToken==ESqlRightBracket)
1.320 + {
1.321 + NextToken();
1.322 + return node;
1.323 + }
1.324 + delete node;
1.325 + return SqlError();
1.326 + }
1.327 +
1.328 +CSqlSearchCondition* TSqlParser::Predicate(TInt aNot)
1.329 +//
1.330 +// Parse predicate
1.331 +// On null return, error will already be set
1.332 +//
1.333 + {
1.334 + if (iToken!=ESqlIdentifier) // column name
1.335 + return SqlError();
1.336 + TPtrC column(iToken.Literal().DesC());
1.337 + TSqlTokenType t=NextToken();
1.338 + if (t==ESqlIdentifier)
1.339 + { // like-predicate or null-predicate
1.340 + switch (Keyword())
1.341 + {
1.342 + case ESqlKeyword_is: // IS [NOT] NULL
1.343 + if (Parse(ESqlKeyword_not))
1.344 + aNot=~aNot;
1.345 + if (Parse(ESqlKeyword_null)==ESqlNoToken)
1.346 + return SqlError();
1.347 + return new CSqlNullPredicate(aNot ? CSqlNullPredicate::EIsNotNull : CSqlNullPredicate::EIsNull,column);
1.348 + case ESqlKeyword_not: // NOT LIKE
1.349 + if (Parse(ESqlKeyword_like)==ESqlNoToken)
1.350 + return SqlError();
1.351 + aNot=~aNot;
1.352 + // drop through to Like
1.353 + case ESqlKeyword_like: // LIKE
1.354 + {
1.355 + if (iToken!=ESqlLiteralText)
1.356 + return SqlError();
1.357 +
1.358 + //Following code is for the implementation of limited-ESCAPE-clause
1.359 + const TText *next = iSql.Next();
1.360 + TPtrC pattern(iToken.Literal().DesC());
1.361 + RSqlLiteral tmp = iToken.Literal();
1.362 +
1.363 + NextToken(); // Searching for ESCAPE Key word
1.364 +
1.365 + if (Keyword() == ESqlKeyword_escape)
1.366 + {
1.367 + TInt length = pattern.Length();
1.368 + if (length <= 0 || length > (KMaxSegmentLength + 2 ))
1.369 + return SqlError();
1.370 + TPtrC escapeChar(iToken.Literal().DesC());
1.371 + if (escapeChar.Length() <= 0)
1.372 + return SqlError();
1.373 + TChar escchar = escapeChar[0];
1.374 + TText newPattern[KMaxSegmentLength + 2]; // '*' can come as first and last char
1.375 + TInt count = PatternFilter(pattern,escchar, newPattern);
1.376 + if (count <=0 )
1.377 + return SqlError();
1.378 + iToken.Literal().SetText(newPattern,(newPattern + count));
1.379 + // copy the text to RSqlLiteral as newpattern could go out of scope
1.380 + if (iToken.Literal().CopyText() != KErrNone)
1.381 + {
1.382 + return SqlError();
1.383 + }
1.384 + CSqlSearchCondition* node = new CSqlLikePredicate(aNot ? CSqlLikePredicate::ENotLike : CSqlLikePredicate::ELike,column,iToken.Literal());
1.385 + if (node)
1.386 + {
1.387 + NextToken();
1.388 + node->iIsEscape = ETrue;
1.389 + }
1.390 + return node;
1.391 + }
1.392 + else
1.393 + {
1.394 + //Setto the previous node
1.395 + iSql.Set(next);
1.396 + CSqlSearchCondition* node = new CSqlLikePredicate(aNot ? CSqlLikePredicate::ENotLike : CSqlLikePredicate::ELike,column,tmp);
1.397 + if(node)
1.398 + NextToken();
1.399 + return node;
1.400 +
1.401 + }
1.402 + }
1.403 + default:
1.404 + return SqlError();
1.405 + }
1.406 + }
1.407 + // Comparison predicate...
1.408 + CSqlSearchCondition::TType op;
1.409 + switch (t)
1.410 + {
1.411 + case ESqlGreaterEqual:
1.412 + aNot=~aNot;
1.413 + // drop through to less
1.414 + case ESqlLess:
1.415 + op=aNot ? CSqlSearchCondition::EGreaterEqual : CSqlSearchCondition::ELess;
1.416 + break;
1.417 + case ESqlGreater:
1.418 + aNot=~aNot;
1.419 + // drop through to less equal
1.420 + case ESqlLessEqual:
1.421 + op=aNot ? CSqlSearchCondition::EGreater: CSqlSearchCondition::ELessEqual;
1.422 + break;
1.423 + case ESqlNotEqual:
1.424 + aNot=~aNot;
1.425 + // drop through to equal
1.426 + case ESqlEqual:
1.427 + op=aNot ? CSqlSearchCondition::ENotEqual : CSqlSearchCondition::EEqual;
1.428 + break;
1.429 + default:
1.430 + return SqlError();
1.431 + }
1.432 + t=NextToken();
1.433 + if (t!=ESqlLiteralInt && t!=ESqlLiteralReal &&
1.434 + t!=ESqlLiteralTime && t!=ESqlLiteralText &&
1.435 + t!=ESqlLiteralBlob )
1.436 + return SqlError();
1.437 + CSqlSearchCondition* node=new CSqlCompPredicate(op,column,iToken.Literal());
1.438 + if (node)
1.439 + NextToken();
1.440 + return node;
1.441 + }
1.442 +
1.443 +CSqlSearchCondition* TSqlParser::SearchConditionL()
1.444 +//
1.445 +// Parse a search-condition
1.446 +//
1.447 + {
1.448 + CSqlSearchCondition* sc=SearchCondition(0);
1.449 + if (!sc)
1.450 + {
1.451 + __LEAVE_IF_ERROR(Error()); // syntax error
1.452 + User::LeaveNoMemory(); // otherwise a OOM error
1.453 + }
1.454 + return sc;
1.455 + }
1.456 +
1.457 +void TSqlParser::SortSpecificationL(CDbKey& aKey)
1.458 +//
1.459 +// Parse a sort-specification
1.460 +//
1.461 + {
1.462 + for (;;)
1.463 + {
1.464 + TDbKeyCol col(IdentifierL());
1.465 + NextToken();
1.466 + if (Parse(ESqlKeyword_desc))
1.467 + col.iOrder=col.EDesc;
1.468 + else
1.469 + {
1.470 + Parse(ESqlKeyword_asc);
1.471 + col.iOrder=col.EAsc;
1.472 + }
1.473 + aKey.AddL(col);
1.474 + if (iToken!=ESqlComma)
1.475 + break;
1.476 + NextToken();
1.477 + }
1.478 + }
1.479 +
1.480 +CSqlQuery* TSqlParser::QueryLC()
1.481 +//
1.482 +// Generate a CSqlQuery
1.483 +//
1.484 + {
1.485 + CSqlQuery* query=new(ELeave) CSqlQuery;
1.486 + CleanupStack::PushL(query);
1.487 + if (ParseL(ESqlKeyword_select)==ESqlAsterisk)
1.488 + NextToken();
1.489 + else
1.490 + ColumnListL(query->iColumns);
1.491 + ParseL(ESqlKeyword_from);
1.492 + IdentifierL(query->iTable);
1.493 + if (Parse(ESqlKeyword_where))
1.494 + query->iSearchCondition=SearchConditionL();
1.495 + if (Parse(ESqlKeyword_order))
1.496 + {
1.497 + ParseL(ESqlKeyword_by);
1.498 + SortSpecificationL(query->SortSpecificationL());
1.499 + }
1.500 + EndL();
1.501 + return query;
1.502 + }
1.503 +
1.504 +CSqlSearchCondition* TSqlParser::SearchConditionLC()
1.505 +//
1.506 +// Parse a standalone search-condition
1.507 +//
1.508 + {
1.509 + CSqlSearchCondition* sc=SearchConditionL();
1.510 + CleanupStack::PushL(sc);
1.511 + EndL();
1.512 + return sc;
1.513 + }
1.514 +
1.515 +CSqlDDLStatement* TSqlParser::CreateTableLC()
1.516 +//
1.517 +// Parse a CREATE TABLE statement
1.518 +//
1.519 + {
1.520 + CSqlCreateTableStatement* statement=new(ELeave) CSqlCreateTableStatement;
1.521 + CleanupStack::PushL(statement);
1.522 + IdentifierL(statement->iName);
1.523 + ParseL(ESqlLeftBracket);
1.524 + TDbCol def;
1.525 + for (;;)
1.526 + {
1.527 + AddColumnSpecL(def);
1.528 + if (Parse(ESqlKeyword_not))
1.529 + {
1.530 + ParseL(ESqlKeyword_null);
1.531 + def.iAttributes|=TDbCol::ENotNull;
1.532 + }
1.533 + if (Parse(ESqlKeyword_autoincrement))
1.534 + {
1.535 + def.iAttributes|=TDbCol::EAutoIncrement;
1.536 + }
1.537 + statement->iColumns.AddL(def);
1.538 + if (iToken!=ESqlComma)
1.539 + break;
1.540 + NextToken();
1.541 + }
1.542 + RightBracketL();
1.543 + return statement;
1.544 + }
1.545 +
1.546 +CSqlDDLStatement* TSqlParser::DropTableLC()
1.547 +//
1.548 +// Parse a DROP TABLE statement
1.549 +//
1.550 + {
1.551 + CSqlDropTableStatement* statement=new(ELeave) CSqlDropTableStatement;
1.552 + CleanupStack::PushL(statement);
1.553 + IdentifierL(statement->iName);
1.554 + return statement;
1.555 + }
1.556 +
1.557 +CSqlDDLStatement* TSqlParser::AlterTableLC()
1.558 +//
1.559 +// Parse a CREATE TABLE statement
1.560 +//
1.561 + {
1.562 + CSqlAlterTableStatement* statement=new(ELeave) CSqlAlterTableStatement;
1.563 + CleanupStack::PushL(statement);
1.564 + IdentifierL(statement->iName);
1.565 + TSqlTokenType t=Parse(ESqlKeyword_add);
1.566 + if (t!=ESqlNoToken)
1.567 + {
1.568 + TDbCol def;
1.569 + if (t==ESqlLeftBracket)
1.570 + {
1.571 + NextToken();
1.572 + for (;;)
1.573 + {
1.574 + t=AddColumnSpecL(def);
1.575 + statement->iAdd.AddL(def);
1.576 + if (t!=ESqlComma)
1.577 + break;
1.578 + NextToken();
1.579 + }
1.580 + RightBracketL();
1.581 + }
1.582 + else
1.583 + {
1.584 + AddColumnSpecL(def);
1.585 + statement->iAdd.AddL(def);
1.586 + }
1.587 + }
1.588 + t=Parse(ESqlKeyword_drop);
1.589 + if (t!=ESqlNoToken)
1.590 + {
1.591 + if (t!=ESqlLeftBracket)
1.592 + ColumnNameL(statement->iDrop);
1.593 + else
1.594 + {
1.595 + NextToken();
1.596 + ColumnListL(statement->iDrop);
1.597 + RightBracketL();
1.598 + }
1.599 + }
1.600 + return statement;
1.601 + }
1.602 +
1.603 +CSqlDDLStatement* TSqlParser::CreateIndexLC(TBool aUnique)
1.604 +//
1.605 +// Parse a CREATE INDEX statement
1.606 +//
1.607 + {
1.608 + CSqlCreateIndexStatement* statement=new(ELeave) CSqlCreateIndexStatement;
1.609 + CleanupStack::PushL(statement);
1.610 + if (aUnique)
1.611 + statement->iKey.MakeUnique();
1.612 + IdentifierL(statement->iName);
1.613 + ParseL(ESqlKeyword_on);
1.614 + IdentifierL(statement->iTable);
1.615 + ParseL(ESqlLeftBracket);
1.616 + SortSpecificationL(statement->iKey);
1.617 + RightBracketL();
1.618 + statement->iKey.SetComparison(EDbCompareNormal);
1.619 + TSqlTokenType collate=Parse(ESqlKeyword_collate);
1.620 + if ( collate != ESqlNoToken )
1.621 + {
1.622 + TSqlTokenType normal=Parse(ESqlKeyword_normal);
1.623 + if ( normal == ESqlNoToken )
1.624 + {
1.625 + TSqlTokenType collated=Parse(ESqlKeyword_collated);
1.626 + if ( collated == ESqlNoToken )
1.627 + {
1.628 + TSqlTokenType folded=Parse(ESqlKeyword_folded);
1.629 + if ( folded != ESqlNoToken)
1.630 + {
1.631 + statement->iKey.SetComparison(EDbCompareFolded);
1.632 + }
1.633 + }
1.634 + else
1.635 + {
1.636 + statement->iKey.SetComparison(EDbCompareCollated);
1.637 + }
1.638 + }
1.639 + }
1.640 + return statement;
1.641 + }
1.642 +
1.643 +CSqlDDLStatement* TSqlParser::DropIndexLC()
1.644 +//
1.645 +// Parse a DROP INDEX statement
1.646 +//
1.647 + {
1.648 + CSqlDropIndexStatement* statement=new(ELeave) CSqlDropIndexStatement;
1.649 + CleanupStack::PushL(statement);
1.650 + IdentifierL(statement->iName);
1.651 + ParseL(ESqlKeyword_from);
1.652 + IdentifierL(statement->iTable);
1.653 + return statement;
1.654 + }
1.655 +
1.656 +CSqlDDLStatement* TSqlParser::DDLStatementLC()
1.657 + {
1.658 + CSqlDDLStatement* statement;
1.659 + if (Parse(ESqlKeyword_create))
1.660 + {
1.661 + if (Parse(ESqlKeyword_table))
1.662 + statement=CreateTableLC();
1.663 + else
1.664 + {
1.665 + TSqlTokenType unique=Parse(ESqlKeyword_unique);
1.666 + ParseL(ESqlKeyword_index);
1.667 + statement=CreateIndexLC(unique);
1.668 + }
1.669 + }
1.670 + else if (Parse(ESqlKeyword_drop))
1.671 + {
1.672 + if (Parse(ESqlKeyword_table))
1.673 + statement=DropTableLC();
1.674 + else
1.675 + {
1.676 + ParseL(ESqlKeyword_index);
1.677 + statement=DropIndexLC();
1.678 + }
1.679 + }
1.680 + else
1.681 + {
1.682 + ParseL(ESqlKeyword_alter);
1.683 + ParseL(ESqlKeyword_table);
1.684 + statement=AlterTableLC();
1.685 + }
1.686 + EndL();
1.687 + return statement;
1.688 + }
1.689 +
1.690 +TSqlTokenType TSqlParser::ColumnValueL(CSqlValues& aValues)
1.691 +//
1.692 +// parse a column-value and add to aValues
1.693 +//
1.694 + {
1.695 + switch (iToken.Type())
1.696 + {
1.697 + case ESqlLiteralInt:
1.698 + case ESqlLiteralReal:
1.699 + case ESqlLiteralTime:
1.700 + case ESqlLiteralText:
1.701 + case ESqlLiteralBlob:
1.702 + aValues.AddL(iToken.Literal());
1.703 + return NextToken();
1.704 + case ESqlIdentifier: // NULL
1.705 + {
1.706 + TSqlTokenType t=ParseL(ESqlKeyword_null);
1.707 + aValues.AddL(RSqlLiteral()); // default c'ted RSqlLiteral is null
1.708 + return t;
1.709 + }
1.710 + default: // SQL error
1.711 + return SqlErrorL();
1.712 + }
1.713 + }
1.714 +
1.715 +CSqlDMLStatement* TSqlParser::InsertStatementLC()
1.716 +//
1.717 +// parse an insert-statement
1.718 +//
1.719 + {
1.720 + ParseL(ESqlKeyword_into);
1.721 + CSqlInsertStatement* statement=CSqlInsertStatement::NewLC();
1.722 + if (IdentifierL(statement->iQuery.iTable)==ESqlLeftBracket)
1.723 + {
1.724 + NextToken();
1.725 + ColumnListL(statement->iQuery.iColumns);
1.726 + RightBracketL();
1.727 + }
1.728 + ParseL(ESqlKeyword_values);
1.729 + ParseL(ESqlLeftBracket);
1.730 + CSqlValues& values=statement->ValuesL();
1.731 + while (ColumnValueL(values)==ESqlComma)
1.732 + NextToken();
1.733 + RightBracketL();
1.734 + return statement;
1.735 + }
1.736 +
1.737 +CSqlDMLStatement* TSqlParser::UpdateStatementLC()
1.738 +//
1.739 +// parse an update-statement
1.740 +//
1.741 + {
1.742 + CSqlModifyStatement* statement=CSqlModifyStatement::NewLC();
1.743 + IdentifierL(statement->iQuery.iTable);
1.744 + ParseL(ESqlKeyword_set);
1.745 + CSqlValues& values=statement->ValuesL();
1.746 + for (;;)
1.747 + {
1.748 + ColumnNameL(statement->iQuery.iColumns);
1.749 + ParseL(ESqlEqual);
1.750 + if (ColumnValueL(values)!=ESqlComma)
1.751 + break;
1.752 + NextToken();
1.753 + }
1.754 + if (Parse(ESqlKeyword_where))
1.755 + statement->iQuery.iSearchCondition=SearchConditionL();
1.756 + return statement;
1.757 + }
1.758 +
1.759 +CSqlDMLStatement* TSqlParser::DeleteStatementLC()
1.760 +//
1.761 +// parse a delete-statement
1.762 +//
1.763 + {
1.764 + ParseL(ESqlKeyword_from);
1.765 + CSqlModifyStatement* statement=CSqlModifyStatement::NewLC();
1.766 + IdentifierL(statement->iQuery.iTable);
1.767 + if (Parse(ESqlKeyword_where))
1.768 + statement->iQuery.iSearchCondition=SearchConditionL();
1.769 + return statement;
1.770 + }
1.771 +
1.772 +CSqlDMLStatement* TSqlParser::DMLStatementLC()
1.773 + {
1.774 + CSqlDMLStatement* statement;
1.775 + if (Parse(ESqlKeyword_insert))
1.776 + statement=InsertStatementLC();
1.777 + else if (Parse(ESqlKeyword_update))
1.778 + statement=UpdateStatementLC();
1.779 + else
1.780 + {
1.781 + ParseL(ESqlKeyword_delete);
1.782 + statement=DeleteStatementLC();
1.783 + }
1.784 + EndL();
1.785 + return statement;
1.786 + }
1.787 +
1.788 +Sql::TStatementType TSqlParser::Type()
1.789 + {
1.790 + TSqlKeyword k=TSqlLexer::Keyword(iToken);
1.791 + if (k==ESqlKeyword_create || k==ESqlKeyword_alter || k==ESqlKeyword_drop)
1.792 + return Sql::EDDL;
1.793 + if (k==ESqlKeyword_insert || k==ESqlKeyword_update || k==ESqlKeyword_delete)
1.794 + return Sql::EDML;
1.795 + return Sql::ENone;
1.796 + }
1.797 +
1.798 +TInt TSqlParser::PatternFilter(const TDesC& aPattern,const TChar aEscape,TText *aNewPatternBuffer )
1.799 + {
1.800 + TInt length = aPattern.Length();
1.801 + TInt count =0;
1.802 +
1.803 + // Ensure that the pattern begins and ends with an '*'
1.804 + if ((length < 2) || (aPattern[0] != KMatchAny || aPattern[length-1] != KMatchAny))
1.805 + {
1.806 + return KSqlError;
1.807 + }
1.808 +
1.809 + for (TInt i = 1 ; i< length -1 ;++i)
1.810 + {
1.811 + if (aPattern[i]== (TUint)aEscape)
1.812 + {
1.813 + if ((aPattern[i + 1] == KMatchAny) || (aPattern[i + 1] == KMatchOne) || (aPattern[i + 1] == (TUint)aEscape))
1.814 + {
1.815 + i++;
1.816 + aNewPatternBuffer[count++] = aPattern[i];
1.817 + }
1.818 + else
1.819 + {
1.820 + return KSqlError;
1.821 + }
1.822 + }
1.823 + else
1.824 + {
1.825 + if ((aPattern[i] == KMatchAny || aPattern[i] == KMatchOne) )
1.826 + {
1.827 + return KSqlError;
1.828 + }
1.829 + else
1.830 + {
1.831 + aNewPatternBuffer[count++] = aPattern[i];
1.832 + }
1.833 + }
1.834 + }
1.835 +
1.836 + return count;
1.837 + }