mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 22:43:03 +01:00
Get rid of dsql_str and fix metadata strings.
This commit is contained in:
parent
e31b0e38f3
commit
970677e8de
@ -1019,7 +1019,7 @@ void CommentOnNode::print(string& text) const
|
||||
" objType: %s\n"
|
||||
" objName: %s\n"
|
||||
" text: %s\n",
|
||||
objType, objName.c_str(), this->text->getString().c_str());
|
||||
objType, objName.c_str(), this->text.c_str());
|
||||
}
|
||||
|
||||
// select rdb$relation_name from rdb$relation_fields where rdb$field_name = 'RDB$DESCRIPTION';
|
||||
@ -1225,8 +1225,8 @@ void CommentOnNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScratch,
|
||||
}
|
||||
|
||||
Nullable<string> description;
|
||||
if (!text->isEmpty())
|
||||
description = text->toUtf8(dsqlScratch);
|
||||
if (text.hasData())
|
||||
description = text;
|
||||
|
||||
PreparedStatement::Builder sql;
|
||||
sql << "update" << tableClause << "set rdb$description =" << description;
|
||||
@ -6397,7 +6397,7 @@ void CreateRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScrat
|
||||
REL.RDB$EXTERNAL_FILE.NULL = FALSE;
|
||||
strcpy(REL.RDB$EXTERNAL_FILE, externalFile->c_str());
|
||||
|
||||
if (ISC_check_if_remote(*externalFile, false))
|
||||
if (ISC_check_if_remote(externalFile->c_str(), false))
|
||||
status_exception::raise(Arg::PrivateDyn(163));
|
||||
|
||||
// Check for any path, present in filename.
|
||||
@ -6405,7 +6405,7 @@ void CreateRelationNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScrat
|
||||
// that's why no expand_filename required.
|
||||
|
||||
PathName path, file;
|
||||
PathUtils::splitLastComponent(path, file, *externalFile);
|
||||
PathUtils::splitLastComponent(path, file, externalFile->c_str());
|
||||
|
||||
if (path.hasData()) // path component present in filename
|
||||
{
|
||||
@ -8763,7 +8763,7 @@ void CreateShadowNode::execute(thread_db* tdbb, DsqlCompilerScratch* /*dsqlScrat
|
||||
}
|
||||
|
||||
defineFile(tdbb, transaction, number, manual && first, conditional && first,
|
||||
start, file->name, file->start, file->length);
|
||||
start, file->name.c_str(), file->start, file->length);
|
||||
}
|
||||
|
||||
savePoint.release(); // everything is ok
|
||||
@ -9080,7 +9080,7 @@ void CreateAlterUserNode::execute(thread_db* tdbb, DsqlCompilerScratch* dsqlScra
|
||||
status_exception::raise(Arg::PrivateDyn(250));
|
||||
}
|
||||
|
||||
userData->pass.set(password->toUtf8(dsqlScratch).c_str());
|
||||
userData->pass.set(password->c_str());
|
||||
userData->pass.setEntered(1);
|
||||
}
|
||||
|
||||
@ -9898,12 +9898,12 @@ void AlterDatabaseNode::execute(thread_db* tdbb, DsqlCompilerScratch* /*dsqlScra
|
||||
|
||||
start = MAX(start, file->start);
|
||||
defineFile(tdbb, transaction, 0, false, false, dbAlloc,
|
||||
file->name, start, file->length);
|
||||
file->name.c_str(), start, file->length);
|
||||
start += file->length;
|
||||
}
|
||||
|
||||
if (differenceFile.hasData())
|
||||
defineDifference(tdbb, transaction, differenceFile);
|
||||
defineDifference(tdbb, transaction, differenceFile.c_str());
|
||||
|
||||
if (setDefaultCharSet.hasData())
|
||||
{
|
||||
|
@ -78,7 +78,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
explicit DbFileClause(MemoryPool& p, const Firebird::PathName& aName)
|
||||
explicit DbFileClause(MemoryPool& p, const Firebird::string& aName)
|
||||
: name(p, aName),
|
||||
start(0),
|
||||
length(0)
|
||||
@ -86,9 +86,9 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
Firebird::PathName name; // File name
|
||||
SLONG start; // Starting page
|
||||
SLONG length; // File length in pages
|
||||
Firebird::string name; // File name
|
||||
SLONG start; // Starting page
|
||||
SLONG length; // File length in pages
|
||||
};
|
||||
|
||||
|
||||
@ -214,12 +214,12 @@ class CommentOnNode : public DdlNode
|
||||
public:
|
||||
CommentOnNode(MemoryPool& pool, int aObjType,
|
||||
const Firebird::MetaName& aObjName, const Firebird::MetaName& aSubName,
|
||||
const IntlString* aText)
|
||||
const Firebird::string aText)
|
||||
: DdlNode(pool),
|
||||
objType(aObjType),
|
||||
objName(pool, aObjName),
|
||||
subName(pool, aSubName),
|
||||
text(aText)
|
||||
text(pool, aText)
|
||||
{
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ private:
|
||||
int objType;
|
||||
Firebird::MetaName objName;
|
||||
Firebird::MetaName subName;
|
||||
const IntlString* text;
|
||||
Firebird::string text;
|
||||
};
|
||||
|
||||
|
||||
@ -1283,7 +1283,7 @@ class CreateRelationNode : public RelationNode
|
||||
{
|
||||
public:
|
||||
CreateRelationNode(MemoryPool& p, RelationSourceNode* aDsqlNode,
|
||||
const Firebird::PathName* aExternalFile = NULL)
|
||||
const Firebird::string* aExternalFile = NULL)
|
||||
: RelationNode(p, aDsqlNode),
|
||||
externalFile(aExternalFile),
|
||||
relationType(rel_persistent)
|
||||
@ -1304,7 +1304,7 @@ private:
|
||||
const Firebird::ObjectsArray<Firebird::MetaName>* findPkColumns();
|
||||
|
||||
public:
|
||||
const Firebird::PathName* externalFile;
|
||||
const Firebird::string* externalFile;
|
||||
rel_t relationType;
|
||||
};
|
||||
|
||||
@ -1775,7 +1775,11 @@ public:
|
||||
CreateAlterUserNode(MemoryPool& p, bool creating, const Firebird::MetaName& aName)
|
||||
: DdlNode(p),
|
||||
isCreating(creating),
|
||||
name(p, aName)
|
||||
name(p, aName),
|
||||
password(NULL),
|
||||
firstName(NULL),
|
||||
middleName(NULL),
|
||||
lastName(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1793,7 +1797,7 @@ protected:
|
||||
public:
|
||||
const bool isCreating;
|
||||
const Firebird::MetaName name;
|
||||
const IntlString* password;
|
||||
const Firebird::string* password;
|
||||
const Firebird::string* firstName;
|
||||
const Firebird::string* middleName;
|
||||
const Firebird::string* lastName;
|
||||
@ -1949,7 +1953,7 @@ public:
|
||||
bool create; // Is the node created with a CREATE DATABASE command?
|
||||
SLONG createLength;
|
||||
unsigned clauses;
|
||||
Firebird::PathName differenceFile;
|
||||
Firebird::string differenceFile;
|
||||
Firebird::MetaName setDefaultCharSet;
|
||||
Firebird::MetaName setDefaultCollation;
|
||||
Firebird::Array<NestConst<DbFileClause> > files;
|
||||
|
@ -95,7 +95,7 @@ public:
|
||||
errorHandlers(0),
|
||||
clientDialect(0),
|
||||
inOuterJoin(0),
|
||||
aliasRelationPrefix(NULL),
|
||||
aliasRelationPrefix(p),
|
||||
package(p),
|
||||
currCtes(p),
|
||||
recursiveCtx(0),
|
||||
@ -311,7 +311,7 @@ public:
|
||||
USHORT errorHandlers; // count of active error handlers
|
||||
USHORT clientDialect; // dialect passed into the API call
|
||||
USHORT inOuterJoin; // processing inside outer-join part
|
||||
dsql_str* aliasRelationPrefix; // prefix for every relation-alias.
|
||||
Firebird::string aliasRelationPrefix; // prefix for every relation-alias.
|
||||
Firebird::MetaName package; // package being defined
|
||||
Firebird::Stack<SelectExprNode*> currCtes; // current processing CTE's
|
||||
class dsql_ctx* recursiveCtx; // context of recursive CTE
|
||||
|
@ -6260,18 +6260,16 @@ ValueExprNode* LiteralNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
constant->dsqlStr = dsqlStr;
|
||||
constant->litDesc = litDesc;
|
||||
|
||||
const dsql_str* string = constant->dsqlStr;
|
||||
|
||||
if (string && string->str_charset)
|
||||
if (dsqlStr && dsqlStr->getCharSet().hasData())
|
||||
{
|
||||
const dsql_intlsym* resolved = METD_get_charset(dsqlScratch->getTransaction(),
|
||||
strlen(string->str_charset), string->str_charset);
|
||||
dsqlStr->getCharSet().length(), dsqlStr->getCharSet().c_str());
|
||||
|
||||
if (!resolved)
|
||||
{
|
||||
// character set name is not defined
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-504) <<
|
||||
Arg::Gds(isc_charset_not_found) << Arg::Str(string->str_charset));
|
||||
Arg::Gds(isc_charset_not_found) << dsqlStr->getCharSet());
|
||||
}
|
||||
|
||||
constant->litDesc.setTextType(resolved->intlsym_ttype);
|
||||
@ -6300,7 +6298,7 @@ ValueExprNode* LiteralNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
|
||||
CharSet* charSet = INTL_charset_lookup(tdbb, INTL_GET_CHARSET(&constant->litDesc));
|
||||
|
||||
if (!charSet->wellFormed(string->str_length, constant->litDesc.dsc_address, NULL))
|
||||
if (!charSet->wellFormed(dsqlStr->getString().length(), constant->litDesc.dsc_address, NULL))
|
||||
{
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
|
||||
Arg::Gds(isc_malformed_string));
|
||||
@ -6308,7 +6306,7 @@ ValueExprNode* LiteralNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
else
|
||||
{
|
||||
constant->litDesc.dsc_length =
|
||||
charSet->length(string->str_length, constant->litDesc.dsc_address, true) *
|
||||
charSet->length(dsqlStr->getString().length(), constant->litDesc.dsc_address, true) *
|
||||
charSet->maxBytesPerChar();
|
||||
}
|
||||
|
||||
@ -6331,7 +6329,7 @@ bool LiteralNode::setParameterType(DsqlCompilerScratch* /*dsqlScratch*/,
|
||||
void LiteralNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
{
|
||||
if (litDesc.dsc_dtype == dtype_text)
|
||||
litDesc.dsc_length = dsqlStr->str_length;
|
||||
litDesc.dsc_length = dsqlStr->getString().length();
|
||||
|
||||
genConstant(dsqlScratch, &litDesc, false);
|
||||
}
|
||||
@ -6398,7 +6396,7 @@ bool LiteralNode::dsqlMatch(const ExprNode* other, bool ignoreMapCast) const
|
||||
return false;
|
||||
|
||||
const USHORT len = (litDesc.dsc_dtype == dtype_text) ?
|
||||
dsqlStr->str_length : litDesc.dsc_length;
|
||||
(USHORT) dsqlStr->getString().length() : litDesc.dsc_length;
|
||||
return memcmp(litDesc.dsc_address, o->litDesc.dsc_address, len) == 0;
|
||||
}
|
||||
|
||||
|
@ -752,7 +752,7 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
dsql_str* dsqlStr;
|
||||
const IntlString* dsqlStr;
|
||||
dsc litDesc;
|
||||
};
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "../dsql/Parser.h"
|
||||
#include "../dsql/chars.h"
|
||||
#include "../jrd/jrd.h"
|
||||
#include "../jrd/DataTypeUtil.h"
|
||||
#include "../yvalve/keywords.h"
|
||||
|
||||
using namespace Firebird;
|
||||
@ -37,7 +38,7 @@ namespace
|
||||
|
||||
struct KeywordVersion
|
||||
{
|
||||
KeywordVersion(int aKeyword, dsql_str* aStr, USHORT aVersion)
|
||||
KeywordVersion(int aKeyword, MetaName* aStr, USHORT aVersion)
|
||||
: keyword(aKeyword),
|
||||
str(aStr),
|
||||
version(aVersion)
|
||||
@ -45,26 +46,20 @@ namespace
|
||||
}
|
||||
|
||||
int keyword;
|
||||
dsql_str* str;
|
||||
MetaName* str;
|
||||
USHORT version;
|
||||
};
|
||||
|
||||
class KeywordsMap : public GenericMap<Pair<Left<string, KeywordVersion> > >
|
||||
class KeywordsMap : public GenericMap<Pair<Left<MetaName, KeywordVersion> > >
|
||||
{
|
||||
public:
|
||||
explicit KeywordsMap(MemoryPool& pool)
|
||||
: GenericMap<Pair<Left<string, KeywordVersion> > >(pool)
|
||||
: GenericMap<Pair<Left<MetaName, KeywordVersion> > >(pool)
|
||||
{
|
||||
for (const TOK* token = KEYWORD_getTokens(); token->tok_string; ++token)
|
||||
{
|
||||
size_t len = strlen(token->tok_string);
|
||||
dsql_str* str = FB_NEW_RPT(pool, len) dsql_str;
|
||||
str->str_length = len;
|
||||
strncpy(str->str_data, token->tok_string, len);
|
||||
//str->str_data[str->str_length] = 0; Is it necessary?
|
||||
|
||||
put(string(token->tok_string, len),
|
||||
KeywordVersion(token->tok_ident, str, token->tok_version));
|
||||
MetaName* str = FB_NEW(pool) MetaName(token->tok_string);
|
||||
put(*str, KeywordVersion(token->tok_ident, str, token->tok_version));
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,9 +75,11 @@ namespace
|
||||
}
|
||||
|
||||
|
||||
Parser::Parser(MemoryPool& pool, USHORT aClientDialect, USHORT aDbDialect, USHORT aParserVersion,
|
||||
const TEXT* string, size_t length, SSHORT characterSet)
|
||||
Parser::Parser(MemoryPool& pool, DsqlCompilerScratch* aScratch, USHORT aClientDialect,
|
||||
USHORT aDbDialect, USHORT aParserVersion, const TEXT* string, size_t length,
|
||||
SSHORT characterSet)
|
||||
: PermanentStorage(pool),
|
||||
scratch(aScratch),
|
||||
compilingText(pool, string, length),
|
||||
client_dialect(aClientDialect),
|
||||
db_dialect(aDbDialect),
|
||||
@ -156,30 +153,6 @@ dsql_req* Parser::parse()
|
||||
}
|
||||
|
||||
|
||||
MetaName Parser::toName(dsql_str* str)
|
||||
{
|
||||
if (!str)
|
||||
return "";
|
||||
|
||||
if (str->str_length > MAX_SQL_IDENTIFIER_LEN)
|
||||
yyabandon(-104, isc_dyn_name_longer);
|
||||
|
||||
return MetaName(str->str_data);
|
||||
}
|
||||
|
||||
|
||||
PathName Parser::toPathName(dsql_str* str)
|
||||
{
|
||||
return PathName(str->str_data);
|
||||
}
|
||||
|
||||
|
||||
string Parser::toString(dsql_str* str)
|
||||
{
|
||||
return string(str ? str->str_data : "");
|
||||
}
|
||||
|
||||
|
||||
// Transform strings (or substrings) prefixed with introducer (_charset) to ASCII equivalent.
|
||||
void Parser::transformString(const char* start, unsigned length, string& dest)
|
||||
{
|
||||
@ -195,7 +168,7 @@ void Parser::transformString(const char* start, unsigned length, string& dest)
|
||||
|
||||
SortedArray<StrMark> introducedMarks;
|
||||
|
||||
GenericMap<NonPooled<dsql_str*, StrMark> >::ConstAccessor accessor(&strMarks);
|
||||
GenericMap<NonPooled<IntlString*, StrMark> >::ConstAccessor accessor(&strMarks);
|
||||
for (bool found = accessor.getFirst(); found; found = accessor.getNext())
|
||||
{
|
||||
const StrMark& mark = accessor.current()->second;
|
||||
@ -214,16 +187,16 @@ void Parser::transformString(const char* start, unsigned length, string& dest)
|
||||
buffer.add(' '); // fix _charset'' becoming invalid syntax _charsetX''
|
||||
|
||||
const size_t count = buffer.getCount();
|
||||
const size_t newSize = count + 2 + mark.str->str_length * 2 + 1;
|
||||
const size_t newSize = count + 2 + mark.str->getString().length() * 2 + 1;
|
||||
buffer.grow(newSize);
|
||||
char* p = buffer.begin() + count;
|
||||
|
||||
*p++ = 'X';
|
||||
*p++ = '\'';
|
||||
|
||||
const char* s2 = mark.str->str_data;
|
||||
const char* s2 = mark.str->getString().c_str();
|
||||
|
||||
for (const char* end = s2 + mark.str->str_length; s2 < end; ++s2)
|
||||
for (const char* end = s2 + mark.str->getString().length(); s2 < end; ++s2)
|
||||
{
|
||||
*p++ = HEX_DIGITS[UCHAR(*s2) >> 4];
|
||||
*p++ = HEX_DIGITS[UCHAR(*s2) & 0xF];
|
||||
@ -243,7 +216,7 @@ void Parser::transformString(const char* start, unsigned length, string& dest)
|
||||
|
||||
|
||||
// Make a substring from the command text being parsed.
|
||||
dsql_str* Parser::makeParseStr(const Position& p1, const Position& p2)
|
||||
string Parser::makeParseStr(const Position& p1, const Position& p2)
|
||||
{
|
||||
const char* start = p1.firstPos;
|
||||
const char* end = p2.lastPos;
|
||||
@ -251,7 +224,12 @@ dsql_str* Parser::makeParseStr(const Position& p1, const Position& p2)
|
||||
string str;
|
||||
transformString(start, end - start, str);
|
||||
|
||||
return MAKE_string(str.c_str(), str.length());
|
||||
string ret;
|
||||
|
||||
if (DataTypeUtil::convertToUTF8(str, ret))
|
||||
return ret;
|
||||
else
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@ -394,6 +372,9 @@ int Parser::yylex()
|
||||
|
||||
int Parser::yylexAux()
|
||||
{
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
MemoryPool& pool = *tdbb->getDefaultPool();
|
||||
|
||||
SSHORT c = lex.ptr[-1];
|
||||
UCHAR tok_class = classes(c);
|
||||
char string[MAX_TOKEN_LEN];
|
||||
@ -416,12 +397,14 @@ int Parser::yylexAux()
|
||||
}
|
||||
|
||||
check_bound(p, string);
|
||||
|
||||
if (p - string > MAX_SQL_IDENTIFIER_LEN)
|
||||
yyabandon(-104, isc_dyn_name_longer);
|
||||
|
||||
*p = 0;
|
||||
|
||||
// make a string value to hold the name, the name
|
||||
// is resolved in pass1_constant
|
||||
|
||||
yylval.textPtr = MAKE_string(string, p - string)->str_data;
|
||||
// make a string value to hold the name, the name is resolved in pass1_constant.
|
||||
yylval.metaNamePtr = FB_NEW(pool) MetaName(pool, string, p - string);
|
||||
|
||||
return INTRODUCER;
|
||||
}
|
||||
@ -509,26 +492,23 @@ int Parser::yylexAux()
|
||||
yyabandon(-104, isc_dyn_zero_len_id);
|
||||
}
|
||||
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
Attachment* attachment = tdbb->getAttachment();
|
||||
MetaName name(attachment->nameToMetaCharSet(tdbb, MetaName(buffer, p - buffer)));
|
||||
|
||||
yylval.legacyStr = MAKE_string(name.c_str(), name.length());
|
||||
yylval.metaNamePtr = FB_NEW(pool) MetaName(pool, name);
|
||||
|
||||
dsql_str* delimited_id_str = yylval.legacyStr;
|
||||
delimited_id_str->type = dsql_str::TYPE_DELIMITED;
|
||||
if (buffer != string)
|
||||
gds__free (buffer);
|
||||
|
||||
return SYMBOL;
|
||||
}
|
||||
}
|
||||
yylval.legacyStr = MAKE_string(buffer, p - buffer);
|
||||
yylval.intlStringPtr = newIntlString(Firebird::string(buffer, p - buffer));
|
||||
if (buffer != string)
|
||||
gds__free (buffer);
|
||||
|
||||
mark.length = lex.ptr - lex.last_token;
|
||||
mark.str = yylval.legacyStr;
|
||||
mark.str = yylval.intlStringPtr;
|
||||
strMarks.put(mark.str, mark);
|
||||
|
||||
return STRING;
|
||||
@ -649,10 +629,7 @@ int Parser::yylexAux()
|
||||
byte = c;
|
||||
}
|
||||
|
||||
dsql_str* string = MAKE_string(temp.c_str(), temp.length());
|
||||
string->type = dsql_str::TYPE_HEXA;
|
||||
string->str_charset = "BINARY";
|
||||
yylval.legacyStr = string;
|
||||
yylval.intlStringPtr = newIntlString(temp, "BINARY");
|
||||
|
||||
return STRING;
|
||||
} // if (!hexerror)...
|
||||
@ -691,12 +668,13 @@ int Parser::yylexAux()
|
||||
{
|
||||
if (*lex.ptr == endChar && *++lex.ptr == '\'')
|
||||
{
|
||||
yylval.legacyStr = MAKE_string(lex.last_token + 3, lex.ptr - lex.last_token - 4);
|
||||
yylval.legacyStr->type = dsql_str::TYPE_ALTERNATE;
|
||||
lex.ptr++;
|
||||
yylval.intlStringPtr = newIntlString(
|
||||
Firebird::string(lex.last_token + 3, lex.ptr - lex.last_token - 4));
|
||||
|
||||
++lex.ptr;
|
||||
|
||||
mark.length = lex.ptr - lex.last_token;
|
||||
mark.str = yylval.legacyStr;
|
||||
mark.str = yylval.intlStringPtr;
|
||||
strMarks.put(mark.str, mark);
|
||||
|
||||
return STRING;
|
||||
@ -781,7 +759,7 @@ int Parser::yylexAux()
|
||||
p++;
|
||||
}
|
||||
|
||||
yylval.legacyStr = MAKE_string(cbuff, strlen(cbuff));
|
||||
yylval.stringPtr = newString(cbuff);
|
||||
return NUMBER64BIT;
|
||||
}
|
||||
else
|
||||
@ -929,7 +907,8 @@ int Parser::yylexAux()
|
||||
|
||||
if (have_exp_digit)
|
||||
{
|
||||
yylval.legacyStr = MAKE_string(lex.last_token, lex.ptr - lex.last_token);
|
||||
yylval.stringPtr = newString(
|
||||
Firebird::string(lex.last_token, lex.ptr - lex.last_token));
|
||||
lex.last_token_bk = lex.last_token;
|
||||
lex.line_start_bk = lex.line_start;
|
||||
lex.lines_bk = lex.lines;
|
||||
@ -970,7 +949,7 @@ int Parser::yylexAux()
|
||||
ERRD_post_warning(Arg::Warning(isc_dsql_warning_number_ambiguous1));
|
||||
}
|
||||
|
||||
yylval.legacyStr = MAKE_string(lex.last_token, lex.ptr - lex.last_token);
|
||||
yylval.stringPtr = newString(Firebird::string(lex.last_token, lex.ptr - lex.last_token));
|
||||
|
||||
lex.last_token_bk = lex.last_token;
|
||||
lex.line_start_bk = lex.line_start;
|
||||
@ -1013,23 +992,23 @@ int Parser::yylexAux()
|
||||
check_bound(p, string);
|
||||
*p = 0;
|
||||
|
||||
Firebird::string str(string, p - string);
|
||||
if (p > &string[MAX_SQL_IDENTIFIER_LEN])
|
||||
yyabandon(-104, isc_dyn_name_longer);
|
||||
|
||||
MetaName str(string, p - string);
|
||||
KeywordVersion* keyVer = keywordsMap->get(str);
|
||||
|
||||
if (keyVer && parser_version >= keyVer->version &&
|
||||
(keyVer->keyword != COMMENT || lex.prev_keyword == -1))
|
||||
{
|
||||
yylval.legacyStr = keyVer->str;
|
||||
yylval.metaNamePtr = keyVer->str;
|
||||
lex.last_token_bk = lex.last_token;
|
||||
lex.line_start_bk = lex.line_start;
|
||||
lex.lines_bk = lex.lines;
|
||||
return keyVer->keyword;
|
||||
}
|
||||
|
||||
if (p > &string[MAX_SQL_IDENTIFIER_LEN])
|
||||
yyabandon(-104, isc_dyn_name_longer);
|
||||
|
||||
yylval.legacyStr = MAKE_string(string, p - string);
|
||||
yylval.metaNamePtr = FB_NEW(pool) MetaName(pool, str);
|
||||
lex.last_token_bk = lex.last_token;
|
||||
lex.line_start_bk = lex.line_start;
|
||||
lex.lines_bk = lex.lines;
|
||||
@ -1038,12 +1017,12 @@ int Parser::yylexAux()
|
||||
|
||||
// Must be punctuation -- test for double character punctuation
|
||||
|
||||
if (lex.last_token + 1 < lex.end)
|
||||
if (lex.last_token + 1 < lex.end && !isspace(UCHAR(lex.last_token[1])))
|
||||
{
|
||||
Firebird::string str(lex.last_token, 2);
|
||||
KeywordVersion* keyVer = keywordsMap->get(str);
|
||||
|
||||
if (keyVer && parser_version >= keyVer->version)
|
||||
if (keyVer && keyVer && parser_version >= keyVer->version)
|
||||
{
|
||||
++lex.ptr;
|
||||
return keyVer->keyword;
|
||||
|
@ -112,15 +112,16 @@ private:
|
||||
bool introduced;
|
||||
unsigned pos;
|
||||
unsigned length;
|
||||
dsql_str* str;
|
||||
IntlString* str;
|
||||
};
|
||||
|
||||
public:
|
||||
static const int MAX_TOKEN_LEN = 256;
|
||||
|
||||
public:
|
||||
Parser(MemoryPool& pool, USHORT aClientDialect, USHORT aDbDialect, USHORT aParserVersion,
|
||||
const TEXT* string, size_t length, SSHORT characterSet);
|
||||
Parser(MemoryPool& pool, DsqlCompilerScratch* aScratch, USHORT aClientDialect,
|
||||
USHORT aDbDialect, USHORT aParserVersion, const TEXT* string, size_t length,
|
||||
SSHORT characterSet);
|
||||
~Parser();
|
||||
|
||||
public:
|
||||
@ -136,6 +137,16 @@ public:
|
||||
return stmt_ambiguous;
|
||||
}
|
||||
|
||||
Firebird::string* newString(const Firebird::string& s)
|
||||
{
|
||||
return FB_NEW(getPool()) Firebird::string(getPool(), s);
|
||||
}
|
||||
|
||||
IntlString* newIntlString(const Firebird::string& s, const char* charSet = NULL)
|
||||
{
|
||||
return FB_NEW(getPool()) IntlString(getPool(), s, charSet);
|
||||
}
|
||||
|
||||
// newNode overloads
|
||||
|
||||
template <typename T>
|
||||
@ -208,12 +219,13 @@ private:
|
||||
|
||||
void yyabandon(SLONG, ISC_STATUS);
|
||||
|
||||
Firebird::MetaName toName(dsql_str* str);
|
||||
Firebird::PathName toPathName(dsql_str* str);
|
||||
Firebird::string toString(dsql_str* str);
|
||||
Firebird::MetaName optName(Firebird::MetaName* name)
|
||||
{
|
||||
return (name ? *name : Firebird::MetaName());
|
||||
}
|
||||
|
||||
void transformString(const char* start, unsigned length, Firebird::string& dest);
|
||||
dsql_str* makeParseStr(const Position& p1, const Position& p2);
|
||||
Firebird::string makeParseStr(const Position& p1, const Position& p2);
|
||||
ParameterNode* make_parameter();
|
||||
|
||||
// Set the value of a clause, checking if it was already specified.
|
||||
@ -300,13 +312,14 @@ private:
|
||||
// end - defined in btyacc_fb.ske
|
||||
|
||||
private:
|
||||
DsqlCompilerScratch* scratch;
|
||||
Firebird::string compilingText;
|
||||
USHORT client_dialect;
|
||||
USHORT db_dialect;
|
||||
USHORT parser_version;
|
||||
|
||||
Firebird::string transformedString;
|
||||
Firebird::GenericMap<Firebird::NonPooled<dsql_str*, StrMark> > strMarks;
|
||||
Firebird::GenericMap<Firebird::NonPooled<IntlString*, StrMark> > strMarks;
|
||||
bool stmt_ambiguous;
|
||||
dsql_req* DSQL_parse;
|
||||
|
||||
|
@ -159,8 +159,7 @@ namespace
|
||||
|
||||
oldContext->ctx_alias = oldContext->ctx_internal_alias = OLD_CONTEXT;
|
||||
|
||||
newContext->ctx_alias = newContext->ctx_internal_alias =
|
||||
MAKE_cstring(NEW_CONTEXT)->str_data;
|
||||
newContext->ctx_alias = newContext->ctx_internal_alias = NEW_CONTEXT;
|
||||
newContext->ctx_flags |= CTX_returning;
|
||||
scratch->context->push(newContext);
|
||||
}
|
||||
@ -2926,7 +2925,7 @@ DmlNode* ExecStatementNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScr
|
||||
{
|
||||
if (code == blr_exec_stmt_in_params2)
|
||||
{
|
||||
string name;
|
||||
MetaName name;
|
||||
|
||||
if (PAR_name(csb, name))
|
||||
{
|
||||
@ -2935,7 +2934,7 @@ DmlNode* ExecStatementNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScr
|
||||
if (!node->inputNames)
|
||||
node->inputNames = FB_NEW (pool) EDS::ParamNames(pool);
|
||||
|
||||
string* newName = FB_NEW (pool) string(pool, name);
|
||||
MetaName* newName = FB_NEW (pool) MetaName(pool, name);
|
||||
node->inputNames->add(newName);
|
||||
}
|
||||
}
|
||||
@ -2988,7 +2987,7 @@ StmtNode* ExecStatementNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
|
||||
|
||||
for (size_t i = 0; i != count; ++i)
|
||||
{
|
||||
const string* name = (*node->inputNames)[i];
|
||||
const MetaName* name = (*node->inputNames)[i];
|
||||
|
||||
size_t pos;
|
||||
if (names.find(name->c_str(), pos))
|
||||
@ -3119,7 +3118,7 @@ void ExecStatementNode::genBlr(DsqlCompilerScratch* dsqlScratch)
|
||||
dsqlScratch->appendUChar(blr_exec_stmt_in_params);
|
||||
|
||||
NestConst<ValueExprNode>* ptr = inputs->items.begin();
|
||||
string* const* name = inputNames ? inputNames->begin() : NULL;
|
||||
MetaName* const* name = inputNames ? inputNames->begin() : NULL;
|
||||
|
||||
for (const NestConst<ValueExprNode>* end = inputs->items.end(); ptr != end; ++ptr, ++name)
|
||||
{
|
||||
@ -3215,7 +3214,7 @@ const StmtNode* ExecStatementNode::execute(thread_db* tdbb, jrd_req* request, Ex
|
||||
stmt->bindToRequest(request, stmtPtr);
|
||||
stmt->setCallerPrivileges(useCallerPrivs);
|
||||
|
||||
const string* const* inpNames = inputNames ? inputNames->begin() : NULL;
|
||||
const MetaName* const* inpNames = inputNames ? inputNames->begin() : NULL;
|
||||
stmt->prepare(tdbb, tran, sSql, inputNames != NULL);
|
||||
|
||||
if (stmt->isSelectable())
|
||||
@ -6248,7 +6247,7 @@ StmtNode* StoreNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, bool upd
|
||||
// marks it with CTX_null so all fields be resolved to NULL constant.
|
||||
dsql_ctx* old_context = FB_NEW(dsqlScratch->getPool()) dsql_ctx(dsqlScratch->getPool());
|
||||
*old_context = *context;
|
||||
old_context->ctx_alias = old_context->ctx_internal_alias = MAKE_cstring(OLD_CONTEXT)->str_data;
|
||||
old_context->ctx_alias = old_context->ctx_internal_alias = OLD_CONTEXT;
|
||||
old_context->ctx_flags |= CTX_system | CTX_null | CTX_returning;
|
||||
dsqlScratch->context->push(old_context);
|
||||
|
||||
@ -6256,7 +6255,7 @@ StmtNode* StoreNode::internalDsqlPass(DsqlCompilerScratch* dsqlScratch, bool upd
|
||||
dsql_ctx* new_context = FB_NEW(dsqlScratch->getPool()) dsql_ctx(dsqlScratch->getPool());
|
||||
*new_context = *context;
|
||||
new_context->ctx_scope_level = ++dsqlScratch->scopeLevel;
|
||||
new_context->ctx_alias = new_context->ctx_internal_alias = MAKE_cstring(NEW_CONTEXT)->str_data;
|
||||
new_context->ctx_alias = new_context->ctx_internal_alias = NEW_CONTEXT;
|
||||
new_context->ctx_flags |= CTX_system | CTX_returning;
|
||||
dsqlScratch->context->push(new_context);
|
||||
}
|
||||
|
@ -1589,7 +1589,7 @@ static dsql_req* prepareStatement(thread_db* tdbb, dsql_dbb* database, jrd_tra*
|
||||
{
|
||||
// Parse the SQL statement. If it croaks, return
|
||||
|
||||
Parser parser(*tdbb->getDefaultPool(), clientDialect,
|
||||
Parser parser(*tdbb->getDefaultPool(), scratch, clientDialect,
|
||||
scratch->getAttachment()->dbb_db_SQL_dialect, parserVersion, text, textLength,
|
||||
tdbb->getAttachment()->att_charset);
|
||||
|
||||
|
@ -85,7 +85,6 @@ namespace Jrd
|
||||
class dsql_ctx;
|
||||
class dsql_msg;
|
||||
class dsql_par;
|
||||
class dsql_str;
|
||||
class dsql_map;
|
||||
class dsql_intlsym;
|
||||
|
||||
@ -107,25 +106,6 @@ namespace Firebird
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
//! generic data type used to store strings
|
||||
class dsql_str : public pool_alloc_rpt<char, dsql_type_str>
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
TYPE_SIMPLE = 0, // '...'
|
||||
TYPE_ALTERNATE, // q'{...}'
|
||||
TYPE_HEXA, // x'...'
|
||||
TYPE_DELIMITED // "..."
|
||||
};
|
||||
|
||||
public:
|
||||
const char* str_charset; // ASCIIZ Character set identifier for string
|
||||
Type type;
|
||||
ULONG str_length; // length of string in BYTES
|
||||
char str_data[2]; // one for ALLOC and one for the NULL
|
||||
};
|
||||
|
||||
// blocks used to cache metadata
|
||||
|
||||
// Database Block
|
||||
@ -878,14 +858,25 @@ typedef Firebird::SortedArray<const char*,
|
||||
class IntlString
|
||||
{
|
||||
public:
|
||||
explicit IntlString(const dsql_str* str)
|
||||
: charset(str && str->str_charset ? str->str_charset : ""),
|
||||
s((str ? str->str_data : NULL), (str ? str->str_length : 0))
|
||||
IntlString(Firebird::MemoryPool& p, const Firebird::string& str,
|
||||
const Firebird::MetaName& cs = NULL)
|
||||
: charset(p, cs),
|
||||
s(p, str)
|
||||
{ }
|
||||
|
||||
IntlString(Firebird::MemoryPool& p, const dsql_str* str)
|
||||
: charset(p, str && str->str_charset ? str->str_charset : ""),
|
||||
s(p, (str ? str->str_data : NULL), (str ? str->str_length : 0))
|
||||
IntlString(const Firebird::string& str, const Firebird::MetaName& cs = NULL)
|
||||
: charset(cs),
|
||||
s(str)
|
||||
{ }
|
||||
|
||||
IntlString(Firebird::MemoryPool& p, const IntlString& o)
|
||||
: charset(p, o.charset),
|
||||
s(p, o.s)
|
||||
{ }
|
||||
|
||||
IntlString(Firebird::MemoryPool& p)
|
||||
: charset(p),
|
||||
s(p)
|
||||
{ }
|
||||
|
||||
Firebird::string toUtf8(DsqlCompilerScratch*) const;
|
||||
@ -895,6 +886,11 @@ public:
|
||||
return charset;
|
||||
}
|
||||
|
||||
void setCharSet(const Firebird::MetaName& value)
|
||||
{
|
||||
charset = value;
|
||||
}
|
||||
|
||||
const Firebird::string& getString() const
|
||||
{
|
||||
return s;
|
||||
|
@ -92,7 +92,7 @@ LiteralNode* MAKE_const_slong(SLONG value)
|
||||
@param numeric_flag
|
||||
|
||||
**/
|
||||
ValueExprNode* MAKE_constant(dsql_str* constant, dsql_constant_type numeric_flag)
|
||||
ValueExprNode* MAKE_constant(const string& str, dsql_constant_type numeric_flag)
|
||||
{
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
|
||||
@ -101,8 +101,6 @@ ValueExprNode* MAKE_constant(dsql_str* constant, dsql_constant_type numeric_flag
|
||||
switch (numeric_flag)
|
||||
{
|
||||
case CONSTANT_DOUBLE:
|
||||
DEV_BLKCHK(constant, dsql_type_str);
|
||||
|
||||
// This is a numeric value which is transported to the engine as
|
||||
// a string. The engine will convert it. Use dtype_double so that
|
||||
// the engine can distinguish it from an actual string.
|
||||
@ -111,12 +109,11 @@ ValueExprNode* MAKE_constant(dsql_str* constant, dsql_constant_type numeric_flag
|
||||
|
||||
literal->litDesc.dsc_dtype = dtype_double;
|
||||
// Scale has no use for double
|
||||
literal->litDesc.dsc_scale = static_cast<signed char>(constant->str_length);
|
||||
literal->litDesc.dsc_scale = static_cast<signed char>(str.length());
|
||||
literal->litDesc.dsc_sub_type = 0;
|
||||
literal->litDesc.dsc_length = sizeof(double);
|
||||
literal->litDesc.dsc_address = (UCHAR*) constant->str_data;
|
||||
literal->litDesc.dsc_address = (UCHAR*) str.c_str();
|
||||
literal->litDesc.dsc_ttype() = ttype_ascii;
|
||||
literal->dsqlStr = constant;
|
||||
break;
|
||||
|
||||
case CONSTANT_SINT64:
|
||||
@ -143,14 +140,14 @@ ValueExprNode* MAKE_constant(dsql_str* constant, dsql_constant_type numeric_flag
|
||||
// And, they will fit in a SINT64 without overflow.
|
||||
|
||||
SINT64 value = 0;
|
||||
const UCHAR* p = reinterpret_cast<const UCHAR*>(constant->str_data);
|
||||
const UCHAR* p = reinterpret_cast<const UCHAR*>(str.c_str());
|
||||
|
||||
if (*p == 'X')
|
||||
{
|
||||
// oh no, a hex string!
|
||||
++p; // skip the 'X' part.
|
||||
UCHAR byte = 0;
|
||||
bool nibble = ((strlen(constant->str_data) - 1) & 1);
|
||||
bool nibble = ((str.length() - 1) & 1);
|
||||
SSHORT c;
|
||||
|
||||
// hex string is already upper-cased
|
||||
@ -242,8 +239,8 @@ ValueExprNode* MAKE_constant(dsql_str* constant, dsql_constant_type numeric_flag
|
||||
tmp.dsc_scale = 0;
|
||||
tmp.dsc_flags = 0;
|
||||
tmp.dsc_ttype() = ttype_ascii;
|
||||
tmp.dsc_length = static_cast<USHORT>(constant->str_length);
|
||||
tmp.dsc_address = (UCHAR*) constant->str_data;
|
||||
tmp.dsc_length = static_cast<USHORT>(str.length());
|
||||
tmp.dsc_address = (UCHAR*) str.c_str();
|
||||
|
||||
// Now invoke the string_to_date/time/timestamp routines
|
||||
|
||||
@ -252,24 +249,11 @@ ValueExprNode* MAKE_constant(dsql_str* constant, dsql_constant_type numeric_flag
|
||||
}
|
||||
|
||||
case CONSTANT_BOOLEAN:
|
||||
DEV_BLKCHK(constant, dsql_type_str);
|
||||
|
||||
literal->litDesc.makeBoolean((UCHAR*) constant->str_data);
|
||||
literal->dsqlStr = constant;
|
||||
literal->litDesc.makeBoolean((UCHAR*) str.c_str());
|
||||
break;
|
||||
|
||||
default:
|
||||
fb_assert(numeric_flag == CONSTANT_STRING);
|
||||
DEV_BLKCHK(constant, dsql_type_str);
|
||||
|
||||
literal->litDesc.dsc_dtype = dtype_text;
|
||||
literal->litDesc.dsc_sub_type = 0;
|
||||
literal->litDesc.dsc_scale = 0;
|
||||
literal->litDesc.dsc_length = static_cast<USHORT>(constant->str_length);
|
||||
literal->litDesc.dsc_address = (UCHAR*) constant->str_data;
|
||||
literal->litDesc.dsc_ttype() = ttype_dynamic;
|
||||
// carry a pointer to the constant to resolve character set in pass1
|
||||
literal->dsqlStr = constant;
|
||||
fb_assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -289,18 +273,18 @@ ValueExprNode* MAKE_constant(dsql_str* constant, dsql_constant_type numeric_flag
|
||||
@param character_set
|
||||
|
||||
**/
|
||||
LiteralNode* MAKE_str_constant(dsql_str* constant, SSHORT character_set)
|
||||
LiteralNode* MAKE_str_constant(const IntlString* constant, SSHORT character_set)
|
||||
{
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
|
||||
DEV_BLKCHK(constant, dsql_type_str);
|
||||
const string& str = constant->getString();
|
||||
|
||||
LiteralNode* literal = FB_NEW(*tdbb->getDefaultPool()) LiteralNode(*tdbb->getDefaultPool());
|
||||
literal->litDesc.dsc_dtype = dtype_text;
|
||||
literal->litDesc.dsc_sub_type = 0;
|
||||
literal->litDesc.dsc_scale = 0;
|
||||
literal->litDesc.dsc_length = static_cast<USHORT>(constant->str_length);
|
||||
literal->litDesc.dsc_address = (UCHAR*) constant->str_data;
|
||||
literal->litDesc.dsc_length = static_cast<USHORT>(str.length());
|
||||
literal->litDesc.dsc_address = (UCHAR*) str.c_str();
|
||||
literal->litDesc.dsc_ttype() = character_set;
|
||||
|
||||
literal->dsqlStr = constant;
|
||||
@ -309,23 +293,6 @@ LiteralNode* MAKE_str_constant(dsql_str* constant, SSHORT character_set)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
MAKE_cstring
|
||||
|
||||
@brief Make a string node for a string whose
|
||||
length is not known, but is null-terminated.
|
||||
|
||||
|
||||
@param str
|
||||
|
||||
**/
|
||||
dsql_str* MAKE_cstring(const char* str)
|
||||
{
|
||||
return MAKE_string(str, strlen(str));
|
||||
}
|
||||
|
||||
|
||||
// Make a descriptor from input node.
|
||||
void MAKE_desc(DsqlCompilerScratch* dsqlScratch, dsc* desc, ValueExprNode* node)
|
||||
{
|
||||
@ -577,50 +544,6 @@ dsql_par* MAKE_parameter(dsql_msg* message, bool sqlda_flag, bool null_flag,
|
||||
return parameter;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
MAKE_string
|
||||
|
||||
@brief Generalized routine for making a string block.
|
||||
|
||||
|
||||
@param str
|
||||
@param length
|
||||
|
||||
**/
|
||||
dsql_str* MAKE_string(const char* str, int length)
|
||||
{
|
||||
fb_assert(length >= 0);
|
||||
return MAKE_tagged_string(str, length, NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
MAKE_tagged_string
|
||||
|
||||
@brief Generalized routine for making a string block.
|
||||
Which is tagged with a character set descriptor.
|
||||
|
||||
|
||||
@param str_
|
||||
@param length
|
||||
@param charset
|
||||
|
||||
**/
|
||||
dsql_str* MAKE_tagged_string(const char* strvar, size_t length, const char* charset)
|
||||
{
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
|
||||
dsql_str* string = FB_NEW_RPT(*tdbb->getDefaultPool(), length) dsql_str;
|
||||
string->str_charset = charset;
|
||||
string->str_length = length;
|
||||
memcpy(string->str_data, strvar, length);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
MAKE_parameter_names
|
||||
|
@ -34,8 +34,8 @@ namespace Jrd {
|
||||
class dsql_msg;
|
||||
class dsql_par;
|
||||
class dsql_req;
|
||||
class dsql_str;
|
||||
class DsqlCompilerScratch;
|
||||
class IntlString;
|
||||
class ExprNode;
|
||||
class FieldNode;
|
||||
class LiteralNode;
|
||||
@ -45,7 +45,6 @@ namespace Jrd {
|
||||
|
||||
// Parameters to MAKE_constant
|
||||
enum dsql_constant_type {
|
||||
CONSTANT_STRING = 0, // stored as a string
|
||||
CONSTANT_DOUBLE = 1, // stored as a string
|
||||
CONSTANT_DATE = 2, // stored as a SLONG
|
||||
CONSTANT_TIME = 3, // stored as a ULONG
|
||||
@ -57,9 +56,8 @@ namespace Jrd {
|
||||
|
||||
|
||||
Jrd::LiteralNode* MAKE_const_slong(SLONG);
|
||||
Jrd::ValueExprNode* MAKE_constant(Jrd::dsql_str*, Jrd::dsql_constant_type);
|
||||
Jrd::LiteralNode* MAKE_str_constant(Jrd::dsql_str*, SSHORT);
|
||||
Jrd::dsql_str* MAKE_cstring(const char*);
|
||||
Jrd::ValueExprNode* MAKE_constant(const Firebird::string&, Jrd::dsql_constant_type);
|
||||
Jrd::LiteralNode* MAKE_str_constant(const Jrd::IntlString*, SSHORT);
|
||||
void MAKE_desc(Jrd::DsqlCompilerScratch*, dsc*, Jrd::ValueExprNode*);
|
||||
void MAKE_desc_from_field(dsc*, const Jrd::dsql_fld*);
|
||||
void MAKE_desc_from_list(Jrd::DsqlCompilerScratch*, dsc*, Jrd::ValueListNode*, const TEXT*);
|
||||
@ -67,7 +65,5 @@ Jrd::FieldNode* MAKE_field(Jrd::dsql_ctx*, Jrd::dsql_fld*, Jrd::ValueListNode*);
|
||||
Jrd::FieldNode* MAKE_field_name(const char*);
|
||||
Jrd::dsql_par* MAKE_parameter(Jrd::dsql_msg*, bool, bool, USHORT, const Jrd::ValueExprNode*);
|
||||
void MAKE_parameter_names(Jrd::dsql_par*, const Jrd::ValueExprNode*);
|
||||
Jrd::dsql_str* MAKE_string(const char*, int);
|
||||
Jrd::dsql_str* MAKE_tagged_string(const char* str, size_t length, const char* charset);
|
||||
|
||||
#endif // DSQL_MAKE_PROTO_H
|
||||
|
@ -35,7 +35,6 @@ namespace Jrd {
|
||||
typedef Firebird::GenericMap<Firebird::MetaNamePair> MetaNamePairMap;
|
||||
|
||||
class dsql_req;
|
||||
class dsql_str;
|
||||
class DsqlCompilerScratch;
|
||||
class jrd_tra;
|
||||
class dsql_intlsym;
|
||||
|
1487
src/dsql/parse.y
1487
src/dsql/parse.y
File diff suppressed because it is too large
Load Diff
@ -178,7 +178,7 @@ using namespace Jrd;
|
||||
using namespace Firebird;
|
||||
|
||||
|
||||
static dsql_str* pass1_alias_concat(const dsql_str*, const char*);
|
||||
static string pass1_alias_concat(const string&, const string&);
|
||||
static void pass1_expand_contexts(DsqlContextStack& contexts, dsql_ctx* context);
|
||||
static ValueListNode* pass1_expand_select_list(DsqlCompilerScratch*, ValueListNode*, RecSourceListNode*);
|
||||
static ValueListNode* pass1_group_by_list(DsqlCompilerScratch*, ValueListNode*, ValueListNode*);
|
||||
@ -440,35 +440,35 @@ dsql_ctx* PASS1_make_context(DsqlCompilerScratch* dsqlScratch, RecordSourceNode*
|
||||
context->ctx_in_outer_join = dsqlScratch->inOuterJoin;
|
||||
|
||||
// find the context alias name, if it exists.
|
||||
const char* string = NULL;
|
||||
string str;
|
||||
|
||||
if ((procNode = relationNode->as<ProcedureSourceNode>()))
|
||||
string = procNode->alias.nullStr();
|
||||
str = procNode->alias;
|
||||
else if ((relNode = relationNode->as<RelationSourceNode>()))
|
||||
string = relNode->alias.nullStr();
|
||||
str = relNode->alias;
|
||||
else if ((selNode = relationNode->as<SelectExprNode>()))
|
||||
{
|
||||
string = selNode->alias.nullStr();
|
||||
str = selNode->alias;
|
||||
// ASF: In the case of a UNION contained in a CTE, selNode->querySpec will be a
|
||||
// UnionSourceNode instead of a RseNode. Since ctx_rse is a RseNode and is always accessed
|
||||
// as one, I'll leave this assignment here. It will be set in PASS1_derived_table anyway.
|
||||
///context->ctx_rse = selNode->querySpec;
|
||||
}
|
||||
|
||||
if (string)
|
||||
context->ctx_internal_alias = string;
|
||||
if (str.hasData())
|
||||
context->ctx_internal_alias = str;
|
||||
|
||||
if (dsqlScratch->aliasRelationPrefix && !selNode)
|
||||
if (dsqlScratch->aliasRelationPrefix.hasData() && !selNode)
|
||||
{
|
||||
if (string)
|
||||
string = pass1_alias_concat(dsqlScratch->aliasRelationPrefix, string)->str_data;
|
||||
if (str.hasData())
|
||||
str = pass1_alias_concat(dsqlScratch->aliasRelationPrefix, str);
|
||||
else
|
||||
string = pass1_alias_concat(dsqlScratch->aliasRelationPrefix, relation_name.c_str())->str_data;
|
||||
str = pass1_alias_concat(dsqlScratch->aliasRelationPrefix, relation_name.c_str());
|
||||
}
|
||||
|
||||
if (string)
|
||||
if (str.hasData())
|
||||
{
|
||||
context->ctx_alias = string;
|
||||
context->ctx_alias = str;
|
||||
|
||||
// check to make sure the context is not already used at this same
|
||||
// query level (if there are no subqueries, this checks that the
|
||||
@ -964,7 +964,7 @@ RseNode* PASS1_derived_table(DsqlCompilerScratch* dsqlScratch, SelectExprNode* i
|
||||
|
||||
// Save some values to restore after rse process.
|
||||
DsqlContextStack* const req_base = dsqlScratch->context;
|
||||
dsql_str* const aliasRelationPrefix = dsqlScratch->aliasRelationPrefix;
|
||||
string aliasRelationPrefix = dsqlScratch->aliasRelationPrefix;
|
||||
|
||||
// Change context, because when we are processing the derived table rse
|
||||
// it may not reference to other streams in the same scope_level.
|
||||
@ -986,7 +986,7 @@ RseNode* PASS1_derived_table(DsqlCompilerScratch* dsqlScratch, SelectExprNode* i
|
||||
baseContext = temp.object();
|
||||
|
||||
dsqlScratch->context = &temp;
|
||||
dsqlScratch->aliasRelationPrefix = pass1_alias_concat(aliasRelationPrefix, alias.nullStr());
|
||||
dsqlScratch->aliasRelationPrefix = pass1_alias_concat(aliasRelationPrefix, alias);
|
||||
|
||||
RecordSourceNode* query = input->querySpec;
|
||||
UnionSourceNode* unionQuery = query->as<UnionSourceNode>();
|
||||
@ -1264,7 +1264,6 @@ RseNode* PASS1_derived_table(DsqlCompilerScratch* dsqlScratch, SelectExprNode* i
|
||||
map_context->ctx_recursive = recursive_map_ctx;
|
||||
}
|
||||
|
||||
delete dsqlScratch->aliasRelationPrefix;
|
||||
// Restore our original values.
|
||||
dsqlScratch->context = req_base;
|
||||
dsqlScratch->aliasRelationPrefix = aliasRelationPrefix;
|
||||
@ -1504,7 +1503,6 @@ USHORT PASS1_label(DsqlCompilerScratch* dsqlScratch, bool breakContinue, MetaNam
|
||||
|
||||
// look for a label, if specified
|
||||
|
||||
const dsql_str* string = NULL;
|
||||
USHORT position = 0;
|
||||
|
||||
if (label)
|
||||
@ -1554,8 +1552,8 @@ USHORT PASS1_label(DsqlCompilerScratch* dsqlScratch, bool breakContinue, MetaNam
|
||||
// ERROR: Label %s already exists in the current scope
|
||||
ERRD_post(Arg::Gds(isc_sqlerr) << Arg::Num(-104) <<
|
||||
Arg::Gds(isc_dsql_command_err) <<
|
||||
Arg::Gds(isc_dsql_invalid_label) << Arg::Str(string->str_data) <<
|
||||
Arg::Str("already exists"));
|
||||
Arg::Gds(isc_dsql_invalid_label) << *label <<
|
||||
Arg::Str("already exists"));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1782,46 +1780,21 @@ RecordSourceNode* PASS1_relation(DsqlCompilerScratch* dsqlScratch, RecordSourceN
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
pass1_alias_concat
|
||||
|
||||
@brief Concatenate 2 input strings together for
|
||||
a new alias string.
|
||||
Note: Both input params can be empty.
|
||||
|
||||
|
||||
@param input1
|
||||
@param input2
|
||||
|
||||
**/
|
||||
static dsql_str* pass1_alias_concat(const dsql_str* input1, const char* input2)
|
||||
// Concatenate 2 input strings together for a new alias string
|
||||
// Note: Both input params can be empty.
|
||||
static string pass1_alias_concat(const string& input1, const string& input2)
|
||||
{
|
||||
thread_db* tdbb = JRD_get_thread_data();
|
||||
string output;
|
||||
|
||||
DEV_BLKCHK(input1, dsql_type_str);
|
||||
DEV_BLKCHK(input2, dsql_type_str);
|
||||
if (input1.hasData())
|
||||
output.append(input1);
|
||||
|
||||
int length = (input1 ? input1->str_length : 0);
|
||||
|
||||
if (input1 && input1->str_length && input2)
|
||||
++length; // Room for space character.
|
||||
|
||||
if (input2)
|
||||
length += strlen(input2);
|
||||
|
||||
dsql_str* output = FB_NEW_RPT(*tdbb->getDefaultPool(), length) dsql_str;
|
||||
output->str_length = length;
|
||||
TEXT* ptr = output->str_data;
|
||||
|
||||
if (input1)
|
||||
strcat(ptr, input1->str_data);
|
||||
|
||||
if (input1 && input1->str_length && input2)
|
||||
strcat(ptr, " ");
|
||||
|
||||
if (input2)
|
||||
strcat(ptr, input2);
|
||||
if (input2.hasData())
|
||||
{
|
||||
if (output.hasData())
|
||||
output.append(" ");
|
||||
output.append(input2);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
@ -833,7 +833,7 @@ void Statement::prepare(thread_db* tdbb, Transaction* tran, const string& sql, b
|
||||
}
|
||||
|
||||
void Statement::execute(thread_db* tdbb, Transaction* tran,
|
||||
const string* const* in_names, const ValueListNode* in_params,
|
||||
const MetaName* const* in_names, const ValueListNode* in_params,
|
||||
const ValueListNode* out_params)
|
||||
{
|
||||
fb_assert(isAllocated() && !m_stmt_selectable);
|
||||
@ -847,7 +847,7 @@ void Statement::execute(thread_db* tdbb, Transaction* tran,
|
||||
}
|
||||
|
||||
void Statement::open(thread_db* tdbb, Transaction* tran,
|
||||
const string* const* in_names, const ValueListNode* in_params, bool singleton)
|
||||
const MetaName* const* in_names, const ValueListNode* in_params, bool singleton)
|
||||
{
|
||||
fb_assert(isAllocated() && m_stmt_selectable);
|
||||
fb_assert(!m_error);
|
||||
@ -1161,7 +1161,7 @@ void Statement::preprocess(const string& sql, string& ret)
|
||||
if (n >= m_sqlParamNames.getCount())
|
||||
{
|
||||
n = m_sqlParamNames.getCount();
|
||||
m_sqlParamNames.add(FB_NEW(getPool()) string(getPool(), ident));
|
||||
m_sqlParamNames.add(FB_NEW(getPool()) MetaName(getPool(), ident));
|
||||
}
|
||||
m_sqlParamsMap.add(m_sqlParamNames[n]);
|
||||
}
|
||||
@ -1215,7 +1215,7 @@ void Statement::preprocess(const string& sql, string& ret)
|
||||
return;
|
||||
}
|
||||
|
||||
void Statement::setInParams(thread_db* tdbb, const string* const* names,
|
||||
void Statement::setInParams(thread_db* tdbb, const MetaName* const* names,
|
||||
const ValueListNode* params)
|
||||
{
|
||||
const size_t count = params ? params->items.getCount() : 0;
|
||||
@ -1238,7 +1238,7 @@ void Statement::setInParams(thread_db* tdbb, const string* const* names,
|
||||
|
||||
for (unsigned int sqlNum = 0; sqlNum < sqlCount; sqlNum++)
|
||||
{
|
||||
const string* sqlName = m_sqlParamsMap[sqlNum];
|
||||
const MetaName* sqlName = m_sqlParamsMap[sqlNum];
|
||||
|
||||
unsigned int num = 0;
|
||||
for (; num < count; num++)
|
||||
@ -1262,7 +1262,7 @@ void Statement::setInParams(thread_db* tdbb, const string* const* names,
|
||||
doSetInParams(tdbb, count, names, (params ? params->items.begin() : NULL));
|
||||
}
|
||||
|
||||
void Statement::doSetInParams(thread_db* tdbb, unsigned int count, const string* const* /*names*/,
|
||||
void Statement::doSetInParams(thread_db* tdbb, unsigned int count, const MetaName* const* /*names*/,
|
||||
const NestConst<ValueExprNode>* params)
|
||||
{
|
||||
if (count != getInputs())
|
||||
@ -1473,7 +1473,7 @@ void Statement::putExtBlob(thread_db* tdbb, dsc& src, dsc& dst)
|
||||
|
||||
void Statement::clearNames()
|
||||
{
|
||||
string** s = m_sqlParamNames.begin(), **end = m_sqlParamNames.end();
|
||||
MetaName** s = m_sqlParamNames.begin(), **end = m_sqlParamNames.end();
|
||||
for (; s < end; s++)
|
||||
{
|
||||
delete *s;
|
||||
|
@ -292,7 +292,7 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
typedef Firebird::Array<Firebird::string*> ParamNames;
|
||||
typedef Firebird::Array<Firebird::MetaName*> ParamNames;
|
||||
|
||||
class Statement : public Firebird::PermanentStorage
|
||||
{
|
||||
@ -314,10 +314,10 @@ public:
|
||||
|
||||
void prepare(Jrd::thread_db* tdbb, Transaction* tran, const Firebird::string& sql, bool named);
|
||||
void execute(Jrd::thread_db* tdbb, Transaction* tran,
|
||||
const Firebird::string* const* in_names, const Jrd::ValueListNode* in_params,
|
||||
const Firebird::MetaName* const* in_names, const Jrd::ValueListNode* in_params,
|
||||
const Jrd::ValueListNode* out_params);
|
||||
void open(Jrd::thread_db* tdbb, Transaction* tran,
|
||||
const Firebird::string* const* in_names, const Jrd::ValueListNode* in_params, bool singleton);
|
||||
const Firebird::MetaName* const* in_names, const Jrd::ValueListNode* in_params, bool singleton);
|
||||
bool fetch(Jrd::thread_db* tdbb, const Jrd::ValueListNode* out_params);
|
||||
void close(Jrd::thread_db* tdbb);
|
||||
void deallocate(Jrd::thread_db* tdbb);
|
||||
@ -354,12 +354,12 @@ protected:
|
||||
virtual bool doFetch(Jrd::thread_db* tdbb) = 0;
|
||||
virtual void doClose(Jrd::thread_db* tdbb, bool drop) = 0;
|
||||
|
||||
void setInParams(Jrd::thread_db* tdbb, const Firebird::string* const* names,
|
||||
void setInParams(Jrd::thread_db* tdbb, const Firebird::MetaName* const* names,
|
||||
const Jrd::ValueListNode* params);
|
||||
virtual void getOutParams(Jrd::thread_db* tdbb, const Jrd::ValueListNode* params);
|
||||
|
||||
virtual void doSetInParams(Jrd::thread_db* tdbb, unsigned int count, const Firebird::string* const* names,
|
||||
const NestConst<Jrd::ValueExprNode>* params);
|
||||
virtual void doSetInParams(Jrd::thread_db* tdbb, unsigned int count,
|
||||
const Firebird::MetaName* const* names, const NestConst<Jrd::ValueExprNode>* params);
|
||||
|
||||
virtual void putExtBlob(Jrd::thread_db* tdbb, dsc& src, dsc& dst);
|
||||
virtual void getExtBlob(Jrd::thread_db* tdbb, const dsc& src, dsc& dst);
|
||||
|
@ -515,7 +515,7 @@ void IscStatement::doClose(thread_db* tdbb, bool drop)
|
||||
}
|
||||
}
|
||||
|
||||
void IscStatement::doSetInParams(thread_db* tdbb, unsigned int count, const string* const* names,
|
||||
void IscStatement::doSetInParams(thread_db* tdbb, unsigned int count, const MetaName* const* names,
|
||||
const NestConst<Jrd::ValueExprNode>* params)
|
||||
{
|
||||
Statement::doSetInParams(tdbb, count, names, params);
|
||||
|
@ -578,8 +578,8 @@ protected:
|
||||
virtual bool doFetch(Jrd::thread_db* tdbb);
|
||||
virtual void doClose(Jrd::thread_db* tdbb, bool drop);
|
||||
|
||||
virtual void doSetInParams(Jrd::thread_db* tdbb, unsigned int count, const Firebird::string* const* names,
|
||||
const NestConst<Jrd::ValueExprNode>* params);
|
||||
virtual void doSetInParams(Jrd::thread_db* tdbb, unsigned int count,
|
||||
const Firebird::MetaName* const* names, const NestConst<Jrd::ValueExprNode>* params);
|
||||
|
||||
IscTransaction* getIscTransaction() { return (IscTransaction*) m_transaction; }
|
||||
|
||||
|
@ -44,14 +44,14 @@ static const TOK tokens[] =
|
||||
{NOT_LSS, "!<", 1, false},
|
||||
{NEQ, "!=", 1, false},
|
||||
{NOT_GTR, "!>", 1, false},
|
||||
{LPAREN, "(", 1, false},
|
||||
{RPAREN, ")", 1, false},
|
||||
{COMMA, ",", 1, false},
|
||||
{LSS, "<", 1, false},
|
||||
{'(', "(", 1, false},
|
||||
{')', ")", 1, false},
|
||||
{',', ",", 1, false},
|
||||
{'<', "<", 1, false},
|
||||
{LEQ, "<=", 1, false},
|
||||
{NEQ, "<>", 1, false}, // Alias of !=
|
||||
{EQL, "=", 1, false},
|
||||
{GTR, ">", 1, false},
|
||||
{'=', "=", 1, false},
|
||||
{'>', ">", 1, false},
|
||||
{GEQ, ">=", 1, false},
|
||||
{BIND_PARAM, ":=", 2, false},
|
||||
{ABS, "ABS", 2, false},
|
||||
|
Loading…
Reference in New Issue
Block a user