This is a static copy of a profile report

Home

tabular.subsasgnDot (Calls: 8, Time: 0.029 s)
Generated 16-Jul-2020 17:09:53 using performance time.
function in file /Applications/MATLAB_R2020a.app/toolbox/matlab/datatypes/tabular/@tabular/subsasgnDot.m
Copy to new window for comparing multiple runs

Parents (calling functions)

Function NameFunction TypeCalls
tabular.subsasgnfunction8
Lines where the most time was spent

Line NumberCodeCallsTotal Time% TimeTime Plot
68
t = t.setProperty(s(2:end),b);
80.022 s77.2%
60
if ~deleting && t.varD...
80.003 s8.8%
55
varIndex = find(strcmp(varName...
80.001 s1.9%
63
if strcmp(varName,'Properties'...
80.000 s1.4%
85
return
80.000 s1.3%
All other lines  0.003 s9.4%
Totals  0.029 s100% 
Children (called functions)

Function NameFunction TypeCallsTotal Time% TimeTime Plot
tabular.setPropertyfunction80.021 s71.4%
...Dim>varNamesDim.checkReservedNamesclass method80.002 s5.6%
Self time (built-ins, overhead, etc.)  0.007 s23.1%
Totals  0.029 s100% 
Code Analyzer results
No Code Analyzer messages.
Coverage results
Show coverage for parent directory
Total lines in function478
Non-code lines (comments, blank lines)208
Code lines (lines that can run)270
Code lines that did run22
Code lines that did not run248
Coverage (did run/can run)8.15 %
Function listing
time 
Calls 
 line
   1 
function t = subsasgnDot(t,s,b,deleting)
   2 
%SUBSASGNDOT Subscripted assignment to a table.
   3 

   4 
%   Copyright 2012-2019 The MathWorks, Inc.
   5 

   6 
% '.' is assignment to or into a variable.  Any sort of subscripting
   7 
% may follow that, and row labels are inherited from the table.
   8 

   9 
import matlab.internal.datatypes.emptyLike
  10 
import matlab.internal.datatypes.isCharString
  11 
import matlab.internal.datatypes.isColon
  12 
import matlab.internal.datatypes.isScalarInt
  13 
import matlab.lang.correction.ReplaceIdentifierCorrection
  14 
import matlab.lang.internal.move % Avoid unsharing of shared-data copy across function call boundary
< 0.001 
      8 
  15
subsType = matlab.internal.tabular.private.tabularDimension.subsType; % "import" for calls to subs2inds 
  16 

< 0.001 
      8 
  17
if ~isstruct(s), s = substruct('.',s); end 
  18 

  19 
% Check for deletion of entire variables, t.Var = [], or of columns/pages of a variable,
  20 
% t.Var(:,j) = []. deletion deeper that, e.g. t.Var(i).Field(...) = [] or t.Var{i}(...) = [],
  21 
% is handled by the assignment code path.
< 0.001 
      8 
  22
if nargin < 4 
  23 
    % Short-circuit for performance before calling _isEmptySqrBrktLiteral. isequal is
  24 
    % more expensive than isnumeric, but avoids _isEmptySqrBrktLiteral in more cases. For
  25 
    % built-in types, s(2).type=='()' guarantees that length(s)==2, but for a var that is
  26 
    % itself a table, parens need not be the end, so need to check that.
< 0.001 
      8 
  27
    deleting = isnumeric(b) && isequal(b,[]) && builtin('_isEmptySqrBrktLiteral',b) ... 
  28 
        && (isscalar(s) || ((length(s) == 2) && isequal(s(2).type,'()')));
< 0.001 
      8 
  29
end 
  30 

< 0.001 
      8 
  31
t_nrows = t.rowDim.length; 
< 0.001 
      8 
  32
t_nvars = t.varDim.length; 
  33 

  34 
% Translate variable (column) name into an index. Avoid overhead of
  35 
% t.varDim.subs2inds as much as possible in this simple case.
< 0.001 
      8 
  36
varName = convertStringsToChars(s(1).subs); 
< 0.001 
      8 
  37
if isnumeric(varName) 
  38 
    % Allow t.(i) where i is an integer
  39 
    varIndex = varName;
  40 
    if ~isScalarInt(varName,1)
  41 
        error(message('MATLAB:table:IllegalVarIndex'));
  42 
    end
  43 
    isNewVar = (varIndex > t_nvars);
  44 
    if isNewVar
  45 
        if deleting
  46 
            error(message('MATLAB:table:VarIndexOutOfRange'));
  47 
        elseif varIndex > t_nvars+1
  48 
            error(message('MATLAB:table:DiscontiguousVars'));
  49 
        else
  50 
            [~,~,~,~,~,updatedVarDim] = t.varDim.subs2inds(varIndex,subsType.assignment);
  51 
            varName = updatedVarDim.labels{varIndex};
  52 
        end
  53 
    end
< 0.001 
      8 
  54
elseif ischar(varName) && (isrow(varName) || isequal(varName,'')) % isCharString(varName) 
< 0.001 
      8 
  55
    varIndex = find(strcmp(varName,t.varDim.labels)); 
< 0.001 
      8 
  56
    isNewVar = false; % assume for now, update below 
< 0.001 
      8 
  57
    if isempty(varIndex) 
  58 
        % Check against reserved names first as a failsafe against shadowing
  59 
        % .Properties by a dimension name.
  0.003 
      8 
  60
        if ~deleting && t.varDim.checkReservedNames(varName) % one name, don't need to wrap with any() 
  61 
            % Handle assignment to a property under the 'Properties' (virtual)
  62 
            % property, or to the entire 'Properties' property.
< 0.001 
      8 
  63
            if strcmp(varName,'Properties') 
< 0.001 
      8 
  64
                try 
< 0.001 
      8 
  65
                    if isscalar(s) 
  66 
                        t = setProperties(t,b);
< 0.001 
      8 
  67
                    else 
  0.022 
      8 
  68
                        t = t.setProperty(s(2:end),b); 
< 0.001 
      8 
  69
                    end 
  70 
                catch ME
  71 
                    if ~isscalar(s) && strcmp(ME.identifier,'MATLAB:table:UnknownProperty')
  72 
                        propName = s(2).subs;
  73 
                        match = find(strcmpi(propName,t.propertyNames),1);
  74 
                        if ~isempty(match) % a property name. but with wrong case
  75 
                            match = t.propertyNames{match};
  76 
                            throw(MException(message('MATLAB:table:UnknownPropertyCase',propName,match)) ...
  77 
                            	.addCorrection(ReplaceIdentifierCorrection(propName,match)));
  78 
                        else
  79 
                            throw(ME);
  80 
                        end
  81 
                    else
  82 
                        throw(ME);
  83 
                    end
< 0.001 
      8 
  84
                end 
< 0.001 
      8 
  85
                return 
  86 
            elseif isColon(varName)
  87 
                error(message('MATLAB:table:ReservedVarnameColon'))                
  88 
            else % t.VariableNames or t.RowNames
  89 
                throw(MException(message('MATLAB:table:InvalidPropertyAssignment',varName)) ...
  90 
                	.addCorrection(ReplaceIdentifierCorrection(varName,append('Properties.',varName))));
  91 
            end
  92 
        elseif strcmp(varName,t.metaDim.labels{1})
  93 
            % If it's the row dimension name, assign to the row labels
  94 
            varIndex = 0;
  95 
            % For assignments onto the row labels, accept any vector. For assignments
  96 
            % into, leave the RHS alone.
  97 
            if isscalar(s)
  98 
                if isvector(b), b = b(:); end
  99 
            elseif deleting % && ~isscalar(s)
 100 
                error(message('MATLAB:table:NestedSubscriptingWithDotRowsDeletion',t.metaDim.labels{1}));
 101 
            end
 102 
        elseif strcmp(varName,t.metaDim.labels{2})
 103 
            % If it's the vars dimension name, assign to t{:,:}. Deeper subscripting
 104 
            % is not supported, use explicit braces for that.
 105 
            if ~isscalar(s)
 106 
                error(message('MATLAB:table:NestedSubscriptingWithDotVariables',t.metaDim.labels{2}));
 107 
            end
 108 
            varIndex = -1;
 109 
        elseif deleting
 110 
            error(message('MATLAB:table:UnrecognizedVarNameDeleting',varName));
 111 
        else
 112 
            isNewVar = true;
 113 
            t.varDim.makeValidName(varName,'error'); % error if invalid
 114 

 115 
            % If this is a new variable, it will go at the end. Its name is guaranteed
 116 
            % to not conflict; it it did, we'd be assigning to an existing var.
 117 
            varIndex = t_nvars + 1;
 118 
            updatedVarDim = t.varDim.lengthenTo(varIndex,{varName});
 119 
        end
 120 
    end
 121 
else
 122 
    error(message('MATLAB:table:IllegalVarSubscript'));
 123 
end
 124 

 125 
% Handle empty assignment intended as deletion of an entire variable or of
 126 
% columns/pages/etc. of a variable.  Deletion of rows in a (single)
 127 
% variable is caught here and not allowed.  Other empty assignment
 128 
% syntaxes may be assignment to cells or may be deletion of things deeper
 129 
% in a non-atomic variable, neither is handled here.
 130 
if deleting
 131 
    % Syntax:  t.var = []
 132 
    %
 133 
    % Delete an entire variable.
 134 
    if isscalar(s)
 135 
        if varIndex > 0
 136 
            t.data(varIndex) = [];
 137 
            t.varDim = t.varDim.deleteFrom(varIndex);
 138 
        elseif varIndex == 0
 139 
            t.rowDim = t.rowDim.removeLabels(); % this might error
 140 
        else % varindex == -1
 141 
            varIndex = 1:t.varDim.length;
 142 
            t.data(varIndex) = [];
 143 
            t.varDim = t.varDim.deleteFrom(varIndex);
 144 
        end
 145 
    % Syntax:  t.var(:,...) = []
 146 
    %          t.var(rowIndices,...) = [] is illegal
 147 
    %
 148 
    % Delete columns/pages/etc. of a variable, with ':' as the first index
 149 
    % in subscript.  This may change the dimensionality of the variable,
 150 
    % but won't change the number of rows because we require ':' as the
 151 
    % first index.
 152 
    else % length(s) == 2
 153 
        % All vars in a table must have the same number of rows, so subscripted assignment
 154 
        % deletion on one var isn't allowed to remove rows: no linear indexing, and the
 155 
        % first subscript in 2- or N-D indexing, and all others except one, must be :.
 156 
        if isscalar(s(2).subs) ...
 157 
                || ~isColon(s(2).subs{1}) ...
 158 
                || all(cellfun(@isColon,s(2).subs))
 159 
            error(message('MATLAB:table:EmptyAssignmentToVariableRows'));
 160 
        end
 161 
        
 162 
        var_j = t.data{varIndex}; t.data{varIndex} = []; % DO NOT separate these calls: necessary to avoid shared copy unsharing
 163 
        if isa(var_j,'tabular')
 164 
                % Use dot method to dispatch to overloaded table subscripting
 165 
                var_j = move(var_j).subsasgnParens(s(2),[],false,true);
 166 
        else
 167 
            var_j(s(2).subs{:}) = [];
 168 
        end
 169 
        t.data{varIndex} = var_j;
 170 
    end
 171 
    
 172 
else
 173 
    updatedRowDim = [];
 174 
    
 175 
    % Syntax:  t.var = b
 176 
    %
 177 
    % Replace an entire variable.  It must have the right number of rows, unless
 178 
    % the LHS is 0x0.
 179 
    if isscalar(s)
 180 
        if size(b,1) ~= t_nrows && (t_nrows+t_nvars > 0)
 181 
            % If the assignment has the wrong number of rows, check for some
 182 
            % common mistakes to suggest what may have been intended
 183 
            if strcmpi(varName,'Properties') && ((isstruct(b) && isscalar(b)) || isa(b,'matlab.tabular.TabularProperties')) 
 184 
                % Things like t.properties = scalarStruct
 185 
                str = getString(message('MATLAB:table:IntendedPropertiesAssignment'));
 186 
                throw(MException(message('MATLAB:table:RowDimensionMismatchSuggest',str)) ...
 187 
                    .addCorrection(ReplaceIdentifierCorrection(varName,'Properties')));
 188 
            else
 189 
                match = find(strcmpi(varName,t.propertyNames),1);
 190 
                if ~isempty(match)
 191 
                    % Things like t.PropertyName = ...
 192 
                    match = t.propertyNames{match};
 193 
                    str = getString(message('MATLAB:table:IntendedPropertyAssignment',match));
 194 
                    throw(MException(message('MATLAB:table:RowDimensionMismatchSuggest',str)) ...
 195 
                    	.addCorrection(ReplaceIdentifierCorrection(varName,append('Properties.', match))));
 196 
                end
 197 
            end
 198 
            % Anything else, no suggestion. No point in checking for a case
 199 
            % insensitive match to an existing var, even with the correct case,
 200 
            % this would still be an illegal assignment
 201 
            error(message('MATLAB:table:RowDimensionMismatch'));
 202 
        end
 203 
        var_j = b;
 204 
        
 205 
    % Syntax:  t.var(rowIndices,...) = b
 206 
    %          t.var{rowIndices,...} = b
 207 
    %          t.var{rowIndices,...} = [] (this is assignment, not deletion)
 208 
    %          t.var.field = b
 209 
    %
 210 
    % Assign to elements in a variable.  Assignment can also be used to
 211 
    % expand the variable's number of rows, or along another dimension.
 212 
    %
 213 
    % Cell indexing, e.g. t.var{rowIndices,...}, or a reference to a
 214 
    % field, e.g. t.var.field, may also be followed by deeper levels of
 215 
    % subscripting. Cannot create a new var implicitly by deeper indexing.
 216 
    else % ~isscalar(s)
 217 
        if isNewVar && (length(s) > 2) && ~isequal(s(2).type,'.')
 218 
            % If the assignment is not to an existing var, check for some common
 219 
            % mistakes to suggest what may have been intended
 220 
            match = matches(t.varDim.labels,varName,'IgnoreCase',true);
 221 
            if any(match)
 222 
                % An existing variable name, but with wrong case
 223 
                match = t.varDim.labels{match};
 224 
                str = getString(message('MATLAB:table:IntendedVarAssignment',match));
 225 
                throw(MException(message('MATLAB:table:InvalidExpansionDotDepthSuggest',str)) ...
 226 
                    .addCorrection(ReplaceIdentifierCorrection(varName,match)));
 227 
            elseif matches(varName,t.metaDim.labels{1},'IgnoreCase',true)
 228 
                % The row dimension name, but with wrong case
 229 
                str = getString(message('MATLAB:table:IntendedRowDimAssignment',t.metaDim.labels{1}));
 230 
                throw(MException(message('MATLAB:table:InvalidExpansionDotDepthSuggest',str)) ...
 231 
                    .addCorrection(ReplaceIdentifierCorrection(varName,t.metaDim.labels{1})));
 232 
            end
 233 
            % Anything else, no suggestion
 234 
            error(message('MATLAB:table:InvalidExpansionDotDepth'));
 235 
        end
 236 
        
 237 
        if isequal(s(2).type,'.') % dot indexing into variable
 238 
            % If the assignment is not to an existing var, check for some common
 239 
            % mistakes to suggest what may have been intended
 240 
            if isNewVar
 241 
                if strcmpi(varName,'Properties') && isCharString(s(2).subs)
 242 
                    % Things like t.properties.name
 243 
                    str = getString(message('MATLAB:table:IntendedPropertiesAssignment'));
 244 
                    throw(MException(message('MATLAB:table:InvalidExpansionDotSuggest',str)) ...
 245 
                        .addCorrection(ReplaceIdentifierCorrection(varName,'Properties')));
 246 
                else
 247 
                    match = matches(t.varDim.labels,varName,'IgnoreCase',true);
 248 
                    if any(match)
 249 
                        % An existing variable name, but with wrong case
 250 
                        match = t.varDim.labels{match};
 251 
                        str = getString(message('MATLAB:table:IntendedVarAssignment',match));
 252 
                        throw(MException(message('MATLAB:table:InvalidExpansionDotSuggest',str)) ...
 253 
                        	.addCorrection(ReplaceIdentifierCorrection(varName,match)));
 254 
                    else
 255 
                        % Anything else, no suggestion
 256 
                        error(message('MATLAB:table:InvalidExpansionDot'));
 257 
                    end
 258 
                end
 259 
            end
 260 
            if varIndex > 0
 261 
                var_j = t.data{varIndex}; t.data{varIndex} = []; % DO NOT separate these calls: necessary to avoid shared copy unsharing
 262 
            elseif varIndex == 0
 263 
                var_j = t.rowDim.labels;
 264 
            else % varIndex == -1
 265 
                assert(false);
 266 
            end
 267 
        else % () or {} subscripting into variable
 268 
            % Initialize a new var, or extract an existing var.
 269 
            if isNewVar
 270 
                % Start the new var out as an Nx0 empty of b's class, with the same
 271 
                % number of rows as the table.
 272 
                if isequal(s(2).type,'{}')
 273 
                    % {} subscripting on the new var indicates it should be a cell
 274 
                    % with contents being assigned.
 275 
                    var_j = cell(t_nrows,0);
 276 
                else
 277 
                    var_j = emptyLike([t_nrows,0],'Like',b);
 278 
                end
 279 
                
 280 
                % If the table has no rows, the new var was initialized as 0x0 and
 281 
                % a colon subscript in the first dim would be misinterpreted. Create
 282 
                % explicit row indices instead.
 283 
                if t_nrows == 0 && isColon(s(2).subs{1})
 284 
                    if t_nvars == 0
 285 
                        % If the table is 0x0, a colon subscript in the first dim should
 286 
                        % mean "height of the RHS". t.rowDim.subs2inds would think ':' means
 287 
                        % "height of t", so create explicit row indices to let it know how
 288 
                        % big : really is.
 289 
                        s(2).subs{1} = 1:size(b,1);
 290 
                    else
 291 
                        % Otherwise, a colon subscript in the first dim should mean "height
 292 
                        % of the table", and the RHS must have matching height. var_j is
 293 
                        % initialized to have t_nrows rows to match the table, but when t_nrows
 294 
                        % is 0, var_j is initialized as 0x0, and var_j's subsasgn would treat
 295 
                        % : as "height of the RHS" and not do the proper size checking. Create
 296 
                        % explicit row indices to make sure the RHS's height is checked.
 297 
                        %
 298 
                        s(2).subs{1} = 1:t_nrows;
 299 
                    end
 300 
                end
 301 
                % If the table has one or more rows, a colon subscript in the first dim always
 302 
                % means "height of the table", and that subscript can be left alone.
 303 
                
 304 
                % Convert any trailing colon subscripts into explicit indices with length
 305 
                % inherited from the RHS.
 306 
                for k = 2:length(s(2).subs)
 307 
                    if isColon(s(2).subs{k})
 308 
                        s(2).subs{k} = 1:size(b,k);
 309 
                    end
 310 
                end
 311 
            else
 312 
                if varIndex > 0
 313 
                    var_j = t.data{varIndex}; t.data{varIndex} = []; % DO NOT separate these calls: necessary to avoid shared copy unsharing
 314 
                elseif varIndex == 0
 315 
                    var_j = t.rowDim.labels;
 316 
                else % varIndex == -1
 317 
                    assert(false);
 318 
                end
 319 
            end
 320 
            
 321 
            subs1 = s(2).subs{1};
 322 
            haveLabelSubscripts = ~(isnumeric(subs1) || islogical(subs1) || isColon(subs1));
 323 
            if haveLabelSubscripts
 324 
                % The variable inherits row labels from the table, translate to row indices. The
 325 
                % assignment may add rows, get the updated rowDim object with any new row labels. 
 326 
                % subs2inds returns the indices as a col vector, which prevents reshaping. This
 327 
                % is fine because the var is constrained inside the table.
 328 
                [s(2).subs{1},~,~,~,~,updatedRowDim] = t.rowDim.subs2inds(subs1,subsType.assignment);
 329 
                % There are some linear indexing cases that should have row semantics, or that
 330 
                % are not even legal. In those cases s(2).subs{1} can't be interpreted as row
 331 
                % labels and so calling t.rowDim.subs2inds returns something completely
 332 
                % meaningless. Those cases will be identified and caught immediately below.
 333 
            else
 334 
                % t.rowDim.subs2inds will leave rowSubscripts alone in these cases, other than
 335 
                % making it a column, so avoid calling it for performance. Leave updateRowDim
 336 
                % empty, only need that in the row labels case.
 337 
                s(2).subs{1} = subs1(:);
 338 
            end
 339 
            
 340 
            if isscalar(s(2).subs) % linear indexing into the LHS
 341 
                % If the LHS is linear indexing, e.g. t.var(indices) = b or t.var{indices} = b,
 342 
                % and new elements will be created, there are cases where we need to force it to
 343 
                % grow as a column vector, because it would try to grow as a row vector.
 344 
                %
 345 
                % If the var is
 346 
                %    a scalar or a 0x0
 347 
                %    a new var (which is initialized to Nx0, including possibly 1x0)
 348 
                %    an Nx0 (N>1) or 0xM (M>1) empty matrix
 349 
                % add a column index so it grows as a column vector.
 350 
                if isscalar(var_j)
 351 
                    s(2).subs = [s(2).subs {1}];
 352 
                elseif iscolumn(var_j) % including 0x1
 353 
                    % If the var is already a column, linear indexing will have column semantics,
 354 
                    % leave the subscript alone. A scalar is a column, but need to force it to
 355 
                    % behave like one, so catch those above.
 356 
                elseif all(size(var_j)==0) || isNewVar
 357 
                    s(2).subs = [s(2).subs {1}];
 358 
                elseif ismatrix(var_j) && isempty(var_j) && ~isrow(var_j) % Nx0 or 0xM, excluding 1x0
 359 
                    % This case is analogous to what would happen in the workspace, except in table
 360 
                    % the assignment creates a column instead of a row.
 361 
                    s(2).subs = [s(2).subs {1}];
 362 
                    var_j = var_j(:); % make it a 0x1 column to be safe
 363 

 364 
                % By now var_j must be a row (possibly 1x0), a non-empty matrix, or an N-D array.
 365 
                elseif haveLabelSubscripts
 366 
                    % Numeric, logical, and colon subscripts have unambiguous meaning as in linear
 367 
                    % indexing regardless of the shape of the var being assigned into. But row
 368 
                    % labels have meaning only for column semantics, i.e. only if the var is already
 369 
                    % a column (including a 0x1), or if we've added a column index to force the
 370 
                    % result of the assignment to _become_ a column. Otherwise, linear indexing with
 371 
                    % row labels is an error.
 372 
                    error(message('MATLAB:table:InvalidLinearIndexing'));
 373 
                else
 374 
                    % If the var is a row, linear indexing has row semantics, let that happen.
 375 
                    % If the var is a non-empty matrix, or any N-D array, assignment using linear
 376 
                    % indexing is an ambiguous dimension error, let that happen at the actual
 377 
                    % assignment.
 378 
                end
 379 
            end
 380 
        end
 381 
        
 382 
        % Now let the variable's subsasgn handle the subscripting in
 383 
        % things like t.name(...) or  t.name{...} or t.name.attribute
 384 
        
 385 
        if length(s) == 2
 386 
            % If b is a built-in type, or the same class as var_j, call subsasgn directly
 387 
            % for fastest dispatch to var_j's (possibly overloaded) subscripting. Otherwise,
 388 
            % force dispatch to var_j's subscripting even when b is dominant. In most cases,
 389 
            % calling subsasgn via builtin guarantees dispatch on the first input. However,
 390 
            % if var_j is a table, builtin would dispatch to default, not overloaded,
 391 
            % subscripting, so use dot-method syntax.
 392 
            if isobject(b)
 393 
                if isa(var_j,class(b)) % var_j first is fast when it is built-in
 394 
                    var_j = subsasgn(var_j,s(2),b); % dispatches correctly, even to tabular
 395 
                elseif isa(var_j,'tabular')
 396 
                    var_j = move(var_j).subsasgn(s(2),b);
 397 
                else
 398 
                    var_j = builtin('subsasgn',var_j,s(2),b);
 399 
                end
 400 
            else
 401 
                % If the RHS of the assignment into the table was a literal [], and the LHS
 402 
                % target is t.Var or t.Var(...), that's already been recognized as subscripted
 403 
                % assignment deletion, and handled correctly. A RHS that is a 0x0 double but not
 404 
                % a literal [] should be treated as a genuine assignment, but the built-in
 405 
                % subsasgn called here treats that as deletion when the LHS is a built-in type
 406 
                % subscripted with (). Happily, assignment of any other empty double will have
 407 
                % the desired effect, so turn b into a 0x1. The same must be done for '' (which
 408 
                % "is equal" to []) to prevent it from deleting.
 409 
                if isequal(b,[]) && ~isobject(var_j) && isequal(s(2).type,'()')
 410 
                    % One exception: subscripted assignment deletion other than t.Var=[] or
 411 
                    % t.Var(...)=[], such as t.Var(i).Field(...)=[] or t.Var{i}(...)=[], ends up
 412 
                    % here for delegation to var_j, so don't replace a RHS that _is_ a literal [].
 413 
                    if ischar(b) || ~builtin('_isEmptySqrBrktLiteral',b), b = b(:); end
 414 
                end
 415 
                var_j = subsasgn(move(var_j),s(2),b);
 416 
            end
 417 
        else % length(s) > 2
 418 
            % Trick the third and higher levels of subscripting in things like
 419 
            % t.Var{i}(...) etc. into dispatching to the right place even when
 420 
            % t.Var{i}, or something further down the chain, is itself a table.
 421 
            if isequal(b,[]) && isequal(s(end).type,'()')
 422 
                if ischar(b) || ~builtin('_isEmptySqrBrktLiteral',b), b = b(:); end
 423 
            end
 424 
            var_j = matlab.internal.tabular.private.subsasgnRecurser(move(var_j),s(2:end),b);
 425 
        end
 426 
    end
 427 
    
 428 
    % If this is a new variable, make it official.
 429 
    if isNewVar
 430 
        t.varDim = updatedVarDim;
 431 
    end
 432 
    
 433 
    % If an entire var was replaced or created, the new value was required to have
 434 
    % the same number of rows as the table.  However, when assigning _into_ a new
 435 
    % var, the assignment might create something shorter than the table, so check
 436 
    % for that and tallen the new var to match the table. Also, assigning into an
 437 
    % existing var that is Nx0 using linear indexing will turn it into a col that
 438 
    % might be shorter, so tallen it to match the table, but don't warn since that's
 439 
    % an implementation artifact. (Assigning into an existing var that is 0xM using
 440 
    % linear indexing will also turn it into a col, but it can never be shorter.)
 441 
    % (Historically, a var could also get shorter by assigning a field to a
 442 
    % non-struct, or by assigning via a direct call to subsasgn into new elements of
 443 
    % _any_ matrix using linear indexing. Neither works that way now. Those would
 444 
    % have gotten fixed here too.)
 445 
    varLen = size(var_j,1);
 446 
    if varLen < t_nrows % t's original number of rows
 447 
        if isNewVar
 448 
            warning(message('MATLAB:table:RowsAddedNewVars'));
 449 
        end
 450 
        var_j = t.lengthenVar(var_j,t_nrows);
 451 
    end
 452 
    if varIndex > 0
 453 
        t.data{varIndex} = var_j;
 454 
    elseif varIndex == 0
 455 
        t.rowDim = t.rowDim.setLabels(var_j);
 456 
    else % varIndex == -1
 457 
        t = t.subsasgnBraces({':' ':'},var_j);
 458 
    end
 459 
    
 460 
    % If the var being assigned to is now taller than the table, add rows to
 461 
    % the rest of the table, including row labels.  This might be because the
 462 
    % assignment lengthened an existing var, or because an "into" assignment
 463 
    % created a new var taller than the table.  Warn only if we have to lengthen
 464 
    % existing vars that have not been assigned to -- if there's currently only
 465 
    % one var in the table (which might be existing or new), don't warn about
 466 
    % any default values "filled in in the middle".
 467 
    if varLen > t_nrows % t's original number of rows
 468 
        if t.varDim.length > 1 % some existing vars were not assigned to
 469 
            warning(message('MATLAB:table:RowsAddedExistingVars'));
 470 
        end
 471 
        if isempty(updatedRowDim)
 472 
            t.rowDim = t.rowDim.lengthenTo(varLen);
 473 
        else
 474 
            t.rowDim = updatedRowDim;
 475 
        end
 476 
        t = t.lengthenTo(varLen); % updates nrows
 477 
    end
 478 
end