2424#include " ResultSetMetaData.h"
2525#include " interface/Exception.h"
2626#include " Protocol.h"
27+ #include " class/unique_key.h"
2728
2829#include " ma_odbc.h"
2930
@@ -110,9 +111,6 @@ void MADB_DropStmt(MADB_Stmt *Stmt, bool external= true)
110111 MADB_FREE (Stmt->params );
111112 MADB_FREE (Stmt->result );
112113 MADB_FREE (Stmt->Cursor .Name );
113- MADB_FREE (Stmt->CatalogName );
114- MADB_FREE (Stmt->TableName );
115- MADB_FREE (Stmt->UniqueIndex );
116114 /* For explicit descriptors we only remove reference to the stmt*/
117115 if (Stmt->Apd ->AppType )
118116 {
@@ -277,6 +275,8 @@ MADB_Stmt *MADB_FindCursor(MADB_Stmt *Stmt, const char *CursorName)
277275ResultSetMetaData* FetchMetadata (MADB_Stmt *Stmt, bool early)
278276{
279277 delete Stmt->metadata ;
278+ // unique_key references metadata. TODO: Need to do smth about this
279+ Stmt->UniqueIndex .reset ();
280280 /* TODO early probably is not needed here at all */
281281 if (early)
282282 {
@@ -324,9 +324,7 @@ SQLRETURN MADB_StmtReset(MADB_Stmt* Stmt)
324324 Stmt->PositionedCommand = 0 ;
325325 Stmt->State = MADB_SS_INITED;
326326 MADB_CLEAR_ERROR (&Stmt->Error );
327- MADB_FREE (Stmt->UniqueIndex );
328- Stmt->IndexType = 0 ;
329- MADB_FREE (Stmt->TableName );
327+ Stmt->UniqueIndex .reset ();
330328 }
331329 return SQL_SUCCESS;
332330}
@@ -569,7 +567,6 @@ SQLRETURN MADB_Stmt::Prepare(const char *StatementText, SQLINTEGER TextLength, b
569567 */
570568 if ((CursorName= MADB_ParseCursorName (&Query, &WhereOffset)))
571569 {
572- char *TableName;
573570 /* Make sure we have a delete or update statement
574571 MADB_QUERY_DELETE and MADB_QUERY_UPDATE defined in the enum to have the same value
575572 as SQL_UPDATE and SQL_DELETE, respectively */
@@ -589,10 +586,9 @@ SQLRETURN MADB_Stmt::Prepare(const char *StatementText, SQLINTEGER TextLength, b
589586 goto cleanandexit;
590587 }
591588
592- TableName= MADB_GetTableName (PositionedCursor);
593- SQLString StmtStr (Query.RefinedText .c_str (),WhereOffset);
589+ SQLString StmtStr (Query.RefinedText .c_str (), WhereOffset);
594590 StmtStr.reserve (8192 );
595- if (MADB_DynStrGetWhere (PositionedCursor, StmtStr, TableName, true ))
591+ if (MADB_DynStrGetWhere (PositionedCursor, StmtStr, true ))
596592 {
597593 goto cleanandexit;
598594 }
@@ -834,8 +830,11 @@ SQLRETURN MADB_ExecutePositionedUpdate(MADB_Stmt *Stmt, bool ExecDirect)
834830
835831 for (j= 1 ; j < MADB_STMT_COLUMN_COUNT (Stmt->PositionedCursor ) + 1 ; ++j)
836832 {
837- if (Stmt->PositionedCursor ->UniqueIndex == nullptr ||
838- (Stmt->PositionedCursor ->UniqueIndex [0 ] != 0 && IndexIdx <= Stmt->PositionedCursor ->UniqueIndex [0 ] && j == Stmt->PositionedCursor ->UniqueIndex [IndexIdx] + 1 ))
833+ // unique_key methods use 0 based indexes
834+ if (!Stmt->PositionedCursor ->UniqueIndex ||
835+ (Stmt->PositionedCursor ->UniqueIndex ->exists () &&
836+ IndexIdx <= static_cast <SQLSMALLINT>(Stmt->PositionedCursor ->UniqueIndex ->fieldCount ()) &&
837+ j == Stmt->PositionedCursor ->UniqueIndex ->fieldIndex (IndexIdx - 1 ) + 1 ))
839838 {
840839 SQLLEN Length;
841840 MADB_DescRecord* Rec= MADB_DescGetInternalRecord (Stmt->PositionedCursor ->Ard , j, MADB_DESC_READ);
@@ -845,7 +844,7 @@ SQLRETURN MADB_ExecutePositionedUpdate(MADB_Stmt *Stmt, bool ExecDirect)
845844 if (Stmt->PositionedCursor ->UniqueIndex != nullptr )
846845 {
847846 ParamNumber= /* Param ordnum in pos.cursor condition */ IndexIdx +
848- /* Num of params in main stmt */ (Stmt->ParamCount - Stmt->PositionedCursor ->UniqueIndex [ 0 ] );
847+ /* Num of params in main stmt */ (Stmt->ParamCount - Stmt->PositionedCursor ->UniqueIndex -> fieldCount () );
849848 ++IndexIdx;
850849 }
851850 else
@@ -3628,20 +3627,18 @@ SQLRETURN MADB_StmtSetPos(MADB_Stmt* Stmt, SQLSETPOSIROW RowNumber, SQLUSMALLINT
36283627 /* Nothing else to do (at least for now) in this 2 cases */
36293628 return SQL_SUCCESS;
36303629 };
3631-
3632- char * TableName= MADB_GetTableName (Stmt);
3633- if (!TableName)
3634- {
3635- return MADB_SetError (&Stmt->Error , MADB_ERR_IM001, " Updatable Cursors with multiple tables are not supported" , 0 );
3630+ /* SQL_ADD does not need to know the index */
3631+ if (Operation != SQL_ADD && !Stmt->UniqueIndex ) {
3632+ Stmt->UniqueIndex .reset (new mariadb::unique_key (Stmt->Connection ->guard .get (), Stmt->metadata ));
36363633 }
3637- char * CatalogName= MADB_GetCatalogName (Stmt);
3638-
36393634 switch (Operation) {
36403635 case SQL_ADD:
36413636 {
36423637 MADB_DynString DynStmt;
36433638 SQLRETURN ret;
36443639 int column, param= 0 ;
3640+ // This constructor does not read index info but only verifies that only one table is used
3641+ mariadb::unique_key tableInfo (Stmt->metadata );
36453642
36463643 Stmt->DaeRowNumber = RowNumber;
36473644
@@ -3654,9 +3651,9 @@ SQLRETURN MADB_StmtSetPos(MADB_Stmt* Stmt, SQLSETPOSIROW RowNumber, SQLUSMALLINT
36543651 MADB_StmtInit (Stmt->Connection , (SQLHANDLE *)&Stmt->DaeStmt , false );
36553652
36563653 if (MADB_InitDynamicString (&DynStmt, " INSERT INTO " , 8192 , 1024 ) ||
3657- MADB_DynStrAppendQuoted (&DynStmt, CatalogName ) ||
3654+ MADB_DynStrAppendQuoted (&DynStmt, tableInfo. getSchema (). c_str () ) ||
36583655 MADB_DynstrAppend (&DynStmt, " ." ) ||
3659- MADB_DynStrAppendQuoted (&DynStmt, TableName) ||
3656+ MADB_DynStrAppendQuoted (&DynStmt, tableInfo. getTable (). c_str ()) ||
36603657 MADB_DynStrInsertSet (Stmt, &DynStmt))
36613658 {
36623659 MADB_DynstrFree (&DynStmt);
@@ -3852,7 +3849,7 @@ SQLRETURN MADB_StmtSetPos(MADB_Stmt* Stmt, SQLSETPOSIROW RowNumber, SQLUSMALLINT
38523849 case SQL_DELETE:
38533850 {
38543851 SQLRETURN result = SQL_INVALID_HANDLE; /* Just smth we cannot normally get */
3855- SQLString DynamicStmt ( " DELETE FROM " ) ;
3852+ SQLString DynamicStmt;
38563853 std::size_t baseStmtLen;
38573854 SQLULEN SaveArraySize= Stmt->Ard ->Header .ArraySize ;
38583855 my_ulonglong Start= 0 ,
@@ -3869,14 +3866,15 @@ SQLRETURN MADB_StmtSetPos(MADB_Stmt* Stmt, SQLSETPOSIROW RowNumber, SQLUSMALLINT
38693866 {
38703867 End= Start;
38713868 }
3872- DynamicStmt.reserve (8182 );
3873- DynamicStmt.append (TableName);
3869+ DynamicStmt.reserve (8192 );
3870+ DynamicStmt.append (" DELETE FROM `" , 13 ).append (Stmt->UniqueIndex ->getSchema ()).append (" `.`" , 3 ).
3871+ append (Stmt->UniqueIndex ->getTable ()).append (" `" , 1 );
38743872 baseStmtLen= DynamicStmt.length ();
38753873 while (Start <= End)
38763874 {
38773875 MADB_StmtDataSeek (Stmt, Start);
38783876
3879- if (MADB_DynStrGetWhere (Stmt, DynamicStmt, TableName, false ))
3877+ if (MADB_DynStrGetWhere (Stmt, DynamicStmt, false ))
38803878 {
38813879 MADB_SETPOS_AGG_RESULT (result, Stmt->Error .ReturnValue );
38823880 /* Continuing to next row. If there is no key - we will get it for all rows and as aggregated result.
0 commit comments