@@ -52,7 +52,7 @@ import PostgREST.SchemaCache (SchemaCache (..))
52
52
import PostgREST.SchemaCache.Identifiers (FieldName ,
53
53
QualifiedIdentifier (.. ),
54
54
RelIdentifier (.. ),
55
- Schema )
55
+ Schema , dumpQi )
56
56
import PostgREST.SchemaCache.Relationship (Cardinality (.. ),
57
57
Junction (.. ),
58
58
Relationship (.. ),
@@ -152,14 +152,14 @@ dbActionPlan dbAct conf apiReq sCache = case dbAct of
152
152
153
153
wrappedReadPlan :: QualifiedIdentifier -> AppConfig -> SchemaCache -> ApiRequest -> Bool -> Either Error CrudPlan
154
154
wrappedReadPlan identifier conf sCache apiRequest@ ApiRequest {iPreferences= Preferences {.. },.. } headersOnly = do
155
- rPlan <- readPlan identifier conf sCache apiRequest
155
+ rPlan <- readPlan False identifier conf sCache apiRequest
156
156
(handler, mediaType) <- mapLeft ApiRequestError $ negotiateContent conf apiRequest identifier iAcceptMediaType (dbMediaHandlers sCache) (hasDefaultSelect rPlan)
157
157
if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right ()
158
158
return $ WrappedReadPlan rPlan SQL. Read handler mediaType headersOnly identifier
159
159
160
160
mutateReadPlan :: Mutation -> ApiRequest -> QualifiedIdentifier -> AppConfig -> SchemaCache -> Either Error CrudPlan
161
161
mutateReadPlan mutation apiRequest@ ApiRequest {iPreferences= Preferences {.. },.. } identifier conf sCache = do
162
- rPlan <- readPlan identifier conf sCache apiRequest
162
+ rPlan <- readPlan False identifier conf sCache apiRequest
163
163
mPlan <- mutatePlan mutation identifier apiRequest sCache rPlan
164
164
if not (null invalidPrefs) && preferHandling == Just Strict then Left $ ApiRequestError $ InvalidPreferences invalidPrefs else Right ()
165
165
(handler, mediaType) <- mapLeft ApiRequestError $ negotiateContent conf apiRequest identifier iAcceptMediaType (dbMediaHandlers sCache) (hasDefaultSelect rPlan)
@@ -173,7 +173,7 @@ callReadPlan identifier conf sCache apiRequest@ApiRequest{iPreferences=Preferenc
173
173
proc @ Function {.. } <- mapLeft ApiRequestError $
174
174
findProc identifier paramKeys (dbRoutines sCache) iContentMediaType (invMethod == Inv )
175
175
let relIdentifier = QualifiedIdentifier pdSchema (fromMaybe pdName $ Routine. funcTableName proc ) -- done so a set returning function can embed other relations
176
- rPlan <- readPlan relIdentifier conf sCache apiRequest
176
+ rPlan <- readPlan True relIdentifier conf sCache apiRequest
177
177
let args = case (invMethod, iContentMediaType) of
178
178
(InvRead _, _) -> DirectArgs $ toRpcParams proc qsParams'
179
179
(Inv , MTUrlEncoded ) -> DirectArgs $ maybe mempty (toRpcParams proc . payArray) iPayload
@@ -320,8 +320,8 @@ resolveQueryInputField ctx field = withTextParse ctx $ resolveTypeOrUnknown ctx
320
320
-- | Builds the ReadPlan tree on a number of stages.
321
321
-- | Adds filters, order, limits on its respective nodes.
322
322
-- | Adds joins conditions obtained from resource embedding.
323
- readPlan :: QualifiedIdentifier -> AppConfig -> SchemaCache -> ApiRequest -> Either Error ReadPlanTree
324
- readPlan qi@ QualifiedIdentifier {.. } AppConfig {configDbMaxRows, configDbAggregates} SchemaCache {dbTables, dbRelationships, dbRepresentations} apiRequest =
323
+ readPlan :: Bool -> QualifiedIdentifier -> AppConfig -> SchemaCache -> ApiRequest -> Either Error ReadPlanTree
324
+ readPlan fromCallPlan qi@ QualifiedIdentifier {.. } AppConfig {configDbMaxRows, configDbAggregates} SchemaCache {dbTables, dbRelationships, dbRepresentations} apiRequest =
325
325
let
326
326
-- JSON output format hardcoded for now. In the future we might want to support other output mappings such as CSV.
327
327
ctx = ResolverContext dbTables dbRepresentations qi " json"
@@ -340,7 +340,8 @@ readPlan qi@QualifiedIdentifier{..} AppConfig{configDbMaxRows, configDbAggregate
340
340
addLogicTrees ctx apiRequest =<<
341
341
addRanges apiRequest =<<
342
342
addOrders ctx apiRequest =<<
343
- addFilters ctx apiRequest (initReadRequest ctx $ QueryParams. qsSelect $ iQueryParams apiRequest)
343
+ addFilters ctx apiRequest =<<
344
+ searchTable fromCallPlan qi dbTables (initReadRequest ctx $ QueryParams. qsSelect $ iQueryParams apiRequest)
344
345
345
346
-- Build the initial read plan tree
346
347
initReadRequest :: ResolverContext -> [Tree SelectItem ] -> ReadPlanTree
@@ -738,6 +739,14 @@ validateAggFunctions aggFunctionsAllowed (Node rp@ReadPlan {select} forest)
738
739
| not aggFunctionsAllowed && any (isJust . csAggFunction) select = Left AggregatesNotAllowed
739
740
| otherwise = Node rp <$> traverse (validateAggFunctions aggFunctionsAllowed) forest
740
741
742
+ -- We only search for the table when readPlan is not called from call plan. This
743
+ -- is because we reuse readPlan in callReadPlan to search for function name
744
+ searchTable :: Bool -> QualifiedIdentifier -> TablesMap -> ReadPlanTree -> Either ApiRequestError ReadPlanTree
745
+ searchTable fromCallPlan qi tbls readPlanTree =
746
+ case (fromCallPlan, HM. lookup qi tbls) of
747
+ (False , Nothing ) -> Left (TableNotFound $ dumpQi qi)
748
+ _ -> Right readPlanTree
749
+
741
750
addFilters :: ResolverContext -> ApiRequest -> ReadPlanTree -> Either ApiRequestError ReadPlanTree
742
751
addFilters ctx ApiRequest {.. } rReq =
743
752
foldr addFilterToNode (Right rReq) flts
@@ -961,7 +970,7 @@ mutatePlan mutation qi ApiRequest{iPreferences=Preferences{..}, ..} SchemaCache{
961
970
typedColumnsOrError = resolveOrError ctx tbl `traverse` S. toList iColumns
962
971
963
972
resolveOrError :: ResolverContext -> Maybe Table -> FieldName -> Either ApiRequestError CoercibleField
964
- resolveOrError _ Nothing _ = Left NotFound
973
+ resolveOrError ResolverContext {qi} Nothing _ = Left $ TableNotFound $ dumpQi qi
965
974
resolveOrError ctx (Just table) field =
966
975
case resolveTableFieldName table field of
967
976
CoercibleField {cfIRType= " " } -> Left $ ColumnNotFound (tableName table) field
0 commit comments