Let ParseRoutineStructure() cache values from IS.ROUTINES into TDBObject members. Fixes issue #3108.

This commit is contained in:
Ansgar Becker
2013-02-21 11:19:44 +00:00
parent 53c9553c5b
commit fc015e61bd
3 changed files with 42 additions and 41 deletions

View File

@ -27,9 +27,14 @@ type
function GetCreateCode: String;
procedure SetCreateCode(Value: String);
public
// Table options:
Name, Database, Column, Engine, Comment, RowFormat, CreateOptions, Collation: String;
Created, Updated, LastChecked: TDateTime;
Rows, Size, Version, AvgRowLen, MaxDataLen, IndexLen, DataLen, DataFree, AutoInc, CheckSum: Int64;
// Routine options:
Body, Definer, Returns, DataAccess, Security: String;
Deterministic: Boolean;
NodeType, GroupType: TListNodeType;
constructor Create(OwnerConnection: TDBConnection);
procedure Assign(Source: TPersistent); override;
@ -332,8 +337,7 @@ type
procedure ParseTableStructure(CreateTable: String; Columns: TTableColumnList; Keys: TTableKeyList; ForeignKeys: TForeignKeyList);
procedure ParseViewStructure(CreateCode, ViewName: String; Columns: TTableColumnList;
var Algorithm, Definer, SQLSecurity, CheckOption, SelectCode: String);
procedure ParseRoutineStructure(Obj: TDBObject; Parameters: TRoutineParamList;
var Deterministic: Boolean; var Definer, Returns, DataAccess, Security, Comment, Body: String);
procedure ParseRoutineStructure(Obj: TDBObject; Parameters: TRoutineParamList);
function GetDatatypeByName(Datatype: String): TDBDatatype;
function ApplyLimitClause(QueryType, QueryBody: String; Limit, Offset: Cardinal): String;
property Parameters: TConnectionParameters read FParameters write FParameters;
@ -3422,8 +3426,7 @@ begin
end;
procedure TDBConnection.ParseRoutineStructure(Obj: TDBObject; Parameters: TRoutineParamList;
var Deterministic: Boolean; var Definer, Returns, DataAccess, Security, Comment, Body: String);
procedure TDBConnection.ParseRoutineStructure(Obj: TDBObject; Parameters: TRoutineParamList);
var
CreateCode, Params: String;
ParenthesesCount: Integer;
@ -3469,6 +3472,7 @@ begin
end;
rx.Free;
if Obj.Body = '' then begin
// Get everything else from information_schema.
// See http://www.heidisql.com/forum.php?t=12075
// See issue #3114
@ -3480,13 +3484,14 @@ begin
' AND '+QuoteIdent('ROUTINE_NAME')+'='+EscapeString(Obj.Name)+
' AND '+QuoteIdent('ROUTINE_TYPE')+'='+EscapeString(UpperCase(Obj.ObjType))
);
Body := FromIS.Col('ROUTINE_DEFINITION');
Definer := FromIS.Col('DEFINER');
Returns := FromIS.Col('DTD_IDENTIFIER');
Deterministic := FromIS.Col('IS_DETERMINISTIC') = 'YES';
DataAccess := FromIS.Col('SQL_DATA_ACCESS');
Security := FromIS.Col('SECURITY_TYPE');
Comment := FromIS.Col('ROUTINE_COMMENT');
Obj.Body := FromIS.Col('ROUTINE_DEFINITION');
Obj.Definer := FromIS.Col('DEFINER');
Obj.Returns := FromIS.Col('DTD_IDENTIFIER');
Obj.Deterministic := FromIS.Col('IS_DETERMINISTIC') = 'YES';
Obj.DataAccess := FromIS.Col('SQL_DATA_ACCESS');
Obj.Security := FromIS.Col('SECURITY_TYPE');
Obj.Comment := FromIS.Col('ROUTINE_COMMENT');
end;
end;

View File

