mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 22:03:03 +01:00
Misc
This commit is contained in:
parent
b96703e879
commit
7f4f7b06d6
@ -70,13 +70,15 @@ template <typename T, typename Storage = EmptyStorage<T> >
|
||||
class Array : protected Storage
|
||||
{
|
||||
public:
|
||||
explicit Array(MemoryPool& p) :
|
||||
Storage(p), count(0), capacity(this->getStorageSize()), data(this->getStorage()) { }
|
||||
Array(MemoryPool& p, const size_t InitialCapacity) :
|
||||
Storage(p), count(0), capacity(this->getStorageSize()), data(this->getStorage())
|
||||
explicit Array(MemoryPool& p)
|
||||
: Storage(p), count(0), capacity(this->getStorageSize()), data(this->getStorage()) { }
|
||||
|
||||
Array(MemoryPool& p, const size_t InitialCapacity)
|
||||
: Storage(p), count(0), capacity(this->getStorageSize()), data(this->getStorage())
|
||||
{
|
||||
ensureCapacity(InitialCapacity);
|
||||
}
|
||||
|
||||
Array() : count(0),
|
||||
capacity(this->getStorageSize()), data(this->getStorage()) { }
|
||||
explicit Array(const size_t InitialCapacity)
|
||||
@ -84,15 +86,18 @@ public:
|
||||
{
|
||||
ensureCapacity(InitialCapacity);
|
||||
}
|
||||
Array(const Array<T, Storage>& L)
|
||||
|
||||
Array(const Array<T, Storage>& source)
|
||||
: count(0), capacity(this->getStorageSize()), data(this->getStorage())
|
||||
{
|
||||
copyFrom(L);
|
||||
copyFrom(source);
|
||||
}
|
||||
|
||||
~Array()
|
||||
{
|
||||
freeData();
|
||||
}
|
||||
|
||||
void clear() { count = 0; }
|
||||
|
||||
protected:
|
||||
@ -101,63 +106,78 @@ protected:
|
||||
fb_assert(index < count);
|
||||
return data[index];
|
||||
}
|
||||
|
||||
T& getElement(size_t index)
|
||||
{
|
||||
fb_assert(index < count);
|
||||
return data[index];
|
||||
}
|
||||
|
||||
void freeData()
|
||||
{
|
||||
if (data != this->getStorage())
|
||||
this->getPool().deallocate(data);
|
||||
}
|
||||
void copyFrom(const Array<T, Storage>& L)
|
||||
|
||||
void copyFrom(const Array<T, Storage>& source)
|
||||
{
|
||||
ensureCapacity(L.count, false);
|
||||
memcpy(data, L.data, sizeof(T) * L.count);
|
||||
count = L.count;
|
||||
ensureCapacity(source.count, false);
|
||||
memcpy(data, source.data, sizeof(T) * source.count);
|
||||
count = source.count;
|
||||
}
|
||||
|
||||
public:
|
||||
typedef T* iterator;
|
||||
typedef const T* const_iterator;
|
||||
Array<T, Storage>& operator =(const Array<T, Storage>& L)
|
||||
|
||||
Array<T, Storage>& operator =(const Array<T, Storage>& source)
|
||||
{
|
||||
copyFrom(L);
|
||||
copyFrom(source);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const T& operator[](size_t index) const
|
||||
{
|
||||
return getElement(index);
|
||||
}
|
||||
|
||||
T& operator[](size_t index)
|
||||
{
|
||||
return getElement(index);
|
||||
}
|
||||
|
||||
const T& front() const
|
||||
{
|
||||
fb_assert(count > 0);
|
||||
return *data;
|
||||
}
|
||||
|
||||
const T& back() const
|
||||
{
|
||||
fb_assert(count > 0);
|
||||
return *(data + count - 1);
|
||||
}
|
||||
|
||||
const T* begin() const { return data; }
|
||||
|
||||
const T* end() const { return data + count; }
|
||||
|
||||
T& front()
|
||||
{
|
||||
fb_assert(count > 0);
|
||||
return *data;
|
||||
}
|
||||
|
||||
T& back()
|
||||
{
|
||||
fb_assert(count > 0);
|
||||
return *(data + count - 1);
|
||||
}
|
||||
|
||||
T* begin() { return data; }
|
||||
|
||||
T* end() { return data + count; }
|
||||
|
||||
void insert(const size_t index, const T& item)
|
||||
{
|
||||
fb_assert(index <= count);
|
||||
@ -165,14 +185,16 @@ public:
|
||||
memmove(data + index + 1, data + index, sizeof(T) * (count++ - index));
|
||||
data[index] = item;
|
||||
}
|
||||
void insert(const size_t index, const Array<T, Storage>& L)
|
||||
|
||||
void insert(const size_t index, const Array<T, Storage>& items)
|
||||
{
|
||||
fb_assert(index <= count);
|
||||
ensureCapacity(count + L.count);
|
||||
memmove(data + index + L.count, data + index, sizeof(T) * (count - index));
|
||||
memcpy(data + index, L.data, L.count);
|
||||
count += L.count;
|
||||
ensureCapacity(count + items.count);
|
||||
memmove(data + index + items.count, data + index, sizeof(T) * (count - index));
|
||||
memcpy(data + index, items.data, items.count);
|
||||
count += items.count;
|
||||
}
|
||||
|
||||
void insert(const size_t index, const T* items, const size_t itemsSize)
|
||||
{
|
||||
fb_assert(index <= count);
|
||||
@ -181,18 +203,21 @@ public:
|
||||
memcpy(data + index, items, sizeof(T) * itemsSize);
|
||||
count += itemsSize;
|
||||
}
|
||||
|
||||
size_t add(const T& item)
|
||||
{
|
||||
ensureCapacity(count + 1);
|
||||
data[count] = item;
|
||||
return ++count;
|
||||
}
|
||||
|
||||
void add(const T* items, const size_t itemsSize)
|
||||
{
|
||||
ensureCapacity(count + itemsSize);
|
||||
memcpy(data + count, items, sizeof(T) * itemsSize);
|
||||
count += itemsSize;
|
||||
}
|
||||
|
||||
// NOTE: remove method must be signal safe
|
||||
// This function may be called in AST. The function doesn't wait.
|
||||
T* remove(const size_t index)
|
||||
@ -201,6 +226,7 @@ public:
|
||||
memmove(data + index, data + index + 1, sizeof(T) * (--count - index));
|
||||
return &data[index];
|
||||
}
|
||||
|
||||
T* removeRange(const size_t from, const size_t to)
|
||||
{
|
||||
fb_assert(from <= to);
|
||||
@ -209,6 +235,7 @@ public:
|
||||
count -= (to - from);
|
||||
return &data[from];
|
||||
}
|
||||
|
||||
T* removeCount(const size_t index, const size_t n)
|
||||
{
|
||||
fb_assert(index + n <= count);
|
||||
@ -216,6 +243,7 @@ public:
|
||||
count -= n;
|
||||
return &data[index];
|
||||
}
|
||||
|
||||
T* remove(T* itr)
|
||||
{
|
||||
const size_t index = itr - begin();
|
||||
@ -223,15 +251,18 @@ public:
|
||||
memmove(data + index, data + index + 1, sizeof(T) * (--count - index));
|
||||
return &data[index];
|
||||
}
|
||||
|
||||
T* remove(T* itrFrom, T* itrTo)
|
||||
{
|
||||
return removeRange(itrFrom - begin(), itrTo - begin());
|
||||
}
|
||||
|
||||
void shrink(size_t newCount)
|
||||
{
|
||||
fb_assert(newCount <= count);
|
||||
count = newCount;
|
||||
}
|
||||
|
||||
// Grow size of our array and zero-initialize new items
|
||||
void grow(const size_t newCount)
|
||||
{
|
||||
@ -240,6 +271,7 @@ public:
|
||||
memset(data + count, 0, sizeof(T) * (newCount - count));
|
||||
count = newCount;
|
||||
}
|
||||
|
||||
// Resize array according to STL's vector::resize() rules
|
||||
void resize(const size_t newCount, const T& val)
|
||||
{
|
||||
@ -253,6 +285,7 @@ public:
|
||||
count = newCount;
|
||||
}
|
||||
}
|
||||
|
||||
// Resize array according to STL's vector::resize() rules
|
||||
void resize(const size_t newCount)
|
||||
{
|
||||
@ -263,24 +296,30 @@ public:
|
||||
count = newCount;
|
||||
}
|
||||
}
|
||||
|
||||
void join(const Array<T, Storage>& L)
|
||||
{
|
||||
ensureCapacity(count + L.count);
|
||||
memcpy(data + count, L.data, sizeof(T) * L.count);
|
||||
count += L.count;
|
||||
}
|
||||
void assign(const Array<T, Storage>& L)
|
||||
|
||||
void assign(const Array<T, Storage>& source)
|
||||
{
|
||||
copyFrom(L);
|
||||
copyFrom(source);
|
||||
}
|
||||
|
||||
// NOTE: getCount method must be signal safe
|
||||
// Used as such in GlobalRWLock::blockingAstHandler
|
||||
size_t getCount() const { return count; }
|
||||
|
||||
size_t getCapacity() const { return capacity; }
|
||||
|
||||
void push(const T& item)
|
||||
{
|
||||
add(item);
|
||||
}
|
||||
|
||||
void push(const T* items, const size_t itemsSize)
|
||||
{
|
||||
ensureCapacity(count + itemsSize);
|
||||
@ -293,6 +332,7 @@ public:
|
||||
count--;
|
||||
return data[count];
|
||||
}
|
||||
|
||||
// prepare array to be used as a buffer of capacity items
|
||||
T* getBuffer(const size_t capacityL)
|
||||
{
|
||||
@ -300,6 +340,7 @@ public:
|
||||
count = capacityL;
|
||||
return data;
|
||||
}
|
||||
|
||||
// clear array and release dinamically allocated memory
|
||||
void free()
|
||||
{
|
||||
@ -343,6 +384,7 @@ public:
|
||||
protected:
|
||||
size_t count, capacity;
|
||||
T* data;
|
||||
|
||||
void ensureCapacity(size_t newcapacity, bool preserve = true)
|
||||
{
|
||||
if (newcapacity > capacity) {
|
||||
|
@ -138,7 +138,6 @@ static void integer_to_text(const dsc*, dsc*, Callbacks*);
|
||||
static void string_to_datetime(const dsc*, GDS_TIMESTAMP*, const EXPECT_DATETIME, ErrorFunction);
|
||||
static SINT64 hex_to_value(const char*& string, const char* end);
|
||||
|
||||
|
||||
static bool transliterate(const dsc* from, dsc* to, CHARSET_ID& charset2, ErrorFunction err);
|
||||
static Jrd::CharSet* getToCharset(CHARSET_ID charset2);
|
||||
static void validateData(Jrd::CharSet* toCharSet, SLONG length, const UCHAR* q, ErrorFunction err);
|
||||
|
@ -87,8 +87,7 @@ ULONG CVJIS_eucj_to_unicode(csconvert* obj,
|
||||
/* Step 2: Convert from JIS to UNICODE */
|
||||
ch = ((const USHORT*) impl->csconvert_datatable)
|
||||
[((const USHORT*) impl->csconvert_misc)
|
||||
[(USHORT)wide / 256]
|
||||
+ (wide % 256)];
|
||||
[(USHORT)wide / 256] + (wide % 256)];
|
||||
}
|
||||
|
||||
|
||||
@ -210,8 +209,7 @@ ULONG CVJIS_sjis_to_unicode(csconvert* obj,
|
||||
if (table == 1)
|
||||
ch = ((const USHORT*) impl->csconvert_datatable)
|
||||
[((const USHORT*) impl->csconvert_misc)
|
||||
[(USHORT)wide / 256]
|
||||
+ (wide % 256)];
|
||||
[(USHORT)wide / 256] + (wide % 256)];
|
||||
else {
|
||||
fb_assert(table == 2);
|
||||
fb_assert(wide <= 255);
|
||||
@ -513,8 +511,7 @@ ULONG CVJIS_unicode_to_eucj(csconvert* obj, ULONG unicode_len, const UCHAR* p_un
|
||||
else
|
||||
jis_ch = ((const USHORT*) impl->csconvert_datatable)
|
||||
[((const USHORT*) impl->csconvert_misc)
|
||||
[(USHORT)wide / 256]
|
||||
+ (wide % 256)];
|
||||
[(USHORT)wide / 256] + (wide % 256)];
|
||||
if ((jis_ch == CS_CANT_MAP) && !(wide == CS_CANT_MAP)) {
|
||||
*err_code = CS_CONVERT_ERROR;
|
||||
break;
|
||||
|
@ -92,8 +92,7 @@ ULONG CVKSC_ksc_to_unicode(csconvert* obj,
|
||||
}
|
||||
|
||||
const USHORT ch = ((const USHORT*) impl->csconvert_datatable)
|
||||
[((const USHORT*) impl->csconvert_misc)[(USHORT) wide / 256] +
|
||||
(wide % 256)];
|
||||
[((const USHORT*) impl->csconvert_misc)[(USHORT) wide / 256] + (wide % 256)];
|
||||
|
||||
if ((ch == CS_CANT_MAP) && !(wide == CS_CANT_MAP)) {
|
||||
*err_code = CS_CONVERT_ERROR;
|
||||
|
@ -143,8 +143,7 @@ USHORT LC_NARROW_key_length(texttype* obj, USHORT inLen)
|
||||
|
||||
USHORT len = impl->texttype_bytes_per_key * MAX(inLen, 2);
|
||||
|
||||
if (impl->texttype_expand_table &&
|
||||
((const ExpandChar*) impl->texttype_expand_table)[0].Ch)
|
||||
if (impl->texttype_expand_table && ((const ExpandChar*) impl->texttype_expand_table)[0].Ch)
|
||||
{
|
||||
len += (USHORT) log10(inLen + 1.0) * 4 * impl->texttype_bytes_per_key;
|
||||
}
|
||||
@ -258,9 +257,7 @@ USHORT LC_NARROW_string_to_key(texttype* obj, USHORT iInLen, const BYTE* pInChar
|
||||
fb_assert(exp->Ch == *pInChar);
|
||||
for (int j = 0; j < 2; j++) {
|
||||
if (j)
|
||||
coll =
|
||||
&((const SortOrderTblEntry*) impl->
|
||||
texttype_collation_table)[exp->ExpCh2];
|
||||
coll = &((const SortOrderTblEntry*) impl->texttype_collation_table)[exp->ExpCh2];
|
||||
if (coll->Primary != NULL_WEIGHT && lprimary < iOutLen)
|
||||
outbuff[lprimary++] = coll->Primary + impl->primary_sum;
|
||||
if (coll->Secondary != NULL_SECONDARY && lsecondary < sizeof(secondary))
|
||||
|
@ -655,17 +655,19 @@ static void unicodeDestroy(texttype* tt)
|
||||
|
||||
static USHORT unicodeKeyLength(texttype* tt, USHORT len)
|
||||
{
|
||||
return static_cast<TextTypeImpl*>(tt->texttype_impl)->collation->keyLength(
|
||||
len / static_cast<TextTypeImpl*>(tt->texttype_impl)->cs->charset_max_bytes_per_char * 4);
|
||||
TextTypeImpl* impl = static_cast<TextTypeImpl*>(tt->texttype_impl);
|
||||
return impl->collation->keyLength(len / impl->cs->charset_max_bytes_per_char * 4);
|
||||
}
|
||||
|
||||
|
||||
static USHORT unicodeStrToKey(texttype* tt, USHORT srcLen, const UCHAR* src,
|
||||
USHORT dstLen, UCHAR* dst, USHORT keyType)
|
||||
{
|
||||
TextTypeImpl* impl = static_cast<TextTypeImpl*>(tt->texttype_impl);
|
||||
|
||||
try
|
||||
{
|
||||
charset* cs = static_cast<TextTypeImpl*>(tt->texttype_impl)->cs;
|
||||
charset* cs = impl->cs;
|
||||
|
||||
HalfStaticArray<UCHAR, BUFFER_SMALL> utf16Str;
|
||||
USHORT errorCode;
|
||||
@ -690,8 +692,7 @@ static USHORT unicodeStrToKey(texttype* tt, USHORT srcLen, const UCHAR* src,
|
||||
&errorCode,
|
||||
&offendingPos);
|
||||
|
||||
return static_cast<TextTypeImpl*>(tt->texttype_impl)->collation->stringToKey(
|
||||
utf16Len, (USHORT*)utf16Str.begin(), dstLen, dst, keyType);
|
||||
return impl->collation->stringToKey(utf16Len, (USHORT*)utf16Str.begin(), dstLen, dst, keyType);
|
||||
}
|
||||
catch (BadAlloc)
|
||||
{
|
||||
@ -704,11 +705,13 @@ static USHORT unicodeStrToKey(texttype* tt, USHORT srcLen, const UCHAR* src,
|
||||
static SSHORT unicodeCompare(texttype* tt, ULONG len1, const UCHAR* str1,
|
||||
ULONG len2, const UCHAR* str2, INTL_BOOL* errorFlag)
|
||||
{
|
||||
TextTypeImpl* impl = static_cast<TextTypeImpl*>(tt->texttype_impl);
|
||||
|
||||
try
|
||||
{
|
||||
*errorFlag = false;
|
||||
|
||||
charset* cs = static_cast<TextTypeImpl*>(tt->texttype_impl)->cs;
|
||||
charset* cs = impl->cs;
|
||||
|
||||
HalfStaticArray<UCHAR, BUFFER_SMALL> utf16Str1;
|
||||
HalfStaticArray<UCHAR, BUFFER_SMALL> utf16Str2;
|
||||
@ -753,8 +756,7 @@ static SSHORT unicodeCompare(texttype* tt, ULONG len1, const UCHAR* str1,
|
||||
&errorCode,
|
||||
&offendingPos);
|
||||
|
||||
return static_cast<TextTypeImpl*>(tt->texttype_impl)->collation->compare(
|
||||
utf16Len1, (USHORT*)utf16Str1.begin(),
|
||||
return impl->collation->compare(utf16Len1, (USHORT*)utf16Str1.begin(),
|
||||
utf16Len2, (USHORT*)utf16Str2.begin(), errorFlag);
|
||||
}
|
||||
catch (BadAlloc)
|
||||
@ -767,9 +769,11 @@ static SSHORT unicodeCompare(texttype* tt, ULONG len1, const UCHAR* str1,
|
||||
|
||||
static ULONG unicodeCanonical(texttype* tt, ULONG srcLen, const UCHAR* src, ULONG dstLen, UCHAR* dst)
|
||||
{
|
||||
TextTypeImpl* impl = static_cast<TextTypeImpl*>(tt->texttype_impl);
|
||||
|
||||
try
|
||||
{
|
||||
charset* cs = static_cast<TextTypeImpl*>(tt->texttype_impl)->cs;
|
||||
charset* cs = impl->cs;
|
||||
|
||||
HalfStaticArray<UCHAR, BUFFER_SMALL> utf16Str;
|
||||
USHORT errorCode;
|
||||
@ -794,7 +798,7 @@ static ULONG unicodeCanonical(texttype* tt, ULONG srcLen, const UCHAR* src, ULON
|
||||
&errorCode,
|
||||
&offendingPos);
|
||||
|
||||
return static_cast<TextTypeImpl*>(tt->texttype_impl)->collation->canonical(
|
||||
return impl->collation->canonical(
|
||||
utf16Len, Firebird::Aligner<USHORT>(utf16Str.begin(), utf16Len),
|
||||
dstLen, Firebird::OutAligner<ULONG>(dst, dstLen), NULL);
|
||||
}
|
||||
|
@ -118,9 +118,9 @@ void IbUtil::initialize()
|
||||
{
|
||||
#ifndef BOOT_BUILD
|
||||
#ifdef WIN_NT
|
||||
Firebird::PathName path = "ib_util";
|
||||
PathName path = "ib_util";
|
||||
#else
|
||||
Firebird::PathName path = "libib_util";
|
||||
PathName path = "libib_util";
|
||||
#endif
|
||||
|
||||
ModuleLoader::Module* module = ModuleLoader::loadModule(libUtilPath);
|
||||
|
@ -95,7 +95,7 @@ static SecurityClass::flags_t squeeze_acl(Acl&, const Firebird::MetaName&, SSHOR
|
||||
static bool check_string(const UCHAR*, const Firebird::MetaName&);
|
||||
|
||||
|
||||
bool GRANT_privileges( thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
||||
bool GRANT_privileges(thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
||||
jrd_tra*) // unused param, makes dfw.epp happy
|
||||
{
|
||||
/**************************************
|
||||
@ -201,8 +201,7 @@ bool GRANT_privileges( thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
||||
}
|
||||
|
||||
|
||||
static void define_default_class(
|
||||
thread_db* tdbb,
|
||||
static void define_default_class(thread_db* tdbb,
|
||||
const TEXT* relation_name,
|
||||
Firebird::MetaName& default_class,
|
||||
const Acl& acl)
|
||||
@ -547,8 +546,7 @@ static void grant_user(Acl& acl,
|
||||
}
|
||||
|
||||
#ifdef NOT_USED_OR_REPLACED
|
||||
static void grant_views(
|
||||
Acl& acl,
|
||||
static void grant_views(Acl& acl,
|
||||
SecurityClass::flags_t privs)
|
||||
{
|
||||
/**************************************
|
||||
@ -681,6 +679,7 @@ static SecurityClass::flags_t save_field_privileges(thread_db* tdbb,
|
||||
const SecurityClass::flags_t field_priv =
|
||||
public_priv | priv | squeeze_acl(field_acl, user, user_type);
|
||||
grant_user(field_acl, user, user_type, field_priv);
|
||||
|
||||
const SecurityClass::flags_t relation_priv =
|
||||
public_priv | priv | squeeze_acl(relation_acl, user, user_type);
|
||||
grant_user(relation_acl, user, user_type, relation_priv);
|
||||
@ -771,6 +770,7 @@ static SecurityClass::flags_t save_field_privileges(thread_db* tdbb,
|
||||
const SecurityClass::flags_t field_priv =
|
||||
public_priv | priv | squeeze_acl(field_acl, user, user_type);
|
||||
grant_user(field_acl, user, user_type, field_priv);
|
||||
|
||||
const SecurityClass::flags_t relation_priv =
|
||||
public_priv | priv | squeeze_acl(relation_acl, user, user_type);
|
||||
grant_user(relation_acl, user, user_type, relation_priv);
|
||||
|
@ -49,8 +49,8 @@ struct texttype; /* forward decl for the fc signatures before the struct itself.
|
||||
struct csconvert;
|
||||
struct charset;
|
||||
|
||||
#define INTL_BAD_KEY_LENGTH ((USHORT)(-1))
|
||||
#define INTL_BAD_STR_LENGTH ((ULONG)(-1))
|
||||
#define INTL_BAD_KEY_LENGTH ((USHORT) -1)
|
||||
#define INTL_BAD_STR_LENGTH ((ULONG) -1)
|
||||
|
||||
/* Returned value of INTL_BAD_KEY_LENGTH means that proposed key is too long */
|
||||
typedef USHORT (*pfn_INTL_keylength) (
|
||||
|
@ -1055,13 +1055,10 @@ static SecurityClass::flags_t compute_access(thread_db* tdbb,
|
||||
BLB_close(tdbb, blob);
|
||||
blob = NULL;
|
||||
acl.shrink(end - buffer);
|
||||
|
||||
if (acl.getCount() > 0)
|
||||
{
|
||||
privileges |= walk_acl( tdbb,
|
||||
acl,
|
||||
view,
|
||||
trg_name,
|
||||
prc_name);
|
||||
privileges |= walk_acl(tdbb, acl, view, trg_name, prc_name);
|
||||
}
|
||||
END_FOR;
|
||||
|
||||
@ -1242,9 +1239,12 @@ static SecurityClass::flags_t walk_acl(thread_db* tdbb,
|
||||
break;
|
||||
|
||||
case ACL_priv_list:
|
||||
if (hit) {
|
||||
if (hit)
|
||||
{
|
||||
while ( (c = *a++) )
|
||||
switch (c) {
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case priv_control:
|
||||
privilege |= SCL_control;
|
||||
break;
|
||||
@ -1253,7 +1253,6 @@ static SecurityClass::flags_t walk_acl(thread_db* tdbb,
|
||||
// Note that READ access must imply REFERENCES
|
||||
// access for upward compatibility of existing
|
||||
// security classes
|
||||
|
||||
privilege |= SCL_read | SCL_sql_references;
|
||||
break;
|
||||
|
||||
@ -1298,6 +1297,8 @@ static SecurityClass::flags_t walk_acl(thread_db* tdbb,
|
||||
default:
|
||||
return SCL_corrupt;
|
||||
}
|
||||
}
|
||||
|
||||
// For a relation the first hit does not give the privilege.
|
||||
// Because, there could be some permissions for the table
|
||||
// (for user1) and some permissions for a column on that
|
||||
|
Loading…
Reference in New Issue
Block a user