|
@@ -36,7 +36,7 @@ type
|
|
TSQLScript = class;
|
|
TSQLScript = class;
|
|
|
|
|
|
|
|
|
|
- TStatementType = (stNone, stSelect, stInsert, stUpdate, stDelete,
|
|
|
|
|
|
+ TStatementType = (stUnknown, stSelect, stInsert, stUpdate, stDelete,
|
|
stDDL, stGetSegment, stPutSegment, stExecProcedure,
|
|
stDDL, stGetSegment, stPutSegment, stExecProcedure,
|
|
stStartTrans, stCommit, stRollback, stSelectForUpd);
|
|
stStartTrans, stCommit, stRollback, stSelectForUpd);
|
|
|
|
|
|
@@ -63,7 +63,7 @@ const
|
|
SingleQuotes : TQuoteChars = ('''','''');
|
|
SingleQuotes : TQuoteChars = ('''','''');
|
|
DoubleQuotes : TQuoteChars = ('"','"');
|
|
DoubleQuotes : TQuoteChars = ('"','"');
|
|
LogAllEvents = [detCustom, detPrepare, detExecute, detFetch, detCommit, detRollBack];
|
|
LogAllEvents = [detCustom, detPrepare, detExecute, detFetch, detCommit, detRollBack];
|
|
- StatementTokens : Array[TStatementType] of string = ('(none)', 'select',
|
|
|
|
|
|
+ StatementTokens : Array[TStatementType] of string = ('(unknown)', 'select',
|
|
'insert', 'update', 'delete',
|
|
'insert', 'update', 'delete',
|
|
'create', 'get', 'put', 'execute',
|
|
'create', 'get', 'put', 'execute',
|
|
'start','commit','rollback', '?'
|
|
'start','commit','rollback', '?'
|
|
@@ -542,9 +542,10 @@ var T : TStatementType;
|
|
|
|
|
|
begin
|
|
begin
|
|
S:=Lowercase(s);
|
|
S:=Lowercase(s);
|
|
- For t:=stselect to strollback do
|
|
|
|
- if (S=StatementTokens[t]) then
|
|
|
|
- Exit(t);
|
|
|
|
|
|
+ for T:=stSelect to stRollback do
|
|
|
|
+ if (S=StatementTokens[T]) then
|
|
|
|
+ Exit(T);
|
|
|
|
+ Result:=stUnknown;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TSQLConnection.SetTransaction(Value : TSQLTransaction);
|
|
procedure TSQLConnection.SetTransaction(Value : TSQLTransaction);
|
|
@@ -621,7 +622,7 @@ begin
|
|
DatabaseError(SErrNoStatement);
|
|
DatabaseError(SErrNoStatement);
|
|
|
|
|
|
Cursor := AllocateCursorHandle;
|
|
Cursor := AllocateCursorHandle;
|
|
- Cursor.FStatementType := stNone;
|
|
|
|
|
|
+ Cursor.FStatementType := stUnknown;
|
|
PrepareStatement(cursor,ATransaction,SQL,Nil);
|
|
PrepareStatement(cursor,ATransaction,SQL,Nil);
|
|
execute(cursor,ATransaction, Nil);
|
|
execute(cursor,ATransaction, Nil);
|
|
UnPrepareStatement(Cursor);
|
|
UnPrepareStatement(Cursor);
|
|
@@ -1218,7 +1219,7 @@ end;
|
|
|
|
|
|
function TCustomSQLQuery.SQLParser(const ASQL : string) : TStatementType;
|
|
function TCustomSQLQuery.SQLParser(const ASQL : string) : TStatementType;
|
|
|
|
|
|
-type TParsePart = (ppStart,ppSelect,ppWhere,ppFrom,ppOrder,ppComment,ppGroup,ppBogus);
|
|
|
|
|
|
+type TParsePart = (ppStart,ppWith,ppSelect,ppFrom,ppWhere,ppGroup,ppOrder,ppComment,ppBogus);
|
|
|
|
|
|
Var
|
|
Var
|
|
PSQL,CurrentP,
|
|
PSQL,CurrentP,
|
|
@@ -1248,13 +1249,13 @@ begin
|
|
begin
|
|
begin
|
|
inc(CurrentP);
|
|
inc(CurrentP);
|
|
|
|
|
|
- EndOfComment := SkipComments(CurrentP,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions);
|
|
|
|
- if EndOfcomment then dec(currentp);
|
|
|
|
|
|
+ EndOfComment := SkipComments(CurrentP, sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions);
|
|
|
|
+ if EndOfcomment then dec(CurrentP);
|
|
if EndOfComment and (ParsePart = ppStart) then PhraseP := CurrentP;
|
|
if EndOfComment and (ParsePart = ppStart) then PhraseP := CurrentP;
|
|
|
|
|
|
// skip everything between bracket, since it could be a sub-select, and
|
|
// skip everything between bracket, since it could be a sub-select, and
|
|
// further nothing between brackets could be interesting for the parser.
|
|
// further nothing between brackets could be interesting for the parser.
|
|
- if currentp^='(' then
|
|
|
|
|
|
+ if CurrentP^='(' then
|
|
begin
|
|
begin
|
|
inc(currentp);
|
|
inc(currentp);
|
|
BracketCount := 0;
|
|
BracketCount := 0;
|
|
@@ -1279,10 +1280,25 @@ begin
|
|
case ParsePart of
|
|
case ParsePart of
|
|
ppStart : begin
|
|
ppStart : begin
|
|
Result := TSQLConnection(Database).StrToStatementType(s);
|
|
Result := TSQLConnection(Database).StrToStatementType(s);
|
|
- if s = 'SELECT' then ParsePart := ppSelect else break;
|
|
|
|
|
|
+ case s of
|
|
|
|
+ 'WITH' : ParsePart := ppWith;
|
|
|
|
+ 'SELECT': ParsePart := ppSelect;
|
|
|
|
+ else break;
|
|
|
|
+ end;
|
|
if not FParseSQL then break;
|
|
if not FParseSQL then break;
|
|
PStatementPart := CurrentP;
|
|
PStatementPart := CurrentP;
|
|
end;
|
|
end;
|
|
|
|
+ ppWith : begin
|
|
|
|
+ // WITH [RECURSIVE] CTE_name [ ( column_names ) ] AS ( CTE_query_definition ) [, ...]
|
|
|
|
+ // { SELECT | INSERT | UPDATE | DELETE } ...
|
|
|
|
+ case s of
|
|
|
|
+ 'SELECT': Result := stSelect;
|
|
|
|
+ 'INSERT': Result := stInsert;
|
|
|
|
+ 'UPDATE': Result := stUpdate;
|
|
|
|
+ 'DELETE': Result := stDelete;
|
|
|
|
+ end;
|
|
|
|
+ if Result <> stUnknown then break;
|
|
|
|
+ end;
|
|
ppSelect : begin
|
|
ppSelect : begin
|
|
if s = 'FROM' then
|
|
if s = 'FROM' then
|
|
begin
|
|
begin
|
|
@@ -1323,7 +1339,7 @@ begin
|
|
begin
|
|
begin
|
|
Setlength(FFromPart,StrLength);
|
|
Setlength(FFromPart,StrLength);
|
|
Move(PStatementPart^,FFromPart[1],(StrLength));
|
|
Move(PStatementPart^,FFromPart[1],(StrLength));
|
|
- FFrompart := trim(FFrompart);
|
|
|
|
|
|
+ FFromPart := trim(FFromPart);
|
|
|
|
|
|
// Meta-data requests and are never updateable select-statements
|
|
// Meta-data requests and are never updateable select-statements
|
|
// from more then one table are not updateable
|
|
// from more then one table are not updateable
|
|
@@ -1749,8 +1765,10 @@ end;
|
|
function TCustomSQLQuery.GetStatementType : TStatementType;
|
|
function TCustomSQLQuery.GetStatementType : TStatementType;
|
|
|
|
|
|
begin
|
|
begin
|
|
- if assigned(FCursor) then Result := FCursor.FStatementType
|
|
|
|
- else Result := stNone;
|
|
|
|
|
|
+ if assigned(FCursor) then
|
|
|
|
+ Result := FCursor.FStatementType
|
|
|
|
+ else
|
|
|
|
+ Result := stUnknown;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TCustomSQLQuery.SetDeleteSQL(const AValue: TStringlist);
|
|
procedure TCustomSQLQuery.SetDeleteSQL(const AValue: TStringlist);
|
|
@@ -1996,7 +2014,7 @@ begin
|
|
inherited DoInternalConnect;
|
|
inherited DoInternalConnect;
|
|
CreateProxy;
|
|
CreateProxy;
|
|
FProxy.CharSet:=Self.CharSet;
|
|
FProxy.CharSet:=Self.CharSet;
|
|
- FProxy.Role:=self.Role;
|
|
|
|
|
|
+ FProxy.Role:=Self.Role;
|
|
FProxy.DatabaseName:=Self.DatabaseName;
|
|
FProxy.DatabaseName:=Self.DatabaseName;
|
|
FProxy.HostName:=Self.HostName;
|
|
FProxy.HostName:=Self.HostName;
|
|
FProxy.UserName:=Self.UserName;
|
|
FProxy.UserName:=Self.UserName;
|