| 520 | */ |
| 521 | |
| 522 | int mysql_create_function(THD *thd,udf_func *udf) |
| 523 | { |
| 524 | int error; |
| 525 | void *dl=0; |
| 526 | bool new_dl=0; |
| 527 | TABLE *table; |
| 528 | TABLE_LIST tables; |
| 529 | udf_func *u_d; |
| 530 | DBUG_ENTER("mysql_create_function"); |
| 531 | |
| 532 | if (!initialized) |
| 533 | { |
| 534 | if (opt_noacl) |
| 535 | my_error(ER_CANT_INITIALIZE_UDF, MYF(0), |
| 536 | udf->name.str, |
| 537 | "UDFs are unavailable with the --skip-grant-tables option"); |
| 538 | else |
| 539 | my_message(ER_OUT_OF_RESOURCES, ER_THD(thd, ER_OUT_OF_RESOURCES), |
| 540 | MYF(0)); |
| 541 | DBUG_RETURN(1); |
| 542 | } |
| 543 | |
| 544 | /* |
| 545 | Ensure that the .dll doesn't have a path |
| 546 | This is done to ensure that only approved dll from the system |
| 547 | directories are used (to make this even remotely secure). |
| 548 | */ |
| 549 | if (check_valid_path(udf->dl, strlen(udf->dl))) |
| 550 | { |
| 551 | my_message(ER_UDF_NO_PATHS, ER_THD(thd, ER_UDF_NO_PATHS), MYF(0)); |
| 552 | DBUG_RETURN(1); |
| 553 | } |
| 554 | if (check_ident_length(&udf->name)) |
| 555 | DBUG_RETURN(1); |
| 556 | |
| 557 | table= open_udf_func_table(thd); |
| 558 | |
| 559 | mysql_rwlock_wrlock(&THR_LOCK_udf); |
| 560 | DEBUG_SYNC(current_thd, "mysql_create_function_after_lock"); |
| 561 | if ((u_d= (udf_func*) my_hash_search(&udf_hash, (uchar*) udf->name.str, |
| 562 | udf->name.length))) |
| 563 | { |
| 564 | if (thd->lex->create_info.or_replace()) |
| 565 | { |
| 566 | if (unlikely((error= mysql_drop_function_internal(thd, u_d, table)))) |
| 567 | goto err; |
| 568 | } |
| 569 | else if (thd->lex->create_info.if_not_exists()) |
| 570 | { |
| 571 | push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_UDF_EXISTS, |
| 572 | ER_THD(thd, ER_UDF_EXISTS), udf->name.str); |
| 573 | |
| 574 | goto done; |
| 575 | } |
| 576 | else |
| 577 | { |
| 578 | my_error(ER_UDF_EXISTS, MYF(0), udf->name.str); |
| 579 | goto err; |
no test coverage detected