@ -3279,9 +3279,8 @@ end;
procedure TMainForm.actRunRoutinesExecute(Sender: TObject);
var
Tab: TQueryTab;
Query, ParamValues, ParamValue, DummyStr: String;
Query, ParamValues, ParamValue: String;
Params: TStringList;
DummyBool: Boolean;
pObj: PDBObject;
Obj: TDBObject;
Objects: TDBObjectList;
@ -3318,7 +3317,7 @@ begin
Query := 'EXEC ';
end;
Parameters := TRoutineParamList.Create;
Obj.Connection.ParseRoutineStructure(Obj, Parameters, DummyBool, DummyStr, DummyStr, DummyStr, DummyStr, DummyStr, DummyStr);
Obj.Connection.ParseRoutineStructure(Obj, Parameters);
Query := Query + Obj.QuotedName;
Params := TStringList.Create;
for Param in Parameters do begin
@ -5058,11 +5057,10 @@ var
LeftText, Identifier: String;
rx: TRegExpr;
i: Integer;
DummyBool: Boolean;
DbObjects: TDBObjectList;
DbObj: TDbObject;
Params: TRoutineParamList;
ItemText, DummyStr: String;
ItemText: String;
Prop: TSynCompletionProposal;
begin
// Display hint on function and procedure parameters
@ -5092,7 +5090,7 @@ begin
for DbObj in DbObjects do begin
if (CompareText(DbObj.Name, Identifier)=0) and (DbObj.NodeType in [lntFunction, lntProcedure]) then begin
Params := TRoutineParamList.Create(True);
DbObj.Connection.ParseRoutineStructure(DbObj, Params, DummyBool, DummyStr, DummyStr, DummyStr, DummyStr, DummyStr, DummyStr);
DbObj.Connection.ParseRoutineStructure(DbObj, Params);
ItemText := '';
for i:=0 to Params.Count-1 do
ItemText := ItemText + '"' + Params[i].Name + ': ' + Params[i].Datatype + '", ';

View File

@ -132,8 +132,6 @@ end;
procedure TfrmRoutineEditor.Init(Obj: TDBObject);
var
Definer, Returns, DataAccess, Security, Comment, Body: String;
Deterministic: Boolean;
i: Integer;
begin
inherited;
@ -162,19 +160,19 @@ begin
lntProcedure: comboType.ItemIndex := 0;
lntFunction: comboType.ItemIndex := 1;
end;
DBObject.Connection.ParseRoutineStructure(Obj, Parameters, Deterministic, Definer, Returns, DataAccess, Security, Comment, Body);
comboReturns.Text := Returns;
chkDeterministic.Checked := Deterministic;
if DataAccess <> '' then
comboDataAccess.ItemIndex := comboDataAccess.Items.IndexOf(DataAccess);
if Security <> '' then
comboSecurity.ItemIndex := comboSecurity.Items.IndexOf(Security);
editComment.Text := Comment;
comboDefiner.Text := Definer;
DBObject.Connection.ParseRoutineStructure(Obj, Parameters);
comboReturns.Text := Obj.Returns;
chkDeterministic.Checked := Obj.Deterministic;
if Obj.DataAccess <> '' then
comboDataAccess.ItemIndex := comboDataAccess.Items.IndexOf(Obj.DataAccess);
if Obj.Security <> '' then
comboSecurity.ItemIndex := comboSecurity.Items.IndexOf(Obj.Security);
editComment.Text := Obj.Comment;
comboDefiner.Text := Obj.Definer;
// The whole CREATE CODE may be empty if the user is not allowed to view code in SHOW CREATE FUNCTION
// => Disable the whole editor in this case.
SynMemoBody.Text := Body;
lblDisabledWhy.Visible := Body = '';
SynMemoBody.Text := Obj.Body;
lblDisabledWhy.Visible := Obj.Body = '';
PageControlMain.Enabled := not lblDisabledWhy.Visible;
SynMemoBody.Enabled := PageControlMain.Enabled;
end else begin