@@ -428,6 +428,19 @@ func (p *ExecutionPlanner) compileSource(scope *PlanOpQuery, source parser.Sourc
428428			return  op , nil 
429429
430430		}
431+ 432+ 		// get any query hints 
433+ 		queryHints  :=  make ([]* TableQueryHint , 0 )
434+ 		for  _ , o  :=  range  sourceExpr .QueryOptions  {
435+ 			h  :=  & TableQueryHint {
436+ 				name : parser .IdentName (o .OptionName ),
437+ 			}
438+ 			for  _ , op  :=  range  o .OptionParams  {
439+ 				h .params  =  append (h .params , parser .IdentName (op ))
440+ 			}
441+ 			queryHints  =  append (queryHints , h )
442+ 		}
443+ 431444		// get all the columns for this table - we will eliminate unused ones 
432445		// later on in the optimizer 
433446		extractColumns  :=  make ([]string , 0 )
@@ -439,9 +452,9 @@ func (p *ExecutionPlanner) compileSource(scope *PlanOpQuery, source parser.Sourc
439452		if  sourceExpr .Alias  !=  nil  {
440453			aliasName  :=  parser .IdentName (sourceExpr .Alias )
441454
442- 			return  NewPlanOpRelAlias (aliasName , NewPlanOpPQLTableScan (p , tableName , extractColumns )), nil 
455+ 			return  NewPlanOpRelAlias (aliasName , NewPlanOpPQLTableScan (p , tableName , extractColumns ,  queryHints )), nil 
443456		}
444- 		return  NewPlanOpPQLTableScan (p , tableName , extractColumns ), nil 
457+ 		return  NewPlanOpPQLTableScan (p , tableName , extractColumns ,  queryHints ), nil 
445458
446459	case  * parser.TableValuedFunction :
447460		callExpr , err  :=  p .compileCallExpr (sourceExpr .Call )
@@ -557,6 +570,8 @@ func (p *ExecutionPlanner) analyzeSource(ctx context.Context, source parser.Sour
557570			return  paren , nil 
558571		}
559572
573+ 		// if we got to here, not a view, so do table stuff 
574+ 560575		// check table exists 
561576		tname  :=  dax .TableName (objectName )
562577		tbl , err  :=  p .schemaAPI .TableByName (ctx , tname )
@@ -578,6 +593,35 @@ func (p *ExecutionPlanner) analyzeSource(ctx context.Context, source parser.Sour
578593			source .OutputColumns  =  append (source .OutputColumns , soc )
579594		}
580595
596+ 		// check query hints 
597+ 		for  _ , o  :=  range  source .QueryOptions  {
598+ 			opt  :=  parser .IdentName (o .OptionName )
599+ 			switch  strings .ToLower (opt ) {
600+ 			case  "flatten" :
601+ 				// should have 1 param and should be a column name 
602+ 				if  len (o .OptionParams ) !=  1  {
603+ 					// error 
604+ 					return  nil , sql3 .NewErrInvalidQueryHintParameterCount (o .LParen .Column , o .LParen .Line , opt , "column name" , 1 , len (o .OptionParams ))
605+ 				}
606+ 				for  _ , op  :=  range  o .OptionParams  {
607+ 					param  :=  parser .IdentName (op )
608+ 					found  :=  false 
609+ 					for  _ , oc  :=  range  source .OutputColumns  {
610+ 						if  strings .EqualFold (param , oc .ColumnName ) {
611+ 							found  =  true 
612+ 							break 
613+ 						}
614+ 					}
615+ 					if  ! found  {
616+ 						return  nil , sql3 .NewErrColumnNotFound (op .NamePos .Line , op .NamePos .Column , param )
617+ 					}
618+ 				}
619+ 620+ 			default :
621+ 				return  nil , sql3 .NewErrUnknownQueryHint (o .OptionName .NamePos .Line , o .OptionName .NamePos .Column , opt )
622+ 			}
623+ 		}
624+ 581625		return  source , nil 
582626
583627	case  * parser.TableValuedFunction :
0 commit comments