unsigned int GetMultiStatements(MADB_Stmt *Stmt, BOOL ExecDirect) { int i= 0; unsigned int MaxParams= 0; char *p= Stmt->Query.RefinedText; Stmt->MultiStmtNr= 0; Stmt->MultiStmts= (MYSQL_STMT **)MADB_CALLOC(sizeof(MYSQL_STMT) * STMT_COUNT(Stmt->Query)); while (p < Stmt->Query.RefinedText + Stmt->Query.RefinedLength) { Stmt->MultiStmts[i]= i == 0 ? Stmt->stmt : MADB_NewStmtHandle(Stmt); MDBUG_C_PRINT(Stmt->Connection, "-->inited&preparing %0x(%d,%s)", Stmt->MultiStmts[i], i, p); if (mysql_stmt_prepare(Stmt->MultiStmts[i], p, (unsigned long)strlen(p))) { MADB_SetNativeError(&Stmt->Error, SQL_HANDLE_STMT, Stmt->MultiStmts[i]); CloseMultiStatements(Stmt); /* Last paranoid attempt make sure that we did not have a parsing error. More to preserve "backward-compatimility" - we did this before, but before trying to prepare "multi-statement". */ if (i == 0 && Stmt->Error.NativeError !=1295 /*ER_UNSUPPORTED_PS*/) { Stmt->stmt= MADB_NewStmtHandle(Stmt); if (mysql_stmt_prepare(Stmt->stmt, STMT_STRING(Stmt), (unsigned long)strlen(STMT_STRING(Stmt)))) { mysql_stmt_close(Stmt->stmt); Stmt->stmt= NULL; } else { MADB_DeleteSubqueries(&Stmt->Query); return 0; } } return 1; } if (mysql_stmt_param_count(Stmt->MultiStmts[i]) > MaxParams) { MaxParams= mysql_stmt_param_count(Stmt->MultiStmts[i]); } p+= strlen(p) + 1; ++i; } if (MaxParams) { Stmt->params= (MYSQL_BIND *)MADB_CALLOC(sizeof(MYSQL_BIND) * MaxParams); } return 0; }
unsigned int GetMultiStatements(MADB_Stmt *Stmt, char *StmtStr, size_t Length) { char *p, *last, *prev= NULL; unsigned int statements= 1; int quote[2]= {0,0}, comment= 0; char *end; MYSQL_STMT *stmt; p= last= StmtStr; stmt= mysql_stmt_init(Stmt->Connection->mariadb); /* if the entire stmt string passes, we don't have multistatement */ if (stmt && !mysql_stmt_prepare(stmt, StmtStr, Length)) { mysql_stmt_close(stmt); return 1; } mysql_stmt_close(stmt); /* make sure we don't have trailing whitespace or semicolon */ if (Length) { end= StmtStr + Length - 1; while (end > StmtStr && (isspace(*end) || *end == ';')) end--; Length= end - StmtStr; } while (p < StmtStr + Length) { switch (*p) { case ';': if (!quote[0] && !quote[1] && !comment) { statements++; last= p + 1; *p= 0; } break; case '/': if (!comment && (p < StmtStr + Length + 1) && (char)*(p+1) == '*') comment= 1; else if (comment && (p > StmtStr) && (char)*(p-1) == '*') comment= 0; break; case '\"': if (prev && *prev != '\\') quote[0] = !quote[0]; break; case 39: if (prev && *prev != '\\') quote[1] = !quote[1]; break; default: break; } prev= p; p++; } if (statements > 1) { int i=0; unsigned int MaxParams= 0; p= StmtStr; Stmt->MultiStmtCount= 0; Stmt->MultiStmtNr= 0; Stmt->MultiStmts= (MYSQL_STMT **)MADB_CALLOC(sizeof(MYSQL_STMT) * statements); while (p < StmtStr + Length) { Stmt->MultiStmts[i]= mysql_stmt_init(Stmt->Connection->mariadb); if (mysql_stmt_prepare(Stmt->MultiStmts[i], p, strlen(p))) { MADB_SetNativeError(&Stmt->Error, SQL_HANDLE_STMT, Stmt->MultiStmts[i]); CloseMultiStatements(Stmt); return 0; } if (mysql_stmt_param_count(Stmt->MultiStmts[i]) > MaxParams) MaxParams= mysql_stmt_param_count(Stmt->MultiStmts[i]); p+= strlen(p) + 1; ++i; ++Stmt->MultiStmtCount; } if (MaxParams) Stmt->params= (MYSQL_BIND *)MADB_CALLOC(sizeof(MYSQL_BIND) * MaxParams); } return statements; }