I believe I have found an SQL generation issue and possibly a missing feature (or I just can't figure out how to find an existing feature).
(SmartClient Version: v12.1p_2021-07-15/PowerEdition Deployment (built 2021-07-15))
For background and understanding:
For a given Test Bench I want to grab associated name value pairs of "extra data" in the form "Parent2.Partent1.Name", "Value X". The nested name construction is accomplished via a self referencing names table and a custom select expression that concatenates the first few nested names together separated by periods. IncludeFrom Parent fields are referenced in the custom select expression. They join in instances of the self referencing names tables. A Values table holds values and points to their associated first level name. A Bench table is also pointed to in order to group values within a certain bench.
As a Bench Name can exist under multiple revisions, I have to group on the Bench Name in order to get all of the unique name value pairs.
The issue:
I need to create Server side DMI code but I can't get it to generate valid SQL. i.e.
1) The SQL generated for the example query is correct EXCEPT for the GROUP BY clause. I believe this could be a bug related to includes and customSelect expressions. That GROUP BY clause contains not only the customSelectExpression needed for the NestedName field but also an extra comma and the NestedName field's <Table>.<name> expression. Essentially, for the GROUP BY clause generated, it looks like the field is included twice in two different ways .
Extra credit:
2) I want to create that same query but without the need to include the dependent Parent1, Parent2 and Parent3 fields in the output . I found that when creating that query, I have to set the dSRequest outputs and groupby to include the dependent Parent1, Parent2 and Parent3 fields in order to have smartGWT generate the JOIN clauses for those include fields. Is there a way to construct the DSRequest without needing explicit knowledge of Parent to NestedName dependency? What I'm looking for is some sort of DSField attribute or something that I can set on the NestedName fields to let smartGWT know that it depends on the Parent fields. That way smartGWT would generate the Parent fields SQL when the NestedName field was involved in the query. i.e. an DSField attribute like fieldDependencies="Parent1_Name, Parent2_Name, Parent3_Name" that I may have missed?
Here are the two DataSources, and the smartGWT generated SQL code resulting from the DSRequest. The mystery generated code, that throws exceptions, has been commented out. Without it, the query executes as intended.
Generated code:
(SmartClient Version: v12.1p_2021-07-15/PowerEdition Deployment (built 2021-07-15))
For background and understanding:
For a given Test Bench I want to grab associated name value pairs of "extra data" in the form "Parent2.Partent1.Name", "Value X". The nested name construction is accomplished via a self referencing names table and a custom select expression that concatenates the first few nested names together separated by periods. IncludeFrom Parent fields are referenced in the custom select expression. They join in instances of the self referencing names tables. A Values table holds values and points to their associated first level name. A Bench table is also pointed to in order to group values within a certain bench.
As a Bench Name can exist under multiple revisions, I have to group on the Bench Name in order to get all of the unique name value pairs.
The issue:
I need to create Server side DMI code but I can't get it to generate valid SQL. i.e.
Code:
DSRequest edDsRequest = new DSRequest("TestExtraDataValuesNamesBenchView", "fetch"); edDsRequest.setTextMatchStyle("exactCase"); edDsRequest.setAdvancedCriteria(advCrit); // criteria that filters by Bench Name String[] fieldNames = {"PK_Test_ExtraData_Names", "Name", "Parent1_Name", "Parent2_Name", "Parent3_Name", "NestedName", "BenchName"}; edDsRequest.setOutputs(Arrays.asList(fieldNames)); edDsRequest.setGroupBy(fieldNames); DSResponse resp = edDsRequest.execute();
1) The SQL generated for the example query is correct EXCEPT for the GROUP BY clause. I believe this could be a bug related to includes and customSelect expressions. That GROUP BY clause contains not only the customSelectExpression needed for the NestedName field but also an extra comma and the NestedName field's <Table>.<name> expression. Essentially, for the GROUP BY clause generated, it looks like the field is included twice in two different ways .
Extra credit:
2) I want to create that same query but without the need to include the dependent Parent1, Parent2 and Parent3 fields in the output . I found that when creating that query, I have to set the dSRequest outputs and groupby to include the dependent Parent1, Parent2 and Parent3 fields in order to have smartGWT generate the JOIN clauses for those include fields. Is there a way to construct the DSRequest without needing explicit knowledge of Parent to NestedName dependency? What I'm looking for is some sort of DSField attribute or something that I can set on the NestedName fields to let smartGWT know that it depends on the Parent fields. That way smartGWT would generate the Parent fields SQL when the NestedName field was involved in the query. i.e. an DSField attribute like fieldDependencies="Parent1_Name, Parent2_Name, Parent3_Name" that I may have missed?
Here are the two DataSources, and the smartGWT generated SQL code resulting from the DSRequest. The mystery generated code, that throws exceptions, has been commented out. Without it, the query executes as intended.
Code:
<DataSource ID="TestExtraDataValuesNamesBenchView" serverType="sql" tableName="Test_ExtraData_Values"> <fields> <!-- ================================================================================ Text_ExtraData_Values fields ================================================================================ --> <field name="PK_Test_ExtraData_Values" type="sequence" width="60" primaryKey="true" /> <field name="FK_Test_ExtraData_Names" type="integer" hidden="true" width="60" foreignKey="TestExtraDataNamesBenchView.PK_Test_ExtraData_Names" /> <field name="String" type="text" length="999" width="300" title="String Value" /> <!-- ================================================================================ Included fields from the ExtraData Names view . The Parent/GrandParent/GreatGrandParent fields are included to bring in the joins to form the NestedNames field. ================================================================================ --> <field includeFrom="TestExtraDataNamesBenchView.BenchName" /> <field includeFrom="TestExtraDataNamesBenchView.PK_Test_ExtraData_Names" /> <field includeFrom="TestExtraDataNamesBenchView.Name" /> <field includeFrom="TestExtraDataNamesBenchView.Parent1_Name" /> <field includeFrom="TestExtraDataNamesBenchView.Parent2_Name" /> <field includeFrom="TestExtraDataNamesBenchView.Parent3_Name" /> <field includeFrom="TestExtraDataNamesBenchView.NestedName" /> </fields> </DataSource>
Code:
<DataSource ID="TestExtraDataNamesBenchView" serverType="sql" tableName="Test_ExtraData_Names"> <fields> <!-- ================================================================================ Text_ExtraData_Names fields ================================================================================ --> <field name="PK_Test_ExtraData_Names" type="sequence" width="60" primaryKey="true" /> <field name="Name" type="text" width="150" length="63" title="Name" /> <field name="FK_Test_Bench" type="integer" width="100" hidden="true" title="Test_Bench FK" foreignKey="Test_Bench.PK_Test_Bench" /> <field name="FK_Test_ExtraData_Names" type="integer" width="120" hidden="true" title="Self referencing FK" foreignKey="TestExtraDataNamesBenchView.PK_Test_ExtraData_Names" relatedTableAlias="EDTBLX" joinType="outer" /> <field includeFrom="Test_Bench.BenchName" /> <field name="Parent1_Name" title="Parent1 Name" includeFrom="TestExtraDataNamesBenchView.Name" /> <field name="Parent2_Name" title="Parent2 Name" includeFrom="TestExtraDataNamesBenchView.TestExtraDataNamesBenchView.Name" /> <field name="Parent3_Name" title="Parent3 Name" includeFrom="TestExtraDataNamesBenchView.TestExtraDataNamesBenchView.TestExtraDataNamesBenchView.Name" /> <field name="NestedName" type="text" length="63" width="100" title="Nested ExtraData Name" customSelectExpression=" CASE WHEN EDTBLX_EDTBLX_EDTBLX.FK_Test_ExtraData_Names IS NOT NULL THEN '[...].' + EDTBLX_EDTBLX_EDTBLX.Name + '.' + EDTBLX_EDTBLX.Name + '.' + EDTBLX.Name + '.' + Test_ExtraData_Names.Name WHEN EDTBLX_EDTBLX.FK_Test_ExtraData_Names IS NOT NULL THEN EDTBLX_EDTBLX_EDTBLX.Name + '.' + EDTBLX_EDTBLX.Name + '.' + EDTBLX.Name + '.' + Test_ExtraData_Names.Name WHEN EDTBLX_EDTBLX.Name IS NOT NULL THEN EDTBLX_EDTBLX.Name + '.' + EDTBLX.Name + '.' + Test_ExtraData_Names.Name WHEN EDTBLX.Name IS NOT NULL THEN EDTBLX.Name + '.' + Test_ExtraData_Names.Name ELSE Test_ExtraData_Names.Name END " /> </fields> </DataSource>
Generated code:
Code:
SELECT Test_ExtraData_Names.PK_Test_ExtraData_Names, Test_ExtraData_Names.Name, EDTBLX.Name AS Parent1_Name, EDTBLX_EDTBLX.Name AS Parent2_Name, EDTBLX_EDTBLX_EDTBLX.Name AS Parent3_Name, Test_Bench.BenchName, CASE WHEN EDTBLX_EDTBLX_EDTBLX.FK_Test_ExtraData_Names IS NOT NULL THEN '[...].' + EDTBLX_EDTBLX_EDTBLX.Name + '.' + EDTBLX_EDTBLX.Name + '.' + EDTBLX.Name + '.' + Test_ExtraData_Names.Name WHEN EDTBLX_EDTBLX.FK_Test_ExtraData_Names IS NOT NULL THEN EDTBLX_EDTBLX_EDTBLX.Name + '.' + EDTBLX_EDTBLX.Name + '.' + EDTBLX.Name + '.' + Test_ExtraData_Names.Name WHEN EDTBLX_EDTBLX.Name IS NOT NULL THEN EDTBLX_EDTBLX.Name + '.' + EDTBLX.Name + '.' + Test_ExtraData_Names.Name WHEN EDTBLX.Name IS NOT NULL THEN EDTBLX.Name + '.' + Test_ExtraData_Names.Name ELSE Test_ExtraData_Names.Name END AS NestedName, FROM Test_ExtraData_Values JOIN Test_ExtraData_Names ON Test_ExtraData_Values.FK_Test_ExtraData_Names = Test_ExtraData_Names.PK_Test_ExtraData_Names LEFT OUTER JOIN Test_ExtraData_Names EDTBLX ON Test_ExtraData_Names.FK_Test_ExtraData_Names = EDTBLX.PK_Test_ExtraData_Names LEFT OUTER JOIN Test_ExtraData_Names EDTBLX_EDTBLX ON EDTBLX.FK_Test_ExtraData_Names = EDTBLX_EDTBLX.PK_Test_ExtraData_Names LEFT OUTER JOIN Test_ExtraData_Names EDTBLX_EDTBLX_EDTBLX ON EDTBLX_EDTBLX.FK_Test_ExtraData_Names = EDTBLX_EDTBLX_EDTBLX.PK_Test_ExtraData_Names JOIN Test_Bench ON Test_ExtraData_Names.FK_Test_Bench = Test_Bench.PK_Test_Bench WHERE ( Test_Bench.BenchName = 'Memsys FW Bench' AND Test_Bench.BenchName IS NOT NULL ) GROUP BY Test_ExtraData_Names.PK_Test_ExtraData_Names, Test_ExtraData_Names.Name, EDTBLX.Name, EDTBLX_EDTBLX.Name, EDTBLX_EDTBLX_EDTBLX.Name, Test_Bench.BenchName, CASE WHEN EDTBLX_EDTBLX_EDTBLX.FK_Test_ExtraData_Names IS NOT NULL THEN '[...].' + EDTBLX_EDTBLX_EDTBLX.Name + '.' + EDTBLX_EDTBLX.Name + '.' + EDTBLX.Name + '.' + Test_ExtraData_Names.Name WHEN EDTBLX_EDTBLX.FK_Test_ExtraData_Names IS NOT NULL THEN EDTBLX_EDTBLX_EDTBLX.Name + '.' + EDTBLX_EDTBLX.Name + '.' + EDTBLX.Name + '.' + Test_ExtraData_Names.Name WHEN EDTBLX_EDTBLX.Name IS NOT NULL THEN EDTBLX_EDTBLX.Name + '.' + EDTBLX.Name + '.' + Test_ExtraData_Names.Name WHEN EDTBLX.Name IS NOT NULL THEN EDTBLX.Name + '.' + Test_ExtraData_Names.Name ELSE Test_ExtraData_Names.Name END --, -- Test_ExtraData_Names.NestedName
Comment