예제 #1
0
void CChildLinkedDatasetColumnInfo::buildDeserialize(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * helper, IAtom * serializeFormat)
{
    if (isConditional())
        checkAssignOk(translator, ctx, selector, queryZero(), sizeof(size32_t) + sizeof(byte * *));

    OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
    OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(size32_t));

    IHqlExpression * record = column->queryRecord();
    CHqlBoundTarget boundTarget;
    boundTarget.count.setown(convertAddressToValue(addressSize, sizetType));
    boundTarget.expr.setown(convertAddressToValue(addressData, queryType()));

    IIdAtom * func = NULL;
    HqlExprArray args;
    args.append(*translator.createSerializer(ctx, record, serializeFormat, deserializerAtom));
    if (column->isDictionary())
    {
        if (serializeFormat == diskAtom)
        {
            func = deserializeChildDictionaryFromDatasetFromStreamId;
            StringBuffer lookupHelperName;
            translator.buildDictionaryHashClass(record, lookupHelperName);
            args.append(*createQuoted(lookupHelperName.str(), makeBoolType()));
        }
        else
            func = deserializeChildDictionaryFromStreamId;
    }
    else
        func = deserializeChildRowsetFromStreamId;

    args.append(*LINK(helper));
    OwnedHqlExpr call = translator.bindFunctionCall(func, args, queryType());
    translator.buildExprAssign(ctx, boundTarget, call);
}
예제 #2
0
void CChildLinkedDatasetColumnInfo::buildColumnExpr(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, CHqlBoundExpr & bound)
{
    OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
    OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(size32_t));

    bound.count.setown(convertAddressToValue(addressSize, sizetType));
    bound.expr.setown(convertAddressToValue(addressData, queryType()));
}
예제 #3
0
RtlRecord::RtlRecord(const RtlRecordTypeInfo & record, bool expandFields) : fields(record.fields), originalFields(record.fields)
{
    //MORE: Does not cope with ifblocks.
    numVarFields = 0;
    //Optionally expand out nested rows.
    if (expandFields)
    {
        bool containsNested = false;
        numFields = countFields(fields, containsNested);
        if (containsNested)
        {
            const RtlFieldInfo * * allocated  = new const RtlFieldInfo * [numFields+1];
            fields = allocated;
            const RtlFieldInfo * * target = expandNestedRows(allocated, originalFields);
            assertex(target == fields+numFields);
            *target = nullptr;
        }
    }
    else
        numFields = countFields(fields);

    for (unsigned i=0; i < numFields; i++)
    {
        if (!queryType(i)->isFixedSize())
            numVarFields++;
    }

    fixedOffsets = new size_t[numFields + 1];
    whichVariableOffset = new unsigned[numFields + 1];
    variableFieldIds = new unsigned[numVarFields];

    unsigned curVariable = 0;
    size_t fixedOffset = 0;
    for (unsigned i=0;; i++)
    {
        whichVariableOffset[i] = curVariable;
        fixedOffsets[i] = fixedOffset;
        if (i == numFields)
            break;

        const RtlTypeInfo * curType = queryType(i);
        if (curType->isFixedSize())
        {
            size_t thisSize = curType->size(nullptr, nullptr);
            fixedOffset += thisSize;
        }
        else
        {
            variableFieldIds[curVariable] = i;
            curVariable++;
            fixedOffset = 0;
        }
    }
}
void ColumnMapScan::prepareMaterialization() {
    LOG_ASSERT(mColumnMaterializeFuns.empty(), "Scan already finalized");
    auto& context = mTable->context();

    std::unordered_map<QueryDataHolder, std::string> materializeCache;
    for (decltype(mQueries.size()) i = 0; i < mQueries.size(); ++i) {
        auto q = mQueries[i];
        if (q->queryType() == ScanQueryType::FULL) {
            continue;
        }

        QueryDataHolder holder(q->query(), q->queryLength(), crossbow::to_underlying(q->queryType()));
        if (materializeCache.find(holder) != materializeCache.end()) {
            continue;
        }

        std::stringstream ss;
        ss << COLUMN_MATERIALIZE_NAME << i;
        auto name = ss.str();
        materializeCache.emplace(holder, name);

        switch (q->queryType()) {
        case ScanQueryType::PROJECTION: {
            LLVMColumnMapProjectionBuilder::createFunction(context, mMaterializationModule.getModule(),
                    mMaterializationModule.getTargetMachine(), name, q);
        } break;

        case ScanQueryType::AGGREGATION: {
            LLVMColumnMapAggregationBuilder::createFunction(context, mMaterializationModule.getModule(),
                    mMaterializationModule.getTargetMachine(), name, q);
        } break;

        default: {
            LOG_ASSERT(false, "Unknown query type");
        } break;
        }
    }

    LLVMRowScanBase::prepareMaterialization();

    for (decltype(mQueries.size()) i = 0; i < mQueries.size(); ++i) {
        auto q = mQueries[i];

        if (q->queryType() == ScanQueryType::FULL) {
            mColumnMaterializeFuns.emplace_back(reinterpret_cast<void*>(context.materializeFunction()));
            continue;
        }

        QueryDataHolder holder(q->query(), q->queryLength(), crossbow::to_underlying(q->queryType()));
        auto& name = materializeCache.at(holder);
        auto fun = mMaterializationModule.findFunction<void*>(name);
        mColumnMaterializeFuns.emplace_back(fun);
    }
}
예제 #5
0
size32_t RtlRecord::getMinRecordSize() const
{
    if (numVarFields == 0)
        return fixedOffsets[numFields];

    size32_t minSize = 0;
    for (unsigned i=0; i < numFields; i++)
        minSize += queryType(i)->getMinSize();

    return minSize;
}
예제 #6
0
void RtlRecord::calcRowOffsets(size_t * variableOffsets, const void * _row) const
{
    const byte * row = static_cast<const byte *>(_row);
    for (unsigned i = 0; i < numVarFields; i++)
    {
        unsigned fieldIndex = variableFieldIds[i];
        size_t offset = getOffset(variableOffsets, fieldIndex);
        size_t fieldSize = queryType(fieldIndex)->size(row + offset, row);
        variableOffsets[i+1] = offset+fieldSize;
    }
}
예제 #7
0
void CChildDatasetColumnInfo::setColumn(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * _value)
{
    OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
    OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(size32_t));

    OwnedHqlExpr lengthTarget = convertAddressToValue(addressSize, sizetType);

    ITypeInfo * columnType = column->queryType();
    OwnedHqlExpr value = LINK(_value); //ensureExprType(_value, columnType);
    ITypeInfo * valueType = value->queryType();

    assertRecordTypesMatch(valueType, columnType);

    bool assignInline = false;  // canEvaluateInline(value);   // MORE: What is the test
