Пример #1
0
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;
}
Пример #2
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;
}