mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
SET sql_mode=ORACLE;
DELIMITER $$
CREATE OR REPLACE PACKAGE pkg AS
-- Declare a package public data type
TYPE varchar_array IS TABLE OF VARCHAR(2000) INDEX BY INTEGER;
END;
$$
DELIMITER ;
DELIMITER $$
CREATE OR REPLACE PROCEDURE p1 AS
v pkg.varchar_array; -- Use the package public data type
BEGIN
v(0):='test';
SELECT v(0);
END;
$$
DELIMITER ;
Note, the change is done only for sql_mode=ORACLE, because the TYPE
declaration is not available for the default mode.
Where package-wide types are available
--------------------------------------
- Variabe list type:
DECLARE var pkg1.type1;
- RETURN type for a package routine:
CREATE FUNCTION .. RETURN pkg1.type1 ...
- Parameter type for a package routine:
PROCEDURE p1(param1 pkg1.type1);
- Assoc array element type:
TYPE assoc1_t IS TABLE OF pkg1.type1 ...
- REF CURSOR RETURN type:
TYPE cur1_t IS REF CURSOR RETURN pkg1.type1;
Change details
--------------
- Adding a member Lex_length_and_dec_st::m_foreign_module_type
It's set to true when the data type was initialized from a TYPE
in foreign routine (e.g. in PACKAGE spec).
It's needed to prevent use of qualified identifiers in public contexts,
i.e. in schema public routine parameter types and schema publuc function
RETURN types.
Adding a helper method sp_head::check_applicability() which prevents
use of qualified types in public context.
- Adding a helper method sp_head::raise_unknown_data_type().
- Adding methods LEX::set_field_type_typedef_package_spec() for
2-step and 3-step qualified indentifiers.
It's used in field_type_all_with_typedefs which covers cases:
- Variabe list type : DECLARE var pkg1.type1;
- RETURN type : CREATE FUNCTION .. RETURN pkg1.type1 ...
- Parameter type : PROCEDURE p1(param1 pkg1.type1);
- Assoc array element type : TYPE assoc1_t IS TABLE OF pkg1.type1 ...
- Adding a method LEX::declare_type_ref_cursor_return_typedef().
It handles cases when a new TYPE REF CURSOR RETURN is declared,
for both for qualified RETURN types and non-qualified RETURN types:
- TYPE cur0_t IS REF CURSOR RETURN rec1_t;
- TYPE cur0_t IS REF CURSOR RETURN pkg1.rec1_t;
- TYPE cur0_t IS REF CURSOR RETURN db1.pkg1.rec1_t;
The code was moved from LEX::declare_type_ref_cursor() into
LEX::declare_type_ref_cursor_return_typedef() and extended
to cover qualified RETURN types.
- Adding a method Sql_path::find_package_spec_type().
It iterates through all schemas specified in @@path and searches
for the given type in the given package.
- Adding a helper method sp_pcontext::type_defs_add_ref_cursor()
to reuse the code.
- Adding a new method sp_package::get_typedef() to search
for TYPE definitions in PACKAGE specifications.
- Adding a new method sp_head::get_typedef_package_spec()
to search for TYPE definitions used by a PROCEDURE or FUNCTION.
- Adding a helper method
Sp_handler::sp_cache_routine_reentrant_suppress_errors
Adding a method Sp_handler::find_package_spec().
109 lines
3.4 KiB
C++
109 lines
3.4 KiB
C++
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
|
|
Copyright (c) 2010, 2024, MariaDB Corporation.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
|
|
|
|
|
|
#ifndef LEX_IDENT_SYS
|
|
#define LEX_IDENT_SYS
|
|
|
|
#include "lex_ident_cli.h"
|
|
#include "sql_alloc.h"
|
|
#include "char_buffer.h"
|
|
|
|
extern "C" MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info;
|
|
|
|
struct Lex_ident_sys_st: public LEX_CSTRING, Sql_alloc
|
|
{
|
|
public:
|
|
bool copy_ident_cli(const THD *thd, const Lex_ident_cli_st *str);
|
|
bool copy_keyword(const THD *thd, const Lex_ident_cli_st *str);
|
|
bool copy_sys(const THD *thd, const LEX_CSTRING *str);
|
|
bool convert(const THD *thd, const LEX_CSTRING *str, CHARSET_INFO *cs);
|
|
bool copy_or_convert(const THD *thd, const Lex_ident_cli_st *str,
|
|
CHARSET_INFO *cs);
|
|
bool is_null() const { return str == NULL; }
|
|
bool to_size_number(ulonglong *to) const;
|
|
void set_valid_utf8(const LEX_CSTRING *name)
|
|
{
|
|
DBUG_ASSERT(Well_formed_prefix(system_charset_info, name->str,
|
|
name->length).length() == name->length);
|
|
str= name->str ; length= name->length;
|
|
}
|
|
};
|
|
|
|
|
|
class Lex_ident_sys: public Lex_ident_sys_st
|
|
{
|
|
public:
|
|
Lex_ident_sys(const THD *thd, const Lex_ident_cli_st *str)
|
|
{
|
|
if (copy_ident_cli(thd, str))
|
|
*this= Lex_ident_sys();
|
|
}
|
|
Lex_ident_sys()
|
|
{
|
|
((LEX_CSTRING &) *this)= {nullptr, 0};
|
|
}
|
|
Lex_ident_sys(const char *name, size_t length)
|
|
{
|
|
LEX_CSTRING tmp= {name, length};
|
|
set_valid_utf8(&tmp);
|
|
}
|
|
explicit Lex_ident_sys(const LEX_CSTRING &str)
|
|
{
|
|
set_valid_utf8(&str);
|
|
}
|
|
Lex_ident_sys & operator=(const Lex_ident_sys_st &name)
|
|
{
|
|
Lex_ident_sys_st::operator=(name);
|
|
return *this;
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
A buffer to print a qualified data type.
|
|
It does not derive from ErrConv because it does not need lazy calculation yet.
|
|
Also it's size is defined according to the error message in errmsg-utf8.txt:
|
|
"Unknown data type: '%-.384s'" in errmsg-utf8.txt
|
|
*/
|
|
#define DATA_TYPE_FORMAT_LENGTH 384
|
|
class QTypeErrBuffer: public CharBuffer<DATA_TYPE_FORMAT_LENGTH>
|
|
{
|
|
public:
|
|
QTypeErrBuffer(const Lex_ident_sys_st &db, const Lex_ident_sys_st &package,
|
|
const Lex_ident_sys_st &type)
|
|
{
|
|
DBUG_ASSERT(db.str);
|
|
DBUG_ASSERT(package.str);
|
|
DBUG_ASSERT(type.str);
|
|
my_snprintf(m_buff, sizeof(m_buff), "%.*sQ.%.*sQ.%.*sQ",
|
|
(int) db.length, db.str,
|
|
(int) package.length, package.str,
|
|
(int) type.length, type.str);
|
|
}
|
|
QTypeErrBuffer(const Lex_ident_sys_st &package, const Lex_ident_sys_st &type)
|
|
{
|
|
DBUG_ASSERT(package.str);
|
|
DBUG_ASSERT(type.str);
|
|
my_snprintf(m_buff, sizeof(m_buff), "%.*sQ.%.*sQ",
|
|
(int) package.length, package.str,
|
|
(int) type.length, type.str);
|
|
}
|
|
};
|
|
|
|
|
|
#endif // LEX_IDENT_SYS
|