//  bool assignInline = canAssignInline(&ctx, value) && !canEvaluateInline(&ctx, value);
    value.setown(addDatasetLimits(translator, ctx, selector, value));

    IHqlExpression * record = column->queryRecord();
    if (assignInline)
    {
        OwnedHqlExpr inlineSize = getSizetConstant(0);
        checkAssignOk(translator, ctx, selector, inlineSize, sizeof(size32_t));

        //Can only assign inline if we know the maximum length that will be assigned is 0.
        Owned<IHqlCppDatasetBuilder> builder = translator.createInlineDatasetBuilder(record, inlineSize, addressData);
        builder->buildDeclare(ctx);

        translator.buildDatasetAssign(ctx, builder, value);

        CHqlBoundTarget boundTarget;
        boundTarget.length.set(lengthTarget);
        builder->buildFinish(ctx, boundTarget);
    }
    else
    {
        CHqlBoundExpr bound;
        translator.buildDataset(ctx, value, bound, FormatBlockedDataset);
        translator.normalizeBoundExpr(ctx, bound);
        ensureSimpleLength(translator, ctx, bound);

        OwnedHqlExpr length = translator.getBoundLength(bound);
        OwnedHqlExpr size = createValue(no_translated, LINK(sizetType), translator.getBoundSize(bound));
        checkAssignOk(translator, ctx, selector, size, sizeof(size32_t));

        translator.assignBoundToTemp(ctx, lengthTarget, length);
        translator.buildBlockCopy(ctx, addressData, bound);

        //Use the size just calculated for the field
        OwnedHqlExpr sizeOfExpr = createValue(no_sizeof, LINK(sizetType), LINK(selector->queryExpr()));
        OwnedHqlExpr boundSize = translator.getBoundSize(bound);
        OwnedHqlExpr srcSize = adjustValue(boundSize, sizeof(size32_t));
        ctx.associateExpr(sizeOfExpr, srcSize);
    }
}
예제 #8
0
void CChildLimitedDatasetColumnInfo::buildColumnExpr(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, CHqlBoundExpr & bound)
{
    OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), 0);

    if (countField)
    {
        OwnedHqlExpr mappedCount = replaceSelector(countField, querySelfReference(), selector->queryExpr()->queryChild(0));
        CHqlBoundExpr boundCount;
        translator.buildExpr(ctx, mappedCount, boundCount);
        bound.count.set(boundCount.expr);
    }
    else
    {
        OwnedHqlExpr mappedSize = replaceSelector(sizeField, querySelfReference(), selector->queryExpr()->queryChild(0));
        CHqlBoundExpr boundSize;
        translator.buildExpr(ctx, mappedSize, boundSize);
        bound.length.set(boundSize.expr);
    }

    bound.expr.setown(convertAddressToValue(addressData, queryType()));
}
예제 #9
0
void CChildLinkedDatasetColumnInfo::setColumn(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * _value)
{
    OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
    OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(size32_t));

    ITypeInfo * resultType = queryType();
    LinkedHqlExpr value = _value;
    ITypeInfo * valueType = value->queryType();

    assertRecordTypesMatch(resultType, valueType);

    value.setown(addDatasetLimits(translator, ctx, selector, value));

    CHqlBoundTarget boundTarget;
    boundTarget.count.setown(convertAddressToValue(addressSize, sizetType));
    boundTarget.expr.setown(convertAddressToValue(addressData, queryType()));

    if (value->getOperator() == no_null)
        value.setown(createNullExpr(column));
    
    translator.buildDatasetAssign(ctx, boundTarget, value);
}
예제 #10
0
bool CChildLinkedDatasetColumnInfo::modifyColumn(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * value, node_operator op)
{
    if (hasDatasetLimits() || (op != no_assign_addfiles))
        return false;

    OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
    OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(size32_t));

    ITypeInfo * resultType = queryType();
    ITypeInfo * valueType = value->queryType();
    assertex(recordTypesMatch(valueType, resultType));

    CHqlBoundTarget boundTarget;
    boundTarget.count.setown(convertAddressToValue(addressSize, sizetType));
    boundTarget.expr.setown(convertAddressToValue(addressData, queryType()));

    HqlExprArray args;
    args.append(*LINK(value));
    OwnedHqlExpr call = translator.bindFunctionCall(appendRowsToRowsetId, args, resultType);
    translator.buildDatasetAssign(ctx, boundTarget, call);
    return true;
}
예제 #11
0
void CompilerStatsInfo :: translateToExternalFormat(SQL_QUERY_COMPILER_STATS_INFO *query_comp_stats_info, short xnReqd)
{
  query_comp_stats_info->affinityNumber
    = affinityNumber();

  query_comp_stats_info->dop
    = dop();

  query_comp_stats_info->xnNeeded
    = xnReqd;

  query_comp_stats_info->mandatoryCrossProduct
    = mandatoryCrossProduct();

  query_comp_stats_info->missingStats
    = missingStats();
  query_comp_stats_info->numOfJoins
    = totalJoins();
	      
  query_comp_stats_info->fullScanOnTable
    = fullScanOnTable();

  query_comp_stats_info->highDp2MxBufferUsage
    = 0;  // this data member is not present in the TDB yet

  query_comp_stats_info->rowsAccessedForFullScan
    = dp2RowsAccessedForFullScan();

  query_comp_stats_info->dp2RowsAccessed
    = dp2RowsAccessed();

  query_comp_stats_info->dp2RowsUsed
    = dp2RowsUsed();
  query_comp_stats_info->statsCollectionType 
    = collectStatsType();
  query_comp_stats_info->numOfBmos 
    = bmo();
  query_comp_stats_info->numOfUdrs
    = udr();
  query_comp_stats_info->overflowMode
    = ofMode();
  query_comp_stats_info->overflowSize
    = ofSize();
  query_comp_stats_info->queryType
    = queryType();
  query_comp_stats_info->subqueryType
    = subqueryType();
 

}
예제 #12
0
void CChildLimitedDatasetColumnInfo::setColumnFromBuilder(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlCppDatasetBuilder * builder)
{
    CHqlBoundExpr bound;
    builder->buildFinish(ctx, bound);
    if (bound.length)
        bound.length.setown(translator.ensureSimpleTranslatedExpr(ctx, bound.length));

    OwnedHqlExpr size = createValue(no_translated, LINK(sizetType), translator.getBoundSize(bound));
    checkAssignOk(translator, ctx, selector, size, 0);

    OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), 0);
    translator.buildBlockCopy(ctx, addressData, bound);

    //Use the size just calculated for the field
    OwnedHqlExpr sizeOfExpr = createValue(no_sizeof, LINK(sizetType), LINK(selector->queryExpr()));
    OwnedHqlExpr srcSize = translator.getBoundSize(bound);
    ctx.associateExpr(sizeOfExpr, srcSize);
}
예제 #13
0
void CChildSetColumnInfo::buildDeserialize(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * helper, IAtom * serializeForm)
{
    OwnedHqlExpr address = getColumnAddress(translator, ctx, selector, boolType, 0);
    OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, sizeof(bool));
    OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(bool)+sizeof(size32_t));

    size32_t sizeExtra = sizeof(bool)+sizeof(size32_t);

    //Read the all flag and the size
    OwnedHqlExpr sizeAllSizet = getSizetConstant(sizeExtra);
    callDeserializeGetN(translator, ctx, helper, sizeAllSizet, address);

    OwnedHqlExpr targetSize = convertAddressToValue(addressSize, sizetType);
    OwnedHqlExpr unboundSize = createTranslated(targetSize);
    checkAssignOk(translator, ctx, selector, unboundSize, sizeExtra);

    callDeserializeGetN(translator, ctx, helper, targetSize, addressData);

    OwnedHqlExpr sizeOfExpr = createValue(no_sizeof, LINK(sizetType), LINK(selector->queryExpr()));
    OwnedHqlExpr srcSize = adjustValue(targetSize, sizeExtra);
    ctx.associateExpr(sizeOfExpr, srcSize);
}
예제 #14
0
void CChildDatasetColumnInfo::buildDeserialize(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * helper, IAtom * serializeForm)
{
    IHqlExpression * record = column->queryRecord();
    assertex(!recordRequiresLinkCount(record)); // Why would it?
    if (column->isDictionary())
    {
        if (serializeForm == diskAtom)
        {
            //If we ever generate the meta definition for an internal serialization format then the following needs to be implemented
            UNIMPLEMENTED_X("deserialize serialized dictionary from disk");
            return;
        }
    }


    if (isConditional())
        checkAssignOk(translator, ctx, selector, queryZero(), sizeof(size32_t));

    OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, 0);
    OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(size32_t));

    //Read the all flag and the size
    OwnedHqlExpr sizeSizet = getSizetConstant(sizeof(size32_t));
    callDeserializeGetN(translator, ctx, helper, sizeSizet, addressSize);

    OwnedHqlExpr targetSize = convertAddressToValue(addressSize, sizetType);
    OwnedHqlExpr simpleSize = translator.ensureSimpleTranslatedExpr(ctx, targetSize);
    OwnedHqlExpr unboundSize = createTranslated(simpleSize);
    checkAssignOk(translator, ctx, selector, unboundSize, sizeof(size32_t));

    callDeserializeGetN(translator, ctx, helper, simpleSize, addressData);

    OwnedHqlExpr sizeOfExpr = createValue(no_sizeof, LINK(sizetType), LINK(selector->queryExpr()));
    OwnedHqlExpr srcSize = adjustValue(simpleSize, sizeof(size32_t));
    ctx.associateExpr(sizeOfExpr, srcSize);
}
예제 #15
0
void Dispatcher::dispatch_requests(int id) {
    debug("Thread %i started", id);

    while (1) {
        // Get an request out of the request queue
        int socket;
        debug("Try to lock %d", id);
        {
            std::unique_lock<std::mutex> lck(request_queue_mutex);
            while (request_queue.empty()) {
                debug("Wait %d", id);
                request_queue_empty.wait(lck);
            };
            socket = request_queue.front();
            request_queue.pop();
            debug("Unlock %d", id);
        }

        debug("New request: Handled by thread %i", id);

        // Allocates memory for the request
        struct HttpRequest *request;
        int http_error = http_receive_request(socket, &request);
        if (http_error != HTTP_SUCCESS) {
            debug("Invalid Http request.");
            assert(request == NULL);
            // TODO send error msg to client
            close(socket);
            continue;
        }
        debug("Request payload: %s", request->payload);

        if (strncmp(request->resource, "/add_node/", 10) == 0) {
            struct sockaddr addr;
            socklen_t addrlen = sizeof(struct sockaddr);
            if (getpeername(socket, &addr, &addrlen) == 0) {
                if (addr.sa_family == AF_INET || addr.sa_family == AF_UNSPEC) {
                    struct sockaddr_in *sa = (struct sockaddr_in *)&addr;
                    char ip[INET_ADDRSTRLEN];
                    if (inet_ntop(AF_INET, &(sa->sin_addr), ip, INET_ADDRSTRLEN) == NULL) {
                        log_err("/add_node/ - Converting network address to string");
                    }
                    int port = (int)strtol(request->resource+10, (char **)NULL, 10);
                    if (port == 0) {
                        log_err("/add_node/ - Detecting port");
                    }
                    debug("Add host:  %s:%i", ip, port);
                    add_host(ip, port);
                } else {
                    debug("Cannot add host: Unsupported Address family %d", addr.sa_family);
                }
            } else {
                log_err("/add_node/ - getpeername()");
            }

            HttpRequest_free(request);
            close(socket);

        } else if (strncmp(request->resource, "/remove_node/", 13) == 0) {
            char *delimiter = strchr(request->resource, ':');
            if (delimiter != NULL) {
                char *ip = strndup(request->resource + 13, delimiter - (request->resource + 13));
                int port = 0;
                remove_host(ip, port);
                free(ip);
            }

            HttpRequest_free(request);
            close(socket);

        } else if (strcmp(request->resource, "/node_info") == 0) {
            sendNodeInfo(request, socket);

            HttpRequest_free(request);
            close(socket);

        } else if (strcmp(request->resource, "/query") == 0) {
            int query_t = queryType(request->payload);
            switch(query_t) {
                case READ:
                    distributor->distribute(request, socket);
                    break;
                case LOAD:
                    sendToAll(request, socket);
                    break;
                case WRITE:
                    distributor->sendToMaster(request, socket);
                    break;
                default:
                    log_err("Invalid query: %s", request->payload);
                    throw "Invalid query.";
            }
        } else if (strcmp(request->resource, "/procedure") == 0) {
            distributor->sendToMaster(request, socket);
        } else {
            log_err("Invalid HTTP resource: %s", request->resource);
            exit(1);
        }
    }
}
예제 #16
0
void CChildSetColumnInfo::setColumn(HqlCppTranslator & translator, BuildCtx & ctx, IReferenceSelector * selector, IHqlExpression * _value)
{
    OwnedHqlExpr address = getColumnAddress(translator, ctx, selector, boolType, 0);
    OwnedHqlExpr addressSize = getColumnAddress(translator, ctx, selector, sizetType, sizeof(bool));
    OwnedHqlExpr addressData = getColumnAddress(translator, ctx, selector, queryType(), sizeof(bool)+sizeof(size32_t));

    OwnedHqlExpr isAllTarget = convertAddressToValue(address, boolType);
    OwnedHqlExpr lengthTarget = convertAddressToValue(addressSize, sizetType);

    ITypeInfo * columnType = column->queryType();
    ITypeInfo * elementType = columnType->queryChildType();
    OwnedHqlExpr value = ensureExprType(_value, columnType);

    OwnedHqlExpr inlineSize;
    switch (value->getOperator())
    {
    case no_list:
        if ((value->numChildren() != 0) && ::isFixedSize(elementType))
            inlineSize.setown(getSizetConstant(value->numChildren() * elementType->getSize())); 
        break;
    }

    if (inlineSize)
    {
        checkAssignOk(translator, ctx, selector, inlineSize, sizeof(size32_t)+sizeof(bool));

        Owned<IHqlCppSetBuilder> builder = translator.createInlineSetBuilder(elementType, isAllTarget, inlineSize, addressData);
        builder->buildDeclare(ctx);

        translator.buildSetAssign(ctx, builder, value);

        CHqlBoundTarget boundTarget;
        boundTarget.length.set(lengthTarget);
        builder->buildFinish(ctx, boundTarget);
    }
    else
    {
        CHqlBoundExpr bound;
        if ((value->getOperator() == no_list) && value->numChildren())
        {
            CHqlBoundTarget tempTarget;
            translator.createTempFor(ctx, columnType, tempTarget, typemod_none, FormatNatural);
            translator.buildExprAssign(ctx, tempTarget, value);
            bound.setFromTarget(tempTarget);
        }
        else
            translator.buildExpr(ctx, value, bound);
        ensureSimpleLength(translator, ctx, bound);

        OwnedHqlExpr isAll = bound.getIsAll();
        OwnedHqlExpr length = translator.getBoundLength(bound);
        OwnedHqlExpr size = createValue(no_translated, LINK(sizetType), translator.getBoundSize(bound));
        checkAssignOk(translator, ctx, selector, size, sizeof(size32_t)+sizeof(bool));

        translator.assignBoundToTemp(ctx, isAllTarget, isAll);
        translator.assignBoundToTemp(ctx, lengthTarget, length);
        translator.buildBlockCopy(ctx, addressData, bound);

        ensureSimpleLength(translator, ctx, bound);
        OwnedHqlExpr boundSize = translator.getBoundSize(bound);
        associateSizeOf(ctx, selector, boundSize, sizeof(size32_t)+sizeof(bool));
    }
}
예제 #17
0
/**
@SYMTestCaseID			PDS-SQL-UT-4151
@SYMTestCaseDesc		Measures the performance of inserting multiple records
						into the Music Player MPX database.  This test is based on 
						a real Music Player Harvesting use case
@SYMTestPriority		Medium
@SYMTestActions			Reads SQL transactions from a file and executes them.  
						Records the time for executing each statement
@SYMTestExpectedResults All statements should be executed without error and 
						performance measurements logged
@SYMDEF					DEF142306
*/
void RunTest()
	{
	//Open the file with the sql statements 
	_LIT(KSqlFileName,"z:\\test\\t_sqlperformance4.sql");
	RFile sqlFile;
	TInt err = sqlFile.Open(TheFs, KSqlFileName, EFileRead); 
	TEST2(err, KErrNone);
	
	TInt fileLen = 0;
	err = sqlFile.Size(fileLen); 
	TEST2(err, KErrNone);
	
	HBufC8* sqlBuf = HBufC8::New(fileLen); 
	TEST(sqlBuf != NULL);
	TPtr8 sql = sqlBuf->Des();
	err = sqlFile.Read(sql);
	
	sqlFile.Close();
	TEST2(err, KErrNone);
	TEST2(sql.Length(), fileLen);
	
	//Open main database
	err = TheDbC.Open(TheDbFileName, &TheSqlConfigString);
	TEST2(err, KErrNone);
	
	TheTest.Printf(_L("Beginning INSERTS...\n"));
	
	const TInt KRecordCount = 6544;
	TInt recordCount = 0;
	TInt insertCnt = 0;
	TInt updateCnt = 0;
	TInt selectCnt = 0;
	TInt trnCnt = 0;
	TInt totalTime = 0;

	TInt insertTrnCnt = 0;
	TInt updateTrnCnt = 0;
	TInt selectTrnCnt = 0;
	
	for(;sql.Length()>0;)
		{
		TInt eolPos = sql.Locate(TChar('\n'));
		if(eolPos < 0)
			{
			break;//No more SQL statements
			}
		TInt stmtLength = eolPos;
		while (stmtLength > 0 && (sql[stmtLength-1] == '\r'))
			{
			--stmtLength; //Reduce length to remove carriage return characters from the end of the statement string
			}
		TPtrC8 sqlStmt8(sql.Ptr(), stmtLength);
		TPtrC8 ptr = sql.Mid(eolPos + 1);//"eolPos + 1" - first character after '\n'
		sql.Set(const_cast <TUint8*> (ptr.Ptr()), ptr.Length(), ptr.Length());
		++recordCount;
		
		//Convert to 16 bit query string
		TBuf<1024> query;
		query.Copy(sqlStmt8);
		
		//Execute the statement
		TInt start = User::FastCounter();
		err = TheDbC.Exec(query);
		TInt end = User::FastCounter();
		
		TEST(err >= 0);
		
		//Get the execution time for that statement
		TInt duration = GetDuration(start, end);
		totalTime += duration;
		
		if(query == KBeginTransaction)
			{		
			TheTest.Printf(_L("Execute Statement - BEGIN: %d us\n"), duration);
			}
		
		else if(query == KCommitTransaction)
			{
			++trnCnt;
			TheTest.Printf(_L("Execute Statement - COMMIT: %d us, Trn#%d, \"INSERT\" count: %d, \"UPDATE\" count: %d, \"SELECT\" count: %d\n"), 
					duration, trnCnt, insertTrnCnt, updateTrnCnt, selectTrnCnt);
			insertTrnCnt = updateTrnCnt = selectTrnCnt = 0;
			}

		else
			{	
			TPtrC queryType(query.Ptr(), 6);
			TheTest.Printf(_L("Execute Statement - %S: %d us\n"),&queryType, duration);
			if(queryType.FindF(_L("INSERT")) >= 0)
				{
				++insertCnt;
				++insertTrnCnt;
				}
			else if(queryType.FindF(_L("UPDATE")) >= 0)
				{
				++updateCnt;
				++updateTrnCnt;
				}
			else if(queryType.FindF(_L("SELECT")) >= 0)
				{
				++selectCnt;
				++selectTrnCnt;
				}
			}
		}
	delete sqlBuf;
	
	TheDbC.Close();
	
	TheTest.Printf(_L("Total time to process Songs: %d us\n"), totalTime);
	TheTest.Printf(_L("Transactions count: %d, \"INSERT\" count: %d, \"UPDATE\" count: %d, \"SELECT\" count: %d\n"), 
			               trnCnt, insertCnt, updateCnt, selectCnt);
	TEST2(recordCount, KRecordCount);
	}