persistentstorage/sql/TEST/t_sqlapi2.cpp
changeset 0 08ec8eefde2f
child 10 fa9941cf3867
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/sql/TEST/t_sqlapi2.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,1744 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <e32test.h>
+#include <e32math.h>
+#include <bautils.h>
+#include <s32buf.h>				//MStreamBuf
+#include <sqldb.h>
+#include "SqlResourceProfiler.h"
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+RTest TheTest(_L("t_sqlapi2 test"));
+RSqlDatabase TheDb;
+RSqlStatement TheStmt;
+
+_LIT(KTestDir, "c:\\test\\");
+_LIT(KTestDbName1, "c:\\test\\t_sqlapi2_1.db");
+_LIT(KTestDbName2, "c:\\private\\1111C1EF\\t_sqlapi2_2.db");//t_sqlapi2 app - private database
+
+_LIT(KDbInjectedName1, "DELETE FROM symbian_settings;c:\\test\\A.db");
+_LIT(KDbInjectedName2, "c:\\test\\A.db;DELETE FROM symbian_settings;");
+
+const TInt KBufLen = 8192;
+TBuf<KBufLen> TheBuf;
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+void DeleteTestFiles()
+	{
+	TheStmt.Close();
+	TheDb.Close();
+	(void)RSqlDatabase::Delete(KDbInjectedName2);
+	(void)RSqlDatabase::Delete(KDbInjectedName1);
+	(void)RSqlDatabase::Delete(KTestDbName2);
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+
+///////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////
+//Test macros and functions
+void Check(TInt aValue, TInt aLine)
+	{
+	if(!aValue)
+		{
+		DeleteTestFiles();
+		TheTest(EFalse, aLine);
+		}
+	}
+void Check(TInt aValue, TInt aExpected, TInt aLine)
+	{
+	if(aValue != aExpected)
+		{
+		DeleteTestFiles();
+		RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
+		TheTest(EFalse, aLine);
+		}
+	}
+#define TEST(arg) ::Check((arg), __LINE__)
+#define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+void CreateTestEnv()
+    {
+    RFs fs;
+	TInt err = fs.Connect();
+	TEST2(err, KErrNone);
+
+	err = fs.MkDir(KTestDir);
+	TEST(err == KErrNone || err == KErrAlreadyExists);
+
+	err = fs.CreatePrivatePath(EDriveC);
+	TEST(err == KErrNone || err == KErrAlreadyExists);
+
+	fs.Close();
+	}
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-3512
+@SYMTestCaseDesc		RSqlStatement::ColumnCount() - SELECT statements test
+						The test creates a database with a table and then checks the ColumnCount()
+						return result for the following statements:
+						- select all columns;
+						- select a subset;
+						- select an expression;
+						- select a constant;
+						- multi-table select;
+						- select a function;
+						- select plus sub-query;
+@SYMTestPriority		High
+@SYMTestActions			RSqlStatement::ColumnCount() test
+@SYMTestExpectedResults Test must not fail
+@SYMREQ					REQ8035
+*/
+void ColumnCountTest()
+	{
+
+	TInt err = TheDb.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+	//Create table 1
+	err = TheDb.Exec(_L("CREATE TABLE A(Id INTEGER,Name TEXT,Id2 INTEGER,Data BLOB)"));
+	TEST(err >= 0);
+	
+	err = TheDb.Exec(_L("INSERT INTO A VALUES(1,'AAA',6234567890,x'11AAFD0C771188')"));
+	TEST2(err, 1);
+		
+	//Select all columns (SELECT *)
+	err = TheStmt.Prepare(TheDb, _L("SELECT * FROM A"));
+	TEST2(err, KErrNone);
+	TInt cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 4);
+	TheStmt.Close();
+	//Select all columns (SELECT a,b,c...)
+	err = TheStmt.Prepare(TheDb, _L("SELECT Id,Name,Id2,Data FROM A"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 4);
+	TheStmt.Close();
+	//Select column subset
+	err = TheStmt.Prepare(TheDb, _L("SELECT Id,Name,Data FROM A"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 3);
+	TheStmt.Close();
+	//Select column subset + expression
+	err = TheStmt.Prepare(TheDb, _L("SELECT Id,Id+Id2 FROM A"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 2);
+	TheStmt.Close();
+	//Select column subset + constant
+	err = TheStmt.Prepare(TheDb, _L("SELECT Id,Id2,345.78 FROM A"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 3);
+	TheStmt.Close();
+	//Select SQL function
+	err = TheStmt.Prepare(TheDb, _L("SELECT COUNT(*) FROM A"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 1);
+	TheStmt.Close();
+	//Create table 2
+	err = TheDb.Exec(_L("CREATE TABLE B(Id INTEGER, S INTEGER)"));
+	TEST(err >= 0);
+	err = TheDb.Exec(_L("INSERT INTO B VALUES(1,25)"));
+	TEST2(err, 1);
+	//Multitable select
+	err = TheStmt.Prepare(TheDb, _L("SELECT A.Id,B.S FROM A,B WHERE A.Id = B.Id"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 2);
+	TheStmt.Close();
+	//Select + Subquery
+	err = TheStmt.Prepare(TheDb, _L("SELECT Id FROM A WHERE (SELECT S FROM B WHERE A.Id = B.Id) > 10"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 1);
+	TheStmt.Close();
+	//Cleanup
+	TheDb.Close();
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-3513
+@SYMTestCaseDesc		RSqlStatement::ColumnCount() - DDL and DML statements test
+						The test creates a database with a table and then checks the ColumnCount() return result for
+						DML statements (INSERT/UPDATE/DELETE) and DDL statements (CREATE TABLE/INDEX, DROP TABLE?INDEX).
+						The column count for DML and DDL statements should be 0.
+@SYMTestPriority		High
+@SYMTestActions			RSqlStatement::ColumnCount() test
+@SYMTestExpectedResults Test must not fail
+@SYMREQ					REQ8035
+*/
+void ColumnCountTest2()
+	{
+	TInt err = TheDb.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+	//Create table
+	err = TheDb.Exec(_L("CREATE TABLE A(Id INTEGER,Name TEXT,Id2 INTEGER,Data BLOB)"));
+	TEST(err >= 0);
+	err = TheDb.Exec(_L("INSERT INTO A VALUES(1,'AAA',6234567890,x'11AAFD0C771188')"));
+	TEST2(err, 1);
+	//INSERT statement
+	err = TheStmt.Prepare(TheDb, _L("INSERT INTO A(Id,Id2) VALUES(:P1,:P2)"));
+	TEST2(err, KErrNone);
+	TInt cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 0);
+	TheStmt.Close();
+	//UPDATE statement
+	err = TheStmt.Prepare(TheDb, _L("UPDATE A SET Id2=100 WHERE Id=:P1"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 0);
+	TheStmt.Close();
+	//DELETE statement
+	err = TheStmt.Prepare(TheDb, _L("DELETE FROM A WHERE Id=:P1"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 0);
+	TheStmt.Close();
+	//CREATE TABLE statement
+	err = TheStmt.Prepare(TheDb, _L("CREATE TABLE B AS SELECT * FROM A"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 0);
+	TheStmt.Close();
+	//DROP TABLE statement
+	err = TheStmt.Prepare(TheDb, _L("DROP TABLE A"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 0);
+	TheStmt.Close();
+	//CREATE INDEX statement
+	err = TheStmt.Prepare(TheDb, _L("CREATE INDEX I ON A(Id)"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 0);
+	err = TheStmt.Exec();
+	TEST(err >= 0);
+	TheStmt.Close();
+	//DROP INDEX statement
+	err = TheStmt.Prepare(TheDb, _L("DROP INDEX I"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 0);
+	TheStmt.Close();
+	//CREATE TRIGGER statement
+	err = TheStmt.Prepare(TheDb,
+			_L("CREATE TRIGGER Trg BEFORE DELETE ON A \
+	             BEGIN \
+	                SELECT CASE WHEN ((SELECT Id2 FROM A WHERE A.Id = old.Id) > 0) \
+	                            THEN RAISE (ABORT, 'Id2 > 0') \
+	                END;\
+	             END;"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 0);
+	TheStmt.Close();
+	//CREATE VIEW statement
+	err = TheStmt.Prepare(TheDb, _L("CREATE VIEW V AS SELECT * FROM A"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 0);
+	err = TheStmt.Exec();
+	TEST(err >= 0);
+	TheStmt.Close();
+	//DROP VIEW statement
+	err = TheStmt.Prepare(TheDb, _L("DROP VIEW V"));
+	TEST2(err, KErrNone);
+	cnt = TheStmt.ColumnCount();
+	TEST2(cnt, 0);
+	TheStmt.Close();
+	//Cleanup
+	TheDb.Close();
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-3514
+@SYMTestCaseDesc		RSqlStatement::DeclaredColumnType() test
+						The test creates a database with a table and then checks the DeclaredColumnType() return result for:
+						- select all column from the table and check their types;
+						- multi-table select plus column type checks;
+						- select expression - the expected column type is ESqlInt;
+						- select constant - the expected column type is ESqlInt;
+@SYMTestPriority		High
+@SYMTestActions			RSqlStatement::ColumnCount() test
+@SYMTestExpectedResults Test must not fail
+@SYMREQ					REQ8035
+*/
+void DeclaredColumnTypeTest()
+	{
+	TInt err = TheDb.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+	const char* KColTypeNames[] =
+		{"INTEGER", "LONG INTEGER", "INT", "SHORT INT", "SMALL INT", "TINY INT", "SHORT", "INT64",
+		"TEXT", "LONGTEXT", "CLOB", "CHAR", "CHARACTER(20)", "LONG TEXT",
+		"BINARY", "LONG BINARY", "LONGBINARY", "BLOB", "LONGBLOB", "LONG BLOB",
+		"REAL", "FLOAT", "DOUBLE", "LONG DOUBLE",
+		"LONG LONG", "BOO HOO"};
+	const TSqlColumnType KColTypes[] =
+		{ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,
+		 ESqlText,ESqlText,ESqlText,ESqlText,ESqlText,ESqlText,
+		 ESqlBinary,ESqlBinary,ESqlBinary,ESqlBinary,ESqlBinary,ESqlBinary,
+		 ESqlReal,ESqlReal,ESqlReal,ESqlReal,
+		 ESqlInt,ESqlInt};
+	const TInt KColTypeCnt = sizeof(KColTypes) / sizeof(KColTypes[0]);
+	TEST2(sizeof(KColTypeNames) / sizeof(KColTypeNames[0]), KColTypeCnt);
+	//Create table 1
+	TBuf8<512> sql;
+	sql.Copy(_L8("CREATE TABLE T("));
+	for(TInt i=0;i<KColTypeCnt;++i)
+		{
+		sql.Append(TChar('A'));
+		sql.AppendNum(i + 1);
+		sql.Append(TChar(' '));
+		sql.Append((TUint8*)KColTypeNames[i], User::StringLength((TUint8*)KColTypeNames[i]));
+		sql.Append(TChar(','));
+		}
+	sql.Replace(sql.Length() - 1, 1, _L8(")"));
+	err = TheDb.Exec(sql);
+	TEST(err >= 0);
+	//Select all columns (SELECT *)
+	err = TheStmt.Prepare(TheDb, _L("SELECT * FROM T"));
+	TEST2(err, KErrNone);
+	TInt cnt = TheStmt.ColumnCount();
+	TEST2(cnt, KColTypeCnt);
+	TSqlColumnType colType;
+	for(TInt i=0;i<KColTypeCnt;++i)
+		{
+		TInt err = TheStmt.DeclaredColumnType(i, colType);
+		TEST2(err, KErrNone);
+		TEST2(colType, KColTypes[i]);
+		}
+	TheStmt.Close();
+	//Create table 2
+	err = TheDb.Exec(_L8("CREATE TABLE T2(Id INTEGER, DATA BLOB)"));
+	TEST(err >= 0);
+	//Multi-table select
+	err = TheStmt.Prepare(TheDb, _L("SELECT T.A1,T2.Id,T.A9,T2.Data FROM T,T2"));
+	TEST2(err, KErrNone);
+	err = TheStmt.DeclaredColumnType(0, colType);
+	TEST2(err, KErrNone);
+	TEST2(colType, ESqlInt);
+	err = TheStmt.DeclaredColumnType(1, colType);
+	TEST2(err, KErrNone);
+	TEST2(colType, ESqlInt);
+	err = TheStmt.DeclaredColumnType(2, colType);
+	TEST2(err, KErrNone);
+	TEST2(colType, ESqlText);
+	err = TheStmt.DeclaredColumnType(3, colType);
+	TEST2(err, KErrNone);
+	TEST2(colType, ESqlBinary);
+	TheStmt.Close();
+	//Select expression
+	err = TheStmt.Prepare(TheDb, _L("SELECT (Id + Data) AS RES FROM t2"));
+	TEST2(err, KErrNone);
+	err = TheStmt.DeclaredColumnType(0, colType);
+	TEST2(err, KErrNone);
+	TEST2(colType, ESqlInt);
+	TheStmt.Close();
+	//Select constant
+	err = TheStmt.Prepare(TheDb, _L("SELECT (Id + Data) AS RES, 55.89 FROM t2"));
+	TEST2(err, KErrNone);
+	err = TheStmt.DeclaredColumnType(1, colType);
+	TEST2(err, KErrNone);
+	TEST2(colType, ESqlInt);
+	TheStmt.Close();
+	//Cleanup
+	TheDb.Close();
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4017
+@SYMTestCaseDesc		RSqlStatement::ColumnName(TInt, TPtrC&) test
+						The test creates a database with a table and then checks the ColumnName() return result for:
+						- select all column from the table and check their names;
+						- multi-table select plus column name checks;
+						- select expression - the expected column name is RES
+						- select constant - the expected column type is 55.89 
+@SYMTestPriority		High
+@SYMTestActions			RSqlStatement::ColumnName() test
+@SYMTestExpectedResults Test must not fail
+@SYMCR				    RMAD-7B7EV5
+                        Add SQL Server APIs to retrieve column and parameter names
+*/	
+void ColumnNameTest()
+	{
+	TInt err = TheDb.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+	const char* KColTypeNames[] = 
+		{"INTEGER", "LONG INTEGER", "INT", "SHORT INT", "SMALL INT", "TINY INT", "SHORT", "INT64",
+		"TEXT", "LONGTEXT", "CLOB", "CHAR", "CHARACTER(20)", "LONG TEXT",
+		"BINARY", "LONG BINARY", "LONGBINARY", "BLOB", "LONGBLOB", "LONG BLOB",
+		"REAL", "FLOAT", "DOUBLE", "LONG DOUBLE",
+		"LONG LONG", "BOO HOO"};
+	const TSqlColumnType KColTypes[] = 
+		{ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,ESqlInt,
+		 ESqlText,ESqlText,ESqlText,ESqlText,ESqlText,ESqlText,
+		 ESqlBinary,ESqlBinary,ESqlBinary,ESqlBinary,ESqlBinary,ESqlBinary,
+		 ESqlReal,ESqlReal,ESqlReal,ESqlReal,
+		 ESqlInt,ESqlInt};
+	const TInt KColTypeCnt = sizeof(KColTypes) / sizeof(KColTypes[0]);
+	TEST2(sizeof(KColTypeNames) / sizeof(KColTypeNames[0]), KColTypeCnt);
+	//Create table 1
+	TBuf8<512> sql;
+	sql.Copy(_L8("CREATE TABLE T("));
+	for(TInt i=0;i<KColTypeCnt;++i)
+		{
+		sql.Append(TChar('A'));
+		sql.AppendNum(i + 1);
+		sql.Append(TChar(' '));
+		sql.Append((TUint8*)KColTypeNames[i], User::StringLength((TUint8*)KColTypeNames[i]));
+		sql.Append(TChar(','));
+		}
+	sql.Replace(sql.Length() - 1, 1, _L8(")"));
+	err = TheDb.Exec(sql);
+	TEST(err >= 0);
+	//Select all columns (SELECT *)
+	err = TheStmt.Prepare(TheDb, _L("SELECT * FROM T"));
+	TEST2(err, KErrNone);
+	TInt cnt = TheStmt.ColumnCount();
+	TEST2(cnt, KColTypeCnt);
+	TPtrC colName;
+	TBuf<128> expectedColName;
+	for(TInt i=0;i<KColTypeCnt;++i)
+		{
+		expectedColName.Zero();
+		expectedColName.Append(TChar('A'));
+		expectedColName.AppendNum(i + 1);
+		TInt err = TheStmt.ColumnName(i, colName);
+		TEST2(err, KErrNone);
+		TEST2(colName.Compare(expectedColName), 0);
+		TSqlColumnType type;
+		err = TheStmt.DeclaredColumnType(i, type);
+		TEST2(err, KErrNone);
+		TEST2(type, KColTypes[i]);
+		}
+	TheStmt.Close();
+	//Create table 2
+	err = TheDb.Exec(_L8("CREATE TABLE T2(Id INTEGER, DATA BLOB)"));
+	TEST(err >= 0);
+	//Multi-table select
+	err = TheStmt.Prepare(TheDb, _L("SELECT T.A1,T2.Id,T.A9,T2.DATA FROM T,T2"));
+	TEST2(err, KErrNone);
+	err = TheStmt.ColumnName(0, colName);
+	TEST2(err, KErrNone);
+	TEST2(colName.Compare(_L("A1")), 0);
+	err = TheStmt.ColumnName(1, colName);
+	TEST2(err, KErrNone);
+	TEST2(colName.Compare(_L("Id")), 0);
+	err = TheStmt.ColumnName(2, colName);
+	TEST2(err, KErrNone);
+	TEST2(colName.Compare(_L("A9")), 0);
+	err = TheStmt.ColumnName(3, colName);
+	TEST2(err, KErrNone);
+	TEST2(colName.Compare(_L("DATA")), 0);
+	TheStmt.Close();
+	//Select expression
+	err = TheStmt.Prepare(TheDb, _L("SELECT (Id + Data) AS RES FROM t2"));
+	TEST2(err, KErrNone);
+	err = TheStmt.ColumnName(0, colName);
+	TEST2(err, KErrNone);
+	TEST2(colName.Compare(_L("RES")), 0);
+	TheStmt.Close();
+	//Select constant
+	err = TheStmt.Prepare(TheDb, _L("SELECT (Id + Data) AS RES, 55.89 FROM t2"));
+	TEST2(err, KErrNone);
+	err = TheStmt.ColumnName(1, colName);
+	TEST2(err, KErrNone);
+	TEST2(colName.Compare(_L("55.89")), 0);
+	TheStmt.Close();
+	//Cleanup
+	TheDb.Close();
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4018
+@SYMTestCaseDesc		RSqlStatement::ParameterName(TInt, TPtrC&) and RSqlStatement::ParamName(TInt, TPtrC&) test
+						DML test:
+						The test creates a database with a table and prepares an insert query.
+						The test then checks the ParameterName() and ParamName() return result for:
+						- Named parameters - return the named param
+						- Unnamed parameters - return ?<param-index>
+@SYMTestPriority		High
+@SYMTestActions			RSqlStatement::ParameterName() and RSqlStatement::ParamName() test
+@SYMTestExpectedResults Test must not fail
+@SYMCR					RMAD-7B7EV5
+                        Add SQL Server APIs to retrieve column and parameter names
+*/	
+void ParamNameTest()
+	{
+	TInt err = TheDb.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+	const char* KColTypeNames[] = 
+		{"INTEGER", "TEXT"};
+	const TInt KColTypeCnt = sizeof(KColTypeNames) / sizeof(KColTypeNames[0]);
+	//Create table 1
+	TBuf8<256> sql;
+	sql.Copy(_L8("CREATE TABLE T("));
+	for(TInt i=0;i<KColTypeCnt;++i)
+		{
+		sql.Append(TChar('A'));
+		sql.AppendNum(i + 1);
+		sql.Append(TChar(' '));
+		sql.Append((TUint8*)KColTypeNames[i], User::StringLength((TUint8*)KColTypeNames[i]));
+		sql.Append(TChar(','));
+		}
+	sql.Replace(sql.Length() - 1, 1, _L8(")"));
+	err = TheDb.Exec(sql);
+	TEST(err >= 0);
+	TheStmt.Close();
+	
+	// Create insert statement, then check param names
+	err = TheStmt.Prepare(TheDb, _L("INSERT INTO T (A1, A2) VALUES (:prm1, :prm2)"));
+	TEST2(err, KErrNone);
+	TPtrC paramName;
+	TBuf<128> expectedParamName;
+	for(TInt i=0;i<KColTypeCnt;++i)
+		{
+		expectedParamName.Zero();
+		expectedParamName.Append(_L(":prm"));
+		expectedParamName.AppendNum(i + 1);
+		TInt paramIndex = TheStmt.ParameterIndex(expectedParamName);
+		TEST2(paramIndex, i);
+		TInt err = TheStmt.ParameterName(i, paramName);
+		TEST2(err, KErrNone);
+		TEST2(paramName.Compare(expectedParamName), 0);
+		err = TheStmt.ParamName(i, paramName);
+		TEST2(err, KErrNone);
+		TEST2(paramName.Compare(expectedParamName), 0);
+		}
+	TheStmt.Close();
+
+	// Create insert statement, then check param names
+	err = TheStmt.Prepare(TheDb, _L("INSERT INTO T (A1, A2) VALUES (:prm1, ?)"));
+	TEST2(err, KErrNone);
+	
+	expectedParamName.Zero();
+	expectedParamName.Append(_L(":prm1"));
+	TInt paramIndex = TheStmt.ParameterIndex(expectedParamName);
+	TEST2(paramIndex, 0);
+	err = TheStmt.ParameterName(0, paramName);
+	TEST2(err, KErrNone);
+	TEST2(paramName.Compare(expectedParamName), 0);
+	err = TheStmt.ParamName(0, paramName);
+	TEST2(err, KErrNone);
+	TEST2(paramName.Compare(expectedParamName), 0);
+
+	expectedParamName.Zero();
+	expectedParamName.Append(_L("?1"));
+	err = TheStmt.ParameterName(1, paramName);
+	TEST2(err, KErrNone);
+	paramIndex = TheStmt.ParameterIndex(expectedParamName);
+	TEST2(paramIndex, 1);
+	TEST2(paramName.Compare(expectedParamName), 0);
+	
+	err = TheStmt.ParamName(1, paramName);
+	TEST2(err, KErrNone);
+	TEST2(paramName.Compare(expectedParamName), 0);
+
+	TheStmt.Close();
+	
+	//Cleanup
+	TheDb.Close();
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4006
+@SYMTestCaseDesc		Test for DEF115300 - SqlSrv.EXE::!SQL Server when preparing invalid LEFT JOIN sql query.
+						The test does the following steps:
+						1) Creates a 16-bit database and using 16-bit queries proves that the "GROUP BY GROUP BY" syntax error
+						   does not cause an assert inside the SQLITE code.
+						2) Creates a 8-bit database and using 8-bit queries proves that the "GROUP BY GROUP BY" syntax error
+						   does not cause an assert inside the SQLITE code.
+@SYMTestPriority		Medium
+@SYMTestActions			Test for DEF115300 - SqlSrv.EXE::!SQL Server when preparing invalid LEFT JOIN sql query.
+@SYMTestExpectedResults Test must not fail
+@SYMDEF					DEF115300
+*/
+void DEF115300()
+	{
+
+	//Step 1: 16-bit statements
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	TInt err = TheDb.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+
+	err = TheDb.Exec(_L("CREATE TABLE MAIN(Id INTEGER, Id1 INTEGER, F2 BLOB)"));
+	TEST2(err, 1);
+	err = TheDb.Exec(_L("INSERT INTO MAIN(Id,Id1) VALUES(2,3)"));
+	TEST2(err, 1);
+	err = TheDb.Exec(_L("INSERT INTO MAIN(Id,Id1) VALUES(3,4)"));
+	TEST2(err, 1);
+
+	err = TheDb.Exec(_L("CREATE TABLE A(Id INTEGER, Id1 INTEGER, F2 BLOB)"));
+	TEST2(err, 1);
+	err = TheDb.Exec(_L("INSERT INTO A(Id, Id1) VALUES(2,3)"));
+	TEST2(err, 1);
+	err = TheDb.Exec(_L("INSERT INTO A(Id, Id1) VALUES(4,4)"));
+	TEST2(err, 1);
+
+	err = TheDb.Exec(_L("CREATE TABLE B(Id INTEGER, Id1 INTEGER, F2 BLOB)"));
+	TEST2(err, 1);
+	err = TheDb.Exec(_L("INSERT INTO B(Id, Id1) VALUES(2,3)"));
+	TEST2(err, 1);
+	err = TheDb.Exec(_L("INSERT INTO B(Id, Id1) VALUES(5,4)"));
+	TEST2(err, 1);
+	err = TheDb.Exec(_L("INSERT INTO B(Id, Id1) VALUES(5,4)"));
+	TEST2(err, 1);
+
+	err = TheDb.Exec(_L("CREATE VIEW v2 AS SELECT Id,Id1,F2 FROM B"));
+	TEST2(err, 1);
+	err = TheDb.Exec(_L("CREATE VIEW v1 AS SELECT Id,Id1,F2 FROM A"));
+	TEST2(err, 1);
+	err = TheDb.Exec(_L("CREATE VIEW v3 AS SELECT Id,Id1,F2 FROM B"));
+	TEST2(err, 1);
+
+	RSqlStatement stmt;
+	err = stmt.Prepare(TheDb, _L("SELECT * FROM v2 LEFT JOIN MAIN ON v2.Id = MAIN.Id LEFT JOIN A ON MAIN.Id = A.Id GROUP BY GROUP BY MAIN.Id"));
+	stmt.Close();
+	TEST(err != KErrNone && err != KErrServerTerminated);
+
+	TheDb.Close();
+	err = RSqlDatabase::Delete(KTestDbName1);
+	TEST2(err, KErrNone);
+
+	//Step 2: 8-bit statements
+	_LIT8(KServerConfigString1, "encoding=\"UTF-8\"");
+	err = TheDb.Create(KTestDbName1, &KServerConfigString1);
+	TEST2(err, KErrNone);
+
+	err = TheDb.Exec(_L8("CREATE TABLE MAIN(Id INTEGER, Id1 INTEGER, F2 BLOB)"));
+	TEST2(err, 1);
+
+	err = stmt.Prepare(TheDb, _L8("SELECT * FROM main GROUP BY GROUP BY main.Id"));
+	stmt.Close();
+	TEST(err != KErrNone && err != KErrServerTerminated);
+
+	TheDb.Close();
+	err = RSqlDatabase::Delete(KTestDbName1);
+	TEST2(err, KErrNone);
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4007
+@SYMTestCaseDesc		Test for DEF115331 - SQL, bad code coverage for db reindexing if default collation has changed.
+						The test does the following steps, using public shared and private secure database:
+						1) Creates a test database with a table and one index using one of the collations.
+						2) Updates the symbian_settings table, setting the collation dll name column value 
+						   to be a "bbbababz" string (Simulates that there is no valid collation dll name).
+						3) Reopens the database. This operation should cause a database reindexing, since the index uses
+						   one of the user-defined collation methods.
+						   The default system collation dll name should be stored in the symbian_settings table.
+						4) Verifies that symbian_settings table contains only one record and that the collation dll name
+						   column value has been updated.
+@SYMTestPriority		Medium
+@SYMTestActions			Test for DEF115331 - SQL, bad code coverage for db reindexing if default collation has changed.
+@SYMTestExpectedResults Test must not fail
+@SYMDEF					DEF115331
+*/
+void DEF115331L()
+	{
+	const TPtrC KDbNames[]		=	{KTestDbName1(),	KTestDbName2()};
+
+	for(TInt i=0;i<(sizeof(KDbNames)/sizeof(KDbNames[0]));++i)
+		{
+		//Step 1: Create a test database with a table and one index using one of the collations.
+		(void)RSqlDatabase::Delete(KDbNames[i]);
+		TInt err = TheDb.Create(KDbNames[i]);
+		TEST2(err, KErrNone);
+
+		err = TheDb.Exec(_L("CREATE TABLE A(C TEXT)"));
+		TEST2(err, 1);
+
+		err = TheDb.Exec(_L("CREATE INDEX I ON A(C COLLATE CompareC1)"));
+		TEST2(err, 1);
+
+		//Step 2: Make sure that the collation dll name is set and unique (not the default collation).
+		err = TheDb.Exec(_L("UPDATE symbian_settings SET CollationDllName='bbbababz'"));
+		TEST2(err, 1);
+
+		TheDb.Close();
+
+		//Step 3: Reopen the database. That step should cause a database reindexing, because the default collation dll 
+		//        name is not the one stored in the table.
+		err = TheDb.Open(KDbNames[i]);
+		TEST2(err, KErrNone);
+
+		TSqlScalarFullSelectQuery query(TheDb);
+
+		//Step 4: Check that the settigns table has only one record.
+		TInt cnt = query.SelectIntL(_L("SELECT COUNT(*) FROM symbian_settings"));
+		TEST2(cnt, 1);
+
+		//Step 5: Check that the collation dll name in the settings table has been updated.
+		TFileName collationDllName;
+		err = query.SelectTextL(_L("SELECT CollationDllName FROM symbian_settings"), collationDllName);
+		TEST2(err, KErrNone);
+		_LIT(KTestCollationDllName, "bbbababz");//The same as the used in step 2 - above.
+		TEST(collationDllName != KTestCollationDllName);
+
+		TheDb.Close();
+		err = RSqlDatabase::Delete(KDbNames[i]);
+		TEST2(err, KErrNone);
+		}
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4079
+@SYMTestCaseDesc		RSqlDatabase::Create() and RSqlDatabase::Open() - injection test
+						The test attempts to create or open a database which name contains
+						"DELETE FROM symbian_settings" statement.If it is possible to open or
+						create a database with that name, the "symbian_settings" table content
+						should stay unchanged.
+@SYMTestPriority		Medium
+@SYMTestActions			RSqlDatabase::Create() and RSqlDatabase::Open() - injection test
+@SYMTestExpectedResults Test must not fail
+@SYMREQ					REQ5792
+*/
+void InjectionTest()
+	{
+	TInt err = TheDb.Create(KDbInjectedName1);
+	TEST(err != KErrNone);
+
+	err = TheDb.Create(KDbInjectedName2);
+	TEST2(err, KErrNone);
+	
+	TSqlScalarFullSelectQuery query(TheDb);
+	TInt recCount = 0;
+	TRAP(err, recCount = query.SelectIntL(_L("SELECT COUNT(*) FROM symbian_settings")));
+	TEST2(err, KErrNone);
+	TEST2(recCount, 1);
+	TheDb.Close();
+	
+	err = TheDb.Open(KDbInjectedName2);
+	TEST2(err, KErrNone);
+	recCount = 0;
+	query.SetDatabase(TheDb);
+	TRAP(err, recCount = query.SelectIntL(_L("SELECT COUNT(*) FROM symbian_settings")));
+	TEST2(err, KErrNone);
+	TEST2(recCount, 1);
+	TheDb.Close();
+		
+	(void)RSqlDatabase::Delete(KDbInjectedName2);
+	(void)RSqlDatabase::Delete(KDbInjectedName1);
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4038
+@SYMTestCaseDesc		Background compaction - two connections usability test.
+						The test creates a database connection with a background compaction mode. The the test 
+						locks the database in a transaction. Then the test creates a second connection
+						to the same database while the first connection is in a transaction.
+@SYMTestPriority		Medium
+@SYMTestActions			Background compaction - two connections usability test.
+@SYMTestExpectedResults Test must not fail
+@SYMREQ					REQ10271
+*/
+void TwoConnectionsTest()
+	{
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	RSqlDatabase db1, db2;
+	TInt err = db1.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+	err = db1.Exec(_L("CREATE TABLE A(I INTEGER); INSERT INTO A VALUES(1)"));
+	TEST2(err, 1);
+	err = db1.Exec(_L("BEGIN TRANSACTION"));
+	TEST(err >= 0);
+	err = db1.Exec(_L("INSERT INTO A VALUES(2)"));
+	TEST2(err, 1);
+	err = db2.Open(KTestDbName1);
+	TEST2(err, KErrNone);
+	err = db1.Exec(_L("COMMIT TRANSACTION"));
+	TEST(err >= 0);
+	db2.Close();		
+	db1.Close();		
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+
+TInt StackOverflowThreadFunc(void* aData)
+	{
+	CTrapCleanup* tc = CTrapCleanup::New();
+	TEST(tc != NULL);
+	
+	User::SetJustInTime(EFalse);	// disable debugger panic handling
+	
+	TInt* cntptr = reinterpret_cast<TInt*> (aData);
+	TEST(cntptr != NULL);
+	TInt cnt = *cntptr;
+
+	HBufC* buf = HBufC::New(cnt * 12 + 32);//enough for the "SELECT Id FROM A WHERE Id=v1 OR Id=v2 OR ..." string
+	if(!buf)
+		{
+		delete tc;
+		return KErrNoMemory;	
+		}
+	TPtr sql = buf->Des();
+	
+	TInt err = TheDb.Open(KTestDbName1);
+	if(err != KErrNone)
+		{
+		delete buf;
+		delete tc;
+		return err;	
+		}
+
+	TTime now;
+	now.UniversalTime();
+	TInt64 seed = now.Int64();
+
+	sql.Copy(_L("SELECT Id FROM A WHERE "));
+	for(TInt i=0;i<cnt;++i)
+		{
+		sql.Append(_L("Id="));
+		sql.AppendNum(Math::Rand(seed) % cnt);
+		sql.Append(_L(" OR "));
+		}
+	sql.SetLength(sql.Length() - 4);//Remove the last " OR "
+
+	RSqlStatement stmt;
+	err = stmt.Prepare(TheDb, sql);
+	stmt.Close();
+	
+	TheDb.Close();
+	delete buf;
+	delete tc;
+	
+	return err;
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4080
+@SYMTestCaseDesc		SQL server stack overflow test
+						The test creates a database and runs a thread. The thread opens the database
+						and attempts to execute a SELECT statement, which format is:
+						"SELECT Id FROM A WHERE Id=1 OR Id=2 OR...OR Id=N",
+						where N is a number passed as an argument from the main thread, starts from 100000
+						and is increased or decreased on each test iteration, depending on the reported result from the thread.
+						Finally, the main thread will report the max number of the OR subexpressions that can be included
+						in the SELECT statement, without an error to be reported.
+						The test should not crash the SQL server, if the server stack size and parsing tree depth has
+						been properly configured.
+@SYMTestPriority		Medium
+@SYMTestActions			SQL server stack overflow test
+@SYMTestExpectedResults Test must not fail
+@SYMREQ					REQ5792
+*/
+void SqlServerStackOverflowTest()
+	{
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	TInt err = TheDb.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+	err = TheDb.Exec(_L("CREATE TABLE A(Id INTEGER PRIMARY KEY AUTOINCREMENT)"));
+	TEST2(err, 1);
+	TheDb.Close();
+	
+	TInt prev = 0, next = 100000;
+	while(Abs(next - prev) > 0)
+		{
+		TInt count = next;
+		TheTest.Printf(_L("'OR' expr. count: %d\r\n"), count);
+		RThread thread;
+		_LIT(KThreadName,"ORThread");						//stack	minheap		maxheap
+		err = thread.Create(KThreadName, &StackOverflowThreadFunc, 0x2000, 0x00100000, 0x02000000, &count);
+		TEST2(err, KErrNone);
+		
+		TRequestStatus status;
+		thread.Logon(status);
+		TEST2(status.Int(), KRequestPending);
+		thread.Resume();
+		User::WaitForRequest(status);
+		User::SetJustInTime(ETrue);	// enable debugger panic handling
+
+		TInt exitType = thread.ExitType();
+		const TDesC& exitCategory = thread.ExitCategory();
+		TInt exitReason = thread.ExitReason();
+		TheTest.Printf(_L("Exit type: %d, exit reason: %d, exit category: %S\r\n"), exitType, exitReason, &exitCategory);
+		thread.Close();
+		TEST(exitReason != KErrServerTerminated);
+		TEST(exitType != EExitPanic);
+
+		TInt tmp = next;		
+		if(status.Int() != KErrNone)
+			{//The number of the OR subexpressions is too big and cannot be parsed. Decrease the number, repeat the test.
+			next -= Abs(next - prev) / 2;
+			}
+		else
+			{//KErrNone: The number of the OR subexpressions has been successfully parsed. Increase the number, repeat the test.
+			next += Abs(next - prev) / 2;
+			}
+		prev = tmp;
+		}
+	TheTest.Printf(_L("The test has succeeded with an expression with %d ORs\r\n"), prev);
+	}
+
+void AssertSettingsTable()
+	{
+	TSqlScalarFullSelectQuery query(TheDb);
+	TInt recCount = 0;
+	TRAPD(err, recCount = query.SelectIntL(_L("SELECT COUNT(*) FROM symbian_settings")));
+	TEST2(err, KErrNone);
+	TEST2(recCount, 1);
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4086
+@SYMTestCaseDesc		RSqlBlobWriteStream::OpenL() and RSqlBlobReadStream::OpenL() - injection test
+						The test attempts to open a blob stream with an attached database name containing
+						"DELETE FROM symbian_settings" statement. The test should not delete the content of the
+						"symbian_settings" table.
+						The test also attempts to open a blob stream with a set of very long database/table/column names.
+@SYMTestPriority		Medium
+@SYMTestActions			RSqlBlobWriteStream::OpenL() and RSqlBlobReadStream::OpenL() - injection test
+@SYMTestExpectedResults Test must not fail
+@SYMREQ					REQ5792
+                        REQ10410
+						REQ10411
+						REQ10418
+*/
+void BlobStreamInjectionTest()
+	{
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	TInt err = TheDb.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+	err = TheDb.Exec(_L("CREATE TABLE A(Id INTEGER,Data BLOB)"));
+	TEST2(err, 1);
+	err = TheDb.Exec(_L("INSERT INTO A VALUES(1, x'11223344556677889900')"));
+	TEST2(err, 1);
+	_LIT(KAttachDb, "AttachDb");
+	err = TheDb.Attach(KTestDbName1, KAttachDb);
+	TEST2(err, KErrNone);
+	//RSqlBlobWriteStream::OpenL() - attached database  name injected
+	RSqlBlobWriteStream strm1;
+	TRAP(err, strm1.OpenL(TheDb, _L("A"), _L("Data"), 1, _L("Id;DELETE FROM symbian_settings;")));
+	TEST(err != KErrNone);
+	AssertSettingsTable();
+	//RSqlBlobReadStream::OpenL() - attached database  name injected
+	RSqlBlobReadStream strm2;
+	TRAP(err, strm2.OpenL(TheDb, _L("A"), _L("Data"), 1, _L("Id;DELETE FROM symbian_settings;")));
+	TEST(err != KErrNone);
+	AssertSettingsTable();
+	//Attempt to open a write blob stream with a set of very long database/table/column names.
+	TBuf<KMaxFileName + 10> longName;
+	longName.SetLength(longName.MaxLength());
+	RSqlBlobWriteStream strm3;
+	TRAP(err, strm3.OpenL(TheDb, longName, longName, 1, longName));
+	TEST(err != KErrNone);
+	//Attempt to open a read blob stream with a set of very long database/table/column names.
+	RSqlBlobReadStream strm4;
+	TRAP(err, strm4.OpenL(TheDb, longName, longName, 1, longName));
+	TEST(err != KErrNone);
+	//Attempt to open a write blob stream with a set of KNullDesC database/table/column names.
+	RSqlBlobWriteStream strm5;
+	TRAP(err, strm5.OpenL(TheDb, KNullDesC, KNullDesC, 1, KNullDesC));
+	TEST(err != KErrNone);
+	//Attempt to open a read blob stream with a set of KNullDesC database/table/column names.
+	RSqlBlobReadStream strm6;
+	TRAP(err, strm6.OpenL(TheDb, KNullDesC, KNullDesC, 1, KNullDesC));
+	TEST(err != KErrNone);
+	//
+	err = TheDb.Detach(KAttachDb);
+	TEST2(err, KErrNone);
+	TheDb.Close();
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+	
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4087
+@SYMTestCaseDesc		Bound parameter values test.
+						The test verifies that bound parameters with big text/binary values retain their values after
+						the RSqlStatement::Reset() call. The old bound paramegter values can be used for the next 
+						RSqlStatement::Exec() call.
+@SYMTestActions			Bound parameter values test.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority		High
+@SYMREQ					REQ5792
+*/
+void BoundParameterValuesTest()
+	{
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	TInt err = TheDb.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+	err = TheDb.Exec(_L("CREATE TABLE A1(T1 TEXT, T2 TEXT)"));
+	TEST2(err, 1);
+	err = TheDb.Exec(_L("CREATE TABLE A2(T1 TEXT, T2 TEXT)"));
+	TEST2(err, 1);
+	
+	RSqlStatement stmt1, stmt2;
+	err = stmt1.Prepare(TheDb, _L("INSERT INTO A1 VALUES(:Prm1, :Prm2)"));
+	TEST2(err, KErrNone);
+	err = stmt2.Prepare(TheDb, _L("INSERT INTO A2 VALUES(:Prm1, :Prm2)"));
+	TEST2(err, KErrNone);
+	//Insert 1 record into table "A1". T2 = "ZZZZ.....".
+	TheBuf.SetLength(KBufLen - 100);
+	TheBuf.Fill(TChar('Z'));
+	err = stmt1.BindText(0, TheBuf);
+	TEST2(err, KErrNone);
+	err = stmt1.BindText(1, TheBuf);
+	TEST2(err, KErrNone);
+	err = stmt1.Exec();
+	TEST2(err, 1);
+	err = stmt1.Reset();
+	TEST2(err, KErrNone);
+	//Insert 1 record into table "A2". T2 = "AAAAAAA.....".
+	TheBuf.SetLength(KBufLen);
+	TheBuf.Fill(TChar('A'));
+	err = stmt2.BindText(0, TheBuf);
+	TEST2(err, KErrNone);
+	err = stmt2.BindText(1, TheBuf);
+	TEST2(err, KErrNone);
+	err = stmt2.Exec();
+	TEST2(err, 1);
+	err = stmt2.Reset();
+	TEST2(err, KErrNone);
+	//Insert 1 record into table "A1". T2 not set. T2 should be initialized with the previous bound value - "ZZZZZZ....".
+	//If the problem is not fixed, the SQLITE will attempt to access an already deleted region of memory.
+	TheBuf.SetLength(KBufLen - 100);
+	TheBuf.Fill(TChar('B'));
+	err = stmt1.BindText(0, TheBuf);
+	TEST2(err, KErrNone);
+	err = stmt1.Exec();
+	TEST2(err, 1);
+	err = stmt1.Reset();
+	TEST2(err, KErrNone);
+	
+	stmt2.Close();
+	stmt1.Close();
+	
+	//Check the inserted records.
+	TSqlScalarFullSelectQuery q(TheDb);
+	TRAP(err, q.SelectTextL(_L("SELECT T2 FROM A1 WHERE ROWID=1"), TheBuf));
+	TEST2(err, KErrNone);
+	TEST2(TheBuf.Length(), (KBufLen - 100));
+	for(TInt i1=0;i1<(KBufLen - 100);++i1)
+		{
+		TEST2(TheBuf[i1], TChar('Z'));	
+		}
+	TRAP(err, q.SelectTextL(_L("SELECT T2 FROM A1 WHERE ROWID=2"), TheBuf));
+	TEST2(err, KErrNone);
+	TEST2(TheBuf.Length(), (KBufLen - 100));
+	for(TInt i2=0;i2<(KBufLen - 100);++i2)
+		{
+		TEST2(TheBuf[i2], TChar('Z'));	
+		}
+	
+	TheDb.Close();
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4076
+@SYMTestCaseDesc		Bound parameter values test.
+						The test verifies that when a RSqlParamWriteStream object is used for binding parameter values,
+						it is safe to erverse the order of RSqlParamWriteStream::Close() and RSqlStatement::Close() calls.
+@SYMTestActions			Bound parameter values test.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority		High
+@SYMREQ					REQ5792
+*/
+void BoundParameterValuesTest2()
+	{
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	TInt err = TheDb.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+	err = TheDb.Exec(_L("CREATE TABLE A1(T1 TEXT, T2 TEXT)"));
+	TEST2(err, 1);
+	
+	RSqlStatement stmt;
+	err = stmt.Prepare(TheDb, _L("INSERT INTO A1 VALUES(:Prm1, :Prm2)"));
+	TEST2(err, KErrNone);
+	RSqlParamWriteStream strm;
+	err = strm.BindText(stmt, 0);
+	TEST2(err, KErrNone);
+	err = stmt.Exec();
+	TEST2(err, 1);
+	stmt.Close();
+	strm.Close();
+
+	TheDb.Close();
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4077
+@SYMTestCaseDesc		Bound parameter values test.
+						The test verifies that when a RSqlParamWriteStream object is used for binding parameter values,
+						it is possible to write the parameter value, then call RSqlParamWriteStream::Close() and finally -
+						RSqlStatement::Exec() to execute the operation (an INSERT statement). The test verifies that the record
+						has really been inserted and the column value is equal to the bound parameter value
+@SYMTestActions			Bound parameter values test.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority		High
+@SYMREQ					REQ5792
+*/
+void BoundParameterValuesTest3()
+	{
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	TInt err = TheDb.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+	err = TheDb.Exec(_L("CREATE TABLE A1(T1 TEXT, T2 TEXT)"));
+	TEST2(err, 1);
+	
+	RSqlStatement stmt;
+	err = stmt.Prepare(TheDb, _L("INSERT INTO A1 VALUES(:Prm1, :Prm2)"));
+	TEST2(err, KErrNone);
+	RSqlParamWriteStream strm;
+	err = strm.BindText(stmt, 0);
+	TEST2(err, KErrNone);
+	_LIT(KText, "AAAA");
+	TRAP(err, strm.WriteL(KText));
+	TEST2(err, KErrNone);
+	TRAP(err, strm.CommitL());
+	TEST2(err, KErrNone);
+	strm.Close();
+	err = stmt.Exec();
+	TEST2(err, 1);
+	stmt.Close();
+
+	TSqlScalarFullSelectQuery q(TheDb);
+	TRAP(err, q.SelectTextL(_L("SELECT T1 FROM A1"), TheBuf));
+	TEST2(err, KErrNone);
+	TEST(KText() == TheBuf);	
+
+	TheDb.Close();
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4083
+@SYMTestCaseDesc		Bound parameter values test.
+						The test prepares an INSERT sql statement and inserts two records using streams to bind the parameter values.
+						For the second INSERT no parameter value is bound to the first parameter. The expectation is that the value
+						that has been bound for the first record will be used for the second record also.
+@SYMTestActions			Bound parameter values test.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority		High
+@SYMREQ					REQ5792
+*/
+void BoundParameterValuesTest4()
+	{
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	TInt err = TheDb.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+	err = TheDb.Exec(_L("CREATE TABLE A1(T1 TEXT, T2 TEXT)"));
+	TEST2(err, 1);
+	
+	RSqlStatement stmt;
+	err = stmt.Prepare(TheDb, _L("INSERT INTO A1 VALUES(:Prm1, :Prm2)"));
+	TEST2(err, KErrNone);
+	
+	RSqlParamWriteStream strm;
+	err = strm.BindText(stmt, 0);
+	TEST2(err, KErrNone);
+	_LIT(KText1, "AAAA");
+	TRAP(err, strm.WriteL(KText1));
+	TEST2(err, KErrNone);
+	TRAP(err, strm.CommitL());
+	TEST2(err, KErrNone);
+	strm.Close();
+	
+	err = strm.BindText(stmt, 1);
+	TEST2(err, KErrNone);
+	_LIT(KText2, "BBBBBBBBBB");
+	TRAP(err, strm.WriteL(KText2));
+	TEST2(err, KErrNone);
+	TRAP(err, strm.CommitL());
+	TEST2(err, KErrNone);
+	strm.Close();
+	
+	err = stmt.Exec();
+	TEST2(err, 1);
+	err = stmt.Reset();
+	TEST2(err, KErrNone);
+	
+	err = strm.BindText(stmt, 1);
+	TEST2(err, KErrNone);
+	_LIT(KText3, "CCCCCCCCCCC");
+	TRAP(err, strm.WriteL(KText3));
+	TEST2(err, KErrNone);
+	TRAP(err, strm.CommitL());
+	TEST2(err, KErrNone);
+	strm.Close();
+	
+	err = stmt.Exec();
+	TEST2(err, 1);
+	
+	stmt.Close();
+
+	TSqlScalarFullSelectQuery q(TheDb);
+	TRAP(err, q.SelectTextL(_L("SELECT T1 FROM A1 WHERE ROWID=1"), TheBuf));
+	TEST2(err, KErrNone);
+	TEST(KText1() == TheBuf);	
+	TRAP(err, q.SelectTextL(_L("SELECT T2 FROM A1 WHERE ROWID=1"), TheBuf));
+	TEST2(err, KErrNone);
+	TEST(KText2() == TheBuf);	
+
+	TRAP(err, q.SelectTextL(_L("SELECT T1 FROM A1 WHERE ROWID=2"), TheBuf));
+	TEST2(err, KErrNone);
+	TEST(KText1() == TheBuf);	
+	TRAP(err, q.SelectTextL(_L("SELECT T2 FROM A1 WHERE ROWID=2"), TheBuf));
+	TEST2(err, KErrNone);
+	TEST(KText3() == TheBuf);	
+
+	TheDb.Close();
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4105
+@SYMTestCaseDesc		Bound parameter values test.
+						BC test. Even though it is correct to execute only one CommitL() on a parameter stream,
+						it should be possible to execute more than one CommitL(). It should be possible also
+						the stream data to be updated after the first commit operation and the expectation is that
+						the updated parameter data should be used for the column value.
+@SYMTestActions			Bound parameter values test.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority		High
+@SYMREQ					REQ5792
+*/
+void BoundParameterValuesTest5()
+	{
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	TInt err = TheDb.Create(KTestDbName1);
+	TEST2(err, KErrNone);
+	err = TheDb.Exec(_L("CREATE TABLE A1(T1 TEXT, T2 TEXT)"));
+	TEST2(err, 1);
+	
+	RSqlStatement stmt;
+	err = stmt.Prepare(TheDb, _L("INSERT INTO A1 VALUES(:Prm1, :Prm2)"));
+	TEST2(err, KErrNone);
+	
+	RSqlParamWriteStream strm;
+	err = strm.BindText(stmt, 0);
+	TEST2(err, KErrNone);
+	_LIT(KText1, "AAAA");
+	TRAP(err, strm.WriteL(KText1));
+	TEST2(err, KErrNone);
+	TRAP(err, strm.CommitL());
+	TEST2(err, KErrNone);
+	TRAP(err, strm.Sink()->SeekL(MStreamBuf::EWrite, EStreamBeginning, 0));
+	TEST2(err, KErrNone);
+	_LIT(KText2, "DTAA");
+	TRAP(err, strm.WriteL(KText2));
+	TEST2(err, KErrNone);
+	TRAP(err, strm.CommitL());
+	TEST2(err, KErrNone);
+	strm.Close();
+
+	err = stmt.Exec();
+	TEST2(err, 1);
+	
+	stmt.Close();
+
+	TSqlScalarFullSelectQuery q(TheDb);
+	TRAP(err, q.SelectTextL(_L("SELECT T1 FROM A1 WHERE ROWID=1"), TheBuf));
+	TEST2(err, KErrNone);
+	TEST(KText2() == TheBuf);	
+
+	TheDb.Close();
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+
+void PrintConfig(TSqlResourceProfiler& aProfiler)
+	{
+	TBuf8<128> config;
+	if(aProfiler.Query(TSqlResourceProfiler::ESqlCounterConfig, config) == KErrNone)
+		{
+		_LIT(KCacheSize, "Cache size: %S pages\r\n");
+		_LIT(KPageSize, "Page size: %S bytes\r\n");
+		_LIT(KEncoding, "Encoding: %S\r\n");
+		_LIT(KDefaultSoftHeapLimit, "Default soft heap limit: %S Kb\r\n");
+		_LIT(KVacuumMode, "Vacuum mode: %S\r\n");
+	
+		TPtrC KText[] = {KCacheSize(), KPageSize(), KEncoding(), KDefaultSoftHeapLimit(), KVacuumMode()};
+	
+		for(TInt i=0;i<config.Length();++i)
+			{
+			if(config[i] == TChar(';'))	
+				{
+				config[i] = TChar(' ');	
+				}
+			}
+		TInt idx = 0;
+		TLex8 lex(config);
+		while (!lex.Eos() && idx < (sizeof(KText)/sizeof(KText[0])))
+			{
+			TPtrC8 num8 = lex.NextToken();
+			TBuf<20> num;
+			num.Copy(num8);
+			TheTest.Printf(KText[idx], &num);
+			++idx;
+			}
+		}
+	}
+
+void PrintFileIo(TSqlResourceProfiler& aProfiler)
+	{
+	TBuf8<300> countersValues;
+	if(aProfiler.Query(TSqlResourceProfiler::ESqlCounterFileIO, countersValues) == KErrNone)
+		{
+		TheTest.Printf(_L("=========================\r\n"));
+		_LIT(KFileCreate, "File Create");
+		_LIT(KFileOpen, "File Open");
+		_LIT(KFileClose, "File Close");
+		_LIT(KFileDelete, "File Delete");
+		_LIT(KFileRead, "File Read");
+		_LIT(KFileWrite, "File Write");
+		_LIT(KFileSeek, "File Seek");
+		_LIT(KFileSize, "File Size");
+		_LIT(KFileSetSize, "File SetSize");
+		_LIT(KFileSync, "File Sync");
+		_LIT(KFileDrive, "File Drive");
+		_LIT(KFileAdopt, "File Adopt");
+		_LIT(KFsClose, "Fs Close");
+		_LIT(KFsConnect, "Fs Connect");
+		_LIT(KFsGetSystemDrive, "Fs GetSystemDrive");
+		_LIT(KFsCreatePrivatePath, "Fs CreatePrivatePath");
+		_LIT(KFsPrivatePath, "Fs PrivatePath");
+		_LIT(KFsVolumeIoParam, "Fs VolumeIoParam");
+		_LIT(KFsEntry, "Fs Entry");
+		_LIT(KFsAtt, "Fs Att");
+		_LIT(KFileCreateTemp, "File CreateTemp");
+		_LIT(KFileAttach, "File Attach");
+		_LIT(KBytesWritten, "File Bytes Written");
+		_LIT(KBytesRead, "File Bytes Read");
+		TPtrC KText[] = 
+			{
+			KFileCreate(), KFileOpen(), KFileClose(), KFileDelete(), KFileRead(), KFileWrite(), KFileSeek(), KFileSize(),
+			KFileSetSize(), KFileSync(), KFileDrive(), KFileAdopt(), KFsClose(), KFsConnect(), KFsGetSystemDrive(), 
+			KFsCreatePrivatePath(), KFsPrivatePath(), KFsVolumeIoParam(), KFsEntry(), KFsAtt(), KFileCreateTemp(), 
+			KFileAttach(), KBytesWritten(), KBytesRead()
+			};
+		
+		for(TInt i=0;i<countersValues.Length();++i)
+			{
+			if(countersValues[i] == TChar(';'))	
+				{
+				countersValues[i] = TChar(' ');	
+				}
+			}
+		TInt idx = 0;
+		TLex8 lex(countersValues);
+		while (!lex.Eos() && idx < (sizeof(KText)/sizeof(KText[0])))
+			{
+			TPtrC8 num8 = lex.NextToken();
+			TBuf<20> num;
+			num.Copy(num8);
+			TheTest.Printf(_L("==Operation %S, count %S\r\n"), &KText[idx], &num);
+			++idx;
+			}
+		}
+	}
+
+void PrintOsCall(TSqlResourceProfiler& aProfiler)
+	{
+	TBuf8<300> countersValues;
+	if(aProfiler.Query(TSqlResourceProfiler::ESqlCounterOsCall, countersValues) == KErrNone)
+		{
+		TheTest.Printf(_L("=========================\r\n"));
+		_LIT(KEOsFileClose, "FileClose");
+		_LIT(KEOsFileRead, "FileRead");
+		_LIT(KEOsFileWrite, "FileWrite");
+		_LIT(KEOsFileTruncate, "FileTruncate");
+		_LIT(KEOsFileSync, "FileSync");
+		_LIT(KEOsFileFileSize, "FileSize");
+		_LIT(KEOsFileLock, "FileLock");
+		_LIT(KEOsFileUnlock, "FileUnlock");
+		_LIT(KEOsFileCheckReservedLock, "FileCheckReservedLock");
+		_LIT(KEOsFileFileControl, "FileIoControl");
+		_LIT(KEOsFileSectorSize, "FileSectorSize");
+		_LIT(KEOsFileDeviceCharacteristics, "FileDeviceCharacteristics");
+		_LIT(KEOsVfsOpen, "VfsOpen");
+		_LIT(KEOsVfsDelete, "VfsDelete");
+		_LIT(KEOsVfsAccess, "VfsAccess");
+		_LIT(KEOsVfsFullPathName, "VfsFullPathName");
+		_LIT(KEOsVfsRandomness, "VfsRandomnes");
+		_LIT(KEOsVfsSleep, "VfsSleep");
+		_LIT(KEOsVfsCurrentTime, "VfsCurrentTime");
+		_LIT(KEOsVfsGetLastError, "VfsGetLastError");
+		TPtrC KText[] = 
+			{
+			KEOsFileClose(), KEOsFileRead(), KEOsFileWrite(), KEOsFileTruncate(), KEOsFileSync(), 
+			KEOsFileFileSize(), KEOsFileLock(), KEOsFileUnlock(), KEOsFileCheckReservedLock(), KEOsFileFileControl(), 
+			KEOsFileSectorSize(), KEOsFileDeviceCharacteristics(), 
+			KEOsVfsOpen(), KEOsVfsDelete(), KEOsVfsAccess(), KEOsVfsFullPathName(), KEOsVfsRandomness(), KEOsVfsSleep(), 
+			KEOsVfsCurrentTime(), KEOsVfsGetLastError()};
+		
+		for(TInt i=0;i<countersValues.Length();++i)
+			{
+			if(countersValues[i] == TChar(';'))	
+				{
+				countersValues[i] = TChar(' ');	
+				}
+			}
+		TInt idx = 0;
+		TLex8 lex(countersValues);
+		while (!lex.Eos() && idx < (sizeof(KText)/sizeof(KText[0])))
+			{
+			TPtrC8 num8 = lex.NextToken();
+			TBuf<20> num;
+			num.Copy(num8);
+			TheTest.Printf(_L("==Operation %S, count %S\r\n"), &KText[idx], &num);
+			++idx;
+			}
+		}
+	}
+
+void PrintOsCallTime(TSqlResourceProfiler& aProfiler)
+	{
+	TBuf8<300> callTimes;
+	if(aProfiler.Query(TSqlResourceProfiler::ESqlCounterOsCallTime, callTimes) == KErrNone)
+		{
+		TheTest.Printf(_L("=========================\r\n"));
+		_LIT(KEOsFileClose, "FileClose");
+		_LIT(KEOsFileRead, "FileRead");
+		_LIT(KEOsFileWrite, "FileWrite");
+		_LIT(KEOsFileTruncate, "FileTruncate");
+		_LIT(KEOsFileSync, "FileSync");
+		_LIT(KEOsFileFileSize, "FileSize");
+		_LIT(KEOsFileLock, "FileLock");
+		_LIT(KEOsFileUnlock, "FileUnlock");
+		_LIT(KEOsFileCheckReservedLock, "FileCheckReservedLock");
+		_LIT(KEOsFileFileControl, "FileIoControl");
+		_LIT(KEOsFileSectorSize, "FileSectorSize");
+		_LIT(KEOsFileDeviceCharacteristics, "FileDeviceCharacteristics");
+		_LIT(KEOsVfsOpen, "VfsOpen");
+		_LIT(KEOsVfsDelete, "VfsDelete");
+		_LIT(KEOsVfsAccess, "VfsAccess");
+		_LIT(KEOsVfsFullPathName, "VfsFullPathName");
+		_LIT(KEOsVfsRandomness, "VfsRandomnes");
+		_LIT(KEOsVfsSleep, "VfsSleep");
+		_LIT(KEOsVfsCurrentTime, "VfsCurrentTime");
+		_LIT(KEOsVfsGetLastError, "VfsGetLastError");
+		TPtrC KText[] = 
+			{
+			KEOsFileClose(), KEOsFileRead(), KEOsFileWrite(), KEOsFileTruncate(), KEOsFileSync(), 
+			KEOsFileFileSize(), KEOsFileLock(), KEOsFileUnlock(), KEOsFileCheckReservedLock(), KEOsFileFileControl(), 
+			KEOsFileSectorSize(), KEOsFileDeviceCharacteristics(), 
+			KEOsVfsOpen(), KEOsVfsDelete(), KEOsVfsAccess(), KEOsVfsFullPathName(), KEOsVfsRandomness(), KEOsVfsSleep(), 
+			KEOsVfsCurrentTime(), KEOsVfsGetLastError()};
+		
+		for(TInt i=0;i<callTimes.Length();++i)
+			{
+			if(callTimes[i] == TChar(';'))	
+				{
+				callTimes[i] = TChar(' ');	
+				}
+			}
+		TInt idx = 0;
+		TLex8 lex(callTimes);
+		while (!lex.Eos() && idx < (sizeof(KText)/sizeof(KText[0])))
+			{
+			TPtrC8 num8 = lex.NextToken();
+			TBuf<20> num;
+			num.Copy(num8);
+			TheTest.Printf(_L("==Operation %S, time %S us\r\n"), &KText[idx], &num);
+			++idx;
+			}
+		}
+	}
+
+void PrintIpc(TSqlResourceProfiler& aProfiler)
+	{
+	TBuf8<300> countersValues;
+	if(aProfiler.Query(TSqlResourceProfiler::ESqlCounterIpc, countersValues) == KErrNone)
+		{
+		TheTest.Printf(_L("=========================\r\n"));
+		_LIT(KIpcRq, "IPC requests");
+		_LIT(KIpcRead, "IPC read");
+		_LIT(KIpcWrite, "IPC write");
+		_LIT(KIpcReadBytes, "IPC read bytes");
+		_LIT(KIpcWriteBytes, "IPC write bytes");
+		TPtrC KText[] = 
+			{
+			KIpcRq(), KIpcRead(), KIpcWrite(), KIpcReadBytes(), KIpcWriteBytes()
+			};
+		
+		for(TInt i=0;i<countersValues.Length();++i)
+			{
+			if(countersValues[i] == TChar(';'))	
+				{
+				countersValues[i] = TChar(' ');	
+				}
+			}
+		TInt idx = 0;
+		TLex8 lex(countersValues);
+		while (!lex.Eos() && idx < (sizeof(KText)/sizeof(KText[0])))
+			{
+			TPtrC8 num8 = lex.NextToken();
+			TBuf<20> num;
+			num.Copy(num8);
+			TheTest.Printf(_L("==Operation %S, count %S\r\n"), &KText[idx], &num);
+			++idx;
+			}
+		}
+	}
+
+void PrintMemory(TSqlResourceProfiler& aProfiler)
+	{
+	TBuf8<300> countersValues;
+	if(aProfiler.Query(TSqlResourceProfiler::ESqlCounterMemory, countersValues) == KErrNone)
+		{
+		TheTest.Printf(_L("=========================\r\n"));
+		_LIT(KMemorySrvAllocatedCnt, "Server allocated cnt");
+		_LIT(KMemorySrvAllocatedSize, "Server allocated size");
+		_LIT(KMemorySrvFreeSpace, "Server free space");
+		_LIT(KMemorySrvLargestBlockSize, "Server larges block size");
+		_LIT(KMemorySQLiteAllocatedCnt, "SQLite allocated cnt");
+		_LIT(KMemorySQLiteReallocatedCnt, "SQLite reallocated cnt");
+		_LIT(KMemorySQLiteFreedCnt, "SQLite freed cnt");
+		_LIT(KMemorySQLiteAllocatedBytes, "SQLite allocated bytes");
+		_LIT(KMemorySQLiteFreedBytes, "SQLite freed bytes");
+		_LIT(KMemorySQLiteAllocTime, "SQLite alloc, us");
+		_LIT(KMemorySQLiteReallocTime, "SQLite realloc, us");
+		_LIT(KMemorySQLiteFreeTime, "SQLite free, us");
+		TPtrC KText[] = 
+			{
+			KMemorySrvAllocatedCnt(), KMemorySrvAllocatedSize(), KMemorySrvFreeSpace(), KMemorySrvLargestBlockSize(), 
+			KMemorySQLiteAllocatedCnt(), KMemorySQLiteReallocatedCnt(), KMemorySQLiteFreedCnt(), 
+			KMemorySQLiteAllocatedBytes(), KMemorySQLiteFreedBytes(),
+			KMemorySQLiteAllocTime(), KMemorySQLiteReallocTime(), KMemorySQLiteFreeTime()
+			};
+		
+		for(TInt i=0;i<countersValues.Length();++i)
+			{
+			if(countersValues[i] == TChar(';'))	
+				{
+				countersValues[i] = TChar(' ');	
+				}
+			}
+		TInt idx = 0;
+		TLex8 lex(countersValues);
+		while (!lex.Eos() && idx < (sizeof(KText)/sizeof(KText[0])))
+			{
+			TPtrC8 num8 = lex.NextToken();
+			TBuf<20> num;
+			num.Copy(num8);
+			TheTest.Printf(_L("==%S=%S\r\n"), &KText[idx], &num);
+			++idx;
+			}
+		}
+	}
+
+/**
+@SYMTestCaseID			SYSLIB-SQL-UT-4088
+@SYMTestCaseDesc		TSqlResouceProfiler - file I/O and configuration test.
+						The test enables the file I/O profiling and then executes a simple INSERT statement
+						and prints out the profiling results. The test also prints the current database configuration.
+@SYMTestActions			TSqlResouceProfiler - file I/O and configuration test.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority		Medium
+@SYMREQ					REQ5792
+*/
+void ProfilerTest()
+	{
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	TInt err = TheDb.Create(KTestDbName1);	
+	TEST2(err, KErrNone);
+	err = TheDb.Exec(_L("CREATE TABLE A(Id INTEGER, T TEXT)"));
+	TEST2(err, 1);
+	
+	TSqlResourceProfiler profiler(TheDb);
+	
+	PrintConfig(profiler);
+	
+	(void)profiler.Start(TSqlResourceProfiler::ESqlCounterFileIO);
+	(void)profiler.Start(TSqlResourceProfiler::ESqlCounterOsCall);
+	(void)profiler.Start(TSqlResourceProfiler::ESqlCounterOsCallTime);
+	(void)profiler.Start(TSqlResourceProfiler::ESqlCounterIpc);
+	(void)profiler.Start(TSqlResourceProfiler::ESqlCounterMemory);
+	
+	(void)profiler.Reset(TSqlResourceProfiler::ESqlCounterFileIO);
+	(void)profiler.Reset(TSqlResourceProfiler::ESqlCounterOsCall);
+	(void)profiler.Reset(TSqlResourceProfiler::ESqlCounterOsCallTime);
+	(void)profiler.Reset(TSqlResourceProfiler::ESqlCounterIpc);
+	(void)profiler.Reset(TSqlResourceProfiler::ESqlCounterMemory);
+
+	err = TheDb.Exec(_L("INSERT INTO A VALUES(1, 'ABCDEEFGH')"));
+	TEST2(err, 1);
+	
+	PrintFileIo(profiler);
+	PrintOsCall(profiler);
+	PrintOsCallTime(profiler);
+	PrintIpc(profiler);
+	PrintMemory(profiler);
+
+	(void)profiler.Stop(TSqlResourceProfiler::ESqlCounterIpc);
+	(void)profiler.Stop(TSqlResourceProfiler::ESqlCounterOsCallTime);
+	(void)profiler.Stop(TSqlResourceProfiler::ESqlCounterOsCall);
+	(void)profiler.Stop(TSqlResourceProfiler::ESqlCounterFileIO);
+	(void)profiler.Stop(TSqlResourceProfiler::ESqlCounterMemory);
+
+	TheDb.Close();
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	}
+
+TInt CompoundSelectStackOverflowThreadFunc(void* aData)
+	{
+	CTrapCleanup* tc = CTrapCleanup::New();
+	TEST(tc != NULL);
+	
+	User::SetJustInTime(EFalse);	// disable debugger panic handling
+	
+	TInt* cntptr = reinterpret_cast<TInt*> (aData);
+	TEST(cntptr != NULL);
+	const TInt KSelectStmtCnt = *cntptr;
+
+	HBufC* buf = HBufC::New(KSelectStmtCnt * 25 + 32);//enough for the "SELECT I FROM A UNION SELECT I FROM A..." string
+	if(!buf)
+		{
+		delete tc;
+		return KErrNoMemory;	
+		}
+	TPtr sql = buf->Des();
+
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	RSqlDatabase db;
+	TInt err = db.Create(KTestDbName1);
+	if(err != KErrNone)
+		{
+		delete buf;
+		return err;	
+		}
+	err = db.Exec(_L("CREATE TABLE A(I INTEGER);INSERT INTO A VALUES(1);"));
+	if(err < 1)
+		{
+		delete buf;
+		return err;	
+		}
+	
+	for(TInt i=0;i<KSelectStmtCnt;i++)
+		{
+		sql.Append(_L("SELECT I FROM A UNION ")); 
+		}
+	sql.SetLength(sql.Length() - 7);
+	RSqlStatement stmt;
+	err = stmt.Prepare(db, sql);//This call can crash the server with "stack overflow"
+	stmt.Close(); 
+	
+	db.Close();
+	delete buf;
+	(void)RSqlDatabase::Delete(KTestDbName1);
+	return err;
+	}
+
+void CompoundSelectStackOverflowTest()
+	{
+	const TInt KMaxSelectStmtCnt = 64;
+	for(TInt cnt=KMaxSelectStmtCnt;cnt>0;--cnt)
+		{
+		TheTest.Printf(_L("SELECT statement count: %d\r\n"), cnt);
+		RThread thread;
+		_LIT(KThreadName,"S2Thread");						//stack	minheap		maxheap
+		TInt err = thread.Create(KThreadName, &CompoundSelectStackOverflowThreadFunc, 0x2000, 0x00100000, 0x02000000, &cnt);
+		TEST2(err, KErrNone);
+		
+		TRequestStatus status;
+		thread.Logon(status);
+		TEST2(status.Int(), KRequestPending);
+		thread.Resume();
+		User::WaitForRequest(status);
+		User::SetJustInTime(ETrue);	// enable debugger panic handling
+
+		TInt exitType = thread.ExitType();
+		const TDesC& exitCategory = thread.ExitCategory();
+		TInt exitReason = thread.ExitReason();
+		TheTest.Printf(_L("Exit type: %d, exit reason: %d, exit category: %S\r\n"), exitType, exitReason, &exitCategory);
+		thread.Close();
+		if(exitReason == KErrServerTerminated)	//SQL server --> stack overflow
+			{
+			continue;	
+			}
+		TEST2(exitReason, KErrNone);
+		TheTest.Printf(_L("  The test has succeeded with SELECT statement count=%d\r\n"), cnt);
+		break;
+		}
+	}
+
+void DoTestsL()
+	{
+	TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3512 RSqlStatement::ColumnCount() tests "));
+	ColumnCountTest();
+	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3513 RSqlStatement::ColumnCount(), non-SELECT tests "));
+	ColumnCountTest2();
+	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3514 RSqlStatement::DeclaredColumnType() tests "));
+	DeclaredColumnTypeTest();
+	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4017 RSqlStatement::ColumnName() tests"));	
+	ColumnNameTest();
+	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4018 RSqlStatement::ParameterName() and RSqlStatement::ParamName() tests"));	
+	ParamNameTest();
+	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4006 DEF115300 - SqlSrv.EXE::!SQL Server when preparing invalid LEFT JOIN sql query "));	
+	DEF115300();
+	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4007 DEF115331 - SQL, bad code coverage for db reindexing if default collation has changed "));
+	DEF115331L();
+	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4079 RSqlDatabase::Create() and RSqlDatabase::Open() - injection tests"));	
+	InjectionTest();
+	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4038 Two connections test"));	
+	TwoConnectionsTest();
+	TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4080 SQL server stack overflow test"));
+	SqlServerStackOverflowTest();
+	TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4086 RSqlBlobWriteStream/RSqlBlobReadStream injection test"));
+	BlobStreamInjectionTest();
+	TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4087 Bound parameter values test 1"));
+	BoundParameterValuesTest();
+	TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4076 Bound parameter values test 2"));
+	BoundParameterValuesTest2();
+	TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4077 Bound parameter values test 3"));
+	BoundParameterValuesTest3();
+	TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4083 Bound parameter values test 4"));
+	BoundParameterValuesTest4();
+	TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4105 Bound parameter values test 5"));
+	BoundParameterValuesTest5();
+	TheTest.Next( _L(" @SYMTestCaseID:SYSLIB-SQL-UT-4088 TSqlResourceProfiler - file I/O and configuration test"));
+	ProfilerTest();
+	TheTest.Next( _L(" Compound SELECT, stack overflow test"));
+	CompoundSelectStackOverflowTest();
+	}
+
+TInt E32Main()
+	{
+	TheTest.Title();
+
+	CTrapCleanup* tc = CTrapCleanup::New();
+
+	__UHEAP_MARK;
+
+	CreateTestEnv();
+	DeleteTestFiles();
+	TRAPD(err, DoTestsL());
+	DeleteTestFiles();
+	TEST2(err, KErrNone);
+
+	__UHEAP_MARKEND;
+
+	TheTest.End();
+	TheTest.Close();
+
+	delete tc;
+
+	User::Heap().Check();
+	return KErrNone;
+	}