@@ -1806,15 +1806,13 @@ DmlNode* DeclareLocalTableNode::parse(thread_db* tdbb, MemoryPool& pool, Compile
18061806 node->format = Format::newFormat (pool, fieldCount);
18071807 node->format ->fmt_length = FLAG_BYTES (fieldCount);
18081808 node->notNullFields .grow (fieldCount);
1809- node->fieldNames .grow (fieldCount);
18101809
18111810 for (USHORT fieldNum = 0 ; fieldNum < fieldCount; ++fieldNum)
18121811 {
18131812 dsc& fmtDesc = node->format ->fmt_desc [fieldNum];
18141813 ItemInfo itemInfo;
18151814 PAR_desc (tdbb, csb, &fmtDesc, &itemInfo);
18161815 node->notNullFields [fieldNum] = !itemInfo.nullable ;
1817- blrReader.getMetaName (node->fieldNames [fieldNum]);
18181816
18191817 if (fmtDesc.dsc_dtype >= dtype_aligned)
18201818 node->format ->fmt_length = FB_ALIGN (node->format ->fmt_length , type_alignments[fmtDesc.dsc_dtype ]);
@@ -1825,11 +1823,31 @@ DmlNode* DeclareLocalTableNode::parse(thread_db* tdbb, MemoryPool& pool, Compile
18251823
18261824 break ;
18271825
1826+ case blr_dcl_local_table_field_names:
1827+ {
1828+ if (node->fieldNames .hasData ())
1829+ PAR_error (csb, Arg::Gds (isc_random) << " duplicate local table field names" );
1830+
1831+ const USHORT nameCount = blrReader.getWord ();
1832+ node->fieldNames .grow (nameCount);
1833+
1834+ for (USHORT fieldNum = 0 ; fieldNum < nameCount; ++fieldNum)
1835+ blrReader.getMetaName (node->fieldNames [fieldNum]);
1836+
1837+ break ;
1838+ }
1839+
18281840 default :
18291841 PAR_error (csb, Arg::Gds (isc_random) << " Invalid blr_dcl_local_table sub code" );
18301842 }
18311843 }
18321844
1845+ if (node->fieldNames .hasData () && node->fieldNames .getCount () != fieldCount)
1846+ {
1847+ PAR_error (csb, Arg::Gds (isc_random) <<
1848+ " Local table field names count does not match format field count" );
1849+ }
1850+
18331851 if (fieldCount == 0 )
18341852 PAR_error (csb, Arg::Gds (isc_random) << " Local table without fields" );
18351853
@@ -1986,14 +2004,19 @@ void DeclareLocalTableNode::genBlr(DsqlCompilerScratch* dsqlScratch)
19862004 for (auto field = dsqlRelation->rel_fields ; field; field = field->fld_next )
19872005 ++fieldCount;
19882006
2007+ // Format layout: count + descriptors only.
19892008 dsqlScratch->appendUChar (blr_dcl_local_table_format);
19902009 dsqlScratch->appendUShort (fieldCount);
19912010
19922011 for (auto field = dsqlRelation->rel_fields ; field; field = field->fld_next )
1993- {
19942012 dsqlScratch->putType (field, true );
2013+
2014+ // Field names are optional and use a separate subcode.
2015+ dsqlScratch->appendUChar (blr_dcl_local_table_field_names);
2016+ dsqlScratch->appendUShort (fieldCount);
2017+
2018+ for (auto field = dsqlRelation->rel_fields ; field; field = field->fld_next )
19952019 dsqlScratch->appendNullString (field->fld_name .c_str ());
1996- }
19972020
19982021 dsqlScratch->appendUChar (blr_end);
19992022 }
@@ -2114,7 +2137,12 @@ jrd_rel* DeclareLocalTableNode::getRelation(thread_db* tdbb, Request* request) c
21142137
21152138 auto & field = (*newRelation->rel_fields )[i];
21162139 field = FB_NEW_POOL (pool) jrd_fld (pool);
2117- field->fld_name .printf (" FIELD_%" SIZEFORMAT , i + 1 );
2140+
2141+ if (i < fieldNames.getCount () && fieldNames[i].hasData ())
2142+ field->fld_name = fieldNames[i];
2143+ else
2144+ field->fld_name .printf (" FIELD_%" SIZEFORMAT , i + 1 );
2145+
21182146 field->fld_length = relFormat->fmt_desc [i].dsc_length ;
21192147 field->fld_pos = i;
21202148 field->fld_flags = notNullFields[i] ? FLD_not_null : 0 ;
0 commit comments