8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 16:43:03 +01:00

Add procedure RDB$SQL.PARSE_UNQUALIFIED_NAMES.

This commit is contained in:
Adriano dos Santos Fernandes 2025-01-12 15:10:41 -03:00
parent 73478271df
commit 589917f45e
3 changed files with 113 additions and 7 deletions

View File

@ -25,12 +25,12 @@ Output parameters:
- `KEY_LENGTH` type `INTEGER` - key length for the record source
- `ACCESS_PATH` type `RDB$DESCRIPTION NOT NULL` - friendly plan description
```
```sql
select *
from rdb$sql.explain('select * from employee where emp_no = ?');
```
```
```sql
select *
from rdb$sql.explain(q'{
select *
@ -43,5 +43,21 @@ select *
}');
```
## Procedure `PARSE_UNQUALIFIED_NAMES`
`RDB$SQL.PARSE_UNQUALIFIED_NAMES` is a selectable procedure that parses a list of unqualified SQL names and returns
one row for each name. The input must follow parse rules for names and the output of unquoted names are uppercased.
```sql
select *
from rdb$sql.parse_unqualified_names('schema1, schema2, "schema3", "schema 4", "schema ""5"""');
-- SCHEMA1
-- SCHEMA2
-- schema3
-- "schema 4"
-- "schema "5"
```
# Authors
- Adriano dos Santos Fernandes

View File

@ -42,9 +42,6 @@ IExternalResultSet* SqlPackage::explainProcedure(ThrowStatusExceptionWrapper* st
}
//--------------------------------------
SqlPackage::ExplainResultSet::ExplainResultSet(ThrowStatusExceptionWrapper* status,
IExternalContext* context, const ExplainInput::Type* in, ExplainOutput::Type* aOut)
: out(aOut)
@ -171,6 +168,42 @@ FB_BOOLEAN SqlPackage::ExplainResultSet::fetch(ThrowStatusExceptionWrapper* stat
//--------------------------------------
IExternalResultSet* SqlPackage::parseUnqualifiedNamesProcedure(ThrowStatusExceptionWrapper* status,
IExternalContext* context, const ParseUnqualifiedNamesInput::Type* in, ParseUnqualifiedNamesOutput::Type* out)
{
return FB_NEW ParseUnqualifiedNamesResultSet(status, context, in, out);
}
SqlPackage::ParseUnqualifiedNamesResultSet::ParseUnqualifiedNamesResultSet(ThrowStatusExceptionWrapper* status,
IExternalContext* context, const ParseUnqualifiedNamesInput::Type* in, ParseUnqualifiedNamesOutput::Type* aOut)
: out(aOut)
{
if (!in->namesNull)
{
const string namesStr(in->names.str, in->names.length);
MetaString::parseList(namesStr, resultEntries);
}
resultIterator = resultEntries.begin();
}
FB_BOOLEAN SqlPackage::ParseUnqualifiedNamesResultSet::fetch(ThrowStatusExceptionWrapper* status)
{
if (resultIterator == resultEntries.end())
return false;
out->name.set(resultIterator->c_str(), resultIterator->length());
out->nameNull = FB_FALSE;
++resultIterator;
return true;
}
//--------------------------------------
SqlPackage::SqlPackage(MemoryPool& pool)
: SystemPackage(
pool,
@ -204,6 +237,21 @@ SqlPackage::SqlPackage(MemoryPool& pool)
{"ACCESS_PATH", fld_description, false}
}
),
SystemProcedure(
pool,
"PARSE_UNQUALIFIED_NAMES",
SystemProcedureFactory<
ParseUnqualifiedNamesInput, ParseUnqualifiedNamesOutput, parseUnqualifiedNamesProcedure>(),
prc_selectable,
// input parameters
{
{"NAMES", fld_text_max, true}
},
// output parameters
{
{"NAME", fld_r_name, false}
}
),
},
// functions
{

View File

@ -26,6 +26,8 @@
#include "firebird.h"
#include "firebird/Message.h"
#include "../common/classes/array.h"
#include "../common/classes/MetaString.h"
#include "../common/classes/objects_array.h"
#include "../jrd/SystemPackages.h"
namespace Jrd {
@ -88,10 +90,50 @@ private:
Firebird::Array<ExplainOutput::Type>::const_iterator resultIterator = nullptr;
};
//----------
static Firebird::IExternalResultSet* explainProcedure(Firebird::ThrowStatusExceptionWrapper* status,
Firebird::IExternalContext* context, const ExplainInput::Type* in, ExplainOutput::Type* out);
//----------
FB_MESSAGE(ParseUnqualifiedNamesInput, Firebird::ThrowStatusExceptionWrapper,
(FB_INTL_VARCHAR(MAX_VARY_COLUMN_SIZE / METADATA_BYTES_PER_CHAR * METADATA_BYTES_PER_CHAR, CS_METADATA), names)
);
FB_MESSAGE(ParseUnqualifiedNamesOutput, Firebird::ThrowStatusExceptionWrapper,
(FB_INTL_VARCHAR(METADATA_IDENTIFIER_CHAR_LEN * METADATA_BYTES_PER_CHAR, CS_METADATA), name)
);
class ParseUnqualifiedNamesResultSet :
public
Firebird::DisposeIface<
Firebird::IExternalResultSetImpl<
ParseUnqualifiedNamesResultSet,
Firebird::ThrowStatusExceptionWrapper
>
>
{
public:
ParseUnqualifiedNamesResultSet(Firebird::ThrowStatusExceptionWrapper* status, Firebird::IExternalContext* context,
const ParseUnqualifiedNamesInput::Type* in, ParseUnqualifiedNamesOutput::Type* out);
public:
void dispose() override
{
delete this;
}
public:
FB_BOOLEAN fetch(Firebird::ThrowStatusExceptionWrapper* status) override;
private:
ParseUnqualifiedNamesOutput::Type* out;
Firebird::ObjectsArray<Firebird::MetaString> resultEntries{*getDefaultMemoryPool()};
Firebird::ObjectsArray<Firebird::MetaString>::const_iterator resultIterator;
};
static Firebird::IExternalResultSet* parseUnqualifiedNamesProcedure(Firebird::ThrowStatusExceptionWrapper* status,
Firebird::IExternalContext* context,
const ParseUnqualifiedNamesInput::Type* in, ParseUnqualifiedNamesOutput::Type* out);